mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-20 11:48:24 -06:00
Fixes #10788 This checks `IsComputed` prior to attempting to use the JSON configurations. Due to a change in 0.8, the prior check for simply map existence would always succeed even with a computed value (as designed), but we forgot to update provisioners to not do that. There are other provisioners that also do this but to no ill effect currently. I've only changed Chef since we know that is an issue. This issue doesn't affect 0.9 due to helper/schema doing this automatically for provisioners.
371 lines
9.8 KiB
Go
371 lines
9.8 KiB
Go
package chef
|
|
|
|
import (
|
|
"fmt"
|
|
"path"
|
|
"testing"
|
|
|
|
"github.com/hashicorp/terraform/communicator"
|
|
"github.com/hashicorp/terraform/config"
|
|
"github.com/hashicorp/terraform/terraform"
|
|
)
|
|
|
|
func TestResourceProvisioner_impl(t *testing.T) {
|
|
var _ terraform.ResourceProvisioner = new(ResourceProvisioner)
|
|
}
|
|
|
|
func TestResourceProvider_Validate_good(t *testing.T) {
|
|
c := testConfig(t, map[string]interface{}{
|
|
"environment": "_default",
|
|
"node_name": "nodename1",
|
|
"run_list": []interface{}{"cookbook::recipe"},
|
|
"server_url": "https://chef.local",
|
|
"user_name": "bob",
|
|
"user_key": "USER-KEY",
|
|
})
|
|
r := new(ResourceProvisioner)
|
|
warn, errs := r.Validate(c)
|
|
if len(warn) > 0 {
|
|
t.Fatalf("Warnings: %v", warn)
|
|
}
|
|
if len(errs) > 0 {
|
|
t.Fatalf("Errors: %v", errs)
|
|
}
|
|
}
|
|
|
|
func TestResourceProvider_Validate_bad(t *testing.T) {
|
|
c := testConfig(t, map[string]interface{}{
|
|
"invalid": "nope",
|
|
})
|
|
p := new(ResourceProvisioner)
|
|
warn, errs := p.Validate(c)
|
|
if len(warn) > 0 {
|
|
t.Fatalf("Warnings: %v", warn)
|
|
}
|
|
if len(errs) == 0 {
|
|
t.Fatalf("Should have errors")
|
|
}
|
|
}
|
|
|
|
// Test that the JSON attributes with an unknown value don't
|
|
// validate.
|
|
func TestResourceProvider_Validate_computedValues(t *testing.T) {
|
|
c := testConfig(t, map[string]interface{}{
|
|
"environment": "_default",
|
|
"node_name": "nodename1",
|
|
"run_list": []interface{}{"cookbook::recipe"},
|
|
"server_url": "https://chef.local",
|
|
"user_name": "bob",
|
|
"user_key": "USER-KEY",
|
|
"attributes_json": config.UnknownVariableValue,
|
|
})
|
|
r := new(ResourceProvisioner)
|
|
warn, errs := r.Validate(c)
|
|
if len(warn) > 0 {
|
|
t.Fatalf("Warnings: %v", warn)
|
|
}
|
|
if len(errs) > 0 {
|
|
t.Fatalf("Errors: %v", errs)
|
|
}
|
|
}
|
|
|
|
func testConfig(t *testing.T, c map[string]interface{}) *terraform.ResourceConfig {
|
|
r, err := config.NewRawConfig(c)
|
|
if err != nil {
|
|
t.Fatalf("bad: %s", err)
|
|
}
|
|
|
|
return terraform.NewResourceConfig(r)
|
|
}
|
|
|
|
func TestResourceProvider_runChefClient(t *testing.T) {
|
|
cases := map[string]struct {
|
|
Config *terraform.ResourceConfig
|
|
ChefCmd string
|
|
ConfDir string
|
|
Commands map[string]bool
|
|
}{
|
|
"Sudo": {
|
|
Config: testConfig(t, map[string]interface{}{
|
|
"node_name": "nodename1",
|
|
"run_list": []interface{}{"cookbook::recipe"},
|
|
"server_url": "https://chef.local",
|
|
"user_name": "bob",
|
|
"user_key": "USER-KEY",
|
|
}),
|
|
|
|
ChefCmd: linuxChefCmd,
|
|
|
|
ConfDir: linuxConfDir,
|
|
|
|
Commands: map[string]bool{
|
|
fmt.Sprintf(`sudo %s -j %q -E "_default"`,
|
|
linuxChefCmd,
|
|
path.Join(linuxConfDir, "first-boot.json")): true,
|
|
},
|
|
},
|
|
|
|
"NoSudo": {
|
|
Config: testConfig(t, map[string]interface{}{
|
|
"node_name": "nodename1",
|
|
"prevent_sudo": true,
|
|
"run_list": []interface{}{"cookbook::recipe"},
|
|
"server_url": "https://chef.local",
|
|
"user_name": "bob",
|
|
"user_key": "USER-KEY",
|
|
}),
|
|
|
|
ChefCmd: linuxChefCmd,
|
|
|
|
ConfDir: linuxConfDir,
|
|
|
|
Commands: map[string]bool{
|
|
fmt.Sprintf(`%s -j %q -E "_default"`,
|
|
linuxChefCmd,
|
|
path.Join(linuxConfDir, "first-boot.json")): true,
|
|
},
|
|
},
|
|
|
|
"Environment": {
|
|
Config: testConfig(t, map[string]interface{}{
|
|
"environment": "production",
|
|
"node_name": "nodename1",
|
|
"prevent_sudo": true,
|
|
"run_list": []interface{}{"cookbook::recipe"},
|
|
"server_url": "https://chef.local",
|
|
"user_name": "bob",
|
|
"user_key": "USER-KEY",
|
|
}),
|
|
|
|
ChefCmd: windowsChefCmd,
|
|
|
|
ConfDir: windowsConfDir,
|
|
|
|
Commands: map[string]bool{
|
|
fmt.Sprintf(`%s -j %q -E "production"`,
|
|
windowsChefCmd,
|
|
path.Join(windowsConfDir, "first-boot.json")): true,
|
|
},
|
|
},
|
|
}
|
|
|
|
r := new(ResourceProvisioner)
|
|
o := new(terraform.MockUIOutput)
|
|
c := new(communicator.MockCommunicator)
|
|
|
|
for k, tc := range cases {
|
|
c.Commands = tc.Commands
|
|
|
|
p, err := r.decodeConfig(tc.Config)
|
|
if err != nil {
|
|
t.Fatalf("Error: %v", err)
|
|
}
|
|
|
|
p.runChefClient = p.runChefClientFunc(tc.ChefCmd, tc.ConfDir)
|
|
p.useSudo = !p.PreventSudo
|
|
|
|
err = p.runChefClient(o, c)
|
|
if err != nil {
|
|
t.Fatalf("Test %q failed: %v", k, err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestResourceProvider_fetchChefCertificates(t *testing.T) {
|
|
cases := map[string]struct {
|
|
Config *terraform.ResourceConfig
|
|
KnifeCmd string
|
|
ConfDir string
|
|
Commands map[string]bool
|
|
}{
|
|
"Sudo": {
|
|
Config: testConfig(t, map[string]interface{}{
|
|
"fetch_chef_certificates": true,
|
|
"node_name": "nodename1",
|
|
"run_list": []interface{}{"cookbook::recipe"},
|
|
"server_url": "https://chef.local",
|
|
"user_name": "bob",
|
|
"user_key": "USER-KEY",
|
|
}),
|
|
|
|
KnifeCmd: linuxKnifeCmd,
|
|
|
|
ConfDir: linuxConfDir,
|
|
|
|
Commands: map[string]bool{
|
|
fmt.Sprintf(`sudo %s ssl fetch -c %s`,
|
|
linuxKnifeCmd,
|
|
path.Join(linuxConfDir, "client.rb")): true,
|
|
},
|
|
},
|
|
|
|
"NoSudo": {
|
|
Config: testConfig(t, map[string]interface{}{
|
|
"fetch_chef_certificates": true,
|
|
"node_name": "nodename1",
|
|
"prevent_sudo": true,
|
|
"run_list": []interface{}{"cookbook::recipe"},
|
|
"server_url": "https://chef.local",
|
|
"user_name": "bob",
|
|
"user_key": "USER-KEY",
|
|
}),
|
|
|
|
KnifeCmd: windowsKnifeCmd,
|
|
|
|
ConfDir: windowsConfDir,
|
|
|
|
Commands: map[string]bool{
|
|
fmt.Sprintf(`%s ssl fetch -c %s`,
|
|
windowsKnifeCmd,
|
|
path.Join(windowsConfDir, "client.rb")): true,
|
|
},
|
|
},
|
|
}
|
|
|
|
r := new(ResourceProvisioner)
|
|
o := new(terraform.MockUIOutput)
|
|
c := new(communicator.MockCommunicator)
|
|
|
|
for k, tc := range cases {
|
|
c.Commands = tc.Commands
|
|
|
|
p, err := r.decodeConfig(tc.Config)
|
|
if err != nil {
|
|
t.Fatalf("Error: %v", err)
|
|
}
|
|
|
|
p.fetchChefCertificates = p.fetchChefCertificatesFunc(tc.KnifeCmd, tc.ConfDir)
|
|
p.useSudo = !p.PreventSudo
|
|
|
|
err = p.fetchChefCertificates(o, c)
|
|
if err != nil {
|
|
t.Fatalf("Test %q failed: %v", k, err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestResourceProvider_configureVaults(t *testing.T) {
|
|
cases := map[string]struct {
|
|
Config *terraform.ResourceConfig
|
|
GemCmd string
|
|
KnifeCmd string
|
|
ConfDir string
|
|
Commands map[string]bool
|
|
}{
|
|
"Linux Vault string": {
|
|
Config: testConfig(t, map[string]interface{}{
|
|
"node_name": "nodename1",
|
|
"prevent_sudo": true,
|
|
"run_list": []interface{}{"cookbook::recipe"},
|
|
"server_url": "https://chef.local",
|
|
"user_name": "bob",
|
|
"user_key": "USER-KEY",
|
|
"vault_json": `{"vault1": "item1"}`,
|
|
}),
|
|
|
|
GemCmd: linuxGemCmd,
|
|
KnifeCmd: linuxKnifeCmd,
|
|
ConfDir: linuxConfDir,
|
|
|
|
Commands: map[string]bool{
|
|
fmt.Sprintf("%s install chef-vault", linuxGemCmd): true,
|
|
fmt.Sprintf("%s vault update vault1 item1 -A nodename1 -M client -c %s/client.rb "+
|
|
"-u bob --key %s/bob.pem", linuxKnifeCmd, linuxConfDir, linuxConfDir): true,
|
|
},
|
|
},
|
|
|
|
"Linux Vault []string": {
|
|
Config: testConfig(t, map[string]interface{}{
|
|
"fetch_chef_certificates": true,
|
|
"node_name": "nodename1",
|
|
"prevent_sudo": true,
|
|
"run_list": []interface{}{"cookbook::recipe"},
|
|
"server_url": "https://chef.local",
|
|
"user_name": "bob",
|
|
"user_key": "USER-KEY",
|
|
"vault_json": `{"vault1": ["item1", "item2"]}`,
|
|
}),
|
|
|
|
GemCmd: linuxGemCmd,
|
|
KnifeCmd: linuxKnifeCmd,
|
|
ConfDir: linuxConfDir,
|
|
|
|
Commands: map[string]bool{
|
|
fmt.Sprintf("%s install chef-vault", linuxGemCmd): true,
|
|
fmt.Sprintf("%s vault update vault1 item1 -A nodename1 -M client -c %s/client.rb "+
|
|
"-u bob --key %s/bob.pem", linuxKnifeCmd, linuxConfDir, linuxConfDir): true,
|
|
fmt.Sprintf("%s vault update vault1 item2 -A nodename1 -M client -c %s/client.rb "+
|
|
"-u bob --key %s/bob.pem", linuxKnifeCmd, linuxConfDir, linuxConfDir): true,
|
|
},
|
|
},
|
|
|
|
"Windows Vault string": {
|
|
Config: testConfig(t, map[string]interface{}{
|
|
"node_name": "nodename1",
|
|
"prevent_sudo": true,
|
|
"run_list": []interface{}{"cookbook::recipe"},
|
|
"server_url": "https://chef.local",
|
|
"user_name": "bob",
|
|
"user_key": "USER-KEY",
|
|
"vault_json": `{"vault1": "item1"}`,
|
|
}),
|
|
|
|
GemCmd: windowsGemCmd,
|
|
KnifeCmd: windowsKnifeCmd,
|
|
ConfDir: windowsConfDir,
|
|
|
|
Commands: map[string]bool{
|
|
fmt.Sprintf("%s install chef-vault", windowsGemCmd): true,
|
|
fmt.Sprintf("%s vault update vault1 item1 -A nodename1 -M client -c %s/client.rb "+
|
|
"-u bob --key %s/bob.pem", windowsKnifeCmd, windowsConfDir, windowsConfDir): true,
|
|
},
|
|
},
|
|
|
|
"Windows Vault []string": {
|
|
Config: testConfig(t, map[string]interface{}{
|
|
"fetch_chef_certificates": true,
|
|
"node_name": "nodename1",
|
|
"prevent_sudo": true,
|
|
"run_list": []interface{}{"cookbook::recipe"},
|
|
"server_url": "https://chef.local",
|
|
"user_name": "bob",
|
|
"user_key": "USER-KEY",
|
|
"vault_json": `{"vault1": ["item1", "item2"]}`,
|
|
}),
|
|
|
|
GemCmd: windowsGemCmd,
|
|
KnifeCmd: windowsKnifeCmd,
|
|
ConfDir: windowsConfDir,
|
|
|
|
Commands: map[string]bool{
|
|
fmt.Sprintf("%s install chef-vault", windowsGemCmd): true,
|
|
fmt.Sprintf("%s vault update vault1 item1 -A nodename1 -M client -c %s/client.rb "+
|
|
"-u bob --key %s/bob.pem", windowsKnifeCmd, windowsConfDir, windowsConfDir): true,
|
|
fmt.Sprintf("%s vault update vault1 item2 -A nodename1 -M client -c %s/client.rb "+
|
|
"-u bob --key %s/bob.pem", windowsKnifeCmd, windowsConfDir, windowsConfDir): true,
|
|
},
|
|
},
|
|
}
|
|
|
|
r := new(ResourceProvisioner)
|
|
o := new(terraform.MockUIOutput)
|
|
c := new(communicator.MockCommunicator)
|
|
|
|
for k, tc := range cases {
|
|
c.Commands = tc.Commands
|
|
|
|
p, err := r.decodeConfig(tc.Config)
|
|
if err != nil {
|
|
t.Fatalf("Error: %v", err)
|
|
}
|
|
|
|
p.configureVaults = p.configureVaultsFunc(tc.GemCmd, tc.KnifeCmd, tc.ConfDir)
|
|
p.useSudo = !p.PreventSudo
|
|
|
|
err = p.configureVaults(o, c)
|
|
if err != nil {
|
|
t.Fatalf("Test %q failed: %v", k, err)
|
|
}
|
|
}
|
|
}
|