This PR is based on the previous work by @snuggie12 in PR #6825. It adds the command consul intention list to list all available intentions. The list functionality for intentions seems a bit overdue as it's just very handy. The web UI cannot list intentions outside of the default namespace, and using the API is sometimes not the friendliest option. ;) I cherry picked snuggie12's commits who did most of the heavy lifting (thanks again @snuggie12 for your great work!). The changes in the original commit mostly still worked on the current HEAD. On top of that I added support for namespaces and fixed the docs as they are managed differently today. Also the requested changes related to the "Connect" references in the original PRs have been addressed. Fixes #5652 Co-authored-by: Matt Hoey <mhoey05@jcu.edu>
This commit is contained in:
parent
5b92255cf5
commit
acc843f04d
|
@ -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.
|
||||
```
|
|
@ -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 })
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
`
|
|
@ -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)
|
||||
}
|
|
@ -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]
|
||||
|
@ -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
|
||||
|
|
|
@ -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
|
||||
```
|
Loading…
Reference in New Issue