github.com/mhilton/juju-juju@v0.0.0-20150901100907-a94dd2c73455/provider/azure/config_test.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package azure
     5  
     6  import (
     7  	"fmt"
     8  	"io/ioutil"
     9  	"regexp"
    10  	"strings"
    11  
    12  	jc "github.com/juju/testing/checkers"
    13  	"github.com/juju/utils"
    14  	gc "gopkg.in/check.v1"
    15  
    16  	"github.com/juju/juju/environs/config"
    17  	envtesting "github.com/juju/juju/environs/testing"
    18  	"github.com/juju/juju/testing"
    19  )
    20  
    21  type configSuite struct {
    22  	testing.BaseSuite
    23  }
    24  
    25  var _ = gc.Suite(&configSuite{})
    26  
    27  // makeConfigMap creates a minimal map of standard configuration items,
    28  // adds the given extra items to that and returns it.
    29  func makeConfigMap(extra map[string]interface{}) map[string]interface{} {
    30  	return testing.FakeConfig().Merge(testing.Attrs{
    31  		"name": "testenv",
    32  		"type": "azure",
    33  	}).Merge(extra)
    34  }
    35  
    36  var testCert = `
    37  -----BEGIN PRIVATE KEY-----
    38  MIIBCgIBADANBgkqhkiG9w0BAQEFAASB9TCB8gIBAAIxAKQGQxP1i0VfCWn4KmMP
    39  taUFn8sMBKjP/9vHnUYdZRvvmoJCA1C6arBUDp8s2DNX+QIDAQABAjBLRqhwN4dU
    40  LfqHDKJ/Vg1aD8u3Buv4gYRBxdFR5PveyqHSt5eJ4g/x/4ndsvr2OqUCGQDNfNlD
    41  zxHCiEAwZZAPaAkn8jDkFupTljcCGQDMWCujiVZ1NNuBD/N32Yt8P9JDiNzZa08C
    42  GBW7VXLxbExpgnhb1V97vjQmTfthXQjYAwIYSTEjoFXm4+Bk5xuBh2IidgSeGZaC
    43  FFY9AhkAsteo31cyQw2xJ80SWrmsIw+ps7Cvt5W9
    44  -----END PRIVATE KEY-----
    45  -----BEGIN CERTIFICATE-----
    46  MIIBDzCByqADAgECAgkAgIBb3+lSwzEwDQYJKoZIhvcNAQEFBQAwFTETMBEGA1UE
    47  AxQKQEhvc3ROYW1lQDAeFw0xMzA3MTkxNjA1NTRaFw0yMzA3MTcxNjA1NTRaMBUx
    48  EzARBgNVBAMUCkBIb3N0TmFtZUAwTDANBgkqhkiG9w0BAQEFAAM7ADA4AjEApAZD
    49  E/WLRV8JafgqYw+1pQWfywwEqM//28edRh1lG++agkIDULpqsFQOnyzYM1f5AgMB
    50  AAGjDTALMAkGA1UdEwQCMAAwDQYJKoZIhvcNAQEFBQADMQABKfn08tKfzzqMMD2w
    51  PI2fs3bw5bRH8tmGjrsJeEdp9crCBS8I3hKcxCkTTRTowdY=
    52  -----END CERTIFICATE-----
    53  `
    54  
    55  func makeAzureConfigMap(c *gc.C) map[string]interface{} {
    56  	azureConfig := map[string]interface{}{
    57  		"location":                   "location",
    58  		"management-subscription-id": "subscription-id",
    59  		"management-certificate":     testCert,
    60  		"storage-account-name":       "account-name",
    61  	}
    62  	return makeConfigMap(azureConfig)
    63  }
    64  
    65  // createTempFile creates a temporary file.  The file will be cleaned
    66  // up at the end of the test calling this method.
    67  func createTempFile(c *gc.C, content []byte) string {
    68  	file, err := ioutil.TempFile(c.MkDir(), "")
    69  	c.Assert(err, jc.ErrorIsNil)
    70  	filename := file.Name()
    71  	err = ioutil.WriteFile(filename, content, 0644)
    72  	c.Assert(err, jc.ErrorIsNil)
    73  	return filename
    74  }
    75  
    76  func (*configSuite) TestValidateAcceptsNilOldConfig(c *gc.C) {
    77  	attrs := makeAzureConfigMap(c)
    78  	provider := azureEnvironProvider{}
    79  	config, err := config.New(config.NoDefaults, attrs)
    80  	c.Assert(err, jc.ErrorIsNil)
    81  	result, err := provider.Validate(config, nil)
    82  	c.Assert(err, jc.ErrorIsNil)
    83  	c.Check(result.Name(), gc.Equals, attrs["name"])
    84  }
    85  
    86  func (*configSuite) TestValidateAcceptsUnchangedConfig(c *gc.C) {
    87  	attrs := makeAzureConfigMap(c)
    88  	provider := azureEnvironProvider{}
    89  	oldConfig, err := config.New(config.NoDefaults, attrs)
    90  	c.Assert(err, jc.ErrorIsNil)
    91  	newConfig, err := config.New(config.NoDefaults, attrs)
    92  	c.Assert(err, jc.ErrorIsNil)
    93  	result, err := provider.Validate(newConfig, oldConfig)
    94  	c.Assert(err, jc.ErrorIsNil)
    95  	c.Check(result.Name(), gc.Equals, attrs["name"])
    96  }
    97  
    98  func (*configSuite) TestValidateChecksConfigChanges(c *gc.C) {
    99  	provider := azureEnvironProvider{}
   100  	oldConfig, err := config.New(config.NoDefaults, makeConfigMap(nil))
   101  	c.Assert(err, jc.ErrorIsNil)
   102  	newAttrs := makeConfigMap(map[string]interface{}{
   103  		"name": "different-name",
   104  	})
   105  	newConfig, err := config.New(config.NoDefaults, newAttrs)
   106  	c.Assert(err, jc.ErrorIsNil)
   107  	_, err = provider.Validate(newConfig, oldConfig)
   108  	c.Check(err, gc.NotNil)
   109  }
   110  
   111  func (*configSuite) TestValidateParsesAzureConfig(c *gc.C) {
   112  	location := "location"
   113  	managementSubscriptionId := "subscription-id"
   114  	certificate := testCert
   115  	storageAccountName := "account-name"
   116  	forceImageName := "force-image-name"
   117  	unknownFutureSetting := "preserved"
   118  	azureConfig := map[string]interface{}{
   119  		"location":                   location,
   120  		"management-subscription-id": managementSubscriptionId,
   121  		"management-certificate":     certificate,
   122  		"storage-account-name":       storageAccountName,
   123  		"force-image-name":           forceImageName,
   124  		"unknown-future-setting":     unknownFutureSetting,
   125  	}
   126  	attrs := makeConfigMap(azureConfig)
   127  	provider := azureEnvironProvider{}
   128  	config, err := config.New(config.NoDefaults, attrs)
   129  	c.Assert(err, jc.ErrorIsNil)
   130  	azConfig, err := provider.newConfig(config)
   131  	c.Assert(err, jc.ErrorIsNil)
   132  	c.Check(azConfig.Name(), gc.Equals, attrs["name"])
   133  	c.Check(azConfig.location(), gc.Equals, location)
   134  	c.Check(azConfig.managementSubscriptionId(), gc.Equals, managementSubscriptionId)
   135  	c.Check(azConfig.managementCertificate(), gc.Equals, certificate)
   136  	c.Check(azConfig.storageAccountName(), gc.Equals, storageAccountName)
   137  	c.Check(azConfig.forceImageName(), gc.Equals, forceImageName)
   138  	c.Check(azConfig.UnknownAttrs()["unknown-future-setting"], gc.Equals, unknownFutureSetting)
   139  }
   140  
   141  func (*configSuite) TestValidateVerifiesCertFileContents(c *gc.C) {
   142  	certFile := createTempFile(c, []byte("definitely not PEM"))
   143  	attrs := makeAzureConfigMap(c)
   144  	delete(attrs, "management-certificate")
   145  	attrs["management-certificate-path"] = certFile
   146  	provider := azureEnvironProvider{}
   147  	newConfig, err := config.New(config.NoDefaults, attrs)
   148  	c.Assert(err, jc.ErrorIsNil)
   149  	_, err = provider.newConfig(newConfig)
   150  	c.Assert(err, gc.ErrorMatches, fmt.Sprintf("invalid management-certificate-path: %q is not a PEM encoded certificate file", regexp.QuoteMeta(certFile)))
   151  }
   152  
   153  func (*configSuite) TestValidateVerifiesCertContents(c *gc.C) {
   154  	attrs := makeAzureConfigMap(c)
   155  	attrs["management-certificate"] = "definitely not PEM"
   156  	provider := azureEnvironProvider{}
   157  	newConfig, err := config.New(config.NoDefaults, attrs)
   158  	c.Assert(err, jc.ErrorIsNil)
   159  	_, err = provider.newConfig(newConfig)
   160  	c.Assert(err, gc.ErrorMatches, fmt.Sprintf("invalid management-certificate: not a PEM encoded certificate"))
   161  }
   162  
   163  func (*configSuite) TestValidateReadsCertFile(c *gc.C) {
   164  	certFile := createTempFile(c, []byte(testCert))
   165  	attrs := makeAzureConfigMap(c)
   166  	delete(attrs, "management-certificate")
   167  	attrs["management-certificate-path"] = certFile
   168  	provider := azureEnvironProvider{}
   169  	newConfig, err := config.New(config.NoDefaults, attrs)
   170  	c.Assert(err, jc.ErrorIsNil)
   171  	azConfig, err := provider.newConfig(newConfig)
   172  	c.Assert(err, jc.ErrorIsNil)
   173  	c.Check(azConfig.managementCertificate(), gc.Equals, testCert)
   174  }
   175  
   176  func (*configSuite) TestChecksExistingCertFile(c *gc.C) {
   177  	nonExistingCertPath := "non-existing-cert-file"
   178  	attrs := makeAzureConfigMap(c)
   179  	delete(attrs, "management-certificate")
   180  	attrs["management-certificate-path"] = nonExistingCertPath
   181  	provider := azureEnvironProvider{}
   182  	newConfig, err := config.New(config.NoDefaults, attrs)
   183  	c.Assert(err, jc.ErrorIsNil)
   184  	_, err = provider.Validate(newConfig, nil)
   185  	c.Check(err, gc.ErrorMatches, ".*"+nonExistingCertPath+": "+utils.NoSuchFileErrRegexp)
   186  }
   187  
   188  func (*configSuite) TestChecksLocationIsRequired(c *gc.C) {
   189  	attrs := makeAzureConfigMap(c)
   190  	attrs["location"] = ""
   191  	provider := azureEnvironProvider{}
   192  	newConfig, err := config.New(config.NoDefaults, attrs)
   193  	c.Assert(err, jc.ErrorIsNil)
   194  	_, err = provider.Validate(newConfig, nil)
   195  	c.Check(err, gc.ErrorMatches, ".*environment has no location.*")
   196  }
   197  
   198  func (*configSuite) TestBoilerplateConfigReturnsAzureConfig(c *gc.C) {
   199  	provider := azureEnvironProvider{}
   200  	boilerPlateConfig := provider.BoilerplateConfig()
   201  	c.Assert(strings.Contains(boilerPlateConfig, "type: azure"), jc.IsTrue)
   202  }
   203  
   204  func (*configSuite) TestSecretAttrsReturnsSensitiveAttributes(c *gc.C) {
   205  	attrs := makeAzureConfigMap(c)
   206  	attrs["management-certificate"] = testCert
   207  	config, err := config.New(config.NoDefaults, attrs)
   208  	c.Assert(err, jc.ErrorIsNil)
   209  
   210  	provider := azureEnvironProvider{}
   211  	secretAttrs, err := provider.SecretAttrs(config)
   212  	c.Assert(err, jc.ErrorIsNil)
   213  
   214  	expectedAttrs := map[string]string{
   215  		"management-certificate": testCert,
   216  	}
   217  	c.Check(secretAttrs, gc.DeepEquals, expectedAttrs)
   218  }
   219  
   220  func (*configSuite) TestEmptyImageStream1dot16Compat(c *gc.C) {
   221  	attrs := makeAzureConfigMap(c)
   222  	attrs["image-stream"] = ""
   223  	provider := azureEnvironProvider{}
   224  	cfg, err := config.New(config.UseDefaults, attrs)
   225  	c.Assert(err, jc.ErrorIsNil)
   226  	_, err = provider.Validate(cfg, nil)
   227  	c.Assert(err, jc.ErrorIsNil)
   228  }
   229  
   230  func (s *configSuite) TestAvailabilitySetsEnabledDefault(c *gc.C) {
   231  	s.PatchValue(&verifyCredentials, func(*azureEnviron) error {
   232  		return nil
   233  	})
   234  	userValues := []interface{}{nil, false, true}
   235  	for _, userValue := range userValues {
   236  		attrs := makeAzureConfigMap(c)
   237  		// If availability-sets-enabled isn't specified, it's set to true.
   238  		checker := jc.IsTrue
   239  		if userValue, ok := userValue.(bool); ok {
   240  			attrs["availability-sets-enabled"] = userValue
   241  			if !userValue {
   242  				checker = jc.IsFalse
   243  			}
   244  		}
   245  		cfg, err := config.New(config.UseDefaults, attrs)
   246  		c.Assert(err, jc.ErrorIsNil)
   247  		env, err := azureEnvironProvider{}.PrepareForBootstrap(envtesting.BootstrapContext(c), cfg)
   248  		c.Assert(err, jc.ErrorIsNil)
   249  		azureEnv := env.(*azureEnviron)
   250  		c.Assert(azureEnv.ecfg.availabilitySetsEnabled(), checker)
   251  	}
   252  }
   253  
   254  func (s *configSuite) TestAvailabilitySetsEnabledImmutable(c *gc.C) {
   255  	s.PatchValue(&verifyCredentials, func(*azureEnviron) error {
   256  		return nil
   257  	})
   258  	cfg, err := config.New(config.UseDefaults, makeAzureConfigMap(c))
   259  	c.Assert(err, jc.ErrorIsNil)
   260  	env, err := azureEnvironProvider{}.PrepareForBootstrap(envtesting.BootstrapContext(c), cfg)
   261  	c.Assert(err, jc.ErrorIsNil)
   262  	cfg, err = env.Config().Apply(map[string]interface{}{"availability-sets-enabled": false})
   263  	c.Assert(err, jc.ErrorIsNil)
   264  	err = env.SetConfig(cfg)
   265  	c.Assert(err, gc.ErrorMatches, "cannot change availability-sets-enabled")
   266  }