feat(cluster): add cluster agent list command

This commit is contained in:
Timo Furrer 2023-09-25 14:41:42 +00:00 committed by Gary Holtz
parent f0916553df
commit 68473b8eda
13 changed files with 447 additions and 0 deletions

16
api/agent.go Normal file
View File

@ -0,0 +1,16 @@
package api
import "github.com/xanzy/go-gitlab"
var ListAgents = func(client *gitlab.Client, projectID interface{}, opts *gitlab.ListAgentsOptions) ([]*gitlab.Agent, error) {
if client == nil {
client = apiClient.Lab()
}
agents, _, err := client.ClusterAgents.ListAgents(projectID, opts)
if err != nil {
return nil, err
}
return agents, nil
}

View File

@ -0,0 +1,21 @@
package cluster
import (
"github.com/spf13/cobra"
agentListCmd "gitlab.com/gitlab-org/cli/commands/cluster/agent/list"
"gitlab.com/gitlab-org/cli/commands/cmdutils"
)
func NewCmdAgent(f *cmdutils.Factory) *cobra.Command {
agentCmd := &cobra.Command{
Use: "agent <command> [flags]",
Short: `Manage GitLab Agents for Kubernetes`,
Long: ``,
}
cmdutils.EnableRepoOverride(agentCmd, f)
agentCmd.AddCommand(agentListCmd.NewCmdAgentList(f))
return agentCmd
}

View File

@ -0,0 +1,34 @@
package cluster
import (
"bytes"
"io"
"os"
"testing"
"github.com/stretchr/testify/assert"
"gitlab.com/gitlab-org/cli/commands/cmdutils"
)
func TestNewCmdAgent(t *testing.T) {
old := os.Stdout // keep backup of the real stdout
r, w, _ := os.Pipe()
os.Stdout = w
assert.Nil(t, NewCmdAgent(&cmdutils.Factory{}).Execute())
outC := make(chan string)
// copy the output in a separate goroutine so printing can't block indefinitely
go func() {
var buf bytes.Buffer
_, _ = io.Copy(&buf, r)
outC <- buf.String()
}()
// back to normal state
w.Close()
os.Stdout = old // restoring the real stdout
out := <-outC
assert.Contains(t, out, "Manage GitLab Agents for Kubernetes")
}

View File

@ -0,0 +1,18 @@
package agentutils
import (
"github.com/xanzy/go-gitlab"
"gitlab.com/gitlab-org/cli/pkg/iostreams"
"gitlab.com/gitlab-org/cli/pkg/tableprinter"
"gitlab.com/gitlab-org/cli/pkg/utils"
)
func DisplayAllAgents(io *iostreams.IOStreams, agents []*gitlab.Agent) string {
c := io.Color()
table := tableprinter.NewTablePrinter()
table.AddRow(c.Bold("ID"), c.Bold("Name"), c.Bold(c.Gray("Created At")))
for _, r := range agents {
table.AddRow(r.ID, r.Name, c.Gray(utils.TimeToPrettyTimeAgo(*r.CreatedAt)))
}
return table.Render()
}

View File

@ -0,0 +1,75 @@
package list
import (
"fmt"
"gitlab.com/gitlab-org/cli/api"
"gitlab.com/gitlab-org/cli/commands/cluster/agent/agentutils"
"gitlab.com/gitlab-org/cli/commands/cmdutils"
"gitlab.com/gitlab-org/cli/pkg/utils"
"github.com/spf13/cobra"
"github.com/xanzy/go-gitlab"
)
var factory *cmdutils.Factory
func NewCmdAgentList(f *cmdutils.Factory) *cobra.Command {
factory = f
agentListCmd := &cobra.Command{
Use: "list [flags]",
Short: `List GitLab Agents for Kubernetes in a project`,
Long: ``,
Aliases: []string{"ls"},
Args: cobra.MaximumNArgs(3),
RunE: func(cmd *cobra.Command, args []string) error {
factory = f
page, err := cmd.Flags().GetUint("page")
if err != nil {
return err
}
perPage, err := cmd.Flags().GetUint("per-page")
if err != nil {
return err
}
return listAgents(int(page), int(perPage))
},
}
agentListCmd.Flags().UintP("page", "p", 1, "Page number")
agentListCmd.Flags().UintP("per-page", "P", uint(api.DefaultListLimit), "Number of items to list per page.")
return agentListCmd
}
func listAgents(page, perPage int) error {
apiClient, err := factory.HttpClient()
if err != nil {
return err
}
repo, err := factory.BaseRepo()
if err != nil {
return err
}
agents, err := api.ListAgents(apiClient, repo.FullName(), &gitlab.ListAgentsOptions{
Page: page,
PerPage: perPage,
})
if err != nil {
return err
}
title := utils.NewListTitle("agent")
title.RepoName = repo.FullName()
title.Page = page
title.CurrentPageTotal = len(agents)
err = factory.IO.StartPager()
if err != nil {
return err
}
defer factory.IO.StopPager()
fmt.Fprintf(factory.IO.StdOut, "%s\n%s\n", title.Describe(), agentutils.DisplayAllAgents(factory.IO, agents))
return nil
}

View File

@ -0,0 +1,103 @@
package list
import (
"fmt"
"net/http"
"testing"
"time"
"github.com/MakeNowJust/heredoc"
"gitlab.com/gitlab-org/cli/pkg/httpmock"
"gitlab.com/gitlab-org/cli/test"
"gitlab.com/gitlab-org/cli/commands/cmdtest"
"github.com/stretchr/testify/assert"
)
func runCommand(rt http.RoundTripper, isTTY bool, cli string, doHyperlinks string) (*test.CmdOut, error) {
ios, _, stdout, stderr := cmdtest.InitIOStreams(isTTY, doHyperlinks)
f := cmdtest.InitFactory(ios, rt)
// TODO: shouldn't be there but the stub doesn't work without it
_, _ = f.HttpClient()
cmd := NewCmdAgentList(f)
return cmdtest.ExecuteCommand(cmd, cli, stdout, stderr)
}
func TestAgentList(t *testing.T) {
fakeHTTP := httpmock.New()
defer fakeHTTP.Verify(t)
deterministicCreatedAt := time.Now().Add(-24 * time.Hour).Format(time.RFC3339)
fakeHTTP.RegisterResponder(http.MethodGet, "/projects/OWNER/REPO/cluster_agents",
httpmock.NewStringResponse(http.StatusOK, fmt.Sprintf(`
[
{
"id": 1,
"name": "local",
"created_at": "%[1]s"
},
{
"id": 2,
"name": "prd",
"created_at": "%[1]s"
}
]
`, deterministicCreatedAt)))
output, err := runCommand(fakeHTTP, true, "", "")
if err != nil {
t.Errorf("error running command `cluster agent list`: %v", err)
}
assert.Equal(t, heredoc.Doc(`
Showing 2 agents on OWNER/REPO (Page 1)
ID Name Created At
1 local about 1 day ago
2 prd about 1 day ago
`), output.String())
assert.Equal(t, ``, output.Stderr())
}
func TestAgentList_Pagination(t *testing.T) {
fakeHTTP := httpmock.New()
defer fakeHTTP.Verify(t)
deterministicCreatedAt := time.Now().Add(-24 * time.Hour).Format(time.RFC3339)
fakeHTTP.RegisterResponder(http.MethodGet, "/projects/OWNER/REPO/cluster_agents",
httpmock.NewStringResponse(http.StatusOK, fmt.Sprintf(`
[
{
"id": 1,
"name": "local",
"created_at": "%[1]s"
},
{
"id": 2,
"name": "prd",
"created_at": "%[1]s"
}
]
`, deterministicCreatedAt)))
cli := "--page 42 --per-page 10"
output, err := runCommand(fakeHTTP, true, cli, "")
if err != nil {
t.Errorf("error running command `cluster agent list`: %v", err)
}
assert.Equal(t, heredoc.Doc(`
Showing 2 agents on OWNER/REPO (Page 42)
ID Name Created At
1 local about 1 day ago
2 prd about 1 day ago
`), output.String())
assert.Equal(t, ``, output.Stderr())
}

View File

@ -0,0 +1,21 @@
package cluster
import (
"github.com/spf13/cobra"
agentCmd "gitlab.com/gitlab-org/cli/commands/cluster/agent"
"gitlab.com/gitlab-org/cli/commands/cmdutils"
)
func NewCmdCluster(f *cmdutils.Factory) *cobra.Command {
clusterCmd := &cobra.Command{
Use: "cluster <command> [flags]",
Short: `Manage GitLab Agents for Kubernetes and their clusters`,
Long: ``,
}
cmdutils.EnableRepoOverride(clusterCmd, f)
clusterCmd.AddCommand(agentCmd.NewCmdAgent(f))
return clusterCmd
}

View File

@ -0,0 +1,34 @@
package cluster
import (
"bytes"
"io"
"os"
"testing"
"github.com/stretchr/testify/assert"
"gitlab.com/gitlab-org/cli/commands/cmdutils"
)
func TestNewCmdCluster(t *testing.T) {
old := os.Stdout // keep backup of the real stdout
r, w, _ := os.Pipe()
os.Stdout = w
assert.Nil(t, NewCmdCluster(&cmdutils.Factory{}).Execute())
outC := make(chan string)
// copy the output in a separate goroutine so printing can't block indefinitely
go func() {
var buf bytes.Buffer
_, _ = io.Copy(&buf, r)
outC <- buf.String()
}()
// back to normal state
w.Close()
os.Stdout = old // restoring the real stdout
out := <-outC
assert.Contains(t, out, "Manage GitLab Agents for Kubernetes and their clusters")
}

View File

@ -12,6 +12,7 @@ import (
authCmd "gitlab.com/gitlab-org/cli/commands/auth"
changelogCmd "gitlab.com/gitlab-org/cli/commands/changelog"
pipelineCmd "gitlab.com/gitlab-org/cli/commands/ci"
clusterCmd "gitlab.com/gitlab-org/cli/commands/cluster"
"gitlab.com/gitlab-org/cli/commands/cmdutils"
completionCmd "gitlab.com/gitlab-org/cli/commands/completion"
configCmd "gitlab.com/gitlab-org/cli/commands/config"
@ -110,6 +111,7 @@ func NewCmdRoot(f *cmdutils.Factory, version, buildDate string) *cobra.Command {
cmdutils.HTTPClientFactory(f) // Initialize HTTP Client
rootCmd.AddCommand(changelogCmd.NewCmdChangelog(f))
rootCmd.AddCommand(clusterCmd.NewCmdCluster(f))
rootCmd.AddCommand(issueCmd.NewCmdIssue(f))
rootCmd.AddCommand(incidentCmd.NewCmdIncident(f))
rootCmd.AddCommand(labelCmd.NewCmdLabel(f))

View File

@ -0,0 +1,30 @@
---
stage: Create
group: Code Review
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
---
<!--
This documentation is auto generated by a script.
Please do not edit this file directly. Run `make gen-docs` instead.
-->
# `glab cluster agent`
Manage GitLab Agents for Kubernetes
## Options
```plaintext
-R, --repo OWNER/REPO Select another repository using the OWNER/REPO or `GROUP/NAMESPACE/REPO` format or full URL or git URL
```
## Options inherited from parent commands
```plaintext
--help Show help for command
```
## Subcommands
- [list](list.md)

View File

@ -0,0 +1,38 @@
---
stage: Create
group: Code Review
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
---
<!--
This documentation is auto generated by a script.
Please do not edit this file directly. Run `make gen-docs` instead.
-->
# `glab cluster agent list`
List GitLab Agents for Kubernetes in a project
```plaintext
glab cluster agent list [flags]
```
## Aliases
```plaintext
ls
```
## Options
```plaintext
-p, --page uint Page number (default 1)
-P, --per-page uint Number of items to list per page. (default 30)
```
## Options inherited from parent commands
```plaintext
--help Show help for command
-R, --repo OWNER/REPO Select another repository using the OWNER/REPO or `GROUP/NAMESPACE/REPO` format or full URL or git URL
```

View File

@ -0,0 +1,25 @@
---
stage: Create
group: Code Review
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
---
<!--
This documentation is auto generated by a script.
Please do not edit this file directly. Run `make gen-docs` instead.
-->
# `glab cluster help`
Help about any command
```plaintext
glab cluster help [command] [flags]
```
## Options inherited from parent commands
```plaintext
--help Show help for command
-R, --repo OWNER/REPO Select another repository using the OWNER/REPO or `GROUP/NAMESPACE/REPO` format or full URL or git URL
```

View File

@ -0,0 +1,30 @@
---
stage: Create
group: Code Review
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
---
<!--
This documentation is auto generated by a script.
Please do not edit this file directly. Run `make gen-docs` instead.
-->
# `glab cluster`
Manage GitLab Agents for Kubernetes and their clusters
## Options
```plaintext
-R, --repo OWNER/REPO Select another repository using the OWNER/REPO or `GROUP/NAMESPACE/REPO` format or full URL or git URL
```
## Options inherited from parent commands
```plaintext
--help Show help for command
```
## Subcommands
- [agent](agent/index.md)