mirror of
https://github.com/slackhq/nebula.git
synced 2026-11-15 05:46:52 +01:00
Add support for accessing the previously ssh-only debug commands via `nebula ctl <command>.` - unix socket (named pipe on windows) for communication - sockets scoped to the user + an optional group - in cmd/nebula and cmd/nebula-service, but not nebula.Main Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
102 lines
3.4 KiB
Go
102 lines
3.4 KiB
Go
package commands
|
|
|
|
import (
|
|
"bytes"
|
|
"flag"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// TestParseArgsAllowsFlagsAfterOperands pins the one way ParseArgs departs from fl.Parse,
|
|
// that a flag may follow an operand, and that it departs in no other: a negative number
|
|
// is a flag, as Parse reads it, and goes after "--" when it is meant as an operand.
|
|
func TestParseArgsAllowsFlagsAfterOperands(t *testing.T) {
|
|
cases := map[string]struct {
|
|
args []string
|
|
wantOps []string
|
|
wantN string
|
|
wantV bool
|
|
wantJSON bool
|
|
wantErr string
|
|
}{
|
|
"flag after operand": {args: []string{"x", "-json"}, wantOps: []string{"x"}, wantJSON: true},
|
|
"flags around": {args: []string{"-v", "x", "-n", "1", "y"}, wantOps: []string{"x", "y"}, wantV: true, wantN: "1"},
|
|
"value after operand": {args: []string{"x", "-n", "-1"}, wantOps: []string{"x"}, wantN: "-1"},
|
|
"equals value": {args: []string{"-n=-1", "x"}, wantOps: []string{"x"}, wantN: "-1"},
|
|
"terminator after": {args: []string{"x", "--", "-json", "-1"}, wantOps: []string{"x", "-json", "-1"}},
|
|
"terminator": {args: []string{"--", "-json"}, wantOps: []string{"-json"}},
|
|
"defined numeric": {args: []string{"-2", "x"}, wantOps: []string{"x"}, wantV: true},
|
|
"negative number": {args: []string{"-1"}, wantErr: "flag provided but not defined: -1"},
|
|
"bad flag after": {args: []string{"x", "-nope"}, wantErr: "flag provided but not defined: -nope"},
|
|
"undefined flag": {args: []string{"-nope", "x"}, wantErr: "flag provided but not defined: -nope"},
|
|
"missing value": {args: []string{"-n"}, wantErr: "flag needs an argument: -n"},
|
|
}
|
|
|
|
for name, tc := range cases {
|
|
t.Run(name, func(t *testing.T) {
|
|
fl := flag.NewFlagSet("t", flag.ContinueOnError)
|
|
fl.SetOutput(&bytes.Buffer{})
|
|
n := fl.String("n", "", "")
|
|
v := fl.Bool("v", false, "")
|
|
two := fl.Bool("2", false, "a flag that happens to be a number")
|
|
asJSON := fl.Bool(FlagJSON, false, "")
|
|
|
|
ops, err := ParseArgs(fl, tc.args)
|
|
if tc.wantErr != "" {
|
|
require.ErrorContains(t, err, tc.wantErr)
|
|
return
|
|
}
|
|
|
|
require.NoError(t, err)
|
|
assert.Equal(t, tc.wantOps, ops)
|
|
assert.Equal(t, tc.wantN, *n)
|
|
assert.Equal(t, tc.wantV, *v || *two)
|
|
assert.Equal(t, tc.wantJSON, *asJSON)
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestDispatchFlagAfterOperand: the same through a registered command with no Flags of
|
|
// its own, which only has the presentation flags to find.
|
|
func TestDispatchFlagAfterOperand(t *testing.T) {
|
|
out := &bytes.Buffer{}
|
|
require.NoError(t, testRegistry().DispatchArgs([]string{"served", "x", "-json"}, MergedOutput(out)))
|
|
assert.Equal(t, "\"read x\"\n", out.String())
|
|
}
|
|
|
|
// TestLookupArg pins the reading of an argument's shape that ParseArgs and nebula ctl
|
|
// share.
|
|
func TestLookupArg(t *testing.T) {
|
|
fl := flag.NewFlagSet("t", flag.ContinueOnError)
|
|
fl.String("n", "", "")
|
|
fl.Bool("v", false, "")
|
|
|
|
for _, tc := range []struct {
|
|
arg string
|
|
name string
|
|
hasValue bool
|
|
}{
|
|
{"-n", "n", false},
|
|
{"--n", "n", false},
|
|
{"-n=1", "n", true},
|
|
{"--n=", "n", true},
|
|
{"-v", "v", false},
|
|
{"-nope", "", false},
|
|
{"-1", "", false},
|
|
} {
|
|
f, hasValue := LookupArg(fl, tc.arg)
|
|
if tc.name == "" {
|
|
assert.Nil(t, f, tc.arg)
|
|
} else {
|
|
require.NotNil(t, f, tc.arg)
|
|
assert.Equal(t, tc.name, f.Name, tc.arg)
|
|
}
|
|
assert.Equal(t, tc.hasValue, hasValue, tc.arg)
|
|
}
|
|
|
|
assert.True(t, IsBoolFlag(fl.Lookup("v")))
|
|
assert.False(t, IsBoolFlag(fl.Lookup("n")))
|
|
}
|