Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add remaining XML-RPC endpoints #20

Merged
merged 15 commits into from
May 23, 2024
Merged
20 changes: 20 additions & 0 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,26 @@ func main() {

fmt.Printf("Token: %s\n", c.Token)

res, err := c.BackgroundSync(cobbler.BackgroundSyncOptions{Dhcp: true, Dns: true, Verbose: true})
if err != nil {
fmt.Println(err)
}
eventLog, err := c.GetEventLog(res)
if err != nil {
fmt.Println(err)
}
fmt.Printf("Print event log for %s\n", res)
fmt.Println(eventLog)

events, err := c.GetEvents("")
if err != nil {
fmt.Println(err)
}
fmt.Println("Listing all events")
for _, event := range events {
fmt.Printf("%#v\n", event)
}

fmt.Println("Creating a repo")
r := cobbler.Repo{
Name: "myrepo",
Expand Down
10 changes: 0 additions & 10 deletions cobblerclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,16 +241,6 @@ func (c *Client) GetConfigData(hostname string) error {
return err
}

// GetItemHandle gets the internal ID of a Cobbler item.
func (c *Client) GetItemHandle(what, name string) (string, error) {
result, err := c.Call("get_item_handle", what, name, c.Token)
if err != nil {
return "", err
} else {
return result.(string), err
}
}

// cobblerDataHacks is a hook for the mapstructure decoder. It's only used by
// decodeCobblerItem and should never be invoked directly.
// It's used to smooth out issues with converting fields and types from Cobbler.
Expand Down
145 changes: 123 additions & 22 deletions distro.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package cobblerclient
import (
"fmt"
"reflect"
"time"
)

// Distro is a created distro.
Expand All @@ -29,7 +30,7 @@ type Distro struct {
Depth int `mapstructure:"depth" cobbler:"noupdate"`
Mtime float64 `mapstructure:"mtime" cobbler:"noupdate"` // TODO: convert to time
SourceRepos []string `mapstructure:"source_repos" cobbler:"noupdate"`
TreeBuildTime string `mapstructure:tree_build_time" cobbler:"noupdate"`
TreeBuildTime string `mapstructure:"tree_build_time" cobbler:"noupdate"`
UID string `mapstructure:"uid" cobbler:"noupdate"`
Arch string `mapstructure:"arch"`
BootFiles []string `mapstructure:"boot_files"`
Expand All @@ -48,54 +49,60 @@ type Distro struct {
TemplateFiles []string `mapstructure:"template_files"`
}

// GetDistros returns all systems in Cobbler.
func (c *Client) GetDistros() ([]*Distro, error) {
var distros []*Distro
func convertRawDistro(name string, xmlrpcResult interface{}) (*Distro, error) {
var distro Distro

result, err := c.Call("get_distros", "-1", c.Token)
if xmlrpcResult == "~" {
return nil, fmt.Errorf("distro %s not found", name)
}

decodeResult, err := decodeCobblerItem(xmlrpcResult, &distro)
if err != nil {
return nil, err
}

for _, d := range result.([]interface{}) {
var distro Distro
decodedResult, err := decodeCobblerItem(d, &distro)
return decodeResult.(*Distro), nil
}

func convertRawDistrosList(xmlrpcResult interface{}) ([]*Distro, error) {
var distros []*Distro

for _, d := range xmlrpcResult.([]interface{}) {
distro, err := convertRawDistro("unknown", d)
if err != nil {
return nil, err
}

distros = append(distros, decodedResult.(*Distro))
distros = append(distros, distro)
}

return distros, nil
}

// GetDistro returns a single distro obtained by its name.
func (c *Client) GetDistro(name string) (*Distro, error) {
var distro Distro

result, err := c.Call("get_distro", name, c.Token)
if result == "~" {
return nil, fmt.Errorf("Distro %s not found.", name)
}

// GetDistros returns all distros in Cobbler.
func (c *Client) GetDistros() ([]*Distro, error) {
result, err := c.Call("get_distros", "-1", c.Token)
if err != nil {
return nil, err
}

decodeResult, err := decodeCobblerItem(result, &distro)
return convertRawDistrosList(result)
}

// GetDistro returns a single distro obtained by its name.
func (c *Client) GetDistro(name string) (*Distro, error) {
result, err := c.Call("get_distro", name, c.Token)
if err != nil {
return nil, err
}

return decodeResult.(*Distro), nil
return convertRawDistro(name, result)
}

// CreateDistro creates a distro.
func (c *Client) CreateDistro(distro Distro) (*Distro, error) {
// Make sure a distro with the same name does not already exist
if _, err := c.GetDistro(distro.Name); err == nil {
return nil, fmt.Errorf("A Distro with the name %s already exists.", distro.Name)
return nil, fmt.Errorf("a Distro with the name %s already exists", distro.Name)
}

result, err := c.Call("new_distro", c.Token)
Expand Down Expand Up @@ -135,8 +142,102 @@ func (c *Client) UpdateDistro(distro *Distro) error {
return nil
}

// SaveDistro is ...
SchoolGuy marked this conversation as resolved.
Show resolved Hide resolved
func (c *Client) SaveDistro(objectId, editmode string) error {
_, err := c.Call("save_distro", objectId, c.Token, editmode)
return err
}

// CopyDistro is ...
SchoolGuy marked this conversation as resolved.
Show resolved Hide resolved
func (c *Client) CopyDistro(objectId, newName string) error {
_, err := c.Call("copy_distro", objectId, newName, c.Token)
return err
}

// DeleteDistro deletes a single distro by its name.
func (c *Client) DeleteDistro(name string) error {
_, err := c.Call("remove_distro", name, c.Token)
return err
}

// ListDistroNames is returning a list of all distro names currently available in Cobbler.
func (c *Client) ListDistroNames() ([]string, error) {
return c.GetItemNames("distro")
}

// GetDistrosSince is returning all distros which were created after the specified date.
func (c *Client) GetDistrosSince(mtime time.Time) ([]*Distro, error) {
var distros []*Distro

result, err := c.Call("get_distros_since", float64(mtime.Unix()))
if err != nil {
return nil, err
}

for _, d := range result.([]interface{}) {
var distro Distro
decodedResult, err := decodeCobblerItem(d, &distro)
if err != nil {
return nil, err
}

distros = append(distros, decodedResult.(*Distro))
}

return distros, nil
}

// FindDistro is searching for one or more distros by any of its attributes.
func (c *Client) FindDistro(criteria map[string]interface{}) ([]*Distro, error) {
var distros []*Distro

result, err := c.Call("find_distro", criteria, true, c.Token)
if err != nil {
return nil, err
}

for _, d := range result.([]interface{}) {
var distro Distro
decodedResult, err := decodeCobblerItem(d, &distro)
if err != nil {
return nil, err
}

distros = append(distros, decodedResult.(*Distro))
}

return distros, nil
}

// FindDistroNames is searching for one or more distros by any of its attributes.
func (c *Client) FindDistroNames(criteria map[string]interface{}) ([]string, error) {
var result []string

resultUnmarshalled, err := c.Call("find_distro", criteria, false, c.Token)

if err != nil {
return nil, err
}

for _, name := range resultUnmarshalled.([]interface{}) {
result = append(result, name.(string))
}

return result, nil
}

// RenameDistro is ...
func (c *Client) RenameDistro(objectId, newName string) error {
_, err := c.Call("rename_distro", objectId, newName, c.Token)
return err
}

// GetDistroHandle gets the internal ID of a Cobbler item.
func (c *Client) GetDistroHandle(name string) (string, error) {
result, err := c.Call("get_distro_handle", name, c.Token)
if err != nil {
return "", err
} else {
return result.(string), err
}
}
73 changes: 73 additions & 0 deletions distro_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package cobblerclient

import (
"testing"
"time"

"github.com/ContainerSolutions/go-utils"
)
Expand All @@ -42,6 +43,78 @@ func TestGetDistro(t *testing.T) {
}
}

func TestListDistroNames(t *testing.T) {
c := createStubHTTPClient(t, "get-item-names-distro-req.xml", "get-item-names-distro-res.xml")
distros, err := c.ListDistroNames()
utils.FailOnError(t, err)

if len(distros) != 1 {
t.Errorf("Wrong number of distros returned.")
}
}

func TestGetDistrosSince(t *testing.T) {
c := createStubHTTPClient(t, "get-distros-since-req.xml", "get-distros-since-res.xml")
distros, err := c.GetDistrosSince(time.Date(1970, 1, 1, 0, 0, 0, 0, time.UTC))
utils.FailOnError(t, err)

if len(distros) != 1 {
t.Errorf("Wrong number of distros returned.")
}
}

func TestFindDistro(t *testing.T) {
c := createStubHTTPClient(t, "find-distro-req.xml", "find-distro-res.xml")
criteria := make(map[string]interface{}, 1)
criteria["name"] = "test"
distros, err := c.FindDistro(criteria)
utils.FailOnError(t, err)

if len(distros) != 1 {
t.Errorf("Wrong number of distros returned.")
}
}

func TestFindDistroNames(t *testing.T) {
c := createStubHTTPClient(t, "find-distro-names-req.xml", "find-distro-names-res.xml")
criteria := make(map[string]interface{}, 1)
criteria["name"] = "test"
distros, err := c.FindDistroNames(criteria)
utils.FailOnError(t, err)

if len(distros) != 1 {
t.Error("Wrong number of distros returned.")
}
}

func TestSaveDistro(t *testing.T) {
c := createStubHTTPClient(t, "save-distro-req.xml", "save-distro-res.xml")
err := c.SaveDistro("distro::test", "bypass")
utils.FailOnError(t, err)
}

func TestCopyDistro(t *testing.T) {
c := createStubHTTPClient(t, "copy-distro-req.xml", "copy-distro-res.xml")
err := c.CopyDistro("distro::test", "test2")
utils.FailOnError(t, err)
}

func TestRenameDistro(t *testing.T) {
c := createStubHTTPClient(t, "rename-distro-req.xml", "rename-distro-res.xml")
err := c.RenameDistro("distro::test2", "test1")
utils.FailOnError(t, err)
}

func TestGetDistroHandle(t *testing.T) {
c := createStubHTTPClient(t, "get-distro-handle-req.xml", "get-distro-handle-res.xml")
res, err := c.GetDistroHandle("test")
utils.FailOnError(t, err)

if res != "distro::test" {
t.Error("Wrong object id returned.")
}
}

/*
* NOTE: We're skipping the testing of CREATE, UPDATE, DELETE methods for now because
* the current implementation of the StubHTTPClient does not allow
Expand Down
Loading
Loading