diff --git a/lib/cache/cache.go b/lib/cache/cache.go index e747dee550698..ce6ebc24c524f 100644 --- a/lib/cache/cache.go +++ b/lib/cache/cache.go @@ -33,14 +33,11 @@ import ( "go.opentelemetry.io/otel/attribute" oteltrace "go.opentelemetry.io/otel/trace" "golang.org/x/sync/errgroup" - protobuf "google.golang.org/protobuf/proto" "github.com/gravitational/teleport" "github.com/gravitational/teleport/api/client/proto" apidefaults "github.com/gravitational/teleport/api/defaults" accessmonitoringrulesv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/accessmonitoringrules/v1" - clusterconfigpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/clusterconfig/v1" - crownjewelv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/crownjewel/v1" dbobjectv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/dbobject/v1" identitycenterv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/identitycenter/v1" kubewaitingcontainerpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/kubewaitingcontainer/v1" @@ -509,7 +506,6 @@ type Cache struct { dynamicAccessCache services.DynamicAccessExt presenceCache services.Presence restrictionsCache services.Restrictions - crownJewelsCache services.CrownJewels databaseObjectsCache *local.DatabaseObjectService webTokenCache types.WebTokenInterface dynamicWindowsDesktopsCache services.DynamicWindowsDesktops @@ -980,12 +976,6 @@ func New(config Config) (*Cache, error) { return nil, trace.Wrap(err) } - crownJewelCache, err := local.NewCrownJewelsService(config.Backend) - if err != nil { - cancel() - return nil, trace.Wrap(err) - } - staticHostUserCache, err := local.NewStaticHostUserService(config.Backend) if err != nil { cancel() @@ -1042,7 +1032,6 @@ func New(config Config) (*Cache, error) { dynamicAccessCache: local.NewDynamicAccessService(config.Backend), presenceCache: local.NewPresenceService(config.Backend), restrictionsCache: local.NewRestrictionsService(config.Backend), - crownJewelsCache: crownJewelCache, webTokenCache: identityService.WebTokens(), dynamicWindowsDesktopsCache: dynamicDesktopsService, accessMontoringRuleCache: accessMonitoringRuleCache, @@ -2213,32 +2202,6 @@ func (c *Cache) GetDiscoveryConfig(ctx context.Context, name string) (*discovery return rg.reader.GetDiscoveryConfig(ctx, name) } -// ListCrownJewels returns a list of CrownJewel resources. -func (c *Cache) ListCrownJewels(ctx context.Context, pageSize int64, nextKey string) ([]*crownjewelv1.CrownJewel, string, error) { - ctx, span := c.Tracer.Start(ctx, "cache/ListCrownJewels") - defer span.End() - - rg, err := readLegacyCollectionCache(c, c.legacyCacheCollections.crownJewels) - if err != nil { - return nil, "", trace.Wrap(err) - } - defer rg.Release() - return rg.reader.ListCrownJewels(ctx, pageSize, nextKey) -} - -// GetCrownJewel returns the specified CrownJewel resource. -func (c *Cache) GetCrownJewel(ctx context.Context, name string) (*crownjewelv1.CrownJewel, error) { - ctx, span := c.Tracer.Start(ctx, "cache/GetCrownJewel") - defer span.End() - - rg, err := readLegacyCollectionCache(c, c.legacyCacheCollections.crownJewels) - if err != nil { - return nil, trace.Wrap(err) - } - defer rg.Release() - return rg.reader.GetCrownJewel(ctx, name) -} - // GetSecurityAuditQuery returns the specified audit query resource. func (c *Cache) GetSecurityAuditQuery(ctx context.Context, name string) (*secreports.AuditQuery, error) { ctx, span := c.Tracer.Start(ctx, "cache/GetSecurityAuditQuery") @@ -2652,31 +2615,6 @@ func buildListResourcesResponse[T types.ResourceWithLabels](resources iter.Seq[T return &resp, nil } -// GetAccessGraphSettings gets AccessGraphSettings from the backend. -func (c *Cache) GetAccessGraphSettings(ctx context.Context) (*clusterconfigpb.AccessGraphSettings, error) { - ctx, span := c.Tracer.Start(ctx, "cache/GetAccessGraphSettings") - defer span.End() - - rg, err := readLegacyCollectionCache(c, c.legacyCacheCollections.accessGraphSettings) - if err != nil { - return nil, trace.Wrap(err) - } - defer rg.Release() - if !rg.IsCacheRead() { - cachedCfg, err := utils.FnCacheGet(ctx, c.fnCache, clusterConfigCacheKey{"access_graph_settings"}, func(ctx context.Context) (*clusterconfigpb.AccessGraphSettings, error) { - cfg, err := rg.reader.GetAccessGraphSettings(ctx) - return cfg, err - }) - if err != nil { - return nil, trace.Wrap(err) - } - - clone := protobuf.Clone(cachedCfg).(*clusterconfigpb.AccessGraphSettings) - return clone, nil - } - return rg.reader.GetAccessGraphSettings(ctx) -} - func (c *Cache) GetProvisioningState(ctx context.Context, downstream services.DownstreamID, id services.ProvisioningStateID) (*provisioningv1.PrincipalState, error) { ctx, span := c.Tracer.Start(ctx, "cache/GetProvisioningState") defer span.End() diff --git a/lib/cache/cache_test.go b/lib/cache/cache_test.go index c4e4e72fa7c50..abb11e43e1b43 100644 --- a/lib/cache/cache_test.go +++ b/lib/cache/cache_test.go @@ -1560,34 +1560,6 @@ func TestUserLoginStates(t *testing.T) { }) } -// TestCrownJewel tests that CRUD operations on user notification resources are -// replicated from the backend to the cache. -func TestCrownJewel(t *testing.T) { - t.Parallel() - - p := newTestPack(t, ForAuth) - t.Cleanup(p.Close) - - testResources153(t, p, testFuncs153[*crownjewelv1.CrownJewel]{ - newResource: func(name string) (*crownjewelv1.CrownJewel, error) { - return newCrownJewel(t, name), nil - }, - create: func(ctx context.Context, item *crownjewelv1.CrownJewel) error { - _, err := p.crownJewels.CreateCrownJewel(ctx, item) - return trace.Wrap(err) - }, - list: func(ctx context.Context) ([]*crownjewelv1.CrownJewel, error) { - items, _, err := p.crownJewels.ListCrownJewels(ctx, 0, "") - return items, trace.Wrap(err) - }, - cacheList: func(ctx context.Context) ([]*crownjewelv1.CrownJewel, error) { - items, _, err := p.crownJewels.ListCrownJewels(ctx, 0, "") - return items, trace.Wrap(err) - }, - deleteAll: p.crownJewels.DeleteAllCrownJewels, - }) -} - func TestDatabaseObjects(t *testing.T) { t.Parallel() diff --git a/lib/cache/cluster_config.go b/lib/cache/cluster_config.go index 7ade1581e3a6f..ee3b89e79cb77 100644 --- a/lib/cache/cluster_config.go +++ b/lib/cache/cluster_config.go @@ -21,7 +21,10 @@ import ( "github.com/gravitational/trace" + clusterconfigv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/clusterconfig/v1" + headerv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/header/v1" "github.com/gravitational/teleport/api/types" + apiutils "github.com/gravitational/teleport/api/utils" "github.com/gravitational/teleport/lib/services" "github.com/gravitational/teleport/lib/utils" ) @@ -327,3 +330,65 @@ func (c *Cache) GetSessionRecordingConfig(ctx context.Context) (types.SessionRec cfg, err := c.Config.ClusterConfig.GetSessionRecordingConfig(ctx) return cfg, trace.Wrap(err) } + +type accessGraphSettingsIndex string + +const accessGraphSettingsNameIndex accessGraphSettingsIndex = "name" + +func newAccessGraphSettingsCollection(upstream services.ClusterConfiguration, w types.WatchKind) (*collection[*clusterconfigv1.AccessGraphSettings, accessGraphSettingsIndex], error) { + if upstream == nil { + return nil, trace.BadParameter("missing parameter ClusterConfiguration") + } + + return &collection[*clusterconfigv1.AccessGraphSettings, accessGraphSettingsIndex]{ + store: newStore(map[accessGraphSettingsIndex]func(*clusterconfigv1.AccessGraphSettings) string{ + accessGraphSettingsNameIndex: func(r *clusterconfigv1.AccessGraphSettings) string { + return r.GetMetadata().GetName() + }, + }), + fetcher: func(ctx context.Context, loadSecrets bool) ([]*clusterconfigv1.AccessGraphSettings, error) { + set, err := upstream.GetAccessGraphSettings(ctx) + if err != nil { + return nil, trace.Wrap(err) + } + + return []*clusterconfigv1.AccessGraphSettings{set}, nil + }, + headerTransform: func(hdr *types.ResourceHeader) *clusterconfigv1.AccessGraphSettings { + return &clusterconfigv1.AccessGraphSettings{ + Kind: hdr.Kind, + Version: hdr.Version, + Metadata: &headerv1.Metadata{ + Name: hdr.Metadata.Name, + }, + } + }, + watch: w, + }, nil +} + +// GetAccessGraphSettings gets AccessGraphSettings from the backend. +func (c *Cache) GetAccessGraphSettings(ctx context.Context) (*clusterconfigv1.AccessGraphSettings, error) { + ctx, span := c.Tracer.Start(ctx, "cache/GetAccessGraphSettings") + defer span.End() + + getter := genericGetter[*clusterconfigv1.AccessGraphSettings, accessGraphSettingsIndex]{ + cache: c, + collection: c.collections.accessGraphSettings, + index: accessGraphSettingsNameIndex, + upstreamGet: func(ctx context.Context, s string) (*clusterconfigv1.AccessGraphSettings, error) { + cachedCfg, err := utils.FnCacheGet(ctx, c.fnCache, clusterConfigCacheKey{"access_graph_settings"}, func(ctx context.Context) (*clusterconfigv1.AccessGraphSettings, error) { + cfg, err := c.Config.ClusterConfig.GetAccessGraphSettings(ctx) + return cfg, err + }) + if err != nil { + return nil, trace.Wrap(err) + } + + return apiutils.CloneProtoMsg(cachedCfg), nil + }, + clone: apiutils.CloneProtoMsg[*clusterconfigv1.AccessGraphSettings], + } + out, err := getter.get(ctx, types.MetaNameAccessGraphSettings) + return out, trace.Wrap(err) +} diff --git a/lib/cache/cluster_config_test.go b/lib/cache/cluster_config_test.go index 874944b434f3e..9fe09474ea36f 100644 --- a/lib/cache/cluster_config_test.go +++ b/lib/cache/cluster_config_test.go @@ -23,8 +23,10 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" + "github.com/gravitational/trace" "github.com/stretchr/testify/require" + clusterconfigv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/clusterconfig/v1" "github.com/gravitational/teleport/api/types" "github.com/gravitational/teleport/lib/services" ) @@ -171,3 +173,37 @@ func TestAuthPreference(t *testing.T) { require.Empty(t, cmp.Diff(outAuthPref, authPref, cmpopts.IgnoreFields(types.Metadata{}, "Revision"))) } + +func TestAccessGraphSettings(t *testing.T) { + t.Parallel() + + p := newTestPack(t, ForAuth) + t.Cleanup(p.Close) + + testResources153(t, p, testFuncs153[*clusterconfigv1.AccessGraphSettings]{ + newResource: func(name string) (*clusterconfigv1.AccessGraphSettings, error) { + return newAccessGraphSettings(t), nil + }, + create: func(ctx context.Context, item *clusterconfigv1.AccessGraphSettings) error { + _, err := p.clusterConfigS.UpsertAccessGraphSettings(ctx, item) + return trace.Wrap(err) + }, + list: func(ctx context.Context) ([]*clusterconfigv1.AccessGraphSettings, error) { + item, err := p.clusterConfigS.GetAccessGraphSettings(ctx) + if trace.IsNotFound(err) { + return []*clusterconfigv1.AccessGraphSettings{}, nil + } + return []*clusterconfigv1.AccessGraphSettings{item}, trace.Wrap(err) + }, + cacheList: func(ctx context.Context) ([]*clusterconfigv1.AccessGraphSettings, error) { + item, err := p.cache.GetAccessGraphSettings(ctx) + if trace.IsNotFound(err) { + return []*clusterconfigv1.AccessGraphSettings{}, nil + } + return []*clusterconfigv1.AccessGraphSettings{item}, trace.Wrap(err) + }, + deleteAll: func(ctx context.Context) error { + return trace.Wrap(p.clusterConfigS.DeleteAccessGraphSettings(ctx)) + }, + }) +} diff --git a/lib/cache/collections.go b/lib/cache/collections.go index 4abcd0bcb94eb..865d38c51b5aa 100644 --- a/lib/cache/collections.go +++ b/lib/cache/collections.go @@ -22,6 +22,8 @@ import ( "github.com/gravitational/trace" autoupdatev1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/autoupdate/v1" + clusterconfigv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/clusterconfig/v1" + crownjewelv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/crownjewel/v1" healthcheckconfigv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/healthcheckconfig/v1" identitycenterv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/identitycenter/v1" machineidv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/machineid/v1" @@ -99,6 +101,8 @@ type collections struct { accessLists *collection[*accesslist.AccessList, accessListIndex] accessListMembers *collection[*accesslist.AccessListMember, accessListMemberIndex] accessListReviews *collection[*accesslist.Review, accessListReviewIndex] + crownJewels *collection[*crownjewelv1.CrownJewel, crownJewelIndex] + accessGraphSettings *collection[*clusterconfigv1.AccessGraphSettings, accessGraphSettingsIndex] } // setupCollections ensures that the appropriate [collection] is @@ -468,6 +472,22 @@ func setupCollections(c Config) (*collections, error) { out.accessListReviews = collect out.byKind[resourceKind] = out.accessListReviews + case types.KindCrownJewel: + collect, err := newCrownJewelCollection(c.CrownJewels, watch) + if err != nil { + return nil, trace.Wrap(err) + } + + out.crownJewels = collect + out.byKind[resourceKind] = out.crownJewels + case types.KindAccessGraphSettings: + collect, err := newAccessGraphSettingsCollection(c.ClusterConfig, watch) + if err != nil { + return nil, trace.Wrap(err) + } + + out.accessGraphSettings = collect + out.byKind[resourceKind] = out.accessGraphSettings } } diff --git a/lib/cache/crown_jewel.go b/lib/cache/crown_jewel.go new file mode 100644 index 0000000000000..0e50c56f5de2b --- /dev/null +++ b/lib/cache/crown_jewel.go @@ -0,0 +1,114 @@ +// Teleport +// Copyright (C) 2025 Gravitational, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package cache + +import ( + "context" + + "github.com/gravitational/trace" + + crownjewelv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/crownjewel/v1" + headerv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/header/v1" + "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/api/utils" + "github.com/gravitational/teleport/lib/services" +) + +type crownJewelIndex string + +const crownJewelNameIndex crownJewelIndex = "name" + +func newCrownJewelCollection(upstream services.CrownJewels, w types.WatchKind) (*collection[*crownjewelv1.CrownJewel, crownJewelIndex], error) { + if upstream == nil { + return nil, trace.BadParameter("missing parameter CrownJewels") + } + + return &collection[*crownjewelv1.CrownJewel, crownJewelIndex]{ + store: newStore(map[crownJewelIndex]func(*crownjewelv1.CrownJewel) string{ + crownJewelNameIndex: func(r *crownjewelv1.CrownJewel) string { + return r.GetMetadata().GetName() + }, + }), + fetcher: func(ctx context.Context, loadSecrets bool) ([]*crownjewelv1.CrownJewel, error) { + var out []*crownjewelv1.CrownJewel + var nextToken string + for { + var page []*crownjewelv1.CrownJewel + var err error + + const defaultPageSize = 0 + page, nextToken, err = upstream.ListCrownJewels(ctx, defaultPageSize, nextToken) + if err != nil { + return nil, trace.Wrap(err) + } + out = append(out, page...) + if nextToken == "" { + break + } + } + return out, nil + }, + headerTransform: func(hdr *types.ResourceHeader) *crownjewelv1.CrownJewel { + return &crownjewelv1.CrownJewel{ + Kind: hdr.Kind, + Version: hdr.Version, + Metadata: &headerv1.Metadata{ + Name: hdr.Metadata.Name, + }, + } + }, + watch: w, + }, nil +} + +// ListCrownJewels returns a list of CrownJewel resources. +func (c *Cache) ListCrownJewels(ctx context.Context, pageSize int64, pageToken string) ([]*crownjewelv1.CrownJewel, string, error) { + ctx, span := c.Tracer.Start(ctx, "cache/ListCrownJewels") + defer span.End() + + lister := genericLister[*crownjewelv1.CrownJewel, crownJewelIndex]{ + cache: c, + collection: c.collections.crownJewels, + index: crownJewelNameIndex, + upstreamList: func(ctx context.Context, pageSize int, pageToken string) ([]*crownjewelv1.CrownJewel, string, error) { + out, next, err := c.Config.CrownJewels.ListCrownJewels(ctx, int64(pageSize), pageToken) + return out, next, trace.Wrap(err) + }, + nextToken: func(t *crownjewelv1.CrownJewel) string { + return t.GetMetadata().GetName() + }, + clone: utils.CloneProtoMsg[*crownjewelv1.CrownJewel], + } + out, next, err := lister.list(ctx, int(pageSize), pageToken) + return out, next, trace.Wrap(err) +} + +// GetCrownJewel returns the specified CrownJewel resource. +func (c *Cache) GetCrownJewel(ctx context.Context, name string) (*crownjewelv1.CrownJewel, error) { + ctx, span := c.Tracer.Start(ctx, "cache/GetCrownJewel") + defer span.End() + + getter := genericGetter[*crownjewelv1.CrownJewel, crownJewelIndex]{ + cache: c, + collection: c.collections.crownJewels, + index: crownJewelNameIndex, + upstreamGet: c.Config.CrownJewels.GetCrownJewel, + clone: utils.CloneProtoMsg[*crownjewelv1.CrownJewel], + } + out, err := getter.get(ctx, name) + return out, trace.Wrap(err) +} diff --git a/lib/cache/crown_jewel_test.go b/lib/cache/crown_jewel_test.go new file mode 100644 index 0000000000000..ff4c59bb650fa --- /dev/null +++ b/lib/cache/crown_jewel_test.go @@ -0,0 +1,54 @@ +// Teleport +// Copyright (C) 2025 Gravitational, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package cache + +import ( + "context" + "testing" + + "github.com/gravitational/trace" + + crownjewelv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/crownjewel/v1" +) + +// TestCrownJewel tests that CRUD operations on user notification resources are +// replicated from the backend to the cache. +func TestCrownJewel(t *testing.T) { + t.Parallel() + + p := newTestPack(t, ForAuth) + t.Cleanup(p.Close) + + testResources153(t, p, testFuncs153[*crownjewelv1.CrownJewel]{ + newResource: func(name string) (*crownjewelv1.CrownJewel, error) { + return newCrownJewel(t, name), nil + }, + create: func(ctx context.Context, item *crownjewelv1.CrownJewel) error { + _, err := p.crownJewels.CreateCrownJewel(ctx, item) + return trace.Wrap(err) + }, + list: func(ctx context.Context) ([]*crownjewelv1.CrownJewel, error) { + items, _, err := p.crownJewels.ListCrownJewels(ctx, 0, "") + return items, trace.Wrap(err) + }, + cacheList: func(ctx context.Context) ([]*crownjewelv1.CrownJewel, error) { + items, _, err := p.crownJewels.ListCrownJewels(ctx, 0, "") + return items, trace.Wrap(err) + }, + deleteAll: p.crownJewels.DeleteAllCrownJewels, + }) +} diff --git a/lib/cache/legacy_collections.go b/lib/cache/legacy_collections.go index 4baa117d07cca..64ffea33d356d 100644 --- a/lib/cache/legacy_collections.go +++ b/lib/cache/legacy_collections.go @@ -27,8 +27,6 @@ import ( "github.com/gravitational/teleport/api/client/proto" accessmonitoringrulesv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/accessmonitoringrules/v1" - clusterconfigpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/clusterconfig/v1" - crownjewelv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/crownjewel/v1" dbobjectv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/dbobject/v1" identitycenterv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/identitycenter/v1" kubewaitingcontainerpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/kubewaitingcontainer/v1" @@ -89,11 +87,6 @@ type executor[T any, R any] interface { // noReader is returned by getReader for resources which aren't directly used by the cache, and therefore have no associated reader. type noReader struct{} -type crownjewelsGetter interface { - ListCrownJewels(ctx context.Context, pageSize int64, nextToken string) ([]*crownjewelv1.CrownJewel, string, error) - GetCrownJewel(ctx context.Context, name string) (*crownjewelv1.CrownJewel, error) -} - type userTasksGetter interface { ListUserTasks(ctx context.Context, pageSize int64, nextToken string, filters *usertasksv1.ListUserTasksFilters) ([]*usertasksv1.UserTask, string, error) GetUserTask(ctx context.Context, name string) (*usertasksv1.UserTask, error) @@ -113,7 +106,6 @@ type legacyCollections struct { installers collectionReader[installerGetter] integrations collectionReader[services.IntegrationsGetter] userTasks collectionReader[userTasksGetter] - crownJewels collectionReader[crownjewelsGetter] kubeWaitingContainers collectionReader[kubernetesWaitingContainerGetter] staticHostUsers collectionReader[staticHostUserGetter] locks collectionReader[services.LockGetter] @@ -124,7 +116,6 @@ type legacyCollections struct { userLoginStates collectionReader[services.UserLoginStatesGetter] webTokens collectionReader[webTokenGetter] dynamicWindowsDesktops collectionReader[dynamicWindowsDesktopsGetter] - accessGraphSettings collectionReader[accessGraphSettingsGetter] accessMonitoringRules collectionReader[accessMonitoringRuleGetter] provisioningStates collectionReader[provisioningStateGetter] identityCenterPrincipalAssignments collectionReader[identityCenterPrincipalAssignmentGetter] @@ -200,15 +191,6 @@ func setupLegacyCollections(c *Cache, watches []types.WatchKind) (*legacyCollect watch: watch, } collections.byKind[resourceKind] = collections.databaseObjects - case types.KindCrownJewel: - if c.CrownJewels == nil { - return nil, trace.BadParameter("missing parameter crownjewels") - } - collections.crownJewels = &genericCollection[*crownjewelv1.CrownJewel, crownjewelsGetter, crownJewelsExecutor]{ - cache: c, - watch: watch, - } - collections.byKind[resourceKind] = collections.crownJewels case types.KindNetworkRestrictions: if c.Restrictions == nil { return nil, trace.BadParameter("missing parameter Restrictions") @@ -311,15 +293,7 @@ func setupLegacyCollections(c *Cache, watches []types.WatchKind) (*legacyCollect } collections.accessMonitoringRules = &genericCollection[*accessmonitoringrulesv1.AccessMonitoringRule, accessMonitoringRuleGetter, accessMonitoringRulesExecutor]{cache: c, watch: watch} collections.byKind[resourceKind] = collections.accessMonitoringRules - case types.KindAccessGraphSettings: - if c.ClusterConfig == nil { - return nil, trace.BadParameter("missing parameter ClusterConfig") - } - collections.accessGraphSettings = &genericCollection[*clusterconfigpb.AccessGraphSettings, accessGraphSettingsGetter, accessGraphSettingsExecutor]{ - cache: c, - watch: watch, - } - collections.byKind[resourceKind] = collections.accessGraphSettings + case types.KindProvisioningPrincipalState: if c.ProvisioningStates == nil { return nil, trace.BadParameter("missing parameter KindProvisioningState") @@ -940,51 +914,6 @@ type staticHostUserGetter interface { GetStaticHostUser(ctx context.Context, name string) (*userprovisioningpb.StaticHostUser, error) } -type crownJewelsExecutor struct{} - -func (crownJewelsExecutor) getAll(ctx context.Context, cache *Cache, loadSecrets bool) ([]*crownjewelv1.CrownJewel, error) { - var resources []*crownjewelv1.CrownJewel - var nextToken string - for { - var page []*crownjewelv1.CrownJewel - var err error - page, nextToken, err = cache.CrownJewels.ListCrownJewels(ctx, 0 /* page size */, nextToken) - if err != nil { - return nil, trace.Wrap(err) - } - resources = append(resources, page...) - - if nextToken == "" { - break - } - } - return resources, nil -} - -func (crownJewelsExecutor) upsert(ctx context.Context, cache *Cache, resource *crownjewelv1.CrownJewel) error { - _, err := cache.crownJewelsCache.UpsertCrownJewel(ctx, resource) - return trace.Wrap(err) -} - -func (crownJewelsExecutor) deleteAll(ctx context.Context, cache *Cache) error { - return cache.crownJewelsCache.DeleteAllCrownJewels(ctx) -} - -func (crownJewelsExecutor) delete(ctx context.Context, cache *Cache, resource types.Resource) error { - return cache.crownJewelsCache.DeleteCrownJewel(ctx, resource.GetName()) -} - -func (crownJewelsExecutor) isSingleton() bool { return false } - -func (crownJewelsExecutor) getReader(cache *Cache, cacheOK bool) crownjewelsGetter { - if cacheOK { - return cache.crownJewelsCache - } - return cache.Config.CrownJewels -} - -var _ executor[*crownjewelv1.CrownJewel, crownjewelsGetter] = crownJewelsExecutor{} - type userTasksExecutor struct{} func (userTasksExecutor) getAll(ctx context.Context, cache *Cache, loadSecrets bool) ([]*usertasksv1.UserTask, error) { @@ -1385,42 +1314,3 @@ type accessMonitoringRuleGetter interface { ListAccessMonitoringRules(ctx context.Context, limit int, startKey string) ([]*accessmonitoringrulesv1.AccessMonitoringRule, string, error) ListAccessMonitoringRulesWithFilter(ctx context.Context, req *accessmonitoringrulesv1.ListAccessMonitoringRulesWithFilterRequest) ([]*accessmonitoringrulesv1.AccessMonitoringRule, string, error) } - -type accessGraphSettingsExecutor struct{} - -func (accessGraphSettingsExecutor) getAll(ctx context.Context, cache *Cache, _ bool) ([]*clusterconfigpb.AccessGraphSettings, error) { - set, err := cache.ClusterConfig.GetAccessGraphSettings(ctx) - if err != nil { - return nil, trace.Wrap(err) - } - - return []*clusterconfigpb.AccessGraphSettings{set}, nil -} - -func (accessGraphSettingsExecutor) upsert(ctx context.Context, cache *Cache, resource *clusterconfigpb.AccessGraphSettings) error { - _, err := cache.clusterConfigCache.UpsertAccessGraphSettings(ctx, resource) - return trace.Wrap(err) -} - -func (accessGraphSettingsExecutor) deleteAll(ctx context.Context, cache *Cache) error { - return trace.Wrap(cache.clusterConfigCache.DeleteAccessGraphSettings(ctx)) -} - -func (accessGraphSettingsExecutor) delete(ctx context.Context, cache *Cache, resource types.Resource) error { - return trace.Wrap(cache.clusterConfigCache.DeleteAccessGraphSettings(ctx)) -} - -func (accessGraphSettingsExecutor) isSingleton() bool { return false } - -func (accessGraphSettingsExecutor) getReader(cache *Cache, cacheOK bool) accessGraphSettingsGetter { - if cacheOK { - return cache.clusterConfigCache - } - return cache.Config.ClusterConfig -} - -type accessGraphSettingsGetter interface { - GetAccessGraphSettings(context.Context) (*clusterconfigpb.AccessGraphSettings, error) -} - -var _ executor[*clusterconfigpb.AccessGraphSettings, accessGraphSettingsGetter] = accessGraphSettingsExecutor{}