From 2ba6e282152c697365fc5f485049f78e57f5c591 Mon Sep 17 00:00:00 2001 From: Jonathon Anderson Date: Wed, 2 Jul 2025 21:25:54 -0600 Subject: [PATCH] Remove wwctl node import --csv - Closes #1862 Signed-off-by: Jonathon Anderson --- CHANGELOG.md | 1 + internal/app/wwctl/node/imprt/main.go | 60 ++++----------------------- internal/app/wwctl/node/imprt/root.go | 19 +-------- userdocs/nodes/nodes.rst | 47 ++++----------------- 4 files changed, 19 insertions(+), 108 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b738ca89..21d26535 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Removed - Removed the gRPC API servers and client. #1876 +- Removed ``wwctl node import --csv``. #1862 ## v4.6.1, 2025-04-04 diff --git a/internal/app/wwctl/node/imprt/main.go b/internal/app/wwctl/node/imprt/main.go index 61e5b9cc..67ab62de 100644 --- a/internal/app/wwctl/node/imprt/main.go +++ b/internal/app/wwctl/node/imprt/main.go @@ -1,8 +1,6 @@ package imprt import ( - "bytes" - "encoding/csv" "fmt" "io" "os" @@ -27,56 +25,16 @@ func CobraRunE(cmd *cobra.Command, args []string) error { if err != nil { return fmt.Errorf("could not read: %s", err) } - if !ImportCSV { - err = yaml.Unmarshal(buffer, importMap) - if err == nil { - 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) - } - } - } else { - return fmt.Errorf("could not parse import file: %s", err) - } - } else { - // reading from buffer is a bit overshot - csvReader := csv.NewReader(bytes.NewReader(buffer)) - records, err := csvReader.ReadAll() + + err = yaml.Unmarshal(buffer, importMap) + if err != nil { + return fmt.Errorf("could not parse import file: %s", err) + } + + 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("could not parse %s: %s", args[0], err) - } - if len(records) < 1 || len(records[0]) < 1 { - return fmt.Errorf("did not find any data in %s", args[0]) - } - if !(records[0][0] == "node" || records[0][0] == "nodename") { - Usage() - os.Exit(1) - } - argsLen := len(records[0]) - for i, line := range records[1:] { - if len(line) != argsLen { - return fmt.Errorf("wrong number of fields in lube %d", i+1) - } - for j := range line { - if j == 0 { - continue - } - if importMap[line[0]] == nil { - importMap[line[0]] = new(node.Node) - } - } - } - 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 { - return fmt.Errorf("got following problem when creating yaml: %s", err) - } - err = apinode.NodeAddFromYaml(&wwapiv1.NodeYaml{NodeConfMapYaml: string(buffer)}) - if err != nil { - return fmt.Errorf("got following problem when writing back yaml: %s", err) - } + return fmt.Errorf("got following problem when writing back yaml: %s", err) } } diff --git a/internal/app/wwctl/node/imprt/root.go b/internal/app/wwctl/node/imprt/root.go index 225b0e64..a565efa9 100644 --- a/internal/app/wwctl/node/imprt/root.go +++ b/internal/app/wwctl/node/imprt/root.go @@ -1,8 +1,6 @@ package imprt import ( - "fmt" - "github.com/spf13/cobra" ) @@ -11,22 +9,15 @@ var ( DisableFlagsInUseLine: true, 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.", + Long: "This command imports all the nodes defined in a YAML file. It will overwrite nodes with same name.", RunE: CobraRunE, Args: cobra.ExactArgs(1), Aliases: []string{"import"}, } - ImportCSV bool - setYes bool + setYes bool ) func init() { - 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") } @@ -34,9 +25,3 @@ func init() { func GetCommand() *cobra.Command { return baseCmd } - -func Usage() { - fmt.Println(`The csv file must be structured in following way: -node,option1,option2,net.netname1.netopt -node01,value1,value2,net.netname1,netvalue`) -} diff --git a/userdocs/nodes/nodes.rst b/userdocs/nodes/nodes.rst index f9465ec6..ebc3307f 100644 --- a/userdocs/nodes/nodes.rst +++ b/userdocs/nodes/nodes.rst @@ -203,47 +203,14 @@ Resources can only be managed with ``wwctl node edit``. Importing Nodes From a File =========================== -You can import nodes into Warewulf by using the ``wwctl node import`` command. The -file used must be in YAML or CSV format. +You can import nodes into Warewulf by using the ``wwctl node import`` command. +The file used must be in YAML format. -.. warning:: - Importing a node configuration will fully overwrite the existing settings, - including any customizations not present in the import file. If the node - already exists and you wish to update it, ensure that the import file - includes all the options you want to retain. - -CSV Import ----------- - -.. note:: - As of Warewulf v4.6.1, the csv import functionality is broken and an - `issue `_ - has been created to track this. - -The CSV file must have a header where the first field must always be the nodename, -and the rest of the fields are the same as the long commandline options. Network -device must have the form ``net.$NETNAME.$NETOPTION``. (e.g., ``net.default.ipaddr``). -Tags are currently not supported and must be added separately after the import. - -As an example, the following CSV file: - -.. code-block:: csv - - nodename,net.default.hwaddr,net.default.ipaddr,net.default.netmask,net.default.gateway,discoverable,image - n1,00:00:00:00:00:01,10.0.2.1,255.255.255.0,10.0.2.254,false,rockylinux-9 - -This can be imported with the following command: - -.. code-block:: shell - - wwctl node import --csv /path/to/nodes.csv - -YAML Import ------------ - -The YAML file must be a mapping of node names to their attributes, where each node is represented as a dictionary of attributes. -To simplify the creation of the YAML file, you can use the wwctl node export command to export the current node configuration to a YAML file. -This exported file can serve as a template for creating new nodes. +The YAML file must be a mapping of node names to their attributes, where each +node is represented as a dictionary of attributes. To simplify the creation of +the YAML file, you can use the wwctl node export command to export the current +node configuration to a YAML file. This exported file can serve as a template +for creating new nodes. A minimal example of a YAML file looks like this: