From af206e75435d87a55d27aa165e0662095163078b Mon Sep 17 00:00:00 2001 From: Christoph Kappel Date: Fri, 20 Oct 2017 17:46:29 +0200 Subject: [PATCH] Clean clients from chef-vault on recreate_client enabled (#16357) Fixes #15921 When terraform re-creates an existing node/client with chef provisioner, the already existing client (which has old keys) must be removed from the vault items. Afterwards, the chef-vault will be updated with the newly created client (which has the new keys). Therefore, the recreated client will be able to decrypt the vault items properly. --- .../provisioners/chef/resource_provisioner.go | 19 ++++++ .../chef/resource_provisioner_test.go | 60 +++++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/builtin/provisioners/chef/resource_provisioner.go b/builtin/provisioners/chef/resource_provisioner.go index a459bbe76..8546e04fc 100644 --- a/builtin/provisioners/chef/resource_provisioner.go +++ b/builtin/provisioners/chef/resource_provisioner.go @@ -558,6 +558,25 @@ func (p *provisioner) configureVaultsFunc(gemCmd string, knifeCmd string, confDi path.Join(confDir, p.UserName+".pem"), ) + // if client gets recreated, remove (old) client (with old keys) from vaults/items + // otherwise, the (new) client (with new keys) will not be able to decrypt the vault + if p.RecreateClient { + for vault, items := range p.Vaults { + for _, item := range items { + deleteCmd := fmt.Sprintf("%s vault remove %s %s -C \"%s\" -M client %s", + knifeCmd, + vault, + item, + p.NodeName, + options, + ) + if err := p.runCommand(o, comm, deleteCmd); err != nil { + return err + } + } + } + } + for vault, items := range p.Vaults { for _, item := range items { updateCmd := fmt.Sprintf("%s vault update %s %s -C %s -M client %s", diff --git a/builtin/provisioners/chef/resource_provisioner_test.go b/builtin/provisioners/chef/resource_provisioner_test.go index f9e9f33fe..1585df5a1 100644 --- a/builtin/provisioners/chef/resource_provisioner_test.go +++ b/builtin/provisioners/chef/resource_provisioner_test.go @@ -299,6 +299,36 @@ func TestResourceProvider_configureVaults(t *testing.T) { }, }, + "Linux Vault []string (recreate-client for vault)": { + Config: 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"]}`, + "recreate_client": true, + }, + + GemCmd: linuxGemCmd, + KnifeCmd: linuxKnifeCmd, + ConfDir: linuxConfDir, + + Commands: map[string]bool{ + fmt.Sprintf("%s install chef-vault", linuxGemCmd): true, + fmt.Sprintf("%s vault remove vault1 item1 -C \"nodename1\" -M client -c %s/client.rb "+ + "-u bob --key %s/bob.pem", linuxKnifeCmd, linuxConfDir, linuxConfDir): true, + fmt.Sprintf("%s vault remove vault1 item2 -C \"nodename1\" -M client -c %s/client.rb "+ + "-u bob --key %s/bob.pem", linuxKnifeCmd, linuxConfDir, linuxConfDir): true, + fmt.Sprintf("%s vault update vault1 item1 -C nodename1 -M client -c %s/client.rb "+ + "-u bob --key %s/bob.pem", linuxKnifeCmd, linuxConfDir, linuxConfDir): true, + fmt.Sprintf("%s vault update vault1 item2 -C nodename1 -M client -c %s/client.rb "+ + "-u bob --key %s/bob.pem", linuxKnifeCmd, linuxConfDir, linuxConfDir): true, + }, + }, + "Windows Vault string": { Config: map[string]interface{}{ "node_name": "nodename1", @@ -345,6 +375,36 @@ func TestResourceProvider_configureVaults(t *testing.T) { "-u bob --key %s/bob.pem", windowsKnifeCmd, windowsConfDir, windowsConfDir): true, }, }, + + "Windows Vault [] string (recreate-client for vault)": { + Config: 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"]}`, + "recreate_client": true, + }, + + GemCmd: windowsGemCmd, + KnifeCmd: windowsKnifeCmd, + ConfDir: windowsConfDir, + + Commands: map[string]bool{ + fmt.Sprintf("%s install chef-vault", windowsGemCmd): true, + fmt.Sprintf("%s vault remove vault1 item1 -C \"nodename1\" -M client -c %s/client.rb "+ + "-u bob --key %s/bob.pem", windowsKnifeCmd, windowsConfDir, windowsConfDir): true, + fmt.Sprintf("%s vault remove vault1 item2 -C \"nodename1\" -M client -c %s/client.rb "+ + "-u bob --key %s/bob.pem", windowsKnifeCmd, windowsConfDir, windowsConfDir): true, + fmt.Sprintf("%s vault update vault1 item1 -C nodename1 -M client -c %s/client.rb "+ + "-u bob --key %s/bob.pem", windowsKnifeCmd, windowsConfDir, windowsConfDir): true, + fmt.Sprintf("%s vault update vault1 item2 -C nodename1 -M client -c %s/client.rb "+ + "-u bob --key %s/bob.pem", windowsKnifeCmd, windowsConfDir, windowsConfDir): true, + }, + }, } o := new(terraform.MockUIOutput)