mirror of https://gitlab.com/gitlab-org/cli.git
feat(cluster): add cluster agent list command
This commit is contained in:
parent
f0916553df
commit
68473b8eda
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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")
|
||||
}
|
|
@ -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()
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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())
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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")
|
||||
}
|
|
@ -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))
|
||||
|
|
|
@ -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)
|
|
@ -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
|
||||
```
|
|
@ -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
|
||||
```
|
|
@ -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)
|
Loading…
Reference in New Issue