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