diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b1e9f95..41838b55 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Added `wwctl overlay import --overwrite` to overwrite existing overlay file. - wwclient uses `WW_IPADDR`, if set, to contact the Warewulf server. #1788 +- Add `wwctl node import --yes` to assume yes to confirmations. ### Fixed @@ -31,6 +32,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Update GitHub actions to build aarch64 artifacts. - Explicitly enforce the number or arguments accepted by some `wwctl` subcommands. #1717 +- Renamed `wwctl node import --cvs` to `--csv`. ### Removed diff --git a/internal/app/wwctl/node/imprt/main.go b/internal/app/wwctl/node/imprt/main.go index f83fabd1..61e5b9cc 100644 --- a/internal/app/wwctl/node/imprt/main.go +++ b/internal/app/wwctl/node/imprt/main.go @@ -27,11 +27,10 @@ func CobraRunE(cmd *cobra.Command, args []string) error { if err != nil { return fmt.Errorf("could not read: %s", err) } - if !ImportCVS { + if !ImportCSV { err = yaml.Unmarshal(buffer, importMap) if err == nil { - yes := util.Confirm(fmt.Sprintf("Are you sure you want to modify %d nodes", len(importMap))) - if yes { + if setYes || util.Confirm(fmt.Sprintf("Are you sure you want to modify %d nodes", len(importMap))) { err = apinode.NodeAddFromYaml(&wwapiv1.NodeYaml{NodeConfMapYaml: string(buffer)}) if err != nil { return fmt.Errorf("got following problem when writing back yaml: %s", err) @@ -68,8 +67,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error { } } } - yes := util.Confirm(fmt.Sprintf("Are you sure you want to import %d nodes", len(importMap))) - if yes { + if setYes || util.Confirm(fmt.Sprintf("Are you sure you want to import %d nodes", len(importMap))) { // create second buffer an marshall nodeMap to it buffer, err = yaml.Marshal(importMap) if err != nil { diff --git a/internal/app/wwctl/node/imprt/main_test.go b/internal/app/wwctl/node/imprt/main_test.go new file mode 100644 index 00000000..8ac0ceca --- /dev/null +++ b/internal/app/wwctl/node/imprt/main_test.go @@ -0,0 +1,81 @@ +package imprt + +import ( + "bytes" + "os" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/warewulf/warewulf/internal/pkg/testenv" + "github.com/warewulf/warewulf/internal/pkg/warewulfd" +) + +func Test_Node_Import(t *testing.T) { + tests := map[string]struct { + args []string + importFile string + wantErr bool + inDB string + outDB string + }{ + "import new node": { + args: []string{"importFile"}, + importFile: ` +n1: + id: n1 + profiles: + - default + network devices: + eth0: + device: eth0 + hwaddr: c4:cb:e1:bb:dd:e9 + ipaddr: 192.168.1.10`, + wantErr: false, + inDB: ` +nodeprofiles: {} +nodes: {}`, + outDB: ` +nodeprofiles: {} +nodes: + n1: + profiles: + - default + network devices: + eth0: + device: eth0 + hwaddr: c4:cb:e1:bb:dd:e9 + ipaddr: 192.168.1.10`, + }, + } + + for name, tt := range tests { + t.Run(name, func(t *testing.T) { + env := testenv.New(t) + defer env.RemoveAll() + { + wd, err := os.Getwd() + assert.NoError(t, err) + defer func() { assert.NoError(t, os.Chdir(wd)) }() + } + assert.NoError(t, os.Chdir(env.GetPath("."))) + env.WriteFile("./importFile", tt.importFile) + env.WriteFile("etc/warewulf/nodes.conf", tt.inDB) + warewulfd.SetNoDaemon() + + baseCmd := GetCommand() + args := append(tt.args, "--yes") + baseCmd.SetArgs(args) + buf := new(bytes.Buffer) + baseCmd.SetOut(buf) + baseCmd.SetErr(buf) + err := baseCmd.Execute() + if tt.wantErr { + assert.Error(t, err) + } else { + assert.NoError(t, err) + content := env.ReadFile("etc/warewulf/nodes.conf") + assert.YAMLEq(t, tt.outDB, content) + } + }) + } +} diff --git a/internal/app/wwctl/node/imprt/root.go b/internal/app/wwctl/node/imprt/root.go index 3aa9bbcc..225b0e64 100644 --- a/internal/app/wwctl/node/imprt/root.go +++ b/internal/app/wwctl/node/imprt/root.go @@ -9,18 +9,25 @@ import ( var ( baseCmd = &cobra.Command{ DisableFlagsInUseLine: true, - Use: "import [OPTIONS] NODENAME", - Short: "Import node(s) from yaml file", + Use: "import [OPTIONS] FILE", + Short: "Import node(s) from yaml FILE", Long: "This command imports all the nodes defined in a file. It will overwrite nodes with same name.", RunE: CobraRunE, Args: cobra.ExactArgs(1), Aliases: []string{"import"}, } - ImportCVS bool + ImportCSV bool + setYes bool ) func init() { - baseCmd.PersistentFlags().BoolVarP(&ImportCVS, "cvs", "c", false, "Import CVS file") + baseCmd.PersistentFlags().BoolVarP(&ImportCSV, "csv", "c", false, "Import CSV file") + baseCmd.Flags().BoolVar(&ImportCSV, "cvs", false, "Import CSV file") + baseCmd.Flags().Lookup("cvs").Hidden = true + if err := baseCmd.Flags().MarkDeprecated("cvs", "use --csv instead"); err != nil { + panic(err) + } + baseCmd.PersistentFlags().BoolVarP(&setYes, "yes", "y", false, "Set 'yes' to all questions asked") } // GetRootCommand returns the root cobra.Command for the application.