Remove wwctl node import --csv

- Closes #1862

Signed-off-by: Jonathon Anderson <janderson@ciq.com>
This commit is contained in:
Jonathon Anderson
2025-07-02 21:25:54 -06:00
parent 1d3f0095fa
commit 2ba6e28215
4 changed files with 19 additions and 108 deletions

View File

@@ -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

View File

@@ -1,8 +1,6 @@
package imprt
import (
"bytes"
"encoding/csv"
"fmt"
"io"
"os"
@@ -27,58 +25,18 @@ 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 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("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()
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 nil
}

View File

@@ -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
)
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`)
}

View File

@@ -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 <https://github.com/warewulf/warewulf/issues/1862>`_
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: