mirror of https://github.com/status-im/consul.git
added tenancy to TestBuildL4TrafficPermissions (#19932)
This commit is contained in:
parent
33a90edfab
commit
a6496898de
|
@ -6,8 +6,6 @@ package connect
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
"github.com/hashicorp/consul/acl"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// SpiffeIDWorkloadIdentity is the structure to represent the SPIFFE ID for a workload.
|
// SpiffeIDWorkloadIdentity is the structure to represent the SPIFFE ID for a workload.
|
||||||
|
@ -18,10 +16,6 @@ type SpiffeIDWorkloadIdentity struct {
|
||||||
WorkloadIdentity string
|
WorkloadIdentity string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (id SpiffeIDWorkloadIdentity) NamespaceOrDefault() string {
|
|
||||||
return acl.NamespaceOrDefault(id.Namespace)
|
|
||||||
}
|
|
||||||
|
|
||||||
// URI returns the *url.URL for this SPIFFE ID.
|
// URI returns the *url.URL for this SPIFFE ID.
|
||||||
func (id SpiffeIDWorkloadIdentity) URI() *url.URL {
|
func (id SpiffeIDWorkloadIdentity) URI() *url.URL {
|
||||||
var result url.URL
|
var result url.URL
|
||||||
|
@ -37,8 +31,8 @@ func (id SpiffeIDWorkloadIdentity) uriPath() string {
|
||||||
// to generate the correct SpiffeID.
|
// to generate the correct SpiffeID.
|
||||||
// We intentionally avoid using pbpartition.DefaultName here to be CE friendly.
|
// We intentionally avoid using pbpartition.DefaultName here to be CE friendly.
|
||||||
path := fmt.Sprintf("/ap/%s/ns/%s/identity/%s",
|
path := fmt.Sprintf("/ap/%s/ns/%s/identity/%s",
|
||||||
id.PartitionOrDefault(),
|
id.Partition,
|
||||||
id.NamespaceOrDefault(),
|
id.Namespace,
|
||||||
id.WorkloadIdentity,
|
id.WorkloadIdentity,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -6,25 +6,13 @@
|
||||||
package connect
|
package connect
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/hashicorp/consul/acl"
|
"github.com/hashicorp/consul/acl"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// TODO: this will need to somehow be updated to set namespace here when we include namespaces in CE
|
||||||
|
|
||||||
// GetEnterpriseMeta will synthesize an EnterpriseMeta struct from the SpiffeIDWorkloadIdentity.
|
// GetEnterpriseMeta will synthesize an EnterpriseMeta struct from the SpiffeIDWorkloadIdentity.
|
||||||
// in CE this just returns an empty (but never nil) struct pointer
|
// in CE this just returns an empty (but never nil) struct pointer
|
||||||
func (id SpiffeIDWorkloadIdentity) GetEnterpriseMeta() *acl.EnterpriseMeta {
|
func (id SpiffeIDWorkloadIdentity) GetEnterpriseMeta() *acl.EnterpriseMeta {
|
||||||
return &acl.EnterpriseMeta{}
|
return &acl.EnterpriseMeta{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// PartitionOrDefault breaks from CE's pattern of returning empty strings.
|
|
||||||
// Although CE has no support for partitions, it still needs to be able to
|
|
||||||
// handle exportedPartition from peered Consul Enterprise clusters in order
|
|
||||||
// to generate the correct SpiffeID.
|
|
||||||
func (id SpiffeIDWorkloadIdentity) PartitionOrDefault() string {
|
|
||||||
if id.Partition == "" {
|
|
||||||
return "default"
|
|
||||||
}
|
|
||||||
|
|
||||||
return strings.ToLower(id.Partition)
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,40 +0,0 @@
|
||||||
// Copyright (c) HashiCorp, Inc.
|
|
||||||
// SPDX-License-Identifier: BUSL-1.1
|
|
||||||
|
|
||||||
//go:build !consulent
|
|
||||||
|
|
||||||
package connect
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestSpiffeIDWorkloadURI(t *testing.T) {
|
|
||||||
t.Run("default partition; default namespace", func(t *testing.T) {
|
|
||||||
wl := &SpiffeIDWorkloadIdentity{
|
|
||||||
TrustDomain: "1234.consul",
|
|
||||||
WorkloadIdentity: "web",
|
|
||||||
}
|
|
||||||
require.Equal(t, "spiffe://1234.consul/ap/default/ns/default/identity/web", wl.URI().String())
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("namespaces are ignored", func(t *testing.T) {
|
|
||||||
wl := &SpiffeIDWorkloadIdentity{
|
|
||||||
TrustDomain: "1234.consul",
|
|
||||||
WorkloadIdentity: "web",
|
|
||||||
Namespace: "other",
|
|
||||||
}
|
|
||||||
require.Equal(t, "spiffe://1234.consul/ap/default/ns/default/identity/web", wl.URI().String())
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("partitions are not ignored", func(t *testing.T) {
|
|
||||||
wl := &SpiffeIDWorkloadIdentity{
|
|
||||||
TrustDomain: "1234.consul",
|
|
||||||
WorkloadIdentity: "web",
|
|
||||||
Partition: "other",
|
|
||||||
}
|
|
||||||
require.Equal(t, "spiffe://1234.consul/ap/other/ns/default/identity/web", wl.URI().String())
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
// Copyright (c) HashiCorp, Inc.
|
||||||
|
// SPDX-License-Identifier: BUSL-1.1
|
||||||
|
|
||||||
|
package connect
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSpiffeIDWorkloadURI(t *testing.T) {
|
||||||
|
t.Run("spiffe id workload uri default tenancy", func(t *testing.T) {
|
||||||
|
wl := &SpiffeIDWorkloadIdentity{
|
||||||
|
TrustDomain: "1234.consul",
|
||||||
|
WorkloadIdentity: "web",
|
||||||
|
Partition: "default",
|
||||||
|
Namespace: "default",
|
||||||
|
}
|
||||||
|
require.Equal(t, "spiffe://1234.consul/ap/default/ns/default/identity/web", wl.URI().String())
|
||||||
|
})
|
||||||
|
t.Run("spiffe id workload uri non-default tenancy", func(t *testing.T) {
|
||||||
|
wl := &SpiffeIDWorkloadIdentity{
|
||||||
|
TrustDomain: "1234.consul",
|
||||||
|
WorkloadIdentity: "web",
|
||||||
|
Partition: "part1",
|
||||||
|
Namespace: "dev",
|
||||||
|
}
|
||||||
|
require.Equal(t, "spiffe://1234.consul/ap/part1/ns/dev/identity/web", wl.URI().String())
|
||||||
|
})
|
||||||
|
}
|
|
@ -4,6 +4,7 @@
|
||||||
package builder
|
package builder
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"sort"
|
"sort"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
@ -247,323 +248,428 @@ func TestBuildLocalApp_WithProxyConfiguration(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBuildL4TrafficPermissions(t *testing.T) {
|
func TestBuildL4TrafficPermissions(t *testing.T) {
|
||||||
testTrustDomain := "test.consul"
|
resourcetest.RunWithTenancies(func(tenancy *pbresource.Tenancy) {
|
||||||
|
testTrustDomain := "test.consul"
|
||||||
|
|
||||||
cases := map[string]struct {
|
cases := map[string]struct {
|
||||||
defaultAllow bool
|
defaultAllow bool
|
||||||
workloadPorts map[string]*pbcatalog.WorkloadPort
|
workloadPorts map[string]*pbcatalog.WorkloadPort
|
||||||
ctp *pbauth.ComputedTrafficPermissions
|
ctp *pbauth.ComputedTrafficPermissions
|
||||||
expected map[string]*pbproxystate.TrafficPermissions
|
expected map[string]*pbproxystate.TrafficPermissions
|
||||||
}{
|
}{
|
||||||
"empty": {
|
"empty": {
|
||||||
defaultAllow: true,
|
defaultAllow: true,
|
||||||
workloadPorts: map[string]*pbcatalog.WorkloadPort{
|
workloadPorts: map[string]*pbcatalog.WorkloadPort{
|
||||||
"p1": {
|
"p1": {
|
||||||
Protocol: pbcatalog.Protocol_PROTOCOL_TCP,
|
Protocol: pbcatalog.Protocol_PROTOCOL_TCP,
|
||||||
|
},
|
||||||
|
"p2": {
|
||||||
|
Protocol: pbcatalog.Protocol_PROTOCOL_HTTP,
|
||||||
|
},
|
||||||
|
"p3": {},
|
||||||
|
"mesh": {
|
||||||
|
Protocol: pbcatalog.Protocol_PROTOCOL_MESH,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
"p2": {
|
expected: map[string]*pbproxystate.TrafficPermissions{
|
||||||
Protocol: pbcatalog.Protocol_PROTOCOL_HTTP,
|
"p1": {
|
||||||
},
|
DefaultAllow: false,
|
||||||
"p3": {},
|
},
|
||||||
"mesh": {
|
"p2": {
|
||||||
Protocol: pbcatalog.Protocol_PROTOCOL_MESH,
|
DefaultAllow: false,
|
||||||
},
|
},
|
||||||
},
|
"p3": {
|
||||||
expected: map[string]*pbproxystate.TrafficPermissions{
|
DefaultAllow: false,
|
||||||
"p1": {
|
|
||||||
DefaultAllow: false,
|
|
||||||
},
|
|
||||||
"p2": {
|
|
||||||
DefaultAllow: false,
|
|
||||||
},
|
|
||||||
"p3": {
|
|
||||||
DefaultAllow: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"default allow everywhere": {
|
|
||||||
defaultAllow: true,
|
|
||||||
workloadPorts: map[string]*pbcatalog.WorkloadPort{
|
|
||||||
"p1": {
|
|
||||||
Protocol: pbcatalog.Protocol_PROTOCOL_TCP,
|
|
||||||
},
|
|
||||||
"p2": {
|
|
||||||
Protocol: pbcatalog.Protocol_PROTOCOL_HTTP,
|
|
||||||
},
|
|
||||||
"p3": {},
|
|
||||||
"mesh": {
|
|
||||||
Protocol: pbcatalog.Protocol_PROTOCOL_MESH,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ctp: &pbauth.ComputedTrafficPermissions{
|
|
||||||
IsDefault: true,
|
|
||||||
},
|
|
||||||
expected: map[string]*pbproxystate.TrafficPermissions{
|
|
||||||
"p1": {
|
|
||||||
DefaultAllow: true,
|
|
||||||
},
|
|
||||||
"p2": {
|
|
||||||
DefaultAllow: true,
|
|
||||||
},
|
|
||||||
"p3": {
|
|
||||||
DefaultAllow: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"preserves default deny": {
|
|
||||||
defaultAllow: false,
|
|
||||||
workloadPorts: map[string]*pbcatalog.WorkloadPort{
|
|
||||||
"p1": {
|
|
||||||
Protocol: pbcatalog.Protocol_PROTOCOL_TCP,
|
|
||||||
},
|
|
||||||
"p2": {
|
|
||||||
Protocol: pbcatalog.Protocol_PROTOCOL_HTTP,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ctp: &pbauth.ComputedTrafficPermissions{
|
|
||||||
AllowPermissions: []*pbauth.Permission{
|
|
||||||
{
|
|
||||||
Sources: []*pbauth.Source{
|
|
||||||
{
|
|
||||||
IdentityName: "foo",
|
|
||||||
Partition: "default",
|
|
||||||
Namespace: "default",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
DestinationRules: []*pbauth.DestinationRule{
|
|
||||||
{
|
|
||||||
PortNames: []string{"p1"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expected: map[string]*pbproxystate.TrafficPermissions{
|
"default allow everywhere": {
|
||||||
"p1": {
|
defaultAllow: true,
|
||||||
DefaultAllow: false,
|
workloadPorts: map[string]*pbcatalog.WorkloadPort{
|
||||||
AllowPermissions: []*pbproxystate.Permission{
|
"p1": {
|
||||||
|
Protocol: pbcatalog.Protocol_PROTOCOL_TCP,
|
||||||
|
},
|
||||||
|
"p2": {
|
||||||
|
Protocol: pbcatalog.Protocol_PROTOCOL_HTTP,
|
||||||
|
},
|
||||||
|
"p3": {},
|
||||||
|
"mesh": {
|
||||||
|
Protocol: pbcatalog.Protocol_PROTOCOL_MESH,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ctp: &pbauth.ComputedTrafficPermissions{
|
||||||
|
IsDefault: true,
|
||||||
|
},
|
||||||
|
expected: map[string]*pbproxystate.TrafficPermissions{
|
||||||
|
"p1": {
|
||||||
|
DefaultAllow: true,
|
||||||
|
},
|
||||||
|
"p2": {
|
||||||
|
DefaultAllow: true,
|
||||||
|
},
|
||||||
|
"p3": {
|
||||||
|
DefaultAllow: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"preserves default deny": {
|
||||||
|
defaultAllow: false,
|
||||||
|
workloadPorts: map[string]*pbcatalog.WorkloadPort{
|
||||||
|
"p1": {
|
||||||
|
Protocol: pbcatalog.Protocol_PROTOCOL_TCP,
|
||||||
|
},
|
||||||
|
"p2": {
|
||||||
|
Protocol: pbcatalog.Protocol_PROTOCOL_HTTP,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ctp: &pbauth.ComputedTrafficPermissions{
|
||||||
|
AllowPermissions: []*pbauth.Permission{
|
||||||
{
|
{
|
||||||
Principals: []*pbproxystate.Principal{
|
Sources: []*pbauth.Source{
|
||||||
{
|
{
|
||||||
Spiffe: &pbproxystate.Spiffe{Regex: "^spiffe://test.consul/ap/default/ns/default/identity/foo$"},
|
IdentityName: "foo",
|
||||||
|
Partition: tenancy.Partition,
|
||||||
|
Namespace: tenancy.Namespace,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
DestinationRules: []*pbauth.DestinationRule{
|
||||||
|
{
|
||||||
|
PortNames: []string{"p1"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"p2": {
|
expected: map[string]*pbproxystate.TrafficPermissions{
|
||||||
DefaultAllow: false,
|
"p1": {
|
||||||
},
|
DefaultAllow: false,
|
||||||
},
|
AllowPermissions: []*pbproxystate.Permission{
|
||||||
},
|
|
||||||
"default allow with a non-empty ctp becomes default deny on all ports": {
|
|
||||||
defaultAllow: true,
|
|
||||||
workloadPorts: map[string]*pbcatalog.WorkloadPort{
|
|
||||||
"p1": {
|
|
||||||
Protocol: pbcatalog.Protocol_PROTOCOL_TCP,
|
|
||||||
},
|
|
||||||
"p2": {
|
|
||||||
Protocol: pbcatalog.Protocol_PROTOCOL_HTTP,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ctp: &pbauth.ComputedTrafficPermissions{
|
|
||||||
AllowPermissions: []*pbauth.Permission{
|
|
||||||
{
|
|
||||||
Sources: []*pbauth.Source{
|
|
||||||
{
|
{
|
||||||
IdentityName: "baz",
|
Principals: []*pbproxystate.Principal{
|
||||||
Partition: "default",
|
|
||||||
Namespace: "default",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
DestinationRules: []*pbauth.DestinationRule{
|
|
||||||
{
|
|
||||||
PortNames: []string{"no-match"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
expected: map[string]*pbproxystate.TrafficPermissions{
|
|
||||||
"p1": {
|
|
||||||
DefaultAllow: false,
|
|
||||||
},
|
|
||||||
"p2": {
|
|
||||||
DefaultAllow: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"kitchen sink": {
|
|
||||||
defaultAllow: true,
|
|
||||||
workloadPorts: map[string]*pbcatalog.WorkloadPort{
|
|
||||||
"p1": {
|
|
||||||
Protocol: pbcatalog.Protocol_PROTOCOL_TCP,
|
|
||||||
},
|
|
||||||
"p2": {
|
|
||||||
Protocol: pbcatalog.Protocol_PROTOCOL_HTTP,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ctp: &pbauth.ComputedTrafficPermissions{
|
|
||||||
AllowPermissions: []*pbauth.Permission{
|
|
||||||
{
|
|
||||||
Sources: []*pbauth.Source{
|
|
||||||
{
|
|
||||||
IdentityName: "foo",
|
|
||||||
Partition: "default",
|
|
||||||
Namespace: "default",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
IdentityName: "",
|
|
||||||
Partition: "default",
|
|
||||||
Namespace: "default",
|
|
||||||
Exclude: []*pbauth.ExcludeSource{
|
|
||||||
{
|
{
|
||||||
IdentityName: "bar",
|
Spiffe: &pbproxystate.Spiffe{Regex: fmt.Sprintf("^spiffe://test.consul/ap/%s/ns/%s/identity/foo$", tenancy.Partition, tenancy.Namespace)},
|
||||||
Namespace: "default",
|
|
||||||
Partition: "default",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
DestinationRules: []*pbauth.DestinationRule{
|
|
||||||
// This should be p2.
|
|
||||||
{
|
|
||||||
Exclude: []*pbauth.ExcludePermissionRule{
|
|
||||||
{
|
|
||||||
PortNames: []string{"p1"},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
"p2": {
|
||||||
Sources: []*pbauth.Source{
|
DefaultAllow: false,
|
||||||
{
|
|
||||||
IdentityName: "baz",
|
|
||||||
Partition: "default",
|
|
||||||
Namespace: "default",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
DestinationRules: []*pbauth.DestinationRule{
|
|
||||||
{
|
|
||||||
PortNames: []string{"p1"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
DenyPermissions: []*pbauth.Permission{
|
|
||||||
{
|
|
||||||
Sources: []*pbauth.Source{
|
|
||||||
{
|
|
||||||
IdentityName: "qux",
|
|
||||||
Partition: "default",
|
|
||||||
Namespace: "default",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Sources: []*pbauth.Source{
|
|
||||||
{
|
|
||||||
IdentityName: "",
|
|
||||||
Namespace: "default",
|
|
||||||
Partition: "default",
|
|
||||||
Exclude: []*pbauth.ExcludeSource{
|
|
||||||
{
|
|
||||||
IdentityName: "quux",
|
|
||||||
Partition: "default",
|
|
||||||
Namespace: "default",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expected: map[string]*pbproxystate.TrafficPermissions{
|
"preserves default deny wildcard namespace": {
|
||||||
"p1": {
|
defaultAllow: false,
|
||||||
DefaultAllow: false,
|
workloadPorts: map[string]*pbcatalog.WorkloadPort{
|
||||||
DenyPermissions: []*pbproxystate.Permission{
|
"p1": {
|
||||||
{
|
Protocol: pbcatalog.Protocol_PROTOCOL_TCP,
|
||||||
Principals: []*pbproxystate.Principal{
|
|
||||||
{
|
|
||||||
Spiffe: &pbproxystate.Spiffe{Regex: "^spiffe://test.consul/ap/default/ns/default/identity/qux$"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Principals: []*pbproxystate.Principal{
|
|
||||||
{
|
|
||||||
Spiffe: &pbproxystate.Spiffe{Regex: `^spiffe://test.consul/ap/default/ns/default/identity/[^/]+$`},
|
|
||||||
ExcludeSpiffes: []*pbproxystate.Spiffe{
|
|
||||||
{Regex: "^spiffe://test.consul/ap/default/ns/default/identity/quux$"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
AllowPermissions: []*pbproxystate.Permission{
|
"p2": {
|
||||||
|
Protocol: pbcatalog.Protocol_PROTOCOL_HTTP,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ctp: &pbauth.ComputedTrafficPermissions{
|
||||||
|
AllowPermissions: []*pbauth.Permission{
|
||||||
{
|
{
|
||||||
Principals: []*pbproxystate.Principal{
|
Sources: []*pbauth.Source{
|
||||||
{
|
{
|
||||||
Spiffe: &pbproxystate.Spiffe{Regex: "^spiffe://test.consul/ap/default/ns/default/identity/baz$"},
|
IdentityName: "",
|
||||||
|
Partition: tenancy.Partition,
|
||||||
|
Namespace: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
DestinationRules: []*pbauth.DestinationRule{
|
||||||
|
{
|
||||||
|
PortNames: []string{"p1"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"p2": {
|
expected: map[string]*pbproxystate.TrafficPermissions{
|
||||||
DefaultAllow: false,
|
"p1": {
|
||||||
DenyPermissions: []*pbproxystate.Permission{
|
DefaultAllow: false,
|
||||||
{
|
AllowPermissions: []*pbproxystate.Permission{
|
||||||
Principals: []*pbproxystate.Principal{
|
{
|
||||||
{
|
Principals: []*pbproxystate.Principal{
|
||||||
Spiffe: &pbproxystate.Spiffe{Regex: "^spiffe://test.consul/ap/default/ns/default/identity/qux$"},
|
{
|
||||||
},
|
Spiffe: &pbproxystate.Spiffe{Regex: fmt.Sprintf("^spiffe://test.consul/ap/%s/ns/%s/identity/[^/]+$", tenancy.Partition, anyPath)},
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Principals: []*pbproxystate.Principal{
|
|
||||||
{
|
|
||||||
Spiffe: &pbproxystate.Spiffe{Regex: `^spiffe://test.consul/ap/default/ns/default/identity/[^/]+$`},
|
|
||||||
ExcludeSpiffes: []*pbproxystate.Spiffe{
|
|
||||||
{Regex: "^spiffe://test.consul/ap/default/ns/default/identity/quux$"},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
AllowPermissions: []*pbproxystate.Permission{
|
"p2": {
|
||||||
{
|
DefaultAllow: false,
|
||||||
Principals: []*pbproxystate.Principal{
|
|
||||||
{
|
|
||||||
Spiffe: &pbproxystate.Spiffe{Regex: "^spiffe://test.consul/ap/default/ns/default/identity/foo$"},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Spiffe: &pbproxystate.Spiffe{Regex: `^spiffe://test.consul/ap/default/ns/default/identity/[^/]+$`},
|
|
||||||
ExcludeSpiffes: []*pbproxystate.Spiffe{
|
|
||||||
{Regex: "^spiffe://test.consul/ap/default/ns/default/identity/bar$"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
"preserves default deny wildcard namespace exclude source": {
|
||||||
}
|
defaultAllow: false,
|
||||||
|
workloadPorts: map[string]*pbcatalog.WorkloadPort{
|
||||||
|
"p1": {
|
||||||
|
Protocol: pbcatalog.Protocol_PROTOCOL_TCP,
|
||||||
|
},
|
||||||
|
"p2": {
|
||||||
|
Protocol: pbcatalog.Protocol_PROTOCOL_HTTP,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ctp: &pbauth.ComputedTrafficPermissions{
|
||||||
|
AllowPermissions: []*pbauth.Permission{
|
||||||
|
{
|
||||||
|
Sources: []*pbauth.Source{
|
||||||
|
{
|
||||||
|
IdentityName: "",
|
||||||
|
Partition: tenancy.Partition,
|
||||||
|
Namespace: "",
|
||||||
|
Exclude: []*pbauth.ExcludeSource{
|
||||||
|
{
|
||||||
|
IdentityName: "bar",
|
||||||
|
Namespace: tenancy.Namespace,
|
||||||
|
Partition: tenancy.Partition,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
DestinationRules: []*pbauth.DestinationRule{
|
||||||
|
{
|
||||||
|
PortNames: []string{"p1"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: map[string]*pbproxystate.TrafficPermissions{
|
||||||
|
"p1": {
|
||||||
|
DefaultAllow: false,
|
||||||
|
AllowPermissions: []*pbproxystate.Permission{
|
||||||
|
{
|
||||||
|
Principals: []*pbproxystate.Principal{
|
||||||
|
{
|
||||||
|
Spiffe: &pbproxystate.Spiffe{Regex: fmt.Sprintf("^spiffe://test.consul/ap/%s/ns/%s/identity/[^/]+$", tenancy.Partition, anyPath)},
|
||||||
|
|
||||||
for name, tc := range cases {
|
ExcludeSpiffes: []*pbproxystate.Spiffe{
|
||||||
t.Run(name, func(t *testing.T) {
|
{Regex: fmt.Sprintf("^spiffe://test.consul/ap/%s/ns/%s/identity/bar$", tenancy.Partition, tenancy.Namespace)},
|
||||||
workload := &pbcatalog.Workload{
|
},
|
||||||
Ports: tc.workloadPorts,
|
},
|
||||||
}
|
},
|
||||||
permissions := buildTrafficPermissions(tc.defaultAllow, testTrustDomain, workload, tc.ctp)
|
},
|
||||||
require.Equal(t, len(tc.expected), len(permissions))
|
},
|
||||||
for k, v := range tc.expected {
|
},
|
||||||
prototest.AssertDeepEqual(t, v, permissions[k])
|
"p2": {
|
||||||
}
|
DefaultAllow: false,
|
||||||
})
|
},
|
||||||
}
|
},
|
||||||
|
},
|
||||||
|
"default allow with a non-empty ctp becomes default deny on all ports": {
|
||||||
|
defaultAllow: true,
|
||||||
|
workloadPorts: map[string]*pbcatalog.WorkloadPort{
|
||||||
|
"p1": {
|
||||||
|
Protocol: pbcatalog.Protocol_PROTOCOL_TCP,
|
||||||
|
},
|
||||||
|
"p2": {
|
||||||
|
Protocol: pbcatalog.Protocol_PROTOCOL_HTTP,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ctp: &pbauth.ComputedTrafficPermissions{
|
||||||
|
AllowPermissions: []*pbauth.Permission{
|
||||||
|
{
|
||||||
|
Sources: []*pbauth.Source{
|
||||||
|
{
|
||||||
|
IdentityName: "baz",
|
||||||
|
Partition: tenancy.Partition,
|
||||||
|
Namespace: tenancy.Namespace,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
DestinationRules: []*pbauth.DestinationRule{
|
||||||
|
{
|
||||||
|
PortNames: []string{"no-match"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: map[string]*pbproxystate.TrafficPermissions{
|
||||||
|
"p1": {
|
||||||
|
DefaultAllow: false,
|
||||||
|
},
|
||||||
|
"p2": {
|
||||||
|
DefaultAllow: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"kitchen sink": {
|
||||||
|
defaultAllow: true,
|
||||||
|
workloadPorts: map[string]*pbcatalog.WorkloadPort{
|
||||||
|
"p1": {
|
||||||
|
Protocol: pbcatalog.Protocol_PROTOCOL_TCP,
|
||||||
|
},
|
||||||
|
"p2": {
|
||||||
|
Protocol: pbcatalog.Protocol_PROTOCOL_HTTP,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ctp: &pbauth.ComputedTrafficPermissions{
|
||||||
|
AllowPermissions: []*pbauth.Permission{
|
||||||
|
{
|
||||||
|
Sources: []*pbauth.Source{
|
||||||
|
{
|
||||||
|
IdentityName: "foo",
|
||||||
|
Partition: tenancy.Partition,
|
||||||
|
Namespace: tenancy.Namespace,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
IdentityName: "",
|
||||||
|
Partition: tenancy.Partition,
|
||||||
|
Namespace: tenancy.Namespace,
|
||||||
|
Exclude: []*pbauth.ExcludeSource{
|
||||||
|
{
|
||||||
|
IdentityName: "bar",
|
||||||
|
Namespace: tenancy.Namespace,
|
||||||
|
Partition: tenancy.Partition,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
DestinationRules: []*pbauth.DestinationRule{
|
||||||
|
// This should be p2.
|
||||||
|
{
|
||||||
|
Exclude: []*pbauth.ExcludePermissionRule{
|
||||||
|
{
|
||||||
|
PortNames: []string{"p1"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Sources: []*pbauth.Source{
|
||||||
|
{
|
||||||
|
IdentityName: "baz",
|
||||||
|
Partition: tenancy.Partition,
|
||||||
|
Namespace: tenancy.Namespace,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
DestinationRules: []*pbauth.DestinationRule{
|
||||||
|
{
|
||||||
|
PortNames: []string{"p1"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
DenyPermissions: []*pbauth.Permission{
|
||||||
|
{
|
||||||
|
Sources: []*pbauth.Source{
|
||||||
|
{
|
||||||
|
IdentityName: "qux",
|
||||||
|
Partition: tenancy.Partition,
|
||||||
|
Namespace: tenancy.Namespace,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Sources: []*pbauth.Source{
|
||||||
|
{
|
||||||
|
IdentityName: "",
|
||||||
|
Namespace: tenancy.Namespace,
|
||||||
|
Partition: tenancy.Partition,
|
||||||
|
Exclude: []*pbauth.ExcludeSource{
|
||||||
|
{
|
||||||
|
IdentityName: "quux",
|
||||||
|
Partition: tenancy.Partition,
|
||||||
|
Namespace: tenancy.Namespace,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: map[string]*pbproxystate.TrafficPermissions{
|
||||||
|
"p1": {
|
||||||
|
DefaultAllow: false,
|
||||||
|
DenyPermissions: []*pbproxystate.Permission{
|
||||||
|
{
|
||||||
|
Principals: []*pbproxystate.Principal{
|
||||||
|
{
|
||||||
|
Spiffe: &pbproxystate.Spiffe{Regex: fmt.Sprintf("^spiffe://test.consul/ap/%s/ns/%s/identity/qux$", tenancy.Partition, tenancy.Namespace)},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Principals: []*pbproxystate.Principal{
|
||||||
|
{
|
||||||
|
Spiffe: &pbproxystate.Spiffe{Regex: fmt.Sprintf(`^spiffe://test.consul/ap/%s/ns/%s/identity/[^/]+$`, tenancy.Partition, tenancy.Namespace)},
|
||||||
|
ExcludeSpiffes: []*pbproxystate.Spiffe{
|
||||||
|
{Regex: fmt.Sprintf("^spiffe://test.consul/ap/%s/ns/%s/identity/quux$", tenancy.Partition, tenancy.Namespace)},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
AllowPermissions: []*pbproxystate.Permission{
|
||||||
|
{
|
||||||
|
Principals: []*pbproxystate.Principal{
|
||||||
|
{
|
||||||
|
Spiffe: &pbproxystate.Spiffe{Regex: fmt.Sprintf("^spiffe://test.consul/ap/%s/ns/%s/identity/baz$", tenancy.Partition, tenancy.Namespace)},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"p2": {
|
||||||
|
DefaultAllow: false,
|
||||||
|
DenyPermissions: []*pbproxystate.Permission{
|
||||||
|
{
|
||||||
|
Principals: []*pbproxystate.Principal{
|
||||||
|
{
|
||||||
|
Spiffe: &pbproxystate.Spiffe{Regex: fmt.Sprintf("^spiffe://test.consul/ap/%s/ns/%s/identity/qux$", tenancy.Partition, tenancy.Namespace)},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Principals: []*pbproxystate.Principal{
|
||||||
|
{
|
||||||
|
Spiffe: &pbproxystate.Spiffe{Regex: fmt.Sprintf(`^spiffe://test.consul/ap/%s/ns/%s/identity/[^/]+$`, tenancy.Partition, tenancy.Namespace)},
|
||||||
|
ExcludeSpiffes: []*pbproxystate.Spiffe{
|
||||||
|
{Regex: fmt.Sprintf("^spiffe://test.consul/ap/%s/ns/%s/identity/quux$", tenancy.Partition, tenancy.Namespace)},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
AllowPermissions: []*pbproxystate.Permission{
|
||||||
|
{
|
||||||
|
Principals: []*pbproxystate.Principal{
|
||||||
|
{
|
||||||
|
Spiffe: &pbproxystate.Spiffe{Regex: fmt.Sprintf("^spiffe://test.consul/ap/%s/ns/%s/identity/foo$", tenancy.Partition, tenancy.Namespace)},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Spiffe: &pbproxystate.Spiffe{Regex: fmt.Sprintf(`^spiffe://test.consul/ap/%s/ns/%s/identity/[^/]+$`, tenancy.Partition, tenancy.Namespace)},
|
||||||
|
ExcludeSpiffes: []*pbproxystate.Spiffe{
|
||||||
|
{Regex: fmt.Sprintf("^spiffe://test.consul/ap/%s/ns/%s/identity/bar$", tenancy.Partition, tenancy.Namespace)},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for name, tc := range cases {
|
||||||
|
t.Run(resourcetest.AppendTenancyInfoSubtest(t.Name(), name, tenancy), func(t *testing.T) {
|
||||||
|
workload := &pbcatalog.Workload{
|
||||||
|
Ports: tc.workloadPorts,
|
||||||
|
}
|
||||||
|
permissions := buildTrafficPermissions(tc.defaultAllow, testTrustDomain, workload, tc.ctp)
|
||||||
|
require.Equal(t, len(tc.expected), len(permissions))
|
||||||
|
for k, v := range tc.expected {
|
||||||
|
prototest.AssertDeepEqual(t, v, permissions[k])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, t)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testProxyStateTemplateID(tenancy *pbresource.Tenancy) *pbresource.ID {
|
func testProxyStateTemplateID(tenancy *pbresource.Tenancy) *pbresource.ID {
|
||||||
|
|
Loading…
Reference in New Issue