github.phpd.cn/hashicorp/packer@v1.3.2/builder/oracle/oci/config_test.go (about) 1 package oci 2 3 import ( 4 "crypto/rand" 5 "crypto/rsa" 6 "crypto/x509" 7 "encoding/pem" 8 "io/ioutil" 9 "os" 10 "strings" 11 "testing" 12 13 "github.com/go-ini/ini" 14 ) 15 16 func testConfig(accessConfFile *os.File) map[string]interface{} { 17 return map[string]interface{}{ 18 "availability_domain": "aaaa:PHX-AD-3", 19 "access_cfg_file": accessConfFile.Name(), 20 21 // Image 22 "base_image_ocid": "ocd1...", 23 "shape": "VM.Standard1.1", 24 "image_name": "HelloWorld", 25 26 // Networking 27 "subnet_ocid": "ocd1...", 28 29 // Comm 30 "ssh_username": "opc", 31 "use_private_ip": false, 32 "metadata": map[string]string{ 33 "key": "value", 34 }, 35 } 36 } 37 38 func TestConfig(t *testing.T) { 39 // Shared set-up and deferred deletion 40 41 cfg, keyFile, err := baseTestConfigWithTmpKeyFile() 42 if err != nil { 43 t.Fatal(err) 44 } 45 defer os.Remove(keyFile.Name()) 46 47 cfgFile, err := writeTestConfig(cfg) 48 if err != nil { 49 t.Fatal(err) 50 } 51 defer os.Remove(cfgFile.Name()) 52 53 // Temporarily set $HOME to temp directory to bypass default 54 // access config loading. 55 56 tmpHome, err := ioutil.TempDir("", "packer_config_test") 57 if err != nil { 58 t.Fatalf("Unexpected error when creating temporary directory: %+v", err) 59 } 60 defer os.Remove(tmpHome) 61 62 home := os.Getenv("HOME") 63 os.Setenv("HOME", tmpHome) 64 defer os.Setenv("HOME", home) 65 66 // Config tests 67 t.Run("BaseConfig", func(t *testing.T) { 68 raw := testConfig(cfgFile) 69 _, errs := NewConfig(raw) 70 71 if errs != nil { 72 t.Fatalf("Unexpected error in configuration %+v", errs) 73 } 74 }) 75 76 t.Run("NoAccessConfig", func(t *testing.T) { 77 raw := testConfig(cfgFile) 78 delete(raw, "access_cfg_file") 79 80 _, errs := NewConfig(raw) 81 82 expectedErrors := []string{ 83 "'user_ocid'", "'tenancy_ocid'", "'fingerprint'", "'key_file'", 84 } 85 86 s := errs.Error() 87 for _, expected := range expectedErrors { 88 if !strings.Contains(s, expected) { 89 t.Errorf("Expected %q to contain '%s'", s, expected) 90 } 91 } 92 }) 93 94 t.Run("AccessConfigTemplateOnly", func(t *testing.T) { 95 raw := testConfig(cfgFile) 96 delete(raw, "access_cfg_file") 97 raw["user_ocid"] = "ocid1..." 98 raw["tenancy_ocid"] = "ocid1..." 99 raw["fingerprint"] = "00:00..." 100 raw["key_file"] = keyFile.Name() 101 102 _, errs := NewConfig(raw) 103 104 if errs != nil { 105 t.Fatalf("err: %+v", errs) 106 } 107 108 }) 109 110 t.Run("TenancyReadFromAccessCfgFile", func(t *testing.T) { 111 raw := testConfig(cfgFile) 112 c, errs := NewConfig(raw) 113 if errs != nil { 114 t.Fatalf("Unexpected error in configuration %+v", errs) 115 } 116 117 tenancy, err := c.ConfigProvider.TenancyOCID() 118 if err != nil { 119 t.Fatalf("Unexpected error getting tenancy ocid: %v", err) 120 } 121 122 expected := "ocid1.tenancy.oc1..aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 123 if tenancy != expected { 124 t.Errorf("Expected tenancy: %s, got %s.", expected, tenancy) 125 } 126 127 }) 128 129 t.Run("RegionNotDefaultedToPHXWhenSetInOCISettings", func(t *testing.T) { 130 raw := testConfig(cfgFile) 131 c, errs := NewConfig(raw) 132 if errs != nil { 133 t.Fatalf("Unexpected error in configuration %+v", errs) 134 } 135 136 region, err := c.ConfigProvider.Region() 137 if err != nil { 138 t.Fatalf("Unexpected error getting region: %v", err) 139 } 140 141 expected := "us-ashburn-1" 142 if region != expected { 143 t.Errorf("Expected region: %s, got %s.", expected, region) 144 } 145 146 }) 147 148 // Test the correct errors are produced when required template keys are 149 // omitted. 150 requiredKeys := []string{"availability_domain", "base_image_ocid", "shape", "subnet_ocid"} 151 for _, k := range requiredKeys { 152 t.Run(k+"_required", func(t *testing.T) { 153 raw := testConfig(cfgFile) 154 delete(raw, k) 155 156 _, errs := NewConfig(raw) 157 158 if !strings.Contains(errs.Error(), k) { 159 t.Errorf("Expected '%s' to contain '%s'", errs.Error(), k) 160 } 161 }) 162 } 163 164 t.Run("ImageNameDefaultedIfEmpty", func(t *testing.T) { 165 raw := testConfig(cfgFile) 166 delete(raw, "image_name") 167 168 c, errs := NewConfig(raw) 169 if errs != nil { 170 t.Fatalf("Unexpected error in configuration %+v", errs) 171 } 172 173 if !strings.Contains(c.ImageName, "packer-") { 174 t.Errorf("got default ImageName %q, want image name 'packer-{{timestamp}}'", c.ImageName) 175 } 176 }) 177 178 t.Run("user_ocid_overridden", func(t *testing.T) { 179 expected := "override" 180 raw := testConfig(cfgFile) 181 raw["user_ocid"] = expected 182 183 c, errs := NewConfig(raw) 184 if errs != nil { 185 t.Fatalf("Unexpected error in configuration %+v", errs) 186 } 187 188 user, _ := c.ConfigProvider.UserOCID() 189 if user != expected { 190 t.Errorf("Expected ConfigProvider.UserOCID: %s, got %s", expected, user) 191 } 192 }) 193 194 t.Run("tenancy_ocid_overidden", func(t *testing.T) { 195 expected := "override" 196 raw := testConfig(cfgFile) 197 raw["tenancy_ocid"] = expected 198 199 c, errs := NewConfig(raw) 200 if errs != nil { 201 t.Fatalf("Unexpected error in configuration %+v", errs) 202 } 203 204 tenancy, _ := c.ConfigProvider.TenancyOCID() 205 if tenancy != expected { 206 t.Errorf("Expected ConfigProvider.TenancyOCID: %s, got %s", expected, tenancy) 207 } 208 }) 209 210 t.Run("region_overidden", func(t *testing.T) { 211 expected := "override" 212 raw := testConfig(cfgFile) 213 raw["region"] = expected 214 215 c, errs := NewConfig(raw) 216 if errs != nil { 217 t.Fatalf("Unexpected error in configuration %+v", errs) 218 } 219 220 region, _ := c.ConfigProvider.Region() 221 if region != expected { 222 t.Errorf("Expected ConfigProvider.Region: %s, got %s", expected, region) 223 } 224 }) 225 226 t.Run("fingerprint_overidden", func(t *testing.T) { 227 expected := "override" 228 raw := testConfig(cfgFile) 229 raw["fingerprint"] = expected 230 231 c, errs := NewConfig(raw) 232 if errs != nil { 233 t.Fatalf("Unexpected error in configuration: %+v", errs) 234 } 235 236 fingerprint, _ := c.ConfigProvider.KeyFingerprint() 237 if fingerprint != expected { 238 t.Errorf("Expected ConfigProvider.KeyFingerprint: %s, got %s", expected, fingerprint) 239 } 240 }) 241 } 242 243 // BaseTestConfig creates the base (DEFAULT) config including a temporary key 244 // file. 245 // NOTE: Caller is responsible for removing temporary key file. 246 func baseTestConfigWithTmpKeyFile() (*ini.File, *os.File, error) { 247 keyFile, err := generateRSAKeyFile() 248 if err != nil { 249 return nil, keyFile, err 250 } 251 // Build ini 252 cfg := ini.Empty() 253 section, _ := cfg.NewSection("DEFAULT") 254 section.NewKey("region", "us-ashburn-1") 255 section.NewKey("tenancy", "ocid1.tenancy.oc1..aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") 256 section.NewKey("user", "ocid1.user.oc1..aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") 257 section.NewKey("fingerprint", "70:04:5z:b3:19:ab:90:75:a4:1f:50:d4:c7:c3:33:20") 258 section.NewKey("key_file", keyFile.Name()) 259 260 return cfg, keyFile, nil 261 } 262 263 // WriteTestConfig writes a ini.File to a temporary file for use in unit tests. 264 // NOTE: Caller is responsible for removing temporary file. 265 func writeTestConfig(cfg *ini.File) (*os.File, error) { 266 confFile, err := ioutil.TempFile("", "config_file") 267 if err != nil { 268 return nil, err 269 } 270 271 if _, err := confFile.Write([]byte("[DEFAULT]\n")); err != nil { 272 os.Remove(confFile.Name()) 273 return nil, err 274 } 275 276 if _, err := cfg.WriteTo(confFile); err != nil { 277 os.Remove(confFile.Name()) 278 return nil, err 279 } 280 return confFile, nil 281 } 282 283 // generateRSAKeyFile generates an RSA key file for use in unit tests. 284 // NOTE: The caller is responsible for deleting the temporary file. 285 func generateRSAKeyFile() (*os.File, error) { 286 // Create temporary file for the key 287 f, err := ioutil.TempFile("", "key") 288 if err != nil { 289 return nil, err 290 } 291 292 // Generate key 293 priv, err := rsa.GenerateKey(rand.Reader, 2014) 294 if err != nil { 295 return nil, err 296 } 297 298 // ASN.1 DER encoded form 299 privDer := x509.MarshalPKCS1PrivateKey(priv) 300 privBlk := pem.Block{ 301 Type: "RSA PRIVATE KEY", 302 Headers: nil, 303 Bytes: privDer, 304 } 305 306 // Write the key out 307 if _, err := f.Write(pem.EncodeToMemory(&privBlk)); err != nil { 308 return nil, err 309 } 310 311 return f, nil 312 }