diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c68becc..ea71a3da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add support for resolving absolute path automatically. #493 - The network device "OnBoot" parameter correctly configures the ONBOOT ifcfg parameter. (#644) +- Add support for listing profile/node via comma-separated values. #739 ### Changed diff --git a/internal/app/wwctl/node/list/main.go b/internal/app/wwctl/node/list/main.go index f4e027c0..e4fd1e67 100644 --- a/internal/app/wwctl/node/list/main.go +++ b/internal/app/wwctl/node/list/main.go @@ -11,6 +11,9 @@ import ( func CobraRunE(vars *variables) func(cmd *cobra.Command, args []string) (err error) { return func(cmd *cobra.Command, args []string) (err error) { + if len(args) > 0 && strings.Contains(args[0], ",") { + args = strings.FieldsFunc(args[0], func(r rune) bool { return r == ',' }) + } req := wwapiv1.GetNodeList{ Nodes: args, Type: wwapiv1.GetNodeList_Simple, diff --git a/internal/app/wwctl/node/list/main_test.go b/internal/app/wwctl/node/list/main_test.go index 2717d156..850636f9 100644 --- a/internal/app/wwctl/node/list/main_test.go +++ b/internal/app/wwctl/node/list/main_test.go @@ -4,10 +4,11 @@ import ( "bytes" "io" "os" + "strings" "testing" - "github.com/hpcng/warewulf/internal/pkg/node" warewulfconf "github.com/hpcng/warewulf/internal/pkg/config" + "github.com/hpcng/warewulf/internal/pkg/node" "github.com/hpcng/warewulf/internal/pkg/warewulfd" "github.com/stretchr/testify/assert" ) @@ -20,7 +21,8 @@ func Test_List(t *testing.T) { stdout string inDb string }{ - {name: "single node list", + { + name: "single node list", args: []string{}, wantErr: false, stdout: ` NODE NAME PROFILES NETWORK @@ -33,7 +35,96 @@ nodes: n01: profiles: - default -`}, +`, + }, + { + name: "multiple nodes list", + args: []string{}, + wantErr: false, + stdout: ` NODE NAME PROFILES NETWORK + n01 default + n02 default +`, + inDb: `WW_INTERNAL: 43 +nodeprofiles: + default: {} +nodes: + n01: + profiles: + - default + n02: + profiles: + - default +`, + }, + { + name: "node list returns multiple nodes", + args: []string{"n01,n02"}, + wantErr: false, + stdout: ` NODE NAME PROFILES NETWORK + n01 default + n02 default +`, + inDb: `WW_INTERNAL: 43 +nodeprofiles: + default: {} +nodes: + n01: + profiles: + - default + n02: + profiles: + - default +`, + }, + { + name: "node list returns multiple nodes (case 2)", + args: []string{"n01,n03"}, + wantErr: false, + stdout: ` NODE NAME PROFILES NETWORK + n01 default + n03 default +`, + inDb: `WW_INTERNAL: 43 +nodeprofiles: + default: {} +nodes: + n01: + profiles: + - default + n02: + profiles: + - default + n03: + profiles: + - default + n04: + profiles: + - default + n05: + profiles: + - default +`, + }, + { + name: "node list returns one node", + args: []string{"n01,"}, + wantErr: false, + stdout: ` NODE NAME PROFILES NETWORK + n01 default +`, + inDb: `WW_INTERNAL: 43 +nodeprofiles: + default: {} +nodes: + n01: + profiles: + - default + n02: + profiles: + - default +`, + }, } conf_yml := `WW_INTERNAL: 0` tempWarewulfConf, warewulfConfErr := os.CreateTemp("", "warewulf.conf-") @@ -82,8 +173,8 @@ nodes: w.Close() os.Stdout = old // restoring the real stdout out := <-outC - if out != tt.stdout { - t.Errorf("Got wrong output, got:'%s'\nwant:'%s'", out, tt.stdout) + if strings.ReplaceAll(out, " ", "") != strings.ReplaceAll(tt.stdout, " ", "") { + t.Errorf("Got wrong output, got:\n'%s'\nwant:\n'%s'", out, tt.stdout) t.FailNow() } }) diff --git a/internal/app/wwctl/profile/list/main.go b/internal/app/wwctl/profile/list/main.go index 3a984baf..de4f55ac 100644 --- a/internal/app/wwctl/profile/list/main.go +++ b/internal/app/wwctl/profile/list/main.go @@ -12,6 +12,9 @@ import ( func CobraRunE(vars *variables) func(cmd *cobra.Command, args []string) (err error) { return func(cmd *cobra.Command, args []string) (err error) { + if len(args) > 0 && strings.Contains(args[0], ",") { + args = strings.FieldsFunc(args[0], func(r rune) bool { return r == ',' }) + } req := wwapiv1.GetProfileList{ ShowAll: vars.showAll, Profiles: args, diff --git a/internal/app/wwctl/profile/list/main_test.go b/internal/app/wwctl/profile/list/main_test.go index 62e2ec03..5741e471 100644 --- a/internal/app/wwctl/profile/list/main_test.go +++ b/internal/app/wwctl/profile/list/main_test.go @@ -32,6 +32,53 @@ nodes: n01: profiles: - default +`, + }, + { + name: "profile list returns multiple profiles", + args: []string{"default,test"}, + stdout: `PROFILE NAME COMMENT/DESCRIPTION + default -- + test --`, + inDb: `WW_INTERNAL: 43 +nodeprofiles: + default: {} + test: {} +nodes: + n01: + profiles: + - default +`, + }, + { + name: "profile list returns one profiles", + args: []string{"test,"}, + stdout: `PROFILE NAME COMMENT/DESCRIPTION + test --`, + inDb: `WW_INTERNAL: 43 +nodeprofiles: + default: {} + test: {} +nodes: + n01: + profiles: + - default +`, + }, + { + name: "profile list returns all profiles", + args: []string{","}, + stdout: `PROFILE NAME COMMENT/DESCRIPTION + default -- + test --`, + inDb: `WW_INTERNAL: 43 +nodeprofiles: + default: {} + test: {} +nodes: + n01: + profiles: + - default `, }, }