From f8ee86065d33f0245d1ad64e40feb4076f1a207d Mon Sep 17 00:00:00 2001 From: Alex Dadgar Date: Tue, 16 May 2017 12:59:58 -0400 Subject: [PATCH] Fix Vault Client panic when given nonexistant role The Vault API returns a nil secret and nil error when reading an object that doesn't exist. The old code assumed an error would be returned and thus will panic when trying to validate a non-existant role. --- nomad/vault.go | 3 +++ nomad/vault_test.go | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/nomad/vault.go b/nomad/vault.go index 93624b932a5..0d14ebe5cae 100644 --- a/nomad/vault.go +++ b/nomad/vault.go @@ -782,6 +782,9 @@ func (v *vaultClient) validateRole(role string) error { if err != nil { return fmt.Errorf("failed to lookup role %q: %v", role, err) } + if rsecret == nil { + return fmt.Errorf("Role %q does not exist", role) + } // Read and parse the fields var data struct { diff --git a/nomad/vault_test.go b/nomad/vault_test.go index b874230b42a..0e0c2b64c53 100644 --- a/nomad/vault_test.go +++ b/nomad/vault_test.go @@ -247,6 +247,45 @@ func TestVaultClient_ValidateRole(t *testing.T) { } } +func TestVaultClient_ValidateRole_NonExistant(t *testing.T) { + v := testutil.NewTestVault(t).Start() + defer v.Stop() + + v.Config.Token = defaultTestVaultWhitelistRoleAndToken(v, t, 5) + v.Config.Token = v.RootToken + logger := log.New(os.Stderr, "", log.LstdFlags) + v.Config.ConnectionRetryIntv = 100 * time.Millisecond + v.Config.Role = "test-nonexistant" + client, err := NewVaultClient(v.Config, logger, nil) + if err != nil { + t.Fatalf("failed to build vault client: %v", err) + } + defer client.Stop() + + // Wait for an error + var conn bool + var connErr error + testutil.WaitForResult(func() (bool, error) { + conn, connErr = client.ConnectionEstablished() + if conn { + return false, fmt.Errorf("Should not connect") + } + + if connErr == nil { + return false, fmt.Errorf("expect an error") + } + + return true, nil + }, func(err error) { + t.Fatalf("bad: %v", err) + }) + + errStr := connErr.Error() + if !strings.Contains(errStr, "does not exist") { + t.Fatalf("Expect orphan error") + } +} + func TestVaultClient_ValidateToken(t *testing.T) { v := testutil.NewTestVault(t).Start() defer v.Stop()