diff --git a/cobblerclient.go b/cobblerclient.go
index b0fdf8e..2fd5802 100644
--- a/cobblerclient.go
+++ b/cobblerclient.go
@@ -20,13 +20,14 @@ import (
"bytes"
"errors"
"fmt"
- "github.com/go-viper/mapstructure/v2"
- "github.com/kolo/xmlrpc"
"io"
"net/http"
"reflect"
"sort"
"strings"
+
+ "github.com/go-viper/mapstructure/v2"
+ "github.com/kolo/xmlrpc"
)
const bodyTypeXML = "text/xml"
@@ -157,11 +158,15 @@ func (c *Client) Ping() (bool, error) {
}
}
-// AutoAddRepos automatically imports any repos server side that are known to the daemon. It is the responsitbility
-// of the caller to execute [Client.BackgroundReposync].
-func (c *Client) AutoAddRepos() error {
- _, err := c.Call("auto_add_repos", c.Token)
- return err
+// AutoAddRepos automatically imports any repos server-side that are known to the daemon.
+// Returns whether the operation succeeded. The caller is responsible for following up
+// with [Client.BackgroundReposync].
+func (c *Client) AutoAddRepos() (bool, error) {
+ result, err := c.Call("auto_add_repos", c.Token)
+ if err != nil {
+ return false, err
+ }
+ return result.(bool), nil
}
// GetAutoinstallTemplates retrieves a list of all templates that are in use by Cobbler.
@@ -176,10 +181,13 @@ func (c *Client) GetAutoinstallSnippets() error {
return err
}
-// IsAutoinstallInUse checks if a given system has reported that it is currently installing.
-func (c *Client) IsAutoinstallInUse(name string) error {
- _, err := c.Call("is_autoinstall_in_use", name, c.Token)
- return err
+// IsAutoinstallInUse reports whether the named system is currently installing.
+func (c *Client) IsAutoinstallInUse(name string) (bool, error) {
+ result, err := c.Call("is_autoinstall_in_use", name, c.Token)
+ if err != nil {
+ return false, err
+ }
+ return result.(bool), nil
}
// GenerateIPxe generates the iPXE (formerly gPXE) configuration data.
@@ -206,36 +214,82 @@ func (c *Client) GetBlendedData(profile, system string) (map[string]interface{},
return result.(map[string]interface{}), err
}
-// RegisterNewSystem registers a new system without a Cobbler token. This is normally called
-// during unattended installation by a script.
-func (c *Client) RegisterNewSystem(info map[string]interface{}) error {
- _, err := c.Call("register_new_system", info, c.Token)
- return err
+// RegisterNewSystem registers a new system without a Cobbler token. Normally
+// called during unattended installation by a script. Returns the backend's
+// status code (0 on success).
+func (c *Client) RegisterNewSystem(info map[string]interface{}) (int, error) {
+ result, err := c.Call("register_new_system", info, c.Token)
+ if err != nil {
+ return -1, err
+ }
+ return convertToInt(result)
}
-// RunInstallTriggers runs installation triggers for a given object. This is normally called during
-// unattended installation.
-func (c *Client) RunInstallTriggers(mode string, objtype string, name string, ip string) error {
- _, err := c.Call("run_install_triggers", mode, objtype, name, ip, c.Token)
- return err
+// RunInstallTriggers runs installation triggers for a given object. Normally
+// called during unattended installation. mode is "pre", "post", or "firstboot";
+// objtype is "system" or "profile". Returns whether the trigger ran successfully.
+func (c *Client) RunInstallTriggers(mode, objtype, name, ip string) (bool, error) {
+ result, err := c.Call("run_install_triggers", mode, objtype, name, ip, c.Token)
+ if err != nil {
+ return false, err
+ }
+ return result.(bool), nil
}
-// GetReposCompatibleWithProfile returns all repositories that can be potentially assigned to a given profile.
-func (c *Client) GetReposCompatibleWithProfile(profile_name string) error {
- _, err := c.Call("get_repos_compatible_with_profile", profile_name, c.Token)
- return err
+// GetReposCompatibleWithProfile returns all repositories that can be assigned
+// to the named profile (filtered by arch compatibility with the profile's distro).
+func (c *Client) GetReposCompatibleWithProfile(profileName string) ([]map[string]interface{}, error) {
+ result, err := c.Call("get_repos_compatible_with_profile", profileName, c.Token)
+ if err != nil {
+ return nil, err
+ }
+ raw, ok := result.([]interface{})
+ if !ok {
+ return nil, fmt.Errorf("get_repos_compatible_with_profile returned %T, want list", result)
+ }
+ out := make([]map[string]interface{}, 0, len(raw))
+ for _, v := range raw {
+ if m, ok := v.(map[string]interface{}); ok {
+ out = append(out, m)
+ }
+ }
+ return out, nil
}
-// FindSystemByDnsName searches for a system with a given DNS name.
-func (c *Client) FindSystemByDnsName(dns_name string) error {
- _, err := c.Call("find_system_by_dns_name", dns_name)
- return err
+// FindSystemByDnsName searches for a system by DNS name. Returns the rendered
+// system dict or an empty map if not found.
+func (c *Client) FindSystemByDnsName(dnsName string) (map[string]interface{}, error) {
+ result, err := c.Call("find_system_by_dns_name", dnsName)
+ if err != nil {
+ return nil, err
+ }
+ if m, ok := result.(map[string]interface{}); ok {
+ return m, nil
+ }
+ return map[string]interface{}{}, nil
+}
+
+// GetRandomMacFor returns a random MAC address tailored for the given virt_type.
+// Valid values per Python signature: "qemu", "kvm", "xenpv", "xenfv", "vmware",
+// "vmwarew", "openvz", "auto".
+func (c *Client) GetRandomMacFor(virtType string) (string, error) {
+ if virtType == "" {
+ virtType = "kvm"
+ }
+ result, err := c.Call("get_random_mac", virtType, c.Token)
+ if err != nil {
+ return "", err
+ }
+ s, ok := result.(string)
+ if !ok {
+ return "", fmt.Errorf("get_random_mac returned %T, want string", result)
+ }
+ return s, nil
}
// GetRandomMac generates a random MAC address for use with a virtualized system.
-func (c *Client) GetRandomMac() error {
- _, err := c.Call("get_random_mac")
- return err
+func (c *Client) GetRandomMac() (string, error) {
+ return c.GetRandomMacFor("xenpv")
}
type StatusOption string
diff --git a/cobblerclient_test.go b/cobblerclient_test.go
index c628569..e0f78c9 100644
--- a/cobblerclient_test.go
+++ b/cobblerclient_test.go
@@ -83,7 +83,7 @@ func TestPing(t *testing.T) {
func TestAutoAddRepos(t *testing.T) {
c := createStubHTTPClientSingle(t, "auto-add-repos")
- err := c.AutoAddRepos()
+ _, err := c.AutoAddRepos()
FailOnError(t, err)
}
@@ -110,7 +110,7 @@ func TestGetAutoinstallSnippets(t *testing.T) {
func TestIsAutoinstallInUse(t *testing.T) {
c := createStubHTTPClientSingle(t, "is-autoinstall-in-use")
- err := c.IsAutoinstallInUse("")
+ _, err := c.IsAutoinstallInUse("")
FailOnError(t, err)
}
@@ -151,7 +151,7 @@ func TestRegisterNewSystem(t *testing.T) {
c := createStubHTTPClientSingle(t, "register-new-system")
- err := c.RegisterNewSystem(
+ _, err := c.RegisterNewSystem(
map[string]interface{}{
"name": "test",
"profile": "testprof",
@@ -168,7 +168,7 @@ func TestRegisterNewSystem(t *testing.T) {
func TestRunInstallTriggers(t *testing.T) {
c := createStubHTTPClientSingle(t, "run-install-triggers")
- err := c.RunInstallTriggers("", "", "", "")
+ _, err := c.RunInstallTriggers("", "", "", "")
FailOnError(t, err)
}
@@ -178,7 +178,7 @@ func TestGetReposCompatibleWithProfile(t *testing.T) {
"get-repos-compatible-with-profile",
)
- err := c.GetReposCompatibleWithProfile("testprof")
+ _, err := c.GetReposCompatibleWithProfile("testprof")
FailOnError(t, err)
}
@@ -188,14 +188,14 @@ func TestFindSystemByDnsName(t *testing.T) {
"find-system-by-dns-name",
)
- err := c.FindSystemByDnsName("testname")
+ _, err := c.FindSystemByDnsName("testname")
FailOnError(t, err)
}
func TestGetRandomMac(t *testing.T) {
c := createStubHTTPClientSingle(t, "get-random-mac")
- err := c.GetRandomMac()
+ _, err := c.GetRandomMac()
FailOnError(t, err)
}
diff --git a/distro.go b/distro.go
index 012677e..c144a6b 100644
--- a/distro.go
+++ b/distro.go
@@ -347,3 +347,18 @@ func (c *Client) GetDistroHandle(name string) (string, error) {
res, err := c.Call("get_distro_handle", name, c.Token)
return returnString(res, err)
}
+
+// GetValidDistroBootLoaders retrieves the list of bootloaders that can be assigned to a distro.
+func (c *Client) GetValidDistroBootLoaders(distroName string) ([]string, error) {
+ resultUnmarshalled, err := c.Call("get_valid_distro_boot_loaders", distroName, c.Token)
+ return returnStringSlice(resultUnmarshalled, err)
+}
+
+// GetDistroAsRendered returns the datastructure after it has passed through Cobblers inheritance structure.
+func (c *Client) GetDistroAsRendered(name string) (map[string]interface{}, error) {
+ result, err := c.Call("get_distro_as_rendered", name, c.Token)
+ if err != nil {
+ return nil, err
+ }
+ return result.(map[string]interface{}), nil
+}
diff --git a/distro_test.go b/distro_test.go
index dacdcbe..bb2712e 100644
--- a/distro_test.go
+++ b/distro_test.go
@@ -131,6 +131,26 @@ func TestGetDistroHandle(t *testing.T) {
}
}
+func TestGetValidDistroBootLoaders(t *testing.T) {
+ c := createStubHTTPClientSingle(t, "get-valid-distro-boot-loaders")
+ res, err := c.GetValidDistroBootLoaders("Ubuntu-20.04-x86_64")
+ FailOnError(t, err)
+
+ if len(res) < 1 {
+ t.Error("Expected at least one boot loader.")
+ }
+}
+
+func TestGetDistroAsRendered(t *testing.T) {
+ c := createStubHTTPClientSingle(t, "get-distro-as-rendered")
+ res, err := c.GetDistroAsRendered("Ubuntu-20.04-x86_64")
+ FailOnError(t, err)
+
+ if res["name"] != "Ubuntu-20.04-x86_64" {
+ t.Errorf("Wrong distro name returned: %v", res["name"])
+ }
+}
+
/*
* NOTE: We're skipping the testing of CREATE, UPDATE, DELETE methods for now because
* the current implementation of the StubHTTPClient does not allow
diff --git a/fixtures/clear-system-logs-req.xml b/fixtures/clear-system-logs-req.xml
new file mode 100644
index 0000000..90df395
--- /dev/null
+++ b/fixtures/clear-system-logs-req.xml
@@ -0,0 +1,16 @@
+
+
+ clear_system_logs
+
+
+
+ system::testsys
+
+
+
+
+ securetoken99
+
+
+
+
diff --git a/fixtures/clear-system-logs-res.xml b/fixtures/clear-system-logs-res.xml
new file mode 100644
index 0000000..d02b2d3
--- /dev/null
+++ b/fixtures/clear-system-logs-res.xml
@@ -0,0 +1,8 @@
+
+
+
+
+ 1
+
+
+
diff --git a/fixtures/disable-netboot-req.xml b/fixtures/disable-netboot-req.xml
new file mode 100644
index 0000000..a5a5b40
--- /dev/null
+++ b/fixtures/disable-netboot-req.xml
@@ -0,0 +1,16 @@
+
+
+ disable_netboot
+
+
+
+ testsys
+
+
+
+
+ securetoken99
+
+
+
+
diff --git a/fixtures/disable-netboot-res.xml b/fixtures/disable-netboot-res.xml
new file mode 100644
index 0000000..d02b2d3
--- /dev/null
+++ b/fixtures/disable-netboot-res.xml
@@ -0,0 +1,8 @@
+
+
+
+
+ 1
+
+
+
diff --git a/fixtures/get-distro-as-rendered-req.xml b/fixtures/get-distro-as-rendered-req.xml
new file mode 100644
index 0000000..3560eff
--- /dev/null
+++ b/fixtures/get-distro-as-rendered-req.xml
@@ -0,0 +1,16 @@
+
+
+ get_distro_as_rendered
+
+
+
+ Ubuntu-20.04-x86_64
+
+
+
+
+ securetoken99
+
+
+
+
diff --git a/fixtures/get-distro-as-rendered-res.xml b/fixtures/get-distro-as-rendered-res.xml
new file mode 100644
index 0000000..ae742d7
--- /dev/null
+++ b/fixtures/get-distro-as-rendered-res.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+ name
+
+ Ubuntu-20.04-x86_64
+
+
+
+
+
+
+
diff --git a/fixtures/get-menu-as-rendered-req.xml b/fixtures/get-menu-as-rendered-req.xml
new file mode 100644
index 0000000..64d9764
--- /dev/null
+++ b/fixtures/get-menu-as-rendered-req.xml
@@ -0,0 +1,16 @@
+
+
+ get_menu_as_rendered
+
+
+
+ testmenu
+
+
+
+
+ securetoken99
+
+
+
+
diff --git a/fixtures/get-menu-as-rendered-res.xml b/fixtures/get-menu-as-rendered-res.xml
new file mode 100644
index 0000000..fa620b4
--- /dev/null
+++ b/fixtures/get-menu-as-rendered-res.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+ name
+
+ testmenu
+
+
+
+ display_name
+
+
+
+
+
+
+
+
+
diff --git a/fixtures/get-profile-as-rendered-req.xml b/fixtures/get-profile-as-rendered-req.xml
new file mode 100644
index 0000000..b840dc3
--- /dev/null
+++ b/fixtures/get-profile-as-rendered-req.xml
@@ -0,0 +1,16 @@
+
+
+ get_profile_as_rendered
+
+
+
+ Ubuntu-20.04-x86_64
+
+
+
+
+ securetoken99
+
+
+
+
diff --git a/fixtures/get-profile-as-rendered-res.xml b/fixtures/get-profile-as-rendered-res.xml
new file mode 100644
index 0000000..ae742d7
--- /dev/null
+++ b/fixtures/get-profile-as-rendered-res.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+ name
+
+ Ubuntu-20.04-x86_64
+
+
+
+
+
+
+
diff --git a/fixtures/get-random-mac-req.xml b/fixtures/get-random-mac-req.xml
index 2933a15..f1abe30 100644
--- a/fixtures/get-random-mac-req.xml
+++ b/fixtures/get-random-mac-req.xml
@@ -1,4 +1,8 @@
get_random_mac
+
+ xenpv
+ securetoken99
+
diff --git a/fixtures/get-repo-as-rendered-req.xml b/fixtures/get-repo-as-rendered-req.xml
new file mode 100644
index 0000000..0e022cb
--- /dev/null
+++ b/fixtures/get-repo-as-rendered-req.xml
@@ -0,0 +1,16 @@
+
+
+ get_repo_as_rendered
+
+
+
+ rhel-7-x86_64
+
+
+
+
+ securetoken99
+
+
+
+
diff --git a/fixtures/get-repo-as-rendered-res.xml b/fixtures/get-repo-as-rendered-res.xml
new file mode 100644
index 0000000..861db28
--- /dev/null
+++ b/fixtures/get-repo-as-rendered-res.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+ name
+
+ rhel-7-x86_64
+
+
+
+
+
+
+
diff --git a/fixtures/get-repo-config-for-profile-req.xml b/fixtures/get-repo-config-for-profile-req.xml
new file mode 100644
index 0000000..3f4e972
--- /dev/null
+++ b/fixtures/get-repo-config-for-profile-req.xml
@@ -0,0 +1,11 @@
+
+
+ get_repo_config_for_profile
+
+
+
+ testprof
+
+
+
+
diff --git a/fixtures/get-repo-config-for-profile-res.xml b/fixtures/get-repo-config-for-profile-res.xml
new file mode 100644
index 0000000..580fd99
--- /dev/null
+++ b/fixtures/get-repo-config-for-profile-res.xml
@@ -0,0 +1,13 @@
+
+
+
+
+ [testrepo]
+name=testrepo
+baseurl=http://cobbler.example.com/cobbler/repo_mirror/testrepo
+enabled=1
+gpgcheck=0
+
+
+
+
diff --git a/fixtures/get-repo-config-for-system-req.xml b/fixtures/get-repo-config-for-system-req.xml
new file mode 100644
index 0000000..c0939a7
--- /dev/null
+++ b/fixtures/get-repo-config-for-system-req.xml
@@ -0,0 +1,11 @@
+
+
+ get_repo_config_for_system
+
+
+
+ testsys
+
+
+
+
diff --git a/fixtures/get-repo-config-for-system-res.xml b/fixtures/get-repo-config-for-system-res.xml
new file mode 100644
index 0000000..580fd99
--- /dev/null
+++ b/fixtures/get-repo-config-for-system-res.xml
@@ -0,0 +1,13 @@
+
+
+
+
+ [testrepo]
+name=testrepo
+baseurl=http://cobbler.example.com/cobbler/repo_mirror/testrepo
+enabled=1
+gpgcheck=0
+
+
+
+
diff --git a/fixtures/get-system-as-rendered-req.xml b/fixtures/get-system-as-rendered-req.xml
new file mode 100644
index 0000000..aab9ff1
--- /dev/null
+++ b/fixtures/get-system-as-rendered-req.xml
@@ -0,0 +1,16 @@
+
+
+ get_system_as_rendered
+
+
+
+ test
+
+
+
+
+ securetoken99
+
+
+
+
diff --git a/fixtures/get-system-as-rendered-res.xml b/fixtures/get-system-as-rendered-res.xml
new file mode 100644
index 0000000..5abbf94
--- /dev/null
+++ b/fixtures/get-system-as-rendered-res.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+ name
+
+ test
+
+
+
+
+
+
+
diff --git a/fixtures/get-valid-distro-boot-loaders-req.xml b/fixtures/get-valid-distro-boot-loaders-req.xml
new file mode 100644
index 0000000..fbd2723
--- /dev/null
+++ b/fixtures/get-valid-distro-boot-loaders-req.xml
@@ -0,0 +1,16 @@
+
+
+ get_valid_distro_boot_loaders
+
+
+
+ Ubuntu-20.04-x86_64
+
+
+
+
+ securetoken99
+
+
+
+
diff --git a/fixtures/get-valid-distro-boot-loaders-res.xml b/fixtures/get-valid-distro-boot-loaders-res.xml
new file mode 100644
index 0000000..ffab829
--- /dev/null
+++ b/fixtures/get-valid-distro-boot-loaders-res.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+ grub
+ pxelinux
+
+
+
+
diff --git a/fixtures/get-valid-profile-boot-loaders-req.xml b/fixtures/get-valid-profile-boot-loaders-req.xml
new file mode 100644
index 0000000..00e9018
--- /dev/null
+++ b/fixtures/get-valid-profile-boot-loaders-req.xml
@@ -0,0 +1,16 @@
+
+
+ get_valid_profile_boot_loaders
+
+
+
+ Ubuntu-20.04-x86_64
+
+
+
+
+ securetoken99
+
+
+
+
diff --git a/fixtures/get-valid-profile-boot-loaders-res.xml b/fixtures/get-valid-profile-boot-loaders-res.xml
new file mode 100644
index 0000000..ffab829
--- /dev/null
+++ b/fixtures/get-valid-profile-boot-loaders-res.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+ grub
+ pxelinux
+
+
+
+
diff --git a/fixtures/get-valid-system-boot-loaders-req.xml b/fixtures/get-valid-system-boot-loaders-req.xml
new file mode 100644
index 0000000..dcbc0d1
--- /dev/null
+++ b/fixtures/get-valid-system-boot-loaders-req.xml
@@ -0,0 +1,16 @@
+
+
+ get_valid_system_boot_loaders
+
+
+
+ test
+
+
+
+
+ securetoken99
+
+
+
+
diff --git a/fixtures/get-valid-system-boot-loaders-res.xml b/fixtures/get-valid-system-boot-loaders-res.xml
new file mode 100644
index 0000000..ffab829
--- /dev/null
+++ b/fixtures/get-valid-system-boot-loaders-res.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+ grub
+ pxelinux
+
+
+
+
diff --git a/fixtures/new-subprofile-req.xml b/fixtures/new-subprofile-req.xml
new file mode 100644
index 0000000..e0ff742
--- /dev/null
+++ b/fixtures/new-subprofile-req.xml
@@ -0,0 +1,11 @@
+
+
+ new_subprofile
+
+
+
+ securetoken99
+
+
+
+
diff --git a/fixtures/new-subprofile-res.xml b/fixtures/new-subprofile-res.xml
new file mode 100644
index 0000000..025ab6f
--- /dev/null
+++ b/fixtures/new-subprofile-res.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+ ___NEW___profile::subprof01==
+
+
+
+
diff --git a/fixtures/upload-log-data-req.xml b/fixtures/upload-log-data-req.xml
new file mode 100644
index 0000000..c02f025
--- /dev/null
+++ b/fixtures/upload-log-data-req.xml
@@ -0,0 +1,36 @@
+
+
+ upload_log_data
+
+
+
+ testsys
+
+
+
+
+ /var/log/cobbler/testsys.log
+
+
+
+
+ 12
+
+
+
+
+ 0
+
+
+
+
+ hello world!
+
+
+
+
+ securetoken99
+
+
+
+
diff --git a/fixtures/upload-log-data-res.xml b/fixtures/upload-log-data-res.xml
new file mode 100644
index 0000000..d02b2d3
--- /dev/null
+++ b/fixtures/upload-log-data-res.xml
@@ -0,0 +1,8 @@
+
+
+
+
+ 1
+
+
+
diff --git a/item.go b/item.go
index 04de825..17922d6 100644
--- a/item.go
+++ b/item.go
@@ -149,10 +149,19 @@ func (c *Client) GetItemNames(what string) ([]string, error) {
return returnStringSlice(resultUnmarshalled, err)
}
-// GetItemResolvedValue retrieves the value of a single attribute of a single item which was passed through the
-// inheritance chain of Cobbler.
-func (c *Client) GetItemResolvedValue(itemUuid string, attribute string) error {
- _, err := c.Call("get_item_resolved_value", itemUuid, attribute)
+// GetItemResolvedValue returns the value of a single attribute of a single
+// item with the inheritance chain applied. attribute is the dotted path to
+// the property (e.g. []string{"ipv4", "address"} for a NetworkInterface).
+// Cobbler 4.0.0 returns Union[str, int, float, List, dict].
+func (c *Client) GetItemResolvedValue(itemUuid string, attribute []string) (interface{}, error) {
+ return c.Call("get_item_resolved_value", itemUuid, attribute)
+}
+
+// SetItemResolvedValue sets a single attribute on an item with inheritance
+// rules applied. attribute is the dotted path; value is the desired value.
+// Added in Cobbler 4.0.0.
+func (c *Client) SetItemResolvedValue(itemUuid string, attribute []string, value interface{}) error {
+ _, err := c.Call("set_item_resolved_value", itemUuid, attribute, value, c.Token)
return err
}
diff --git a/menu.go b/menu.go
index 15966ea..afdd201 100644
--- a/menu.go
+++ b/menu.go
@@ -93,13 +93,13 @@ func convertRawMenusList(xmlrpcResult interface{}) ([]*Menu, error) {
}
// GetMenus returns all menus in Cobbler.
-func (c *Client) GetMenus() ([]*Distro, error) {
+func (c *Client) GetMenus() ([]*Menu, error) {
result, err := c.Call("get_menus", "-1", c.Token)
if err != nil {
return nil, err
}
- return convertRawDistrosList(result)
+ return convertRawMenusList(result)
}
// GetMenu returns a single menu obtained by its name.
@@ -234,9 +234,12 @@ func (c *Client) GetMenusSince(mtime time.Time) ([]*Menu, error) {
}
// GetMenuAsRendered returns the datastructure after it has passed through Cobblers inheritance structure.
-func (c *Client) GetMenuAsRendered() error {
- _, err := c.Call("get_menu_as_rendered")
- return err
+func (c *Client) GetMenuAsRendered(name string) (map[string]interface{}, error) {
+ result, err := c.Call("get_menu_as_rendered", name, c.Token)
+ if err != nil {
+ return nil, err
+ }
+ return result.(map[string]interface{}), nil
}
// SaveMenu saves all changes performed via XML-RPC to disk on the server side.
diff --git a/menu_test.go b/menu_test.go
index bb5e5df..f24ecc3 100644
--- a/menu_test.go
+++ b/menu_test.go
@@ -135,6 +135,16 @@ func TestGetMenuHandle(t *testing.T) {
}
}
+func TestGetMenuAsRendered(t *testing.T) {
+ c := createStubHTTPClientSingle(t, "get-menu-as-rendered")
+ res, err := c.GetMenuAsRendered("testmenu")
+ FailOnError(t, err)
+
+ if res["name"] != "testmenu" {
+ t.Errorf("Wrong menu name returned: %v", res["name"])
+ }
+}
+
/*
* NOTE: We're skipping the testing of CREATE, UPDATE, DELETE methods for now because
* the current implementation of the StubHTTPClient does not allow
diff --git a/profile.go b/profile.go
index 82175ff..eb948d0 100644
--- a/profile.go
+++ b/profile.go
@@ -355,3 +355,25 @@ func (c *Client) GetProfileHandle(name string) (string, error) {
res, err := c.Call("get_profile_handle", name, c.Token)
return returnString(res, err)
}
+
+// GetValidProfileBootLoaders retrieves the list of bootloaders that can be assigned to a profile.
+func (c *Client) GetValidProfileBootLoaders(profileName string) ([]string, error) {
+ resultUnmarshalled, err := c.Call("get_valid_profile_boot_loaders", profileName, c.Token)
+ return returnStringSlice(resultUnmarshalled, err)
+}
+
+// GetProfileAsRendered returns the datastructure after it has passed through Cobblers inheritance structure.
+func (c *Client) GetProfileAsRendered(name string) (map[string]interface{}, error) {
+ result, err := c.Call("get_profile_as_rendered", name, c.Token)
+ if err != nil {
+ return nil, err
+ }
+ return result.(map[string]interface{}), nil
+}
+
+// NewSubprofile creates a new blank sub-profile on the server and returns its object ID.
+// A sub-profile inherits from another profile (rather than a distro).
+func (c *Client) NewSubprofile() (string, error) {
+ result, err := c.Call("new_subprofile", c.Token)
+ return returnString(result, err)
+}
diff --git a/profile_test.go b/profile_test.go
index 0e666c9..3b7283e 100644
--- a/profile_test.go
+++ b/profile_test.go
@@ -134,3 +134,32 @@ func TestGetProfileHandle(t *testing.T) {
t.Error("Wrong object id returned.")
}
}
+
+func TestGetValidProfileBootLoaders(t *testing.T) {
+ c := createStubHTTPClientSingle(t, "get-valid-profile-boot-loaders")
+ res, err := c.GetValidProfileBootLoaders("Ubuntu-20.04-x86_64")
+ FailOnError(t, err)
+
+ if len(res) < 1 {
+ t.Error("Expected at least one boot loader.")
+ }
+}
+
+func TestGetProfileAsRendered(t *testing.T) {
+ c := createStubHTTPClientSingle(t, "get-profile-as-rendered")
+ res, err := c.GetProfileAsRendered("Ubuntu-20.04-x86_64")
+ FailOnError(t, err)
+
+ if res["name"] != "Ubuntu-20.04-x86_64" {
+ t.Errorf("Wrong profile name returned: %v", res["name"])
+ }
+}
+
+func TestNewSubprofile(t *testing.T) {
+ c := createStubHTTPClientSingle(t, "new-subprofile")
+ res, err := c.NewSubprofile()
+ FailOnError(t, err)
+ if res == "" {
+ t.Error("Expected a non-empty object ID from NewSubprofile.")
+ }
+}
diff --git a/repo.go b/repo.go
index 644d501..53c5398 100644
--- a/repo.go
+++ b/repo.go
@@ -270,3 +270,24 @@ func (c *Client) GetRepoHandle(name string) (string, error) {
res, err := c.Call("get_repo_handle", name, c.Token)
return returnString(res, err)
}
+
+// GetRepoConfigForProfile returns the rendered repository configuration for a profile.
+func (c *Client) GetRepoConfigForProfile(profileName string) (string, error) {
+ result, err := c.Call("get_repo_config_for_profile", profileName)
+ return returnString(result, err)
+}
+
+// GetRepoConfigForSystem returns the rendered repository configuration for a system.
+func (c *Client) GetRepoConfigForSystem(systemName string) (string, error) {
+ result, err := c.Call("get_repo_config_for_system", systemName)
+ return returnString(result, err)
+}
+
+// GetRepoAsRendered returns the datastructure after it has passed through Cobblers inheritance structure.
+func (c *Client) GetRepoAsRendered(name string) (map[string]interface{}, error) {
+ result, err := c.Call("get_repo_as_rendered", name, c.Token)
+ if err != nil {
+ return nil, err
+ }
+ return result.(map[string]interface{}), nil
+}
diff --git a/repo_test.go b/repo_test.go
index 7dda63b..130bacc 100644
--- a/repo_test.go
+++ b/repo_test.go
@@ -165,6 +165,36 @@ func TestGetRepoHandle(t *testing.T) {
}
}
+func TestGetRepoConfigForProfile(t *testing.T) {
+ c := createStubHTTPClientSingle(t, "get-repo-config-for-profile")
+ res, err := c.GetRepoConfigForProfile("testprof")
+ FailOnError(t, err)
+
+ if res == "" {
+ t.Error("Expected a non-empty repo config.")
+ }
+}
+
+func TestGetRepoConfigForSystem(t *testing.T) {
+ c := createStubHTTPClientSingle(t, "get-repo-config-for-system")
+ res, err := c.GetRepoConfigForSystem("testsys")
+ FailOnError(t, err)
+
+ if res == "" {
+ t.Error("Expected a non-empty repo config.")
+ }
+}
+
+func TestGetRepoAsRendered(t *testing.T) {
+ c := createStubHTTPClientSingle(t, "get-repo-as-rendered")
+ res, err := c.GetRepoAsRendered("rhel-7-x86_64")
+ FailOnError(t, err)
+
+ if res["name"] != "rhel-7-x86_64" {
+ t.Errorf("Wrong repo name returned: %v", res["name"])
+ }
+}
+
/*
* NOTE: We're skipping the testing of CREATE, UPDATE, DELETE methods for now because
* the current implementation of the StubHTTPClient does not allow
diff --git a/system.go b/system.go
index fef2e7d..936cb3d 100644
--- a/system.go
+++ b/system.go
@@ -591,3 +591,36 @@ func (c *Client) GetSystemHandle(name string) (string, error) {
res, err := c.Call("get_system_handle", name, c.Token)
return returnString(res, err)
}
+
+// DisableNetboot disables PXE booting for the named system (pxe_just_once feature).
+func (c *Client) DisableNetboot(name string) error {
+ _, err := c.Call("disable_netboot", name, c.Token)
+ return err
+}
+
+// UploadLogData uploads Anaconda log data for the named system (anamon logging).
+func (c *Client) UploadLogData(sysName, file string, size, offset int, data string) (bool, error) {
+ result, err := c.Call("upload_log_data", sysName, file, size, offset, data, c.Token)
+ return returnBool(result, err)
+}
+
+// ClearSystemLogs clears the console logs for the system identified by its object ID.
+func (c *Client) ClearSystemLogs(objectId string) (bool, error) {
+ result, err := c.Call("clear_system_logs", objectId, c.Token)
+ return returnBool(result, err)
+}
+
+// GetValidSystemBootLoaders retrieves the list of bootloaders that can be assigned to a system.
+func (c *Client) GetValidSystemBootLoaders(systemName string) ([]string, error) {
+ resultUnmarshalled, err := c.Call("get_valid_system_boot_loaders", systemName, c.Token)
+ return returnStringSlice(resultUnmarshalled, err)
+}
+
+// GetSystemAsRendered returns the datastructure after it has passed through Cobblers inheritance structure.
+func (c *Client) GetSystemAsRendered(name string) (map[string]interface{}, error) {
+ result, err := c.Call("get_system_as_rendered", name, c.Token)
+ if err != nil {
+ return nil, err
+ }
+ return result.(map[string]interface{}), nil
+}
diff --git a/system_test.go b/system_test.go
index a2e8d68..e618658 100644
--- a/system_test.go
+++ b/system_test.go
@@ -248,6 +248,26 @@ func TestModifyInterface(t *testing.T) {
FailOnError(t, err)
}
+func TestGetValidSystemBootLoaders(t *testing.T) {
+ c := createStubHTTPClientSingle(t, "get-valid-system-boot-loaders")
+ res, err := c.GetValidSystemBootLoaders("test")
+ FailOnError(t, err)
+
+ if len(res) < 1 {
+ t.Error("Expected at least one boot loader.")
+ }
+}
+
+func TestGetSystemAsRendered(t *testing.T) {
+ c := createStubHTTPClientSingle(t, "get-system-as-rendered")
+ res, err := c.GetSystemAsRendered("test")
+ FailOnError(t, err)
+
+ if res["name"] != "test" {
+ t.Errorf("Wrong system name returned: %v", res["name"])
+ }
+}
+
func TestGetInterfaces(t *testing.T) {
// Arrange
c := createStubHTTPClient(t, []string{
@@ -329,3 +349,27 @@ func TestRenameInterface(t *testing.T) {
// Assert
FailOnError(t, err)
}
+
+func TestDisableNetboot(t *testing.T) {
+ c := createStubHTTPClientSingle(t, "disable-netboot")
+ err := c.DisableNetboot("testsys")
+ FailOnError(t, err)
+}
+
+func TestUploadLogData(t *testing.T) {
+ c := createStubHTTPClientSingle(t, "upload-log-data")
+ res, err := c.UploadLogData("testsys", "/var/log/cobbler/testsys.log", 12, 0, "hello world!")
+ FailOnError(t, err)
+ if !res {
+ t.Error("Expected true result from UploadLogData.")
+ }
+}
+
+func TestClearSystemLogs(t *testing.T) {
+ c := createStubHTTPClientSingle(t, "clear-system-logs")
+ res, err := c.ClearSystemLogs("system::testsys")
+ FailOnError(t, err)
+ if !res {
+ t.Error("Expected true result from ClearSystemLogs.")
+ }
+}