diff --git a/cmd/distro.go b/cmd/distro.go index edd908d..5a45737 100644 --- a/cmd/distro.go +++ b/cmd/distro.go @@ -5,10 +5,12 @@ package cmd import ( + "encoding/json" "fmt" cobbler "github.com/cobbler/cobblerclient" "github.com/spf13/cobra" "github.com/spf13/pflag" + "gopkg.in/yaml.v3" ) func updateDistroFromFlags(cmd *cobra.Command, distro *cobbler.Distro) error { @@ -366,6 +368,7 @@ See https://cobbler.readthedocs.io/en/latest/cobbler.html#cobbler-distro for mor return nil, err } distroCmd.AddCommand(distroReportCmd) + distroCmd.AddCommand(NewDistroExportCmd()) return distroCmd, nil } @@ -678,3 +681,72 @@ func NewDistroReportCmd() (*cobra.Command, error) { distroReportCmd.Flags().String("name", "", "the distro name") return distroReportCmd, nil } + +func NewDistroExportCmd() *cobra.Command { + distroExportCmd := &cobra.Command{ + Use: "export", + Short: "export distributions", + Long: `Export distributions.`, + PreRunE: func(cmd *cobra.Command, args []string) error { + formatOption, err := cmd.Flags().GetString("format") + if err != nil { + return err + } + if formatOption != "json" && formatOption != "yaml" { + return fmt.Errorf("format must be json or yaml") + } + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + err := generateCobblerClient() + if err != nil { + return err + } + + name, err := cmd.Flags().GetString("name") + if err != nil { + return err + } + formatOption, err := cmd.Flags().GetString("format") + if err != nil { + return err + } + + itemNames := make([]string, 0) + if name == "" { + itemNames, err = Client.ListDistroNames() + if err != nil { + return err + } + } else { + itemNames = append(itemNames, name) + } + + for _, itemName := range itemNames { + distro, err := Client.GetDistro(itemName, false, false) + if err != nil { + return err + } + if formatOption == "json" { + jsonDocument, err := json.Marshal(distro) + if err != nil { + return err + } + fmt.Fprintln(cmd.OutOrStdout(), string(jsonDocument)) + } + if formatOption == "yaml" { + yamlDocument, err := yaml.Marshal(distro) + if err != nil { + return err + } + fmt.Fprintln(cmd.OutOrStdout(), "---") + fmt.Fprintln(cmd.OutOrStdout(), string(yamlDocument)) + } + } + return nil + }, + } + distroExportCmd.Flags().String("name", "", "the distro name") + distroExportCmd.Flags().String(exportStringMetadata["format"].Name, exportStringMetadata["format"].DefaultValue, exportStringMetadata["format"].Usage) + return distroExportCmd +} diff --git a/cmd/file.go b/cmd/file.go index 06e090f..6ac1e48 100644 --- a/cmd/file.go +++ b/cmd/file.go @@ -5,10 +5,12 @@ package cmd import ( + "encoding/json" "fmt" cobbler "github.com/cobbler/cobblerclient" "github.com/spf13/cobra" "github.com/spf13/pflag" + "gopkg.in/yaml.v3" ) func updateFileFromFlags(cmd *cobra.Command, file *cobbler.File) error { @@ -103,7 +105,7 @@ func updateFileFromFlags(cmd *cobra.Command, file *cobbler.File) error { } // NewFileCmd builds a new command that represents the file action -func NewFileCmd() *cobra.Command { +func NewFileCmd() (*cobra.Command, error) { fileCmd := &cobra.Command{ Use: "file", Short: "File management", @@ -121,7 +123,8 @@ See https://cobbler.readthedocs.io/en/latest/cobbler.html#cobbler-file for more fileCmd.AddCommand(NewFileRemoveCmd()) fileCmd.AddCommand(NewFileRenameCmd()) fileCmd.AddCommand(NewFileReportCmd()) - return fileCmd + fileCmd.AddCommand(NewFileExportCmd()) + return fileCmd, nil } func NewFileAddCmd() *cobra.Command { @@ -405,3 +408,72 @@ func NewFileReportCmd() *cobra.Command { fileReportCmd.Flags().String("name", "", "the file name") return fileReportCmd } + +func NewFileExportCmd() *cobra.Command { + fileExportCmd := &cobra.Command{ + Use: "export", + Short: "export files", + Long: `Export files.`, + PreRunE: func(cmd *cobra.Command, args []string) error { + formatOption, err := cmd.Flags().GetString("format") + if err != nil { + return err + } + if formatOption != "json" && formatOption != "yaml" { + return fmt.Errorf("format must be json or yaml") + } + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + err := generateCobblerClient() + if err != nil { + return err + } + + name, err := cmd.Flags().GetString("name") + if err != nil { + return err + } + formatOption, err := cmd.Flags().GetString("format") + if err != nil { + return err + } + + itemNames := make([]string, 0) + if name == "" { + itemNames, err = Client.ListFileNames() + if err != nil { + return err + } + } else { + itemNames = append(itemNames, name) + } + + for _, itemName := range itemNames { + file, err := Client.GetFile(itemName, false, false) + if err != nil { + return err + } + if formatOption == "json" { + jsonDocument, err := json.Marshal(file) + if err != nil { + return err + } + fmt.Fprintln(cmd.OutOrStdout(), string(jsonDocument)) + } + if formatOption == "yaml" { + yamlDocument, err := yaml.Marshal(file) + if err != nil { + return err + } + fmt.Fprintln(cmd.OutOrStdout(), "---") + fmt.Fprintln(cmd.OutOrStdout(), string(yamlDocument)) + } + } + return nil + }, + } + fileExportCmd.Flags().String("name", "", "the file name") + fileExportCmd.Flags().String(exportStringMetadata["format"].Name, exportStringMetadata["format"].DefaultValue, exportStringMetadata["format"].Usage) + return fileExportCmd +} diff --git a/cmd/image.go b/cmd/image.go index 4d501bc..238430e 100644 --- a/cmd/image.go +++ b/cmd/image.go @@ -5,10 +5,12 @@ package cmd import ( + "encoding/json" "fmt" cobbler "github.com/cobbler/cobblerclient" "github.com/spf13/cobra" "github.com/spf13/pflag" + "gopkg.in/yaml.v3" ) func updateImageFromFlags(cmd *cobra.Command, image *cobbler.Image) error { @@ -348,7 +350,7 @@ func updateImageFromFlags(cmd *cobra.Command, image *cobbler.Image) error { } // NewImageCmd builds a new command that represents the image action -func NewImageCmd() *cobra.Command { +func NewImageCmd() (*cobra.Command, error) { imageCmd := &cobra.Command{ Use: "image", Short: "Image management", @@ -366,7 +368,8 @@ See https://cobbler.readthedocs.io/en/latest/cobbler.html#cobbler-image for more imageCmd.AddCommand(NewImageRemoveCmd()) imageCmd.AddCommand(NewImageRenameCmd()) imageCmd.AddCommand(NewImageReportCmd()) - return imageCmd + imageCmd.AddCommand(NewImageExportCmd()) + return imageCmd, nil } func NewImageAddCmd() *cobra.Command { @@ -657,3 +660,72 @@ func NewImageReportCmd() *cobra.Command { imageReportCmd.Flags().String("name", "", "the image name") return imageReportCmd } + +func NewImageExportCmd() *cobra.Command { + imageExportCmd := &cobra.Command{ + Use: "export", + Short: "export images", + Long: `Export images.`, + PreRunE: func(cmd *cobra.Command, args []string) error { + formatOption, err := cmd.Flags().GetString("format") + if err != nil { + return err + } + if formatOption != "json" && formatOption != "yaml" { + return fmt.Errorf("format must be json or yaml") + } + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + err := generateCobblerClient() + if err != nil { + return err + } + + name, err := cmd.Flags().GetString("name") + if err != nil { + return err + } + formatOption, err := cmd.Flags().GetString("format") + if err != nil { + return err + } + + itemNames := make([]string, 0) + if name == "" { + itemNames, err = Client.ListImageNames() + if err != nil { + return err + } + } else { + itemNames = append(itemNames, name) + } + + for _, itemName := range itemNames { + image, err := Client.GetImage(itemName, false, false) + if err != nil { + return err + } + if formatOption == "json" { + jsonDocument, err := json.Marshal(image) + if err != nil { + return err + } + fmt.Fprintln(cmd.OutOrStdout(), string(jsonDocument)) + } + if formatOption == "yaml" { + yamlDocument, err := yaml.Marshal(image) + if err != nil { + return err + } + fmt.Fprintln(cmd.OutOrStdout(), "---") + fmt.Fprintln(cmd.OutOrStdout(), string(yamlDocument)) + } + } + return nil + }, + } + imageExportCmd.Flags().String("name", "", "the image name") + imageExportCmd.Flags().String(exportStringMetadata["format"].Name, exportStringMetadata["format"].DefaultValue, exportStringMetadata["format"].Usage) + return imageExportCmd +} diff --git a/cmd/interface.go b/cmd/interface.go index c2c7edf..f61e70f 100644 --- a/cmd/interface.go +++ b/cmd/interface.go @@ -1,10 +1,12 @@ package cmd import ( + "encoding/json" "fmt" cobbler "github.com/cobbler/cobblerclient" "github.com/spf13/cobra" "github.com/spf13/pflag" + "gopkg.in/yaml.v3" "strings" ) @@ -185,7 +187,7 @@ func updateNetworkInterfaceFromFlags(cmd *cobra.Command, networkInterface *cobbl return err } -func NewInterfaceCommand() *cobra.Command { +func NewInterfaceCommand() (*cobra.Command, error) { interfaceCmd := &cobra.Command{ Use: "interface", Short: "Manage interfaces", @@ -199,7 +201,8 @@ func NewInterfaceCommand() *cobra.Command { interfaceCmd.AddCommand(NewInterfaceRemoveCommand()) interfaceCmd.AddCommand(NewInterfaceRenameCommand()) interfaceCmd.AddCommand(NewInterfaceReportCommand()) - return interfaceCmd + interfaceCmd.AddCommand(NewInterfaceExportCmd()) + return interfaceCmd, nil } func NewInterfaceAddCommand() *cobra.Command { @@ -523,3 +526,95 @@ func reportNetworkInterfaces(cmd *cobra.Command, systemNames []string, interface } return nil } + +func NewInterfaceExportCmd() *cobra.Command { + networkInterfaceExportCmd := &cobra.Command{ + Use: "export", + Short: "export network interfaces", + Long: `Export network interfaces.`, + PreRunE: func(cmd *cobra.Command, args []string) error { + formatOption, err := cmd.Flags().GetString("format") + if err != nil { + return err + } + if formatOption != "json" && formatOption != "yaml" { + return fmt.Errorf("format must be json or yaml") + } + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + err := generateCobblerClient() + if err != nil { + return err + } + + systemName, err := cmd.Flags().GetString("system-name") + if err != nil { + return err + } + interfaceName, err := cmd.Flags().GetString("interface-name") + if err != nil { + return err + } + formatOption, err := cmd.Flags().GetString("format") + if err != nil { + return err + } + + itemNames := make([]string, 0) + if systemName == "" { + itemNames, err = Client.ListSystemNames() + if err != nil { + return err + } + } else { + itemNames = append(itemNames, systemName) + } + + for _, itemName := range itemNames { + system, err := Client.GetSystem(itemName, false, false) + if err != nil { + return err + } + + var systemInterfaces cobbler.Interfaces + if interfaceName == "" { + systemInterfaces = system.Interfaces + } else { + systemInterfaces = make(map[string]cobbler.Interface) + intf, interfaceExists := system.Interfaces[interfaceName] + if interfaceExists { + systemInterfaces[interfaceName] = intf + } + } + exportData := struct { + SystemName string `json:"system_name" yaml:"system_name"` + Interfaces cobbler.Interfaces + }{ + itemName, + systemInterfaces, + } + if formatOption == "json" { + jsonDocument, err := json.Marshal(exportData) + if err != nil { + return err + } + fmt.Fprintln(cmd.OutOrStdout(), string(jsonDocument)) + } + if formatOption == "yaml" { + yamlDocument, err := yaml.Marshal(exportData) + if err != nil { + return err + } + fmt.Fprintln(cmd.OutOrStdout(), "---") + fmt.Fprintln(cmd.OutOrStdout(), string(yamlDocument)) + } + } + return nil + }, + } + networkInterfaceExportCmd.Flags().String("interface-name", "", "the network interface name") + networkInterfaceExportCmd.Flags().String("system-name", "", "the system name") + networkInterfaceExportCmd.Flags().String(exportStringMetadata["format"].Name, exportStringMetadata["format"].DefaultValue, exportStringMetadata["format"].Usage) + return networkInterfaceExportCmd +} diff --git a/cmd/menu.go b/cmd/menu.go index 3d6ddc3..0efa43a 100644 --- a/cmd/menu.go +++ b/cmd/menu.go @@ -5,10 +5,12 @@ package cmd import ( + "encoding/json" "fmt" cobbler "github.com/cobbler/cobblerclient" "github.com/spf13/cobra" "github.com/spf13/pflag" + "gopkg.in/yaml.v3" ) func updateMenuFromFlags(cmd *cobra.Command, menu *cobbler.Menu) error { @@ -82,6 +84,7 @@ See https://cobbler.readthedocs.io/en/latest/cobbler.html#cobbler-menu for more } menuCmd.AddCommand(menuRenameCmd) menuCmd.AddCommand(NewMenuReportCmd()) + menuCmd.AddCommand(NewMenuExportCmd()) return menuCmd, nil } @@ -372,3 +375,72 @@ func NewMenuReportCmd() *cobra.Command { menuReportCmd.Flags().String("name", "", "the menu name") return menuReportCmd } + +func NewMenuExportCmd() *cobra.Command { + menuExportCmd := &cobra.Command{ + Use: "export", + Short: "export menus", + Long: `Export menus.`, + PreRunE: func(cmd *cobra.Command, args []string) error { + formatOption, err := cmd.Flags().GetString("format") + if err != nil { + return err + } + if formatOption != "json" && formatOption != "yaml" { + return fmt.Errorf("format must be json or yaml") + } + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + err := generateCobblerClient() + if err != nil { + return err + } + + name, err := cmd.Flags().GetString("name") + if err != nil { + return err + } + formatOption, err := cmd.Flags().GetString("format") + if err != nil { + return err + } + + itemNames := make([]string, 0) + if name == "" { + itemNames, err = Client.ListMenuNames() + if err != nil { + return err + } + } else { + itemNames = append(itemNames, name) + } + + for _, itemName := range itemNames { + menu, err := Client.GetMenu(itemName, false, false) + if err != nil { + return err + } + if formatOption == "json" { + jsonDocument, err := json.Marshal(menu) + if err != nil { + return err + } + fmt.Fprintln(cmd.OutOrStdout(), string(jsonDocument)) + } + if formatOption == "yaml" { + yamlDocument, err := yaml.Marshal(menu) + if err != nil { + return err + } + fmt.Fprintln(cmd.OutOrStdout(), "---") + fmt.Fprintln(cmd.OutOrStdout(), string(yamlDocument)) + } + } + return nil + }, + } + menuExportCmd.Flags().String("name", "", "the menu name") + menuExportCmd.Flags().String(exportStringMetadata["format"].Name, exportStringMetadata["format"].DefaultValue, exportStringMetadata["format"].Usage) + return menuExportCmd +} diff --git a/cmd/metadata.go b/cmd/metadata.go index 548d0b6..b291307 100644 --- a/cmd/metadata.go +++ b/cmd/metadata.go @@ -975,3 +975,11 @@ var findFloatFlagMetadata = map[string]FlagMetadata[float64]{ Usage: "", }, } + +var exportStringMetadata = map[string]FlagMetadata[string]{ + "format": { + Name: "format", + DefaultValue: "json", + Usage: `the export format, must be one of "JSON" or "YAML"`, + }, +} diff --git a/cmd/mgmtclass.go b/cmd/mgmtclass.go index d308081..aaf8848 100644 --- a/cmd/mgmtclass.go +++ b/cmd/mgmtclass.go @@ -5,10 +5,12 @@ package cmd import ( + "encoding/json" "fmt" cobbler "github.com/cobbler/cobblerclient" "github.com/spf13/cobra" "github.com/spf13/pflag" + "gopkg.in/yaml.v3" ) func updateMgmtClassFromFlags(cmd *cobra.Command, mgmtClass *cobbler.MgmtClass) error { @@ -107,7 +109,7 @@ func updateMgmtClassFromFlags(cmd *cobra.Command, mgmtClass *cobbler.MgmtClass) } // NewMgmtClassCmd builds a new command that represents the mgmtclass action -func NewMgmtClassCmd() *cobra.Command { +func NewMgmtClassCmd() (*cobra.Command, error) { mgmtclassCmd := &cobra.Command{ Use: "mgmtclass", Short: "Mgmtclass management", @@ -125,7 +127,8 @@ See https://cobbler.readthedocs.io/en/latest/cobbler.html#cobbler-mgmtclass for mgmtclassCmd.AddCommand(NewMgmtClassRemoveCmd()) mgmtclassCmd.AddCommand(NewMgmtClassRenameCmd()) mgmtclassCmd.AddCommand(NewMgmtClassReportCmd()) - return mgmtclassCmd + mgmtclassCmd.AddCommand(NewMgmtClassExportCmd()) + return mgmtclassCmd, nil } func NewMgmtClassAddCmd() *cobra.Command { @@ -426,3 +429,72 @@ func NewMgmtClassReportCmd() *cobra.Command { mgmtclassReportCmd.Flags().String("name", "", "the mgmtclass name") return mgmtclassReportCmd } + +func NewMgmtClassExportCmd() *cobra.Command { + mgmtClassExportCmd := &cobra.Command{ + Use: "export", + Short: "export management classes", + Long: `Export management classes.`, + PreRunE: func(cmd *cobra.Command, args []string) error { + formatOption, err := cmd.Flags().GetString("format") + if err != nil { + return err + } + if formatOption != "json" && formatOption != "yaml" { + return fmt.Errorf("format must be json or yaml") + } + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + err := generateCobblerClient() + if err != nil { + return err + } + + name, err := cmd.Flags().GetString("name") + if err != nil { + return err + } + formatOption, err := cmd.Flags().GetString("format") + if err != nil { + return err + } + + itemNames := make([]string, 0) + if name == "" { + itemNames, err = Client.ListMgmtClassNames() + if err != nil { + return err + } + } else { + itemNames = append(itemNames, name) + } + + for _, itemName := range itemNames { + mgmtClass, err := Client.GetMgmtClass(itemName, false, false) + if err != nil { + return err + } + if formatOption == "json" { + jsonDocument, err := json.Marshal(mgmtClass) + if err != nil { + return err + } + fmt.Fprintln(cmd.OutOrStdout(), string(jsonDocument)) + } + if formatOption == "yaml" { + yamlDocument, err := yaml.Marshal(mgmtClass) + if err != nil { + return err + } + fmt.Fprintln(cmd.OutOrStdout(), "---") + fmt.Fprintln(cmd.OutOrStdout(), string(yamlDocument)) + } + } + return nil + }, + } + mgmtClassExportCmd.Flags().String("name", "", "the management class name") + mgmtClassExportCmd.Flags().String(exportStringMetadata["format"].Name, exportStringMetadata["format"].DefaultValue, exportStringMetadata["format"].Usage) + return mgmtClassExportCmd +} diff --git a/cmd/package.go b/cmd/package.go index b8b80a4..2a72a4c 100644 --- a/cmd/package.go +++ b/cmd/package.go @@ -5,10 +5,12 @@ package cmd import ( + "encoding/json" "fmt" cobbler "github.com/cobbler/cobblerclient" "github.com/spf13/cobra" "github.com/spf13/pflag" + "gopkg.in/yaml.v3" ) func updatePackageFromFlags(cmd *cobra.Command, p *cobbler.Package) error { @@ -72,7 +74,7 @@ func updatePackageFromFlags(cmd *cobra.Command, p *cobbler.Package) error { } // NewPackageCmd builds a new command that represents the package action -func NewPackageCmd() *cobra.Command { +func NewPackageCmd() (*cobra.Command, error) { packageCmd := &cobra.Command{ Use: "package", Short: "Package management", @@ -90,7 +92,8 @@ See https://cobbler.readthedocs.io/en/latest/cobbler.html#cobbler-package for mo packageCmd.AddCommand(NewPackageRemoveCmd()) packageCmd.AddCommand(NewPackageRenameCmd()) packageCmd.AddCommand(NewPackageReportCmd()) - return packageCmd + packageCmd.AddCommand(NewPackageExportCmd()) + return packageCmd, nil } func NewPackageAddCmd() *cobra.Command { @@ -375,3 +378,72 @@ func NewPackageReportCmd() *cobra.Command { packageReportCmd.Flags().String("name", "", "the package name") return packageReportCmd } + +func NewPackageExportCmd() *cobra.Command { + packageExportCmd := &cobra.Command{ + Use: "export", + Short: "export packages", + Long: `Export packages.`, + PreRunE: func(cmd *cobra.Command, args []string) error { + formatOption, err := cmd.Flags().GetString("format") + if err != nil { + return err + } + if formatOption != "json" && formatOption != "yaml" { + return fmt.Errorf("format must be json or yaml") + } + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + err := generateCobblerClient() + if err != nil { + return err + } + + name, err := cmd.Flags().GetString("name") + if err != nil { + return err + } + formatOption, err := cmd.Flags().GetString("format") + if err != nil { + return err + } + + itemNames := make([]string, 0) + if name == "" { + itemNames, err = Client.ListPackageNames() + if err != nil { + return err + } + } else { + itemNames = append(itemNames, name) + } + + for _, itemName := range itemNames { + linuxpackage, err := Client.GetPackage(itemName, false, false) + if err != nil { + return err + } + if formatOption == "json" { + jsonDocument, err := json.Marshal(linuxpackage) + if err != nil { + return err + } + fmt.Fprintln(cmd.OutOrStdout(), string(jsonDocument)) + } + if formatOption == "yaml" { + yamlDocument, err := yaml.Marshal(linuxpackage) + if err != nil { + return err + } + fmt.Fprintln(cmd.OutOrStdout(), "---") + fmt.Fprintln(cmd.OutOrStdout(), string(yamlDocument)) + } + } + return nil + }, + } + packageExportCmd.Flags().String("name", "", "the package name") + packageExportCmd.Flags().String(exportStringMetadata["format"].Name, exportStringMetadata["format"].DefaultValue, exportStringMetadata["format"].Usage) + return packageExportCmd +} diff --git a/cmd/profile.go b/cmd/profile.go index 452ba11..bc01a59 100644 --- a/cmd/profile.go +++ b/cmd/profile.go @@ -5,10 +5,12 @@ package cmd import ( + "encoding/json" "fmt" cobbler "github.com/cobbler/cobblerclient" "github.com/spf13/cobra" "github.com/spf13/pflag" + "gopkg.in/yaml.v3" ) func updateProfileFromFlags(cmd *cobra.Command, profile *cobbler.Profile) error { @@ -506,7 +508,7 @@ func updateProfileFromFlags(cmd *cobra.Command, profile *cobbler.Profile) error } // NewProfileCmd builds a new command that represents the profile action -func NewProfileCmd() *cobra.Command { +func NewProfileCmd() (*cobra.Command, error) { profileCmd := &cobra.Command{ Use: "profile", Short: "Profile management", @@ -526,7 +528,8 @@ See https://cobbler.readthedocs.io/en/latest/cobbler.html#cobbler-profile for mo profileCmd.AddCommand(NewProfileRemoveCmd()) profileCmd.AddCommand(NewProfileRenameCmd()) profileCmd.AddCommand(NewProfileReportCmd()) - return profileCmd + profileCmd.AddCommand(NewProfileExportCmd()) + return profileCmd, nil } func NewProfileAddCmd() *cobra.Command { @@ -906,3 +909,72 @@ func NewProfileReportCmd() *cobra.Command { profileReportCmd.Flags().String("name", "", "the profile name") return profileReportCmd } + +func NewProfileExportCmd() *cobra.Command { + profileExportCmd := &cobra.Command{ + Use: "export", + Short: "export profiles", + Long: `Export profiles.`, + PreRunE: func(cmd *cobra.Command, args []string) error { + formatOption, err := cmd.Flags().GetString("format") + if err != nil { + return err + } + if formatOption != "json" && formatOption != "yaml" { + return fmt.Errorf("format must be json or yaml") + } + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + err := generateCobblerClient() + if err != nil { + return err + } + + name, err := cmd.Flags().GetString("name") + if err != nil { + return err + } + formatOption, err := cmd.Flags().GetString("format") + if err != nil { + return err + } + + itemNames := make([]string, 0) + if name == "" { + itemNames, err = Client.ListProfileNames() + if err != nil { + return err + } + } else { + itemNames = append(itemNames, name) + } + + for _, itemName := range itemNames { + profile, err := Client.GetProfile(itemName, false, false) + if err != nil { + return err + } + if formatOption == "json" { + jsonDocument, err := json.Marshal(profile) + if err != nil { + return err + } + fmt.Fprintln(cmd.OutOrStdout(), string(jsonDocument)) + } + if formatOption == "yaml" { + yamlDocument, err := yaml.Marshal(profile) + if err != nil { + return err + } + fmt.Fprintln(cmd.OutOrStdout(), "---") + fmt.Fprintln(cmd.OutOrStdout(), string(yamlDocument)) + } + } + return nil + }, + } + profileExportCmd.Flags().String("name", "", "the profile name") + profileExportCmd.Flags().String(exportStringMetadata["format"].Name, exportStringMetadata["format"].DefaultValue, exportStringMetadata["format"].Usage) + return profileExportCmd +} diff --git a/cmd/repo.go b/cmd/repo.go index 8a4d698..0bb54ee 100644 --- a/cmd/repo.go +++ b/cmd/repo.go @@ -5,10 +5,12 @@ package cmd import ( + "encoding/json" "fmt" cobbler "github.com/cobbler/cobblerclient" "github.com/spf13/cobra" "github.com/spf13/pflag" + "gopkg.in/yaml.v3" ) func updateRepoFromFlags(cmd *cobra.Command, repo *cobbler.Repo) error { @@ -171,7 +173,7 @@ func updateRepoFromFlags(cmd *cobra.Command, repo *cobbler.Repo) error { } // NewRepoCmd builds a new command that represents the repo action -func NewRepoCmd() *cobra.Command { +func NewRepoCmd() (*cobra.Command, error) { repoCmd := &cobra.Command{ Use: "repo", Short: "Repository management", @@ -190,7 +192,8 @@ See https://cobbler.readthedocs.io/en/latest/cobbler.html#cobbler-repo for more repoCmd.AddCommand(NewRepoRemoveCmd()) repoCmd.AddCommand(NewRepoRenameCmd()) repoCmd.AddCommand(NewRepoReportCmd()) - return repoCmd + repoCmd.AddCommand(NewRepoExportCmd()) + return repoCmd, nil } func NewRepoAddCmd() *cobra.Command { @@ -506,3 +509,72 @@ func NewRepoReportCmd() *cobra.Command { repoReportCmd.Flags().String("name", "", "the repo name") return repoReportCmd } + +func NewRepoExportCmd() *cobra.Command { + repoExportCmd := &cobra.Command{ + Use: "export", + Short: "export repositories", + Long: `Export repositories.`, + PreRunE: func(cmd *cobra.Command, args []string) error { + formatOption, err := cmd.Flags().GetString("format") + if err != nil { + return err + } + if formatOption != "json" && formatOption != "yaml" { + return fmt.Errorf("format must be json or yaml") + } + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + err := generateCobblerClient() + if err != nil { + return err + } + + name, err := cmd.Flags().GetString("name") + if err != nil { + return err + } + formatOption, err := cmd.Flags().GetString("format") + if err != nil { + return err + } + + itemNames := make([]string, 0) + if name == "" { + itemNames, err = Client.ListRepoNames() + if err != nil { + return err + } + } else { + itemNames = append(itemNames, name) + } + + for _, itemName := range itemNames { + repo, err := Client.GetRepo(itemName, false, false) + if err != nil { + return err + } + if formatOption == "json" { + jsonDocument, err := json.Marshal(repo) + if err != nil { + return err + } + fmt.Fprintln(cmd.OutOrStdout(), string(jsonDocument)) + } + if formatOption == "yaml" { + yamlDocument, err := yaml.Marshal(repo) + if err != nil { + return err + } + fmt.Fprintln(cmd.OutOrStdout(), "---") + fmt.Fprintln(cmd.OutOrStdout(), string(yamlDocument)) + } + } + return nil + }, + } + repoExportCmd.Flags().String("name", "", "the repository name") + repoExportCmd.Flags().String(exportStringMetadata["format"].Name, exportStringMetadata["format"].DefaultValue, exportStringMetadata["format"].Usage) + return repoExportCmd +} diff --git a/cmd/root.go b/cmd/root.go index b252d35..263efde 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -46,28 +46,44 @@ func NewRootCmd() *cobra.Command { cobra.CheckErr(err) rootCmd.AddCommand(distroCmd) rootCmd.AddCommand(NewEventCmd()) - rootCmd.AddCommand(NewFileCmd()) + fileCmd, err := NewFileCmd() + cobra.CheckErr(err) + rootCmd.AddCommand(fileCmd) rootCmd.AddCommand(NewHardlinkCmd()) - rootCmd.AddCommand(NewImageCmd()) + imageCmd, err := NewImageCmd() + cobra.CheckErr(err) + rootCmd.AddCommand(imageCmd) rootCmd.AddCommand(NewImportCmd()) - rootCmd.AddCommand(NewInterfaceCommand()) + networkInterfaceCmd, err := NewInterfaceCommand() + cobra.CheckErr(err) + rootCmd.AddCommand(networkInterfaceCmd) rootCmd.AddCommand(NewListCmd()) menuCmd, err := NewMenuCmd() cobra.CheckErr(err) rootCmd.AddCommand(menuCmd) - rootCmd.AddCommand(NewMgmtClassCmd()) + mgmtClassCmd, err := NewMgmtClassCmd() + cobra.CheckErr(err) + rootCmd.AddCommand(mgmtClassCmd) rootCmd.AddCommand(NewMkLoadersCmd()) - rootCmd.AddCommand(NewPackageCmd()) - rootCmd.AddCommand(NewProfileCmd()) + packageCmd, err := NewPackageCmd() + cobra.CheckErr(err) + rootCmd.AddCommand(packageCmd) + profileCmd, err := NewProfileCmd() + cobra.CheckErr(err) + rootCmd.AddCommand(profileCmd) rootCmd.AddCommand(NewReplicateCmd()) - rootCmd.AddCommand(NewRepoCmd()) + repoCmd, err := NewRepoCmd() + cobra.CheckErr(err) + rootCmd.AddCommand(repoCmd) rootCmd.AddCommand(NewReportCmd()) rootCmd.AddCommand(NewRepoSyncCmd()) rootCmd.AddCommand(NewSettingCmd()) rootCmd.AddCommand(NewSignatureCmd()) rootCmd.AddCommand(NewStatusCmd()) rootCmd.AddCommand(NewSyncCmd()) - rootCmd.AddCommand(NewSystemCmd()) + systemCmd, err := NewSystemCmd() + cobra.CheckErr(err) + rootCmd.AddCommand(systemCmd) rootCmd.AddCommand(NewValidateAutoinstallsCmd()) rootCmd.AddCommand(NewVersionCmd()) return rootCmd diff --git a/cmd/system.go b/cmd/system.go index f4ff70f..0f2aeb1 100644 --- a/cmd/system.go +++ b/cmd/system.go @@ -5,10 +5,12 @@ package cmd import ( + "encoding/json" "fmt" cobbler "github.com/cobbler/cobblerclient" "github.com/spf13/cobra" "github.com/spf13/pflag" + "gopkg.in/yaml.v3" ) func updateSystemFromFlags(cmd *cobra.Command, system *cobbler.System) error { @@ -764,7 +766,7 @@ func updateSystemFromFlags(cmd *cobra.Command, system *cobbler.System) error { } // NewSystemCmd builds a new command that represents the system action -func NewSystemCmd() *cobra.Command { +func NewSystemCmd() (*cobra.Command, error) { systemCmd := &cobra.Command{ Use: "system", Short: "System management", @@ -788,7 +790,8 @@ See https://cobbler.readthedocs.io/en/latest/cobbler.html#cobbler-system for mor systemCmd.AddCommand(NewSystemRemoveCmd()) systemCmd.AddCommand(NewSystemRenameCmd()) systemCmd.AddCommand(NewSystemReportCmd()) - return systemCmd + systemCmd.AddCommand(NewSystemExportCmd()) + return systemCmd, nil } func NewSystemAddCmd() *cobra.Command { @@ -1348,3 +1351,72 @@ func NewSystemReportCmd() *cobra.Command { systemReportCmd.Flags().String("name", "", "the system name") return systemReportCmd } + +func NewSystemExportCmd() *cobra.Command { + systemExportCmd := &cobra.Command{ + Use: "export", + Short: "export systems", + Long: `Export systems.`, + PreRunE: func(cmd *cobra.Command, args []string) error { + formatOption, err := cmd.Flags().GetString("format") + if err != nil { + return err + } + if formatOption != "json" && formatOption != "yaml" { + return fmt.Errorf("format must be json or yaml") + } + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + err := generateCobblerClient() + if err != nil { + return err + } + + name, err := cmd.Flags().GetString("name") + if err != nil { + return err + } + formatOption, err := cmd.Flags().GetString("format") + if err != nil { + return err + } + + itemNames := make([]string, 0) + if name == "" { + itemNames, err = Client.ListSystemNames() + if err != nil { + return err + } + } else { + itemNames = append(itemNames, name) + } + + for _, itemName := range itemNames { + system, err := Client.GetSystem(itemName, false, false) + if err != nil { + return err + } + if formatOption == "json" { + jsonDocument, err := json.Marshal(system) + if err != nil { + return err + } + fmt.Fprintln(cmd.OutOrStdout(), string(jsonDocument)) + } + if formatOption == "yaml" { + yamlDocument, err := yaml.Marshal(system) + if err != nil { + return err + } + fmt.Fprintln(cmd.OutOrStdout(), "---") + fmt.Fprintln(cmd.OutOrStdout(), string(yamlDocument)) + } + } + return nil + }, + } + systemExportCmd.Flags().String("name", "", "the system name") + systemExportCmd.Flags().String(exportStringMetadata["format"].Name, exportStringMetadata["format"].DefaultValue, exportStringMetadata["format"].Usage) + return systemExportCmd +} diff --git a/go.mod b/go.mod index 90c105c..b616681 100644 --- a/go.mod +++ b/go.mod @@ -3,10 +3,11 @@ module github.com/cobbler/cli go 1.22 require ( - github.com/cobbler/cobblerclient v0.5.7 + github.com/cobbler/cobblerclient v0.5.8 github.com/spf13/cobra v1.8.1 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.19.0 + gopkg.in/yaml.v3 v3.0.1 ) require ( @@ -32,5 +33,4 @@ require ( golang.org/x/sys v0.18.0 // indirect golang.org/x/text v0.14.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 39883fc..b483321 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/cobbler/cobblerclient v0.5.7 h1:0G/lvlmssCCpV8MiuqcOlL1P2BwwHh+V05aF3vHnr6k= -github.com/cobbler/cobblerclient v0.5.7/go.mod h1:n6b8fTUOlg7BdMl6FeifUm4Uk1JY6/tlTlOClV4x2Wc= +github.com/cobbler/cobblerclient v0.5.8 h1:4P5x3M0sy0PBgBY7uULI70FXUQqLC2RyTyFhVWusH8o= +github.com/cobbler/cobblerclient v0.5.8/go.mod h1:n6b8fTUOlg7BdMl6FeifUm4Uk1JY6/tlTlOClV4x2Wc= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=