github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/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.v3/aws"
    17  	gc "gopkg.in/check.v1"
    18  
    19  	"github.com/juju/juju/cloud"
    20  	"github.com/juju/juju/environs"
    21  	"github.com/juju/juju/environs/config"
    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 testAuth = aws.Auth{
    35  	AccessKey: "gopher",
    36  	SecretKey: "long teeth",
    37  }
    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  	vpcID              string
    48  	forceVPCID         bool
    49  	firewallMode       string
    50  	blockStorageSource string
    51  	err                string
    52  }
    53  
    54  type attrs map[string]interface{}
    55  
    56  func (t configTest) check(c *gc.C) {
    57  	credential := cloud.NewCredential(
    58  		cloud.AccessKeyAuthType,
    59  		map[string]string{
    60  			"access-key": "x",
    61  			"secret-key": "y",
    62  		},
    63  	)
    64  	cloudSpec := environs.CloudSpec{
    65  		Type:       "ec2",
    66  		Name:       "ec2test",
    67  		Region:     "us-east-1",
    68  		Credential: &credential,
    69  	}
    70  	attrs := testing.FakeConfig().Merge(testing.Attrs{
    71  		"type": "ec2",
    72  	}).Merge(t.config)
    73  	cfg, err := config.New(config.NoDefaults, attrs)
    74  	c.Assert(err, jc.ErrorIsNil)
    75  	e, err := environs.New(environs.OpenParams{
    76  		Cloud:  cloudSpec,
    77  		Config: cfg,
    78  	})
    79  	if t.change != nil {
    80  		c.Assert(err, jc.ErrorIsNil)
    81  
    82  		// Testing a change in configuration.
    83  		var old, changed, valid *config.Config
    84  		ec2env := e.(*environ)
    85  		old = ec2env.ecfg().Config
    86  		changed, err = old.Apply(t.change)
    87  		c.Assert(err, jc.ErrorIsNil)
    88  
    89  		// Keep err for validation below.
    90  		valid, err = providerInstance.Validate(changed, old)
    91  		if err == nil {
    92  			err = ec2env.SetConfig(valid)
    93  		}
    94  	}
    95  	if t.err != "" {
    96  		c.Check(err, gc.ErrorMatches, t.err)
    97  		return
    98  	}
    99  	c.Assert(err, jc.ErrorIsNil)
   100  
   101  	ecfg := e.(*environ).ecfg()
   102  	c.Assert(ecfg.Name(), gc.Equals, "testenv")
   103  	c.Assert(ecfg.vpcID(), gc.Equals, t.vpcID)
   104  	c.Assert(ecfg.forceVPCID(), gc.Equals, t.forceVPCID)
   105  
   106  	if t.firewallMode != "" {
   107  		c.Assert(ecfg.FirewallMode(), gc.Equals, t.firewallMode)
   108  	}
   109  	for name, expect := range t.expect {
   110  		actual, found := ecfg.UnknownAttrs()[name]
   111  		c.Check(found, jc.IsTrue)
   112  		c.Check(actual, gc.Equals, expect)
   113  	}
   114  }
   115  
   116  var configTests = []configTest{
   117  	{
   118  		config: attrs{},
   119  	}, {
   120  		config:     attrs{},
   121  		vpcID:      "",
   122  		forceVPCID: false,
   123  	}, {
   124  		config: attrs{
   125  			"vpc-id": "invalid",
   126  		},
   127  		err:        `.*vpc-id: "invalid" is not a valid AWS VPC ID`,
   128  		vpcID:      "",
   129  		forceVPCID: false,
   130  	}, {
   131  		config: attrs{
   132  			"vpc-id": vpcIDNone,
   133  		},
   134  		vpcID:      "none",
   135  		forceVPCID: false,
   136  	}, {
   137  		config: attrs{
   138  			"vpc-id": 42,
   139  		},
   140  		err:        `.*expected string, got int\(42\)`,
   141  		vpcID:      "",
   142  		forceVPCID: false,
   143  	}, {
   144  		config: attrs{
   145  			"vpc-id-force": "nonsense",
   146  		},
   147  		err:        `.*expected bool, got string\("nonsense"\)`,
   148  		vpcID:      "",
   149  		forceVPCID: false,
   150  	}, {
   151  		config: attrs{
   152  			"vpc-id":       "vpc-anything",
   153  			"vpc-id-force": 999,
   154  		},
   155  		err:        `.*expected bool, got int\(999\)`,
   156  		vpcID:      "",
   157  		forceVPCID: false,
   158  	}, {
   159  		config: attrs{
   160  			"vpc-id":       "",
   161  			"vpc-id-force": true,
   162  		},
   163  		err:        `.*cannot use vpc-id-force without specifying vpc-id as well`,
   164  		vpcID:      "",
   165  		forceVPCID: true,
   166  	}, {
   167  		config: attrs{
   168  			"vpc-id": "vpc-a1b2c3d4",
   169  		},
   170  		vpcID:      "vpc-a1b2c3d4",
   171  		forceVPCID: false,
   172  	}, {
   173  		config: attrs{
   174  			"vpc-id":       "vpc-some-id",
   175  			"vpc-id-force": true,
   176  		},
   177  		vpcID:      "vpc-some-id",
   178  		forceVPCID: true,
   179  	}, {
   180  		config: attrs{
   181  			"vpc-id":       "vpc-abcd",
   182  			"vpc-id-force": false,
   183  		},
   184  		vpcID:      "vpc-abcd",
   185  		forceVPCID: false,
   186  	}, {
   187  		config: attrs{
   188  			"vpc-id":       "vpc-unchanged",
   189  			"vpc-id-force": true,
   190  		},
   191  		change: attrs{
   192  			"vpc-id":       "vpc-unchanged",
   193  			"vpc-id-force": false,
   194  		},
   195  		err:        `.*cannot change vpc-id-force from true to false`,
   196  		vpcID:      "vpc-unchanged",
   197  		forceVPCID: true,
   198  	}, {
   199  		config: attrs{
   200  			"vpc-id": "",
   201  		},
   202  		change: attrs{
   203  			"vpc-id": "none",
   204  		},
   205  		err:        `.*cannot change vpc-id from "" to "none"`,
   206  		vpcID:      "",
   207  		forceVPCID: false,
   208  	}, {
   209  		config: attrs{
   210  			"vpc-id": "",
   211  		},
   212  		change: attrs{
   213  			"vpc-id": "vpc-changed",
   214  		},
   215  		err:        `.*cannot change vpc-id from "" to "vpc-changed"`,
   216  		vpcID:      "",
   217  		forceVPCID: false,
   218  	}, {
   219  		config: attrs{
   220  			"vpc-id": "vpc-initial",
   221  		},
   222  		change: attrs{
   223  			"vpc-id": "",
   224  		},
   225  		err:        `.*cannot change vpc-id from "vpc-initial" to ""`,
   226  		vpcID:      "vpc-initial",
   227  		forceVPCID: false,
   228  	}, {
   229  		config: attrs{
   230  			"vpc-id": "vpc-old",
   231  		},
   232  		change: attrs{
   233  			"vpc-id": "vpc-new",
   234  		},
   235  		err:        `.*cannot change vpc-id from "vpc-old" to "vpc-new"`,
   236  		vpcID:      "vpc-old",
   237  		forceVPCID: false,
   238  	}, {
   239  		config: attrs{
   240  			"vpc-id":       "vpc-foo",
   241  			"vpc-id-force": true,
   242  		},
   243  		change:     attrs{},
   244  		vpcID:      "vpc-foo",
   245  		forceVPCID: true,
   246  	}, {
   247  		config:       attrs{},
   248  		firewallMode: config.FwInstance,
   249  	}, {
   250  		config:             attrs{},
   251  		blockStorageSource: "ebs",
   252  	}, {
   253  		config: attrs{
   254  			"storage-default-block-source": "ebs-fast",
   255  		},
   256  		blockStorageSource: "ebs-fast",
   257  	}, {
   258  		config: attrs{
   259  			"firewall-mode": "instance",
   260  		},
   261  		firewallMode: config.FwInstance,
   262  	}, {
   263  		config: attrs{
   264  			"firewall-mode": "global",
   265  		},
   266  		firewallMode: config.FwGlobal,
   267  	}, {
   268  		config: attrs{
   269  			"firewall-mode": "none",
   270  		},
   271  		firewallMode: config.FwNone,
   272  	}, {
   273  		config: attrs{
   274  			"ssl-hostname-verification": false,
   275  		},
   276  		err: ".*disabling ssh-hostname-verification is not supported",
   277  	}, {
   278  		config: attrs{
   279  			"future": "hammerstein",
   280  		},
   281  		expect: attrs{
   282  			"future": "hammerstein",
   283  		},
   284  	}, {
   285  		change: attrs{
   286  			"future": "hammerstein",
   287  		},
   288  		expect: attrs{
   289  			"future": "hammerstein",
   290  		},
   291  	},
   292  }
   293  
   294  func indent(s string, with string) string {
   295  	var r string
   296  	lines := strings.Split(s, "\n")
   297  	for _, l := range lines {
   298  		r += with + l + "\n"
   299  	}
   300  	return r
   301  }
   302  
   303  func (s *ConfigSuite) SetUpTest(c *gc.C) {
   304  	s.BaseSuite.SetUpTest(c)
   305  	s.savedHome = utils.Home()
   306  
   307  	home := c.MkDir()
   308  	sshDir := filepath.Join(home, ".ssh")
   309  	err := os.Mkdir(sshDir, 0777)
   310  	c.Assert(err, jc.ErrorIsNil)
   311  	err = ioutil.WriteFile(filepath.Join(sshDir, "id_rsa.pub"), []byte("sshkey\n"), 0666)
   312  	c.Assert(err, jc.ErrorIsNil)
   313  
   314  	err = utils.SetHome(home)
   315  	c.Assert(err, jc.ErrorIsNil)
   316  }
   317  
   318  func (s *ConfigSuite) TearDownTest(c *gc.C) {
   319  	err := utils.SetHome(s.savedHome)
   320  	c.Assert(err, jc.ErrorIsNil)
   321  	s.BaseSuite.TearDownTest(c)
   322  }
   323  
   324  func (s *ConfigSuite) TestConfig(c *gc.C) {
   325  	for i, t := range configTests {
   326  		c.Logf("test %d: %v", i, t.config)
   327  		t.check(c)
   328  	}
   329  }
   330  
   331  func (s *ConfigSuite) TestPrepareConfigSetsDefaultBlockSource(c *gc.C) {
   332  	s.PatchValue(&verifyCredentials, func(*environ) error { return nil })
   333  	attrs := testing.FakeConfig().Merge(testing.Attrs{
   334  		"type": "ec2",
   335  	})
   336  	cfg, err := config.New(config.NoDefaults, attrs)
   337  	c.Assert(err, jc.ErrorIsNil)
   338  
   339  	credential := cloud.NewCredential(
   340  		cloud.AccessKeyAuthType,
   341  		map[string]string{
   342  			"access-key": "x",
   343  			"secret-key": "y",
   344  		},
   345  	)
   346  	cfg, err = providerInstance.PrepareConfig(environs.PrepareConfigParams{
   347  		Config: cfg,
   348  		Cloud: environs.CloudSpec{
   349  			Type:       "ec2",
   350  			Name:       "aws",
   351  			Region:     "test",
   352  			Credential: &credential,
   353  		},
   354  	})
   355  	c.Assert(err, jc.ErrorIsNil)
   356  	source, ok := cfg.StorageDefaultBlockSource()
   357  	c.Assert(ok, jc.IsTrue)
   358  	c.Assert(source, gc.Equals, "ebs")
   359  }
   360  
   361  func (s *ConfigSuite) TestPrepareSetsDefaultBlockSource(c *gc.C) {
   362  	s.PatchValue(&verifyCredentials, func(*environ) error { return nil })
   363  	attrs := testing.FakeConfig().Merge(testing.Attrs{
   364  		"type": "ec2",
   365  	})
   366  	config, err := config.New(config.NoDefaults, attrs)
   367  	c.Assert(err, jc.ErrorIsNil)
   368  
   369  	credential := cloud.NewCredential(
   370  		cloud.AccessKeyAuthType,
   371  		map[string]string{
   372  			"access-key": "x",
   373  			"secret-key": "y",
   374  		},
   375  	)
   376  	cfg, err := providerInstance.PrepareConfig(environs.PrepareConfigParams{
   377  		Config: config,
   378  		Cloud: environs.CloudSpec{
   379  			Type:       "ec2",
   380  			Name:       "aws",
   381  			Region:     "test",
   382  			Credential: &credential,
   383  		},
   384  	})
   385  	c.Assert(err, jc.ErrorIsNil)
   386  
   387  	source, ok := cfg.StorageDefaultBlockSource()
   388  	c.Assert(ok, jc.IsTrue)
   389  	c.Assert(source, gc.Equals, "ebs")
   390  }
   391  
   392  func (*ConfigSuite) TestSchema(c *gc.C) {
   393  	fields := providerInstance.Schema()
   394  	// Check that all the fields defined in environs/config
   395  	// are in the returned schema.
   396  	globalFields, err := config.Schema(nil)
   397  	c.Assert(err, gc.IsNil)
   398  	for name, field := range globalFields {
   399  		c.Check(fields[name], jc.DeepEquals, field)
   400  	}
   401  }