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

Client: Add return value for GetStatus #77

Merged
merged 1 commit into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 70 additions & 4 deletions cobblerclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,10 +238,76 @@ func (c *Client) GetRandomMac() error {
return err
}

// GetStatus retrieves the current status of installation progress that has been reported to Cobbler.
func (c *Client) GetStatus(mode string) error {
_, err := c.Call("get_status", mode, c.Token)
return err
type StatusOption string

const StatusNormal StatusOption = "normal"
const StatusText StatusOption = "text"

// GetStatus retrieves the current status of installation progress that has been reported to Cobbler. This can be called
// with two modes: "normal" or "text. In case this is called in mode "normal" you might want to use ParseStatus to
// get a parsed version of the data. For mode "text" you can cast the interface to string.
func (c *Client) GetStatus(mode StatusOption) (interface{}, error) {
return c.Call("get_status", mode, c.Token)
}

// InstallationStatus represents the structured return value of GetStatus.
type InstallationStatus struct {
IP string `json:"ip"`
MostRecentStart float64 `json:"most_recent_start"`
MostRecentStop float64 `json:"most_recent_stop"`
MostRecentTarget string `json:"most_recent_target"`
SeenStart int `json:"seen_start"`
SeenStop int `json:"seen_stop"`
State string `json:"state"`
}

// ParseStatus takes the interface returned by GetStatus and converts it into a list of well-defined structs.
func (c *Client) ParseStatus(status interface{}) ([]InstallationStatus, error) {
result := make([]InstallationStatus, 0)
statusStruct, ok := status.(map[string]interface{})
if !ok {
return result, errors.New("cobblerclient: invalid status structure")
}
for k, v := range statusStruct {
installation := InstallationStatus{}
installation.IP = k
statusArray, okArray := v.([]interface{})
if !okArray {
return result, errors.New("cobblerclient: invalid status structure")
}
mostRecentStart, err := convertToFloat(statusArray[0])
if err != nil {
return result, err
}
mostRecentStop, err := convertToFloat(statusArray[1])
if err != nil {
return result, err
}
mostRecentTarget, okTarget := statusArray[2].(string)
if !okTarget {
return result, errors.New("cobblerclient: invalid status structure")
}
seenStart, err := convertToInt(statusArray[3])
if err != nil {
return result, err
}
seenStop, err := convertToInt(statusArray[4])
if err != nil {
return result, err
}
state, stateOk := statusArray[5].(string)
if !stateOk {
return result, errors.New("cobblerclient: invalid status structure")
}
installation.MostRecentStart = mostRecentStart
installation.MostRecentStop = mostRecentStop
installation.MostRecentTarget = mostRecentTarget
installation.SeenStart = seenStart
installation.SeenStop = seenStop
installation.State = state
result = append(result, installation)
}
return result, nil
}

// SyncDhcp updates the DHCP configuration synchronous.
Expand Down
28 changes: 25 additions & 3 deletions cobblerclient_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,11 +199,33 @@ func TestGetRandomMac(t *testing.T) {
FailOnError(t, err)
}

func TestGetStatus(t *testing.T) {
c := createStubHTTPClientSingle(t, "get-status")
func TestGetStatusNormal(t *testing.T) {
c := createStubHTTPClientSingle(t, "get-status-normal")

err := c.GetStatus("normal")
res, err := c.GetStatus(StatusNormal)
resParsed, err := c.ParseStatus(res)
FailOnError(t, err)
if len(resParsed) != 1 {
t.Fatalf("Expected a single result of 1, got %d", len(resParsed))
}
if resParsed[0].IP != "2a07:de00:a100:8:bbbb:111:ffff:aaaa" {
t.Fatalf("IP address not correctly parsed")
}
if resParsed[0].State != "finished" {
t.Fatalf("State not correctly parsed")
}
}

func TestGetStatusText(t *testing.T) {
c := createStubHTTPClientSingle(t, "get-status-text")
expectedResult := "ip |target |start |state\n2a07:de00:a100:8:bbbb:111:ffff:aaaa|system:test.example.org|Tue Jul 9 13:02:17 2024|finished "

res, err := c.GetStatus(StatusText)
FailOnError(t, err)
if res != expectedResult {
t.Fatalf("Expected %s, got %s", expectedResult, res)
}

}

func TestSyncDhcp(t *testing.T) {
Expand Down
File renamed without changes.
20 changes: 20 additions & 0 deletions fixtures/get-status-normal-res.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version='1.0'?>
<methodResponse>
<params>
<param>
<value><struct>
<member>
<name>2a07:de00:a100:8:bbbb:111:ffff:aaaa</name>
<value><array><data>
<value><double>1720530137.188196</double></value>
<value><double>1720530144.7982686</double></value>
<value><string>system:test.example.org</string></value>
<value><int>1</int></value>
<value><int>1</int></value>
<value><string>finished</string></value>
</data></array></value>
</member>
</struct></value>
</param>
</params>
</methodResponse>
11 changes: 0 additions & 11 deletions fixtures/get-status-res.xml

This file was deleted.

16 changes: 16 additions & 0 deletions fixtures/get-status-text-req.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<methodCall>
<methodName>get_status</methodName>
<params>
<param>
<value>
<string>text</string>
</value>
</param>
<param>
<value>
<string>securetoken99</string>
</value>
</param>
</params>
</methodCall>
9 changes: 9 additions & 0 deletions fixtures/get-status-text-res.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version='1.0'?>
<methodResponse>
<params>
<param>
<value><string>ip |target |start |state
2a07:de00:a100:8:bbbb:111:ffff:aaaa|system:test.example.org|Tue Jul 9 13:02:17 2024|finished </string></value>
</param>
</params>
</methodResponse>
Loading