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 }