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.
This commit is contained in:
Christoph Kappel 2017-10-20 17:46:29 +02:00 committed by Sander van Harmelen
parent d5b0beac01
commit af206e7543
2 changed files with 79 additions and 0 deletions

View File

@ -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",

View File

@ -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)