Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

debug: Improve namespace and region support #11269

Merged
merged 24 commits into from
Oct 12, 2021
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
6b13b90
Rename argNodes to generic utility function
davemay99 Oct 6, 2021
3c47f92
Add region and prefix matching for server members
davemay99 Oct 6, 2021
8897ed6
Include region and namespace in CLI output
davemay99 Oct 6, 2021
25ed8ff
Add region awareness to WaitForClient helper
davemay99 Oct 6, 2021
2db750d
Align variable names with underlying type
davemay99 Oct 6, 2021
4c8fa58
Add test for region
davemay99 Oct 6, 2021
33132cf
Add namespaces and regions to cluster meta info
davemay99 Oct 6, 2021
c43b697
Add changelog
davemay99 Oct 6, 2021
d45cfa0
Refactor WaitForClient helper function
davemay99 Oct 7, 2021
74867b1
Simplify test agent configuration functions
davemay99 Oct 7, 2021
8274faf
Tighten StringToSlice test coverage
davemay99 Oct 7, 2021
23bd22e
Clarify test names
davemay99 Oct 7, 2021
38bb29b
Rename server filter function for clarity
davemay99 Oct 7, 2021
a99ab0e
Move leader check outside loop to prevent duplicates
davemay99 Oct 7, 2021
1db4315
Adjust comment for clarity
davemay99 Oct 7, 2021
1ee480e
Fix region regression
davemay99 Oct 12, 2021
c9b0393
Refactor test client agent generation
davemay99 Oct 12, 2021
6d3c8ec
testServer already handles agent shutdown
davemay99 Oct 12, 2021
668e3bd
Use region var for expected outputs
davemay99 Oct 12, 2021
48ff716
Add test for SliceStringContainsPrefix
davemay99 Oct 12, 2021
4c9f655
Fix logic/tests for slice prefix helper functions
davemay99 Oct 12, 2021
037e801
revert testutil.WaitForClient addition
davemay99 Oct 12, 2021
37e5e22
eliminate import cycle caused by nomad/client
davemay99 Oct 12, 2021
4059695
Clarify slice HasPrefix tests
davemay99 Oct 12, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changelog/11269.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:improvement
cli: Improve debug namespace and region support
```
69 changes: 58 additions & 11 deletions command/operator_debug.go
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ func (c *OperatorDebugCommand) Run(args []string) int {
nodeLookupFailCount := 0
nodeCaptureCount := 0

for _, id := range argNodes(nodeIDs) {
for _, id := range stringToSlice(nodeIDs) {
if id == "all" {
// Capture from all nodes using empty prefix filter
id = ""
Expand Down Expand Up @@ -382,15 +382,15 @@ func (c *OperatorDebugCommand) Run(args []string) int {
c.Ui.Error(fmt.Sprintf("Failed to retrieve server list; err: %v", err))
return 1
}

// Write complete list of server members to file
c.writeJSON("version", "members.json", members, err)
// We always write the error to the file, but don't range if no members found
if serverIDs == "all" && members != nil {
// Special case to capture from all servers
for _, member := range members.Members {
c.serverIDs = append(c.serverIDs, member.Name)
}
} else {
c.serverIDs = append(c.serverIDs, argNodes(serverIDs)...)

// Filter for servers matching criteria
c.serverIDs, err = filterServerMembers(members, serverIDs, c.region)
if err != nil {
c.Ui.Error(fmt.Sprintf("Failed to parse server list; err: %v", err))
return 1
}

serversFound := 0
Expand All @@ -412,6 +412,8 @@ func (c *OperatorDebugCommand) Run(args []string) int {
// Display general info about the capture
c.Ui.Output("Starting debugger...")
c.Ui.Output("")
c.Ui.Output(fmt.Sprintf(" Region: %s", c.region))
c.Ui.Output(fmt.Sprintf(" Namespace: %s", c.namespace))
c.Ui.Output(fmt.Sprintf(" Servers: (%d/%d) %v", serverCaptureCount, serversFound, c.serverIDs))
c.Ui.Output(fmt.Sprintf(" Clients: (%d/%d) %v", nodeCaptureCount, nodesFound, c.nodeIDs))
if nodeCaptureCount > 0 && nodeCaptureCount == c.maxNodes {
Expand Down Expand Up @@ -468,6 +470,13 @@ func (c *OperatorDebugCommand) collect(client *api.Client) error {
self, err := client.Agent().Self()
c.writeJSON(dir, "agent-self.json", self, err)

var qo *api.QueryOptions
namespaces, _, err := client.Namespaces().List(qo)
c.writeJSON(dir, "namespaces.json", namespaces, err)

regions, err := client.Regions().List()
c.writeJSON(dir, "regions.json", regions, err)

// Fetch data directly from consul and vault. Ignore errors
var consul, vault string

Expand Down Expand Up @@ -1055,8 +1064,46 @@ func TarCZF(archive string, src, target string) error {
})
}

// argNodes splits node ids from the command line by ","
func argNodes(input string) []string {
// filterServerMembers returns a slice of server member names matching the search criteria
func filterServerMembers(serverMembers *api.ServerMembers, serverIDs string, region string) (membersFound []string, err error) {
if serverMembers.Members == nil {
return nil, fmt.Errorf("Failed to parse server members, members==nil")
}
davemay99 marked this conversation as resolved.
Show resolved Hide resolved

prefixes := stringToSlice(serverIDs)

// "leader" is a special case which Nomad handles in the API. If "leader"
// appears in serverIDs, add it to membersFound and remove it from the list
// so that it isn't processed by the range loop
if helper.SliceStringContains(prefixes, "leader") {
membersFound = append(membersFound, "leader")
helper.RemoveEqualFold(&prefixes, "leader")
}

for _, member := range serverMembers.Members {
// If region is provided it must match exactly
if region != "" && member.Tags["region"] != region {
continue
}

// Always include "all"
if serverIDs == "all" {
membersFound = append(membersFound, member.Name)
continue
}

// Include member if name matches any prefix from serverIDs
if helper.StringHasPrefixInSlice(member.Name, prefixes) {
membersFound = append(membersFound, member.Name)
}
}

return membersFound, nil
}

// stringToSlice splits comma-separated input string into slice, trims
// whitespace, and prunes empty values
func stringToSlice(input string) []string {
ns := strings.Split(input, ",")
var out []string
for _, n := range ns {
Expand Down
Loading