From 51b2069af15c764a2d20a56b76d7fe8688b80519 Mon Sep 17 00:00:00 2001 From: James Bishopp Date: Mon, 13 Jul 2015 07:56:11 -0700 Subject: [PATCH] Added fixer for ssh_key_path - ssh_key_path is removed in all cases. - The new fixer is not checking the builder type so it will execute for all builders. - If ssh_key_path exists without ssh_private_key_file then it will assign the value of ssh_path_path to ssh_private_key_file - If ssh_private_key_file and ssh_key_path exist, then ssh_key_path is simply removed I wanted to emit a warning messsage to the user but it didn't seem like the ui.* interface was exposed to fixers. --- fix/fixer.go | 2 + fix/fixer_sshkeypath.go | 50 ++++++++++++++++++++++ fix/fixer_sshkeypath_test.go | 83 ++++++++++++++++++++++++++++++++++++ 3 files changed, 135 insertions(+) create mode 100644 fix/fixer_sshkeypath.go create mode 100644 fix/fixer_sshkeypath_test.go diff --git a/fix/fixer.go b/fix/fixer.go index 5f7dd7a12..78f58f546 100644 --- a/fix/fixer.go +++ b/fix/fixer.go @@ -28,6 +28,7 @@ func init() { "vmware-rename": new(FixerVMwareRename), "parallels-headless": new(FixerParallelsHeadless), "parallels-deprecations": new(FixerParallelsDeprecations), + "sshkeypath": new(FixerSSHKeyPath), } FixerOrder = []string{ @@ -39,5 +40,6 @@ func init() { "vmware-rename", "parallels-headless", "parallels-deprecations", + "sshkeypath", } } diff --git a/fix/fixer_sshkeypath.go b/fix/fixer_sshkeypath.go new file mode 100644 index 000000000..b57cf762b --- /dev/null +++ b/fix/fixer_sshkeypath.go @@ -0,0 +1,50 @@ +package fix + +import ( + "github.com/mitchellh/mapstructure" +) + +// FixerSSHKeyPath changes the "ssh_key_path" of a template +// to "ssh_private_key_file". +type FixerSSHKeyPath struct{} + +func (FixerSSHKeyPath) Fix(input map[string]interface{}) (map[string]interface{}, error) { + // The type we'll decode into; we only care about builders + type template struct { + Builders []map[string]interface{} + } + + // Decode the input into our structure, if we can + var tpl template + if err := mapstructure.Decode(input, &tpl); err != nil { + return nil, err + } + + for _, builder := range tpl.Builders { + sshKeyPathRaw, ok := builder["ssh_key_path"] + if !ok { + continue + } + + sshKeyPath, ok := sshKeyPathRaw.(string) + if !ok { + continue + } + + // only assign to ssh_private_key_file if it doesn't + // already exist; otherwise we'll just ignore ssh_key_path + _, sshPrivateIncluded := builder["ssh_private_key_file"] + if !sshPrivateIncluded { + builder["ssh_private_key_file"] = sshKeyPath + } + + delete(builder, "ssh_key_path") + } + + input["builders"] = tpl.Builders + return input, nil +} + +func (FixerSSHKeyPath) Synopsis() string { + return `Updates builders using "ssh_key_path" to use "ssh_private_key_file"` +} diff --git a/fix/fixer_sshkeypath_test.go b/fix/fixer_sshkeypath_test.go new file mode 100644 index 000000000..865f8c1de --- /dev/null +++ b/fix/fixer_sshkeypath_test.go @@ -0,0 +1,83 @@ +package fix + +import ( + "reflect" + "testing" +) + +func TestFixerSSHKeyPath_Impl(t *testing.T) { + var _ Fixer = new(FixerSSHKeyPath) +} + +func TestFixerSSHKeyPath_Fix(t *testing.T) { + cases := []struct { + Input map[string]interface{} + Expected map[string]interface{} + }{ + // No key_path field + { + Input: map[string]interface{}{ + "type": "virtualbox", + }, + + Expected: map[string]interface{}{ + "type": "virtualbox", + }, + }, + + // private_key_file without key_path + { + Input: map[string]interface{}{ + "ssh_private_key_file": "id_rsa", + }, + + Expected: map[string]interface{}{ + "ssh_private_key_file": "id_rsa", + }, + }, + + // key_path without private_key_file + { + Input: map[string]interface{}{ + "ssh_key_path": "id_rsa", + }, + + Expected: map[string]interface{}{ + "ssh_private_key_file": "id_rsa", + }, + }, + + // key_path and private_key_file + { + Input: map[string]interface{}{ + "ssh_key_path": "key_id_rsa", + "ssh_private_key_file": "private_id_rsa", + }, + + Expected: map[string]interface{}{ + "ssh_private_key_file": "private_id_rsa", + }, + }, + } + + for _, tc := range cases { + var f FixerSSHKeyPath + + input := map[string]interface{}{ + "builders": []map[string]interface{}{tc.Input}, + } + + expected := map[string]interface{}{ + "builders": []map[string]interface{}{tc.Expected}, + } + + output, err := f.Fix(input) + if err != nil { + t.Fatalf("err: %s", err) + } + + if !reflect.DeepEqual(output, expected) { + t.Fatalf("unexpected: %#v\nexpected: %#v\n", output, expected) + } + } +}