Skip to content

Commit

Permalink
Add support for GET agent API
Browse files Browse the repository at this point in the history
  • Loading branch information
nikhilsbhat committed Mar 8, 2023
1 parent a4494a5 commit 0145c89
Show file tree
Hide file tree
Showing 7 changed files with 235 additions and 22 deletions.
32 changes: 30 additions & 2 deletions agents.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,34 @@ func (conf *client) GetAgents() ([]Agent, error) {
return agentsConf.Config.Config, nil
}

// GetAgent implements method that fetches the details of a specific agent present in GoCD server.
func (conf *client) GetAgent(agentID string) (Agent, error) {
newClient := &client{}
if err := copier.CopyWithOption(newClient, conf, copier.Option{IgnoreEmpty: true, DeepCopy: true}); err != nil {
return Agent{}, err
}

var agentConf Agent
resp, err := newClient.httpClient.R().
SetHeaders(map[string]string{
"Accept": HeaderVersionSeven,
}).
Get(filepath.Join(AgentsEndpoint, agentID))
if err != nil {
return Agent{}, &errors.APIError{Err: err, Message: fmt.Sprintf("get agent '%s' information", agentID)}
}

if resp.StatusCode() != http.StatusOK {
return Agent{}, &errors.NonOkError{Code: resp.StatusCode(), Response: resp}
}

if err = json.Unmarshal(resp.Body(), &agentConf); err != nil {
return Agent{}, &errors.MarshalError{Err: err}
}

return agentConf, nil
}

// GetAgentJobRunHistory implements method that fetches job run history from selected agents.
func (conf *client) GetAgentJobRunHistory(agentID string) (AgentJobHistory, error) {
newClient := &client{}
Expand Down Expand Up @@ -68,7 +96,7 @@ func (conf *client) GetAgentJobRunHistory(agentID string) (AgentJobHistory, erro
}

// UpdateAgent updates specific agent with updated configuration passed.
func (conf *client) UpdateAgent(agentID string, agent Agent) error {
func (conf *client) UpdateAgent(agent Agent) error {
newClient := &client{}
if err := copier.CopyWithOption(newClient, conf, copier.Option{IgnoreEmpty: true, DeepCopy: true}); err != nil {
return err
Expand All @@ -80,7 +108,7 @@ func (conf *client) UpdateAgent(agentID string, agent Agent) error {
"Content-Type": ContentJSON,
}).
SetBody(agent).
Patch(filepath.Join(AgentsEndpoint, agentID))
Patch(filepath.Join(AgentsEndpoint, agent.ID))
if err != nil {
return &errors.APIError{Err: err, Message: fmt.Sprintf("update %s agent information", agent.Name)}
}
Expand Down
127 changes: 113 additions & 14 deletions agents_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ import (
)

var (
//go:embed internal/fixtures/agent.json
agentJSON string

//go:embed internal/fixtures/agents.json
agentsJSON string

Expand Down Expand Up @@ -75,7 +78,7 @@ func Test_client_GetAgentsInfo(t *testing.T) {
Sandbox: "/Users/ketanpadegaonkar/projects/gocd/gocd/agent",
DiskSpaceAvailable: 8.4983328768e+10,
Resources: []string{"java", "linux", "firefox"},
Environments: make([]interface{}, 0),
BuildState: "Idle",
},
}

Expand All @@ -85,6 +88,101 @@ func Test_client_GetAgentsInfo(t *testing.T) {
})
}

func Test_client_GetAgent(t *testing.T) {
correctAgentHeader := map[string]string{"Accept": gocd.HeaderVersionSeven}
agentID := "adb9540a-b954-4571-9d9b-2f330739d4da"
t.Run("should be able to fetch a specific agent successfully", func(t *testing.T) {
server := mockServer([]byte(agentJSON), http.StatusOK,
correctAgentHeader, false, nil)

client := gocd.NewClient(server.URL, auth, "info", nil)

expected := gocd.Agent{
Name: "ketanpkr.corporate.thoughtworks.com",
IPAddress: "10.12.20.47",
ID: "adb9540a-b954-4571-9d9b-2f330739d4da",
Version: "20.5.0",
CurrentState: "Building",
OS: "Mac OS X",
ConfigState: "Enabled",
Sandbox: "/Users/ketanpadegaonkar/projects/gocd/gocd/agent",
DiskSpaceAvailable: 85890146304,
Resources: []string{"java", "linux", "firefox"},
Environments: []gocd.Environment{
{
Name: "perf",
},
{
Name: "UAT",
},
},
BuildState: "Building",
BuildDetails: gocd.BuildInfo{
Pipeline: "up42",
Stage: "up42_stage",
Job: "up42_job",
},
}

actual, err := client.GetAgent(agentID)
assert.NoError(t, err)
assert.Equal(t, expected, actual)
})

t.Run("should error out while fetching a specific agent present in GoCD due to wrong headers", func(t *testing.T) {
server := mockServer([]byte(agentJSON), http.StatusOK,
map[string]string{"Accept": gocd.HeaderVersionThree}, false, nil)

client := gocd.NewClient(server.URL, auth, "info", nil)

expected := gocd.Agent{}

actual, err := client.GetAgent(agentID)
assert.EqualError(t, err, "got 404 from GoCD while making GET call for "+server.URL+
"/api/agents/adb9540a-b954-4571-9d9b-2f330739d4da\nwith BODY:<html>\n<body>\n\t<h2>404 Not found</h2>\n</body>\n\n</html>")
assert.Equal(t, expected, actual)
})

t.Run("should error out while fetching a specific agent present in GoCD due to missing headers", func(t *testing.T) {
server := mockServer([]byte(agentJSON), http.StatusOK,
nil, false, nil)
client := gocd.NewClient(server.URL, auth, "info", nil)

expected := gocd.Agent{}

actual, err := client.GetAgent(agentID)
assert.EqualError(t, err, "got 404 from GoCD while making GET call for "+server.URL+
"/api/agents/adb9540a-b954-4571-9d9b-2f330739d4da\nwith BODY:<html>\n<body>\n\t<h2>404 Not found</h2>\n</body>\n\n</html>")
assert.Equal(t, expected, actual)
})

t.Run("should error out while fetching a specific agent from GoCD as server returned malformed response", func(t *testing.T) {
server := mockServer([]byte("agentJSON"), http.StatusOK, correctAgentHeader,
false, nil)
client := gocd.NewClient(server.URL, auth, "info", nil)

expected := gocd.Agent{}

actual, err := client.GetAgent(agentID)
assert.EqualError(t, err, "reading response body errored with: invalid character 'a' looking for beginning of value")
assert.Equal(t, expected, actual)
})

t.Run("should error out while fetching a specific agent present in GoCD as server is not reachable", func(t *testing.T) {
client := gocd.NewClient("http://localhost:8156/go", auth, "info", nil)

client.SetRetryCount(1)
client.SetRetryWaitTime(1)

expected := gocd.Agent{}

actual, err := client.GetAgent(agentID)
assert.EqualError(t, err, "call made to get agent 'adb9540a-b954-4571-9d9b-2f330739d4da' information errored with: "+
"Get \"http://localhost:8156/go/api/agents/adb9540a-b954-4571-9d9b-2f330739d4da\": dial tcp [::1]:8156: connect: connection refused")
assert.Equal(t, expected, actual)
})
}

func Test_client_GetAgentJobRunHistory1(t *testing.T) {
agentID := "adb9540a-b954-4571-9d9b-2f330739d4da" //nolint:goconst
correctAgentsHeader := map[string]string{"Accept": gocd.HeaderVersionOne}
Expand Down Expand Up @@ -152,21 +250,18 @@ func Test_client_UpdateAgent(t *testing.T) {
correctAgentUpdateHeader := map[string]string{"Accept": gocd.HeaderVersionSeven, "Content-Type": gocd.ContentJSON}

t.Run("should update agent with updated configuration successfully", func(t *testing.T) {
var agentInfo gocd.Agent
err := json.Unmarshal([]byte(agentUpdateJSON), &agentInfo)
assert.NoError(t, err)
server := mockServer([]byte(agentUpdateJSON), http.StatusOK,
correctAgentUpdateHeader, false, map[string]string{"ETag": "61406622382e51c2079c11dcbdb978fb"})

server := agentMockServer(agentInfo, http.MethodPatch, correctAgentUpdateHeader)
client := gocd.NewClient(server.URL, auth, "info", nil)

agentUpdateInfo := gocd.Agent{
Name: "agent02.example.com",
ConfigState: "Enabled",
Resources: nil,
Environments: nil,
ID: agentID,
Name: "agent02.example.com",
ConfigState: "Enabled",
}

err = client.UpdateAgent(agentID, agentUpdateInfo)
err := client.UpdateAgent(agentUpdateInfo)
assert.NoError(t, err)
})

Expand All @@ -175,13 +270,14 @@ func Test_client_UpdateAgent(t *testing.T) {
client := gocd.NewClient(server.URL, auth, "info", nil)

agentUpdateInfo := gocd.Agent{
ID: agentID,
Name: "agent02.example.com",
ConfigState: "Enabled",
Resources: nil,
Environments: nil,
}

err := client.UpdateAgent(agentID, agentUpdateInfo)
err := client.UpdateAgent(agentUpdateInfo)
assert.EqualError(t, err, "got 404 from GoCD while making PATCH call for "+server.URL+
"/api/agents/adb9540a-b954-4571-9d9b-2f330739d4da\nwith BODY:<html>\n<body>\n\t<h2>404 Not found</h2>\n</body>\n\n</html>")
})
Expand All @@ -191,13 +287,14 @@ func Test_client_UpdateAgent(t *testing.T) {
client := gocd.NewClient(server.URL, auth, "info", nil)

agentUpdateInfo := gocd.Agent{
ID: agentID,
Name: "agent02.example.com",
ConfigState: "Enabled",
Resources: nil,
Environments: nil,
}

err := client.UpdateAgent(agentID, agentUpdateInfo)
err := client.UpdateAgent(agentUpdateInfo)
assert.EqualError(t, err, "got 404 from GoCD while making PATCH call for "+server.URL+
"/api/agents/adb9540a-b954-4571-9d9b-2f330739d4da\nwith BODY:<html>\n<body>\n\t<h2>404 Not found</h2>\n</body>\n\n</html>")
})
Expand All @@ -207,13 +304,14 @@ func Test_client_UpdateAgent(t *testing.T) {
client := gocd.NewClient(server.URL, auth, "info", nil)

agentUpdateInfo := gocd.Agent{
ID: agentID,
Name: "agent02.example.com",
ConfigState: "Enabled",
Resources: nil,
Environments: nil,
}

err := client.UpdateAgent(agentID, agentUpdateInfo)
err := client.UpdateAgent(agentUpdateInfo)
assert.EqualError(t, err, "got 500 from GoCD while making PATCH call for "+server.URL+
"/api/agents/adb9540a-b954-4571-9d9b-2f330739d4da\nwith BODY:json: cannot unmarshal string into Go value of type gocd.Agent")
})
Expand All @@ -225,13 +323,14 @@ func Test_client_UpdateAgent(t *testing.T) {
client.SetRetryWaitTime(1)

agentUpdateInfo := gocd.Agent{
ID: agentID,
Name: "agent02.example.com",
ConfigState: "Enabled",
Resources: nil,
Environments: nil,
}

err := client.UpdateAgent(agentID, agentUpdateInfo)
err := client.UpdateAgent(agentUpdateInfo)
assert.EqualError(t, err, "call made to update agent02.example.com agent information errored with: "+
"Patch \"http://localhost:8156/go/api/agents/adb9540a-b954-4571-9d9b-2f330739d4da\": dial tcp [::1]:8156: connect: connection refused")
})
Expand Down
3 changes: 2 additions & 1 deletion gocd.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ type client struct {
// GoCd implements methods to get various information from GoCD.
type GoCd interface {
GetAgents() ([]Agent, error)
GetAgent(agentID string) (Agent, error)
GetAgentJobRunHistory(agent string) (AgentJobHistory, error)
UpdateAgent(id string, agent Agent) error
UpdateAgent(agent Agent) error
UpdateAgentBulk(agent Agent) error
DeleteAgent(id string) (string, error)
DeleteAgentBulk(agent Agent) (string, error)
Expand Down
4 changes: 2 additions & 2 deletions gocd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ func Test_getLoglevel(t *testing.T) {
func TestGetGoCDMethodNames(t *testing.T) {
t.Run("should list all method names", func(t *testing.T) {
response := gocd.GetGoCDMethodNames()
assert.Equal(t, 117, len(response))
assert.Equal(t, 118, len(response))
assert.Equal(t, "AgentKillTask", response[0])
assert.Equal(t, "UpdateUser", response[116])
assert.Equal(t, "UpdateUser", response[117])
})
}
78 changes: 78 additions & 0 deletions internal/fixtures/agent.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
{
"_links": {
"self": {
"href": "https://ci.example.com/go/api/agents/adb9540a-b954-4571-9d9b-2f330739d4da"
},
"doc": {
"href": "https://api.gocd.org/#agents"
},
"find": {
"href": "https://ci.example.com/go/api/agents/:uuid"
}
},
"uuid": "adb9540a-b954-4571-9d9b-2f330739d4da",
"hostname": "ketanpkr.corporate.thoughtworks.com",
"ip_address": "10.12.20.47",
"sandbox": "/Users/ketanpadegaonkar/projects/gocd/gocd/agent",
"operating_system": "Mac OS X",
"free_space": 85890146304,
"agent_config_state": "Enabled",
"agent_state": "Building",
"agent_version": "20.5.0",
"agent_bootstrapper_version": "20.5.0",
"resources": [
"java",
"linux",
"firefox"
],
"environments": [
{
"name": "perf",
"origin": {
"type": "gocd",
"_links": {
"self": {
"href": "https://ci.example.com/go/admin/config_xml"
},
"doc": {
"href": "https://api.gocd.org/#get-configuration"
}
}
}
},
{
"name": "UAT",
"origin": {
"type": "config-repo",
"_links": {
"self": {
"href": "https://ci.example.com/go/api/admin/config_repos/foo"
},
"doc": {
"href": "https://api.gocd.org/#config-repos"
},
"find": {
"href": "https://ci.example.com/go/api/admin/config_repos/:id"
}
}
}
}
],
"build_state": "Building",
"build_details": {
"_links": {
"job": {
"href": "https://ci.example.com/go/tab/build/detail/up42/1/up42_stage/1/up42_job"
},
"stage": {
"href": "https://ci.example.com/go/pipelines/up42/1/up42_stage/1"
},
"pipeline": {
"href": "https://ci.example.com/go/tab/pipeline/history/up42"
}
},
"pipeline_name": "up42",
"stage_name": "up42_stage",
"job_name": "up42_job"
}
}
1 change: 0 additions & 1 deletion internal/fixtures/agents.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
"linux",
"firefox"
],
"environments": [],
"build_state": "Idle"
}
]
Expand Down
Loading

0 comments on commit 0145c89

Please sign in to comment.