Skip to content

Commit

Permalink
cli: improve debug error messages (#11507)
Browse files Browse the repository at this point in the history
Improves `nomad debug` error messages when contacting agents that do not
have /v1/agent/host endpoints (the endpoint was added in v0.12.0)

Part of #9568 and manually tested against Nomad v0.8.7.

Hopefully isRedirectError can be reused for more cases listed in #9568
  • Loading branch information
schmichael authored Jan 17, 2022
1 parent ac18d71 commit dc81f26
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .changelog/11507.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```improvement
cli: improve `nomad operator debug` error messages
```
15 changes: 15 additions & 0 deletions command/operator_debug.go
Original file line number Diff line number Diff line change
Expand Up @@ -707,6 +707,11 @@ func (c *OperatorDebugCommand) collectAgentHost(path, id string, client *api.Cli
host, err = client.Agent().Host("", id, c.queryOpts())
}

if isRedirectError(err) {
c.Ui.Warn(fmt.Sprintf("%s/%s: /v1/agent/host unavailable on this agent", path, id))
return
}

if err != nil {
c.Ui.Error(fmt.Sprintf("%s/%s: Failed to retrieve agent host data, err: %v", path, id, err))

Expand Down Expand Up @@ -1428,3 +1433,13 @@ func defaultHttpClient() *http.Client {

return httpClient
}

// isRedirectError returns true if an error is a redirect error.
func isRedirectError(err error) bool {
if err == nil {
return false
}

const redirectErr string = `invalid character '<' looking for beginning of value`
return strings.Contains(err.Error(), redirectErr)
}
32 changes: 32 additions & 0 deletions command/operator_debug_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ package command
import (
"fmt"
"io/ioutil"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"strings"
"testing"
"time"

Expand Down Expand Up @@ -741,6 +744,35 @@ func TestDebug_CollectVault(t *testing.T) {
require.FileExists(t, filepath.Join(testDir, "test", "vault-sys-health.json"))
}

// TestDebug_RedirectError asserts that redirect errors are detected so they
// can be translated into more understandable output.
func TestDebug_RedirectError(t *testing.T) {
// Create a test server that always returns the error many versions of
// Nomad return instead of a 404 for unknown paths.
// 1st request redirects to /ui/
// 2nd request returns UI's HTML
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if strings.HasSuffix(r.URL.String(), "/ui/") {
fmt.Fprintln(w, `<html>Fake UI HTML</html>`)
return
}

w.Header().Set("Location", "/ui/")
w.WriteHeader(307)
fmt.Fprintln(w, `<a href="/ui/">Temporary Redirect</a>.`)
}))
defer ts.Close()

config := api.DefaultConfig()
config.Address = ts.URL
client, err := api.NewClient(config)
require.NoError(t, err)

resp, err := client.Agent().Host("abc", "", nil)
assert.Nil(t, resp)
assert.True(t, isRedirectError(err), err.Error())
}

// TestDebug_StaleLeadership verifies that APIs that are required to
// complete a debug run have their query options configured with the
// -stale flag
Expand Down

0 comments on commit dc81f26

Please sign in to comment.