From daab8d6f518e25cb6cfb0d2df96a742b79b081f0 Mon Sep 17 00:00:00 2001 From: Matt Hoey Date: Wed, 20 Nov 2019 13:49:40 -0800 Subject: [PATCH 1/8] 5652 - Adds consul intention list command --- command/commands_oss.go | 2 + command/intention/intention.go | 4 + command/intention/list/intention_list.go | 84 +++++++++++++++++++ command/intention/list/intention_list_test.go | 46 ++++++++++ 4 files changed, 136 insertions(+) create mode 100644 command/intention/list/intention_list.go create mode 100644 command/intention/list/intention_list_test.go diff --git a/command/commands_oss.go b/command/commands_oss.go index d8e42f6424d..781f7441245 100644 --- a/command/commands_oss.go +++ b/command/commands_oss.go @@ -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" @@ -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 }) diff --git a/command/intention/intention.go b/command/intention/intention.go index 94de2647229..44cc7db42de 100644 --- a/command/intention/intention.go +++ b/command/intention/intention.go @@ -40,6 +40,10 @@ Usage: consul intention [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 diff --git a/command/intention/list/intention_list.go b/command/intention/list/intention_list.go new file mode 100644 index 00000000000..fdd19254ca8 --- /dev/null +++ b/command/intention/list/intention_list.go @@ -0,0 +1,84 @@ +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()) + 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|Source|Action|Destination|Precedence" + result = append(result, header) + for _, ixn := range ixns { + line := fmt.Sprintf("%s|%s|%s|%s|%d", + ixn.ID, ixn.SourceName, ixn.Action, ixn.DestinationName, ixn.Precedence) + result = append(result, line) + } + + output := columnize.SimpleFormat(result) + c.UI.Output(output) + + return 0 +} + +func (c *cmd) Synopsis() string { + return synopsis +} + +func (c *cmd) Help() string { + return c.help +} + +const synopsis = "List connect intentions" +const help = ` +Usage: consul intention list + + List all consul connect intentions. +` diff --git a/command/intention/list/intention_list_test.go b/command/intention/list/intention_list_test.go new file mode 100644 index 00000000000..f6506b6cf72 --- /dev/null +++ b/command/intention/list/intention_list_test.go @@ -0,0 +1,46 @@ +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, t.Name(), ``) + defer a.Shutdown() + client := a.Client() + + // Create the intention + var id string + { + var err error + 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) +} From 7b3f14befde1e6ca53472b47d71be8e205acfc7f Mon Sep 17 00:00:00 2001 From: Matt Hoey Date: Wed, 20 Nov 2019 14:16:22 -0800 Subject: [PATCH 2/8] Fixed formatting in test --- command/intention/list/intention_list_test.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/command/intention/list/intention_list_test.go b/command/intention/list/intention_list_test.go index f6506b6cf72..c43aa2f00f8 100644 --- a/command/intention/list/intention_list_test.go +++ b/command/intention/list/intention_list_test.go @@ -27,14 +27,14 @@ func TestIntentionListCommand(t *testing.T) { // Create the intention var id string { - var err error - id, _, err = client.Connect().IntentionCreate(&api.Intention{ - SourceName: "web", - DestinationName: "db", - Action: api.IntentionActionAllow, - }, nil) - require.NoError(err) - } + var err error + id, _, err = client.Connect().IntentionCreate(&api.Intention{ + SourceName: "web", + DestinationName: "db", + Action: api.IntentionActionAllow, + }, nil) + require.NoError(err) + } // List all intentions ui := cli.NewMockUi() @@ -42,5 +42,5 @@ func TestIntentionListCommand(t *testing.T) { args := []string{"-http-addr=" + a.HTTPAddr()} require.Equal(0, cmd.Run(args), ui.ErrorWriter.String()) - require.Contains(ui.OutputWriter.String(), id) + require.Contains(ui.OutputWriter.String(), id) } From 1d2739778bbe9f3a648b919abe118798fcd26bfe Mon Sep 17 00:00:00 2001 From: Michael Hofer Date: Thu, 24 Dec 2020 16:02:11 +0100 Subject: [PATCH 3/8] Add namespace support to consul intention list --- command/intention/list/intention_list.go | 1 + 1 file changed, 1 insertion(+) diff --git a/command/intention/list/intention_list.go b/command/intention/list/intention_list.go index fdd19254ca8..fb5368db382 100644 --- a/command/intention/list/intention_list.go +++ b/command/intention/list/intention_list.go @@ -28,6 +28,7 @@ func (c *cmd) init() { 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) } From 4121a44003d8366dd92dc41be7621141002a973b Mon Sep 17 00:00:00 2001 From: Michael Hofer Date: Thu, 24 Dec 2020 16:02:46 +0100 Subject: [PATCH 4/8] Remove references to Connect for consul intention list --- command/intention/list/intention_list.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/command/intention/list/intention_list.go b/command/intention/list/intention_list.go index fb5368db382..5bfc601a579 100644 --- a/command/intention/list/intention_list.go +++ b/command/intention/list/intention_list.go @@ -77,9 +77,9 @@ func (c *cmd) Help() string { return c.help } -const synopsis = "List connect intentions" +const synopsis = "List intentions." const help = ` Usage: consul intention list - List all consul connect intentions. + List all intentions. ` From ca37099f3a26387cc1f68cf6bf4c892561aec9c5 Mon Sep 17 00:00:00 2001 From: Michael Hofer Date: Thu, 24 Dec 2020 16:03:14 +0100 Subject: [PATCH 5/8] Fix consul intention list tests --- command/intention/list/intention_list_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/command/intention/list/intention_list_test.go b/command/intention/list/intention_list_test.go index c43aa2f00f8..674efcc39ba 100644 --- a/command/intention/list/intention_list_test.go +++ b/command/intention/list/intention_list_test.go @@ -20,7 +20,7 @@ func TestIntentionListCommand_noTabs(t *testing.T) { func TestIntentionListCommand(t *testing.T) { t.Parallel() require := require.New(t) - a := agent.NewTestAgent(t, t.Name(), ``) + a := agent.NewTestAgent(t, ``) defer a.Shutdown() client := a.Client() @@ -28,6 +28,7 @@ func TestIntentionListCommand(t *testing.T) { var id string { var err error + //nolint:staticcheck id, _, err = client.Connect().IntentionCreate(&api.Intention{ SourceName: "web", DestinationName: "db", From b6aee293d573e8d3ea8d9ba1e6f0611297b50269 Mon Sep 17 00:00:00 2001 From: Michael Hofer Date: Thu, 24 Dec 2020 16:03:49 +0100 Subject: [PATCH 6/8] Add consul intention list docs --- website/content/commands/intention/index.mdx | 11 +++++-- website/content/commands/intention/list.mdx | 34 ++++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 website/content/commands/intention/list.mdx diff --git a/website/content/commands/intention/index.mdx b/website/content/commands/intention/index.mdx index 0c0073df29d..898a2187818 100644 --- a/website/content/commands/intention/index.mdx +++ b/website/content/commands/intention/index.mdx @@ -22,8 +22,8 @@ API](/api/connect/intentions). Usage: `consul intention ` -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 [options] [args] @@ -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. ``` @@ -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 diff --git a/website/content/commands/intention/list.mdx b/website/content/commands/intention/list.mdx new file mode 100644 index 00000000000..54168e2eef1 --- /dev/null +++ b/website/content/commands/intention/list.mdx @@ -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 +``` From 2787b8e6c632c8ff035028b54a8fb79bcb72fc8f Mon Sep 17 00:00:00 2001 From: Michael Hofer Date: Mon, 11 Jan 2021 19:57:31 +0100 Subject: [PATCH 7/8] Change delim for intention list command to \x1f --- command/intention/list/intention_list.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/command/intention/list/intention_list.go b/command/intention/list/intention_list.go index 5bfc601a579..929c99cb07a 100644 --- a/command/intention/list/intention_list.go +++ b/command/intention/list/intention_list.go @@ -55,15 +55,15 @@ func (c *cmd) Run(args []string) int { } result := make([]string, 0, len(ixns)) - header := "ID|Source|Action|Destination|Precedence" + header := "ID\x1fSource\x1fAction\x1fDestination\x1fPrecedence" result = append(result, header) for _, ixn := range ixns { - line := fmt.Sprintf("%s|%s|%s|%s|%d", + 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.SimpleFormat(result) + output := columnize.Format(result, &columnize.Config{Delim: string([]byte{0x1f})}) c.UI.Output(output) return 0 From 63deb7d65ac703ac28a9b1f0b775f7f34ad74ccc Mon Sep 17 00:00:00 2001 From: Michael Hofer Date: Mon, 11 Jan 2021 20:10:34 +0100 Subject: [PATCH 8/8] Add changelog entry for new consul intention list command --- .changelog/9468.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/9468.txt diff --git a/.changelog/9468.txt b/.changelog/9468.txt new file mode 100644 index 00000000000..80bfc591e5f --- /dev/null +++ b/.changelog/9468.txt @@ -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. +```