api: IntentionCheck
This commit is contained in:
parent
b5b29cd6af
commit
bf99a7f54a
|
@ -1159,7 +1159,7 @@ func TestAPI_AgentConnectProxyConfig(t *testing.T) {
|
|||
TargetServiceName: "foo",
|
||||
ContentHash: "93baee1d838888ae",
|
||||
ExecMode: "daemon",
|
||||
Command: []string{"consul connect proxy"},
|
||||
Command: []string{"consul", "connect", "proxy"},
|
||||
Config: map[string]interface{}{
|
||||
"bind_address": "127.0.0.1",
|
||||
"bind_port": float64(20000),
|
||||
|
|
|
@ -83,6 +83,18 @@ const (
|
|||
IntentionMatchDestination IntentionMatchType = "destination"
|
||||
)
|
||||
|
||||
// IntentionCheck are the arguments for the intention check API. For
|
||||
// more documentation see the IntentionCheck function.
|
||||
type IntentionCheck struct {
|
||||
// Source and Destination are the source and destination values to
|
||||
// check. The destination is always a Consul service, but the source
|
||||
// may be other values as defined by the SourceType.
|
||||
Source, Destination string
|
||||
|
||||
// SourceType is the type of the value for the source.
|
||||
SourceType IntentionSourceType
|
||||
}
|
||||
|
||||
// Intentions returns the list of intentions.
|
||||
func (h *Connect) Intentions(q *QueryOptions) ([]*Intention, *QueryMeta, error) {
|
||||
r := h.c.newRequest("GET", "/v1/connect/intentions")
|
||||
|
@ -156,6 +168,33 @@ func (h *Connect) IntentionMatch(args *IntentionMatch, q *QueryOptions) (map[str
|
|||
return out, qm, nil
|
||||
}
|
||||
|
||||
// IntentionCheck returns whether a given source/destination would be allowed
|
||||
// or not given the current set of intentions and the configuration of Consul.
|
||||
func (h *Connect) IntentionCheck(args *IntentionCheck, q *QueryOptions) (bool, *QueryMeta, error) {
|
||||
r := h.c.newRequest("GET", "/v1/connect/intentions/check")
|
||||
r.setQueryOptions(q)
|
||||
r.params.Set("source", args.Source)
|
||||
r.params.Set("destination", args.Destination)
|
||||
if args.SourceType != "" {
|
||||
r.params.Set("source-type", string(args.SourceType))
|
||||
}
|
||||
rtt, resp, err := requireOK(h.c.doRequest(r))
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
qm := &QueryMeta{}
|
||||
parseQueryMeta(resp, qm)
|
||||
qm.RequestTime = rtt
|
||||
|
||||
var out struct{ Allowed bool }
|
||||
if err := decodeBody(resp, &out); err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
return out.Allowed, qm, nil
|
||||
}
|
||||
|
||||
// IntentionCreate will create a new intention. The ID in the given
|
||||
// structure must be empty and a generate ID will be returned on
|
||||
// success.
|
||||
|
|
|
@ -87,6 +87,55 @@ func TestAPI_ConnectIntentionMatch(t *testing.T) {
|
|||
require.Equal(expected, actual)
|
||||
}
|
||||
|
||||
func TestAPI_ConnectIntentionCheck(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require := require.New(t)
|
||||
c, s := makeClient(t)
|
||||
defer s.Stop()
|
||||
|
||||
connect := c.Connect()
|
||||
|
||||
// Create
|
||||
{
|
||||
insert := [][]string{
|
||||
{"foo", "*", "foo", "bar"},
|
||||
}
|
||||
|
||||
for _, v := range insert {
|
||||
ixn := testIntention()
|
||||
ixn.SourceNS = v[0]
|
||||
ixn.SourceName = v[1]
|
||||
ixn.DestinationNS = v[2]
|
||||
ixn.DestinationName = v[3]
|
||||
ixn.Action = IntentionActionDeny
|
||||
id, _, err := connect.IntentionCreate(ixn, nil)
|
||||
require.Nil(err)
|
||||
require.NotEmpty(id)
|
||||
}
|
||||
}
|
||||
|
||||
// Match it
|
||||
{
|
||||
result, _, err := connect.IntentionCheck(&IntentionCheck{
|
||||
Source: "foo/qux",
|
||||
Destination: "foo/bar",
|
||||
}, nil)
|
||||
require.Nil(err)
|
||||
require.False(result)
|
||||
}
|
||||
|
||||
// Match it (non-matching)
|
||||
{
|
||||
result, _, err := connect.IntentionCheck(&IntentionCheck{
|
||||
Source: "bar/qux",
|
||||
Destination: "foo/bar",
|
||||
}, nil)
|
||||
require.Nil(err)
|
||||
require.True(result)
|
||||
}
|
||||
}
|
||||
|
||||
func testIntention() *Intention {
|
||||
return &Intention{
|
||||
SourceNS: "eng",
|
||||
|
|
Loading…
Reference in New Issue