github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/cloudconfig/machinecloudconfig_test.go (about) 1 package cloudconfig_test 2 3 import ( 4 "io/ioutil" 5 "os" 6 "path" 7 8 "github.com/juju/errors" 9 "github.com/juju/loggo" 10 utilsseries "github.com/juju/os/series" 11 gc "gopkg.in/check.v1" 12 13 "github.com/juju/juju/cloudconfig" 14 "github.com/juju/juju/testing" 15 ) 16 17 type fromHostSuite struct { 18 testing.BaseSuite 19 20 tempCloudCfgDir string 21 tempCloudInitDir string 22 } 23 24 var _ = gc.Suite(&fromHostSuite{}) 25 26 func (s *fromHostSuite) SetUpSuite(c *gc.C) { 27 s.BaseSuite.SetUpSuite(c) 28 29 // Pre-seed /etc/cloud/cloud.cfg.d replacement for testing 30 s.tempCloudCfgDir = c.MkDir() // will clean up 31 ioutil.WriteFile(path.Join(s.tempCloudCfgDir, "90_dpkg_local_cloud_config.cfg"), []byte(dpkgLocalCloudConfig078), 0644) 32 ioutil.WriteFile(path.Join(s.tempCloudCfgDir, "50-curtin-networking.cfg"), []byte(curtinNetworking), 0644) 33 ioutil.WriteFile(path.Join(s.tempCloudCfgDir, "10_random.cfg"), []byte(otherConfig), 0644) 34 ioutil.WriteFile(path.Join(s.tempCloudCfgDir, "Readme"), []byte(readmeFile), 0644) 35 36 // Pre-seed /var/lib/cloud/instance replacement for testing 37 s.tempCloudInitDir = c.MkDir() 38 ioutil.WriteFile(path.Join(s.tempCloudInitDir, "vendor-data.txt"), []byte(vendorData), 0644) 39 } 40 41 func (s *fromHostSuite) SetUpTest(c *gc.C) { 42 s.PatchValue(&cloudconfig.CloudInitCfgDir, func(_ string) (string, error) { return s.tempCloudCfgDir, nil }) 43 s.PatchValue(&cloudconfig.MachineCloudInitDir, func(string) (string, error) { return s.tempCloudInitDir, nil }) 44 s.PatchValue(&utilsseries.MustHostSeries, func() string { return "xenial" }) 45 } 46 47 func (s *fromHostSuite) TestGetMachineCloudInitData(c *gc.C) { 48 obtained, err := cloudconfig.GetMachineCloudInitData("xenial") 49 c.Assert(err, gc.IsNil) 50 c.Assert(obtained, gc.DeepEquals, expectedResult078) 51 } 52 53 type cloudinitDataVerifyTest struct { 54 description string 55 machineSeries string 56 containerSeries string 57 err string 58 result map[string]interface{} 59 } 60 61 var cloudinitDataVerifyTests = []cloudinitDataVerifyTest{ 62 { 63 description: "xenial on xenial", 64 machineSeries: "xenial", 65 containerSeries: "xenial", 66 result: expectedResult078, 67 }, 68 { 69 description: "trusty on trusty", 70 machineSeries: "trusty", 71 containerSeries: "trusty", 72 result: expectedResult078, 73 }, 74 { 75 description: "xenial on trusty", 76 machineSeries: "trusty", 77 containerSeries: "xenial", 78 }, 79 { 80 description: "opensuseleap on opensuseleap", 81 machineSeries: "opensuseleap", 82 containerSeries: "opensuseleap", 83 result: expectedResult078, 84 }, 85 { 86 description: "centos7 on centos7", 87 machineSeries: "centos7", 88 containerSeries: "centos7", 89 result: expectedResult078, 90 }, 91 { 92 description: "win2012 on win2012", 93 machineSeries: "win2012", 94 containerSeries: "win2012", 95 }, 96 { 97 description: "highsierra on highsierra", 98 machineSeries: "highsierra", 99 containerSeries: "highsierra", 100 }, 101 } 102 103 func (s *fromHostSuite) TestGetMachineCloudInitDataVerifySeries(c *gc.C) { 104 for i, test := range cloudinitDataVerifyTests { 105 c.Logf("Test %d of %d: %s", i, len(cloudinitDataVerifyTests), test.description) 106 s.PatchValue(&utilsseries.MustHostSeries, func() string { return test.machineSeries }) 107 obtained, err := cloudconfig.GetMachineCloudInitData(test.containerSeries) 108 c.Assert(err, gc.IsNil) 109 if test.result != nil { 110 c.Assert(obtained, gc.DeepEquals, expectedResult078) 111 } else { 112 c.Assert(obtained, gc.IsNil) 113 } 114 } 115 } 116 117 func (s *fromHostSuite) TestMissingVendorDataFile(c *gc.C) { 118 dir := c.MkDir() 119 s.PatchValue(&cloudconfig.MachineCloudInitDir, func(string) (string, error) { return dir, nil }) 120 obtained, err := cloudconfig.GetMachineData("xenial", "vendor-data.txt") 121 c.Assert(err, gc.ErrorMatches, "cannot read \"vendor-data.txt\" from machine.*") 122 c.Assert(obtained, gc.IsNil) 123 } 124 125 func (s *fromHostSuite) TestMissingVendorDataFileTrusty(c *gc.C) { 126 ioutil.WriteFile(path.Join(s.tempCloudInitDir, "vendor-data.txt"), []byte(vendorDataTrusty), 0644) 127 obtained, err := cloudconfig.GetMachineData("trusty", "vendor-data.txt") 128 c.Assert(err, gc.IsNil) 129 c.Assert(obtained, gc.IsNil) 130 } 131 132 func (s *fromHostSuite) TestGetMachineCloudCfgDirDataReadDirFailed(c *gc.C) { 133 dir := c.MkDir() 134 os.RemoveAll(dir) 135 s.PatchValue(&cloudconfig.CloudInitCfgDir, func(string) (string, error) { return dir, nil }) 136 obtained, err := cloudconfig.GetMachineCloudCfgDirData("xenial") 137 c.Assert(err, gc.ErrorMatches, "cannot determine files in CloudInitCfgDir for the machine: .* no such file or directory") 138 c.Assert(obtained, gc.IsNil) 139 } 140 141 func (s *fromHostSuite) TestGetMachineCloudCfgDirDataReadDirNotFound(c *gc.C) { 142 s.PatchValue(&cloudconfig.CloudInitCfgDir, func(string) (string, error) { return "", errors.New("test failure") }) 143 obtained, err := cloudconfig.GetMachineCloudCfgDirData("xenial") 144 c.Assert(err, gc.ErrorMatches, "cannot determine CloudInitCfgDir for the machine: test failure") 145 c.Assert(obtained, gc.IsNil) 146 } 147 148 func (s *fromHostSuite) TestGetMachineDataReadDirNotFound(c *gc.C) { 149 s.PatchValue(&cloudconfig.MachineCloudInitDir, func(string) (string, error) { return "", errors.New("test failure") }) 150 obtained, err := cloudconfig.GetMachineData("xenial", "") 151 c.Assert(err, gc.ErrorMatches, "cannot determine MachineCloudInitDir for the machine: test failure") 152 c.Assert(obtained, gc.IsNil) 153 } 154 155 func (s *fromHostSuite) TestCloudConfigVersionV078(c *gc.C) { 156 obtained, err := cloudconfig.GetMachineCloudInitData("xenial") 157 c.Assert(err, gc.IsNil) 158 c.Assert(obtained, gc.DeepEquals, expectedResult078) 159 160 resultMap := cloudconfig.CloudConfigByVersionFunc("xenial")("apt-primary,ca-certs,apt-security", obtained, 161 loggo.GetLogger("juju.machinecloudconfig")) 162 c.Assert(resultMap, gc.DeepEquals, 163 map[string]interface{}{ 164 "apt": map[string]interface{}{ 165 "primary": []interface{}{ 166 map[interface{}]interface{}{ 167 "arches": []interface{}{"default"}, 168 "uri": "http://archive.ubuntu.com/ubuntu", 169 }, 170 }, 171 "security": []interface{}{ 172 map[interface{}]interface{}{ 173 "arches": []interface{}{"default"}, 174 "uri": "http://archive.ubuntu.com/ubuntu", 175 }, 176 }, 177 }, 178 "ca-certs": map[interface{}]interface{}{ 179 "remove-defaults": true, 180 "trusted": []interface{}{"-----BEGIN CERTIFICATE-----\nYOUR-ORGS-TRUSTED-CA-CERT-HERE\n-----END CERTIFICATE-----\n"}, 181 }, 182 }) 183 } 184 185 func (s *fromHostSuite) TestCloudConfigVersionNoContainerInheritPropertiesV078(c *gc.C) { 186 resultMap := cloudconfig.CloudConfigByVersionFunc("xenial")("", nil, loggo.GetLogger("juju.machinecloudconfig")) 187 c.Assert(resultMap, gc.IsNil) 188 } 189 190 func (s *fromHostSuite) TestCloudConfigVersionV077(c *gc.C) { 191 s.PatchValue(&utilsseries.MustHostSeries, func() string { return "trusty" }) 192 obtained, err := cloudconfig.GetMachineCloudInitData("trusty") 193 c.Assert(err, gc.IsNil) 194 c.Assert(obtained, gc.DeepEquals, expectedResult078) 195 196 resultMap := cloudconfig.CloudConfigByVersionFunc("xenial")("apt-primary,ca-certs,apt-security", obtained, 197 loggo.GetLogger("juju.machinecloudconfig")) 198 c.Assert(resultMap, gc.DeepEquals, 199 map[string]interface{}{ 200 "apt": map[string]interface{}{ 201 "primary": []interface{}{ 202 map[interface{}]interface{}{ 203 "arches": []interface{}{"default"}, 204 "uri": "http://archive.ubuntu.com/ubuntu", 205 }, 206 }, 207 "security": []interface{}{ 208 map[interface{}]interface{}{ 209 "arches": []interface{}{"default"}, 210 "uri": "http://archive.ubuntu.com/ubuntu", 211 }, 212 }, 213 }, 214 "ca-certs": map[interface{}]interface{}{ 215 "remove-defaults": true, 216 "trusted": []interface{}{"-----BEGIN CERTIFICATE-----\nYOUR-ORGS-TRUSTED-CA-CERT-HERE\n-----END CERTIFICATE-----\n"}, 217 }, 218 }) 219 } 220 221 func (s *fromHostSuite) TestCloudConfigVersionNoContainerInheritPropertiesV077(c *gc.C) { 222 resultMap := cloudconfig.CloudConfigByVersionFunc("trusty")("", nil, loggo.GetLogger("juju.machinecloudconfig")) 223 c.Assert(resultMap, gc.IsNil) 224 } 225 226 var dpkgLocalCloudConfig077 = ` 227 # cloud-init/local-cloud-config 228 apt_mirror: http://archive.ubuntu.com/ubuntu 229 apt_mirror_search: 230 - http://local-mirror.mydomain 231 - http://archive.ubuntu.com 232 apt_mirror_search_dns: False 233 apt_sources: 234 - source: "deb http://apt.opscode.com/ $RELEASE-0.10 main" 235 key: | 236 -----BEGIN PGP PUBLIC KEY BLOCK----- 237 Version: GnuPG v1.4.9 (GNU/Linux) 238 -----END PGP PUBLIC KEY BLOCK----- 239 apt_preserve_sources_list: true 240 reporting: 241 maas: {consumer_key: mpU9YZLWDG7ZQubksN, endpoint: 'http://10.10.101.2/MAAS/metadata/status/cmfcxx', 242 token_key: tgEn5v5TcakKwWKwCf, token_secret: jzLdPTuh7hHqHTG9kGEHSG7F25GMAmzJ, 243 type: webhook} 244 system_info: 245 package_mirrors: 246 - arches: [i386, amd64] 247 failsafe: {primary: 'http://archive.ubuntu.com/ubuntu', security: 'http://security.ubuntu.com/ubuntu'} 248 search: 249 primary: ['http://archive.ubuntu.com/ubuntu'] 250 security: ['http://archive.ubuntu.com/ubuntu'] 251 - arches: [default] 252 failsafe: {primary: 'http://ports.ubuntu.com/ubuntu-ports', security: 'http://ports.ubuntu.com/ubuntu-ports'} 253 search: 254 primary: ['http://ports.ubuntu.com/ubuntu-ports'] 255 security: ['http://ports.ubuntu.com/ubuntu-ports'] 256 `[1:] 257 258 var dpkgLocalCloudConfig078 = ` 259 # cloud-init/local-cloud-config 260 apt: 261 preserve_sources_list: false 262 primary: 263 - arches: [default] 264 uri: http://archive.ubuntu.com/ubuntu 265 security: 266 - arches: [default] 267 uri: http://archive.ubuntu.com/ubuntu 268 apt_preserve_sources_list: true 269 reporting: 270 maas: {consumer_key: mpU9YZLWDG7ZQubksN, endpoint: 'http://10.10.101.2/MAAS/metadata/status/cmfcxx', 271 token_key: tgEn5v5TcakKwWKwCf, token_secret: jzLdPTuh7hHqHTG9kGEHSG7F25GMAmzJ, 272 type: webhook} 273 system_info: 274 package_mirrors: 275 - arches: [i386, amd64] 276 failsafe: {primary: 'http://archive.ubuntu.com/ubuntu', security: 'http://security.ubuntu.com/ubuntu'} 277 search: 278 primary: ['http://archive.ubuntu.com/ubuntu'] 279 security: ['http://archive.ubuntu.com/ubuntu'] 280 - arches: [default] 281 failsafe: {primary: 'http://ports.ubuntu.com/ubuntu-ports', security: 'http://ports.ubuntu.com/ubuntu-ports'} 282 search: 283 primary: ['http://ports.ubuntu.com/ubuntu-ports'] 284 security: ['http://ports.ubuntu.com/ubuntu-ports'] 285 `[1:] 286 287 var curtinNetworking = ` 288 network: 289 config: 290 - id: ens3 291 mac_address: 52:54:00:0c:xx:e0 292 mtu: 1500 293 name: ens3 294 subnets: 295 - address: 10.10.76.124/24 296 dns_nameservers: 297 - 10.10.76.45 298 gateway: 10.10.76.1 299 type: static 300 type: physical 301 `[1:] 302 303 var otherConfig = ` 304 #cloud-config 305 packages: 306 - ‘python-novaclient’ 307 write_files: 308 - path: /tmp/juju-test 309 permissions: 0644 310 content: | 311 Hello World! 312 apt_preserve_sources_list: false 313 ca-certs: 314 remove-defaults: true 315 trusted: 316 - | 317 -----BEGIN CERTIFICATE----- 318 YOUR-ORGS-TRUSTED-CA-CERT-HERE 319 -----END CERTIFICATE----- 320 `[1:] 321 322 var vendorData = ` 323 #cloud-config 324 ntp: 325 pools: [] 326 servers: [10.10.76.2] 327 `[1:] 328 329 var vendorDataTrusty = ` 330 None 331 `[1:] 332 333 var readmeFile = ` 334 # All files in this directory will be read by cloud-init 335 # They are read in lexical order. Later files overwrite values in 336 # earlier files. 337 `[1:] 338 339 var expectedResult078 = map[string]interface{}{ 340 "apt": map[interface{}]interface{}{ 341 "preserve_sources_list": false, 342 "primary": []interface{}{ 343 map[interface{}]interface{}{ 344 "arches": []interface{}{"default"}, 345 "uri": "http://archive.ubuntu.com/ubuntu", 346 }, 347 }, 348 "security": []interface{}{ 349 map[interface{}]interface{}{ 350 "arches": []interface{}{"default"}, 351 "uri": "http://archive.ubuntu.com/ubuntu", 352 }, 353 }, 354 }, 355 "reporting": map[interface{}]interface{}{ 356 "maas": map[interface{}]interface{}{ 357 "endpoint": "http://10.10.101.2/MAAS/metadata/status/cmfcxx", 358 "token_key": "tgEn5v5TcakKwWKwCf", 359 "token_secret": "jzLdPTuh7hHqHTG9kGEHSG7F25GMAmzJ", 360 "type": "webhook", 361 "consumer_key": "mpU9YZLWDG7ZQubksN", 362 }, 363 }, 364 "system_info": map[interface{}]interface{}{ 365 "package_mirrors": []interface{}{map[interface{}]interface{}{ 366 "arches": []interface{}{"i386", "amd64"}, 367 "failsafe": map[interface{}]interface{}{ 368 "primary": "http://archive.ubuntu.com/ubuntu", 369 "security": "http://security.ubuntu.com/ubuntu", 370 }, 371 "search": map[interface{}]interface{}{ 372 "primary": []interface{}{"http://archive.ubuntu.com/ubuntu"}, 373 "security": []interface{}{"http://archive.ubuntu.com/ubuntu"}, 374 }, 375 }, 376 map[interface{}]interface{}{ 377 "arches": []interface{}{"default"}, 378 "failsafe": map[interface{}]interface{}{ 379 "primary": "http://ports.ubuntu.com/ubuntu-ports", 380 "security": "http://ports.ubuntu.com/ubuntu-ports", 381 }, 382 "search": map[interface{}]interface{}{ 383 "primary": []interface{}{"http://ports.ubuntu.com/ubuntu-ports"}, 384 "security": []interface{}{"http://ports.ubuntu.com/ubuntu-ports"}, 385 }, 386 }, 387 }, 388 }, 389 "ntp": map[interface{}]interface{}{ 390 "servers": []interface{}{"10.10.76.2"}, 391 "pools": []interface{}{}, 392 }, 393 "write_files": []interface{}{ 394 map[interface{}]interface{}{ 395 "path": "/tmp/juju-test", 396 "permissions": 420, 397 "content": "Hello World!\n", 398 }}, 399 "apt_preserve_sources_list": true, 400 "packages": []interface{}{"‘python-novaclient’"}, 401 "ca-certs": map[interface{}]interface{}{ 402 "remove-defaults": true, 403 "trusted": []interface{}{"-----BEGIN CERTIFICATE-----\nYOUR-ORGS-TRUSTED-CA-CERT-HERE\n-----END CERTIFICATE-----\n"}, 404 }, 405 "network": map[interface{}]interface{}{ 406 "config": []interface{}{map[interface{}]interface{}{ 407 "mtu": 1500, 408 "name": "ens3", 409 "subnets": []interface{}{ 410 map[interface{}]interface{}{ 411 "type": "static", 412 "address": "10.10.76.124/24", 413 "dns_nameservers": []interface{}{"10.10.76.45"}, 414 "gateway": "10.10.76.1", 415 }, 416 }, 417 "type": "physical", 418 "id": "ens3", 419 "mac_address": "52:54:00:0c:xx:e0"}, 420 }, 421 }, 422 }