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

cli: Add consul intention list command (based on PR #6825) #9468

Merged
merged 8 commits into from
Jan 12, 2021
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
3 changes: 3 additions & 0 deletions .changelog/9468.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:feature
cli: The `consul intention` command now has a new `list` subcommand to allow the listing of configured intentions. It also supports the `-namespace=` option.
```
2 changes: 2 additions & 0 deletions command/commands_oss.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ import (
ixncreate "github.com/hashicorp/consul/command/intention/create"
ixndelete "github.com/hashicorp/consul/command/intention/delete"
ixnget "github.com/hashicorp/consul/command/intention/get"
ixnlist "github.com/hashicorp/consul/command/intention/list"
ixnmatch "github.com/hashicorp/consul/command/intention/match"
"github.com/hashicorp/consul/command/join"
"github.com/hashicorp/consul/command/keygen"
Expand Down Expand Up @@ -182,6 +183,7 @@ func init() {
Register("intention create", func(ui cli.Ui) (cli.Command, error) { return ixncreate.New(ui), nil })
Register("intention delete", func(ui cli.Ui) (cli.Command, error) { return ixndelete.New(ui), nil })
Register("intention get", func(ui cli.Ui) (cli.Command, error) { return ixnget.New(ui), nil })
Register("intention list", func(ui cli.Ui) (cli.Command, error) { return ixnlist.New(ui), nil })
Register("intention match", func(ui cli.Ui) (cli.Command, error) { return ixnmatch.New(ui), nil })
Register("join", func(ui cli.Ui) (cli.Command, error) { return join.New(ui), nil })
Register("keygen", func(ui cli.Ui) (cli.Command, error) { return keygen.New(ui), nil })
Expand Down
4 changes: 4 additions & 0 deletions command/intention/intention.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ Usage: consul intention <subcommand> [options] [args]

$ consul intention check web db

List all intentions:

$ consul intention list

Find all intentions for communicating to the "db" service:

$ consul intention match db
Expand Down
85 changes: 85 additions & 0 deletions command/intention/list/intention_list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package list

import (
"flag"
"fmt"

"github.com/hashicorp/consul/command/flags"
"github.com/mitchellh/cli"
"github.com/ryanuber/columnize"
)

func New(ui cli.Ui) *cmd {
c := &cmd{UI: ui}
c.init()
return c
}

type cmd struct {
UI cli.Ui
flags *flag.FlagSet
http *flags.HTTPFlags
help string
}

func (c *cmd) init() {
c.flags = flag.NewFlagSet("", flag.ContinueOnError)

c.http = &flags.HTTPFlags{}
flags.Merge(c.flags, c.http.ClientFlags())
flags.Merge(c.flags, c.http.ServerFlags())
flags.Merge(c.flags, c.http.NamespaceFlags())
c.help = flags.Usage(help, c.flags)
}

func (c *cmd) Run(args []string) int {
if err := c.flags.Parse(args); err != nil {
return 1
}

client, err := c.http.APIClient()
if err != nil {
c.UI.Error(fmt.Sprintf("Error connecting to Consul agent: %s", err))
return 1
}

ixns, _, err := client.Connect().Intentions(nil)
if err != nil {
c.UI.Error(fmt.Sprintf("Failed to retrieve the intentions list: %s", err))
return 1
}

if len(ixns) == 0 {
c.UI.Error(fmt.Sprintf("There are no intentions."))
return 2
}

result := make([]string, 0, len(ixns))
header := "ID\x1fSource\x1fAction\x1fDestination\x1fPrecedence"
result = append(result, header)
for _, ixn := range ixns {
line := fmt.Sprintf("%s\x1f%s\x1f%s\x1f%s\x1f%d",
ixn.ID, ixn.SourceName, ixn.Action, ixn.DestinationName, ixn.Precedence)
result = append(result, line)
}

output := columnize.Format(result, &columnize.Config{Delim: string([]byte{0x1f})})
c.UI.Output(output)

return 0
}

func (c *cmd) Synopsis() string {
return synopsis
}

func (c *cmd) Help() string {
return c.help
}

const synopsis = "List intentions."
const help = `
Usage: consul intention list

List all intentions.
`
47 changes: 47 additions & 0 deletions command/intention/list/intention_list_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package list

import (
"strings"
"testing"

"github.com/hashicorp/consul/agent"
"github.com/hashicorp/consul/api"
"github.com/mitchellh/cli"
"github.com/stretchr/testify/require"
)

func TestIntentionListCommand_noTabs(t *testing.T) {
t.Parallel()
if strings.ContainsRune(New(cli.NewMockUi()).Help(), '\t') {
t.Fatal("help has tabs")
}
}

func TestIntentionListCommand(t *testing.T) {
t.Parallel()
require := require.New(t)
a := agent.NewTestAgent(t, ``)
defer a.Shutdown()
client := a.Client()

// Create the intention
var id string
{
var err error
//nolint:staticcheck
id, _, err = client.Connect().IntentionCreate(&api.Intention{
SourceName: "web",
DestinationName: "db",
Action: api.IntentionActionAllow,
}, nil)
require.NoError(err)
}

// List all intentions
ui := cli.NewMockUi()
cmd := New(ui)
args := []string{"-http-addr=" + a.HTTPAddr()}

require.Equal(0, cmd.Run(args), ui.ErrorWriter.String())
require.Contains(ui.OutputWriter.String(), id)
}
11 changes: 9 additions & 2 deletions website/content/commands/intention/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ API](/api/connect/intentions).

Usage: `consul intention <subcommand>`

For the exact documentation for your Consul version, run `consul intention -h` to view
the complete list of subcommands.
For the exact documentation for your Consul version, run `consul intention -h`
to view the complete list of subcommands.

```text
Usage: consul intention <subcommand> [options] [args]
Expand All @@ -34,6 +34,7 @@ Subcommands:
check Check whether a connection between two services is allowed.
create Create intentions for service connections.
delete Delete an intention.
list Lists all intentions.
get Show information about an intention.
match Show intentions that match a source or destination.
```
Expand Down Expand Up @@ -62,6 +63,12 @@ Test whether a "web" is allowed to connect to "db":
$ consul intention check web db
```

List all intentions:

```shell-session
$ consul intention list
```

Find all intentions for communicating to the "db" service:

```shell-session
Expand Down
34 changes: 34 additions & 0 deletions website/content/commands/intention/list.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
layout: commands
page_title: 'Commands: Intention List'
sidebar_title: list
---

# Consul Intention List

Command: `consul intention list`

The `intention list` command shows all intentions including ID and precedence.

## Usage

Usage:

- `consul intention list`

#### API Options

@include 'http_api_options_client.mdx'

#### Enterprise Options

@include 'http_api_namespace_options.mdx'

## Examples

```shell-session
$ consul intention list
ID Source Action Destination Precedence
web allow db 9
36a6cf15-5f0e-a388-163e-0f608009704a dashboard allow counting 9
```