Skip to content
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
36 changes: 36 additions & 0 deletions api/types/authority.go
Original file line number Diff line number Diff line change
Expand Up @@ -728,3 +728,39 @@ func (f *CertAuthorityFilter) FromMap(m map[string]string) {
(*f)[CertAuthType(key)] = val
}
}

// Contains checks if the CA filter contains another CA filter as a subset.
// Unlike other filters, a CA filter's scope becomes more broad as map keys
// are added to it.
// Therefore, to check if kind's filter contains the subset's filter,
// we should check that the subset's keys are all present in kind and as
// narrow or narrower.
// A special case is when kind's filter is either empty or specifies all
// authorities, in which case it is as broad as possible and subset's filter
// is always contained within it.
func (f CertAuthorityFilter) Contains(other CertAuthorityFilter) bool {
if len(f) == 0 {
// f has no filter, which is as broad as possible.
return true
}

if len(other) == 0 {
// f has a filter, but other does not.
// treat this as "contained" if f's filter is for all authorities.
for _, caType := range CertAuthTypes {
clusterName, ok := f[caType]
if !ok || clusterName != Wildcard {
return false
}
}
return true
}

for k, v := range other {
v2, ok := f[k]
if !ok || (v2 != Wildcard && v2 != v) {
return false
}
}
return true
}
7 changes: 7 additions & 0 deletions api/types/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,13 @@ func (kind WatchKind) Contains(subset WatchKind) bool {
return false
}

if kind.Kind == KindCertAuthority {
var a, b CertAuthorityFilter
a.FromMap(kind.Filter)
b.FromMap(subset.Filter)
return a.Contains(b)
}

for k, v := range kind.Filter {
if subset.Filter[k] != v {
return false
Expand Down
107 changes: 107 additions & 0 deletions api/types/events_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ import (
// TestWatchKindContains tests that the WatchKind.Contains method correctly detects whether its receiver contains its
// argument.
func TestWatchKindContains(t *testing.T) {
allCAFilter := make(CertAuthorityFilter)
for _, caType := range CertAuthTypes {
allCAFilter[caType] = Wildcard
}
testCases := []struct {
name string
kind WatchKind
Expand Down Expand Up @@ -148,6 +152,109 @@ func TestWatchKindContains(t *testing.T) {
},
assertion: require.False,
},
{
name: "yes: superset and subset have no CA filter",
kind: WatchKind{
Kind: "cert_authority",
},
other: WatchKind{
Kind: "cert_authority",
},
assertion: require.True,
},
{
name: "yes: superset has no CA filter",
kind: WatchKind{
Kind: "cert_authority",
},
other: WatchKind{
Kind: "cert_authority",
Filter: map[string]string{
"a": "b",
"c": "d",
},
},
assertion: require.True,
},
{
name: "yes: superset filter matches all, subset has no CA filter",
kind: WatchKind{
Kind: "cert_authority",
Filter: allCAFilter.IntoMap(),
},
other: WatchKind{
Kind: "cert_authority",
},
assertion: require.True,
},
{
name: "yes: subset has narrower CA filter",
kind: WatchKind{
Kind: "cert_authority",
Filter: map[string]string{
"a": "b",
"c": Wildcard,
"e": "f",
},
},
other: WatchKind{
Kind: "cert_authority",
Filter: map[string]string{
"a": "b",
"c": "d",
},
},
assertion: require.True,
},
{
name: "no: superset filter does not match all, subset has no CA filter",
kind: WatchKind{
Kind: "cert_authority",
Filter: map[string]string{
"a": "b",
"c": "d",
},
},
other: WatchKind{
Kind: "cert_authority",
},
assertion: require.False,
},
{
name: "no: subset has wider CA filter",
Comment thread
GavinFrazar marked this conversation as resolved.
Outdated
kind: WatchKind{
Kind: "cert_authority",
Filter: map[string]string{
"a": "b",
"c": "d",
},
},
other: WatchKind{
Kind: "cert_authority",
Filter: map[string]string{
"a": "b",
"c": "d",
"e": "",
},
},
assertion: require.False,
},
{
name: "no: subset filter does not match",
kind: WatchKind{
Kind: "cert_authority",
Filter: map[string]string{
"a": "b",
},
},
other: WatchKind{
Kind: "cert_authority",
Filter: map[string]string{
"a": "",
},
},
assertion: require.False,
},
}

for _, tc := range testCases {
Expand Down
33 changes: 24 additions & 9 deletions lib/cache/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,21 @@ func isHighVolumeResource(kind string) bool {
return ok
}

// makeAllKnownCAsFilter makes a filter that matches all known CA types.
// This should be installed by default on every CA watcher, unless a filter is
// otherwise specified, to avoid complicated server-side hacks if/when we add
// a new CA type.
// This is different from a nil/empty filter in that all the CA types that the
// client knows about will be returned rather than all the CA types that the
// server knows about.
func makeAllKnownCAsFilter() types.CertAuthorityFilter {
filter := make(types.CertAuthorityFilter, len(types.CertAuthTypes))
for _, t := range types.CertAuthTypes {
filter[t] = types.Wildcard
}
return filter
}

// ForAuth sets up watch configuration for the auth server
func ForAuth(cfg Config) Config {
cfg.target = "auth"
Expand Down Expand Up @@ -164,7 +179,7 @@ func ForAuth(cfg Config) Config {
func ForProxy(cfg Config) Config {
cfg.target = "proxy"
cfg.Watches = []types.WatchKind{
{Kind: types.KindCertAuthority, LoadSecrets: false},
{Kind: types.KindCertAuthority, LoadSecrets: false, Filter: makeAllKnownCAsFilter().IntoMap()},
{Kind: types.KindClusterName},
{Kind: types.KindClusterAuditConfig},
{Kind: types.KindClusterNetworkingConfig},
Expand Down Expand Up @@ -221,7 +236,7 @@ func ForProxy(cfg Config) Config {
func ForRemoteProxy(cfg Config) Config {
cfg.target = "remote-proxy"
cfg.Watches = []types.WatchKind{
{Kind: types.KindCertAuthority, LoadSecrets: false},
{Kind: types.KindCertAuthority, LoadSecrets: false, Filter: makeAllKnownCAsFilter().IntoMap()},
{Kind: types.KindClusterName},
{Kind: types.KindClusterAuditConfig},
{Kind: types.KindClusterNetworkingConfig},
Expand Down Expand Up @@ -253,7 +268,7 @@ func ForRemoteProxy(cfg Config) Config {
func ForOldRemoteProxy(cfg Config) Config {
cfg.target = "remote-proxy-old"
cfg.Watches = []types.WatchKind{
{Kind: types.KindCertAuthority, LoadSecrets: false},
{Kind: types.KindCertAuthority, LoadSecrets: false, Filter: makeAllKnownCAsFilter().IntoMap()},
{Kind: types.KindClusterName},
{Kind: types.KindClusterAuditConfig},
{Kind: types.KindClusterNetworkingConfig},
Expand Down Expand Up @@ -313,7 +328,7 @@ func ForNode(cfg Config) Config {
func ForKubernetes(cfg Config) Config {
cfg.target = "kube"
cfg.Watches = []types.WatchKind{
{Kind: types.KindCertAuthority, LoadSecrets: false},
{Kind: types.KindCertAuthority, LoadSecrets: false, Filter: makeAllKnownCAsFilter().IntoMap()},
{Kind: types.KindClusterName},
{Kind: types.KindClusterAuditConfig},
{Kind: types.KindClusterNetworkingConfig},
Expand All @@ -333,7 +348,7 @@ func ForKubernetes(cfg Config) Config {
func ForApps(cfg Config) Config {
cfg.target = "apps"
cfg.Watches = []types.WatchKind{
{Kind: types.KindCertAuthority, LoadSecrets: false},
{Kind: types.KindCertAuthority, LoadSecrets: false, Filter: makeAllKnownCAsFilter().IntoMap()},
{Kind: types.KindClusterName},
{Kind: types.KindClusterAuditConfig},
{Kind: types.KindClusterNetworkingConfig},
Expand All @@ -355,7 +370,7 @@ func ForApps(cfg Config) Config {
func ForDatabases(cfg Config) Config {
cfg.target = "db"
cfg.Watches = []types.WatchKind{
{Kind: types.KindCertAuthority, LoadSecrets: false},
{Kind: types.KindCertAuthority, LoadSecrets: false, Filter: makeAllKnownCAsFilter().IntoMap()},
{Kind: types.KindClusterName},
{Kind: types.KindClusterAuditConfig},
{Kind: types.KindClusterNetworkingConfig},
Expand All @@ -377,7 +392,7 @@ func ForDatabases(cfg Config) Config {
func ForWindowsDesktop(cfg Config) Config {
cfg.target = "windows_desktop"
cfg.Watches = []types.WatchKind{
{Kind: types.KindCertAuthority, LoadSecrets: false},
{Kind: types.KindCertAuthority, LoadSecrets: false, Filter: makeAllKnownCAsFilter().IntoMap()},
{Kind: types.KindClusterName},
{Kind: types.KindClusterAuditConfig},
{Kind: types.KindClusterNetworkingConfig},
Expand All @@ -397,7 +412,7 @@ func ForWindowsDesktop(cfg Config) Config {
func ForDiscovery(cfg Config) Config {
cfg.target = "discovery"
cfg.Watches = []types.WatchKind{
{Kind: types.KindCertAuthority, LoadSecrets: false},
{Kind: types.KindCertAuthority, LoadSecrets: false, Filter: makeAllKnownCAsFilter().IntoMap()},
{Kind: types.KindClusterName},
{Kind: types.KindNamespace, Name: apidefaults.Namespace},
{Kind: types.KindNode},
Expand All @@ -417,7 +432,7 @@ func ForOkta(cfg Config) Config {
cfg.target = "okta"
cfg.Watches = []types.WatchKind{
{Kind: types.KindClusterName},
{Kind: types.KindCertAuthority, LoadSecrets: false},
{Kind: types.KindCertAuthority, LoadSecrets: false, Filter: makeAllKnownCAsFilter().IntoMap()},
{Kind: types.KindUser},
{Kind: types.KindAppServer},
{Kind: types.KindClusterNetworkingConfig},
Expand Down
Loading