Skip to content

Commit 1ff50a5

Browse files
committed
Convert network restrictions to new cache mechanism
Moves networking restrictins to the new cache collection scheme that was introduced in #52210. No additional functionality changes have been made here. This should be a purely mechanical translation to the new internal caching machinery.
1 parent 151fc29 commit 1ff50a5

8 files changed

+150
-70
lines changed

api/types/restrictions.go

+9
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import (
2020
"time"
2121

2222
"github.com/gravitational/trace"
23+
24+
"github.com/gravitational/teleport/api/utils"
2325
)
2426

2527
// NetworkRestrictions defines network restrictions applied to SSH session.
@@ -33,6 +35,8 @@ type NetworkRestrictions interface {
3335
GetDeny() []AddressCondition
3436
// SetDeny sets a list of denied network addresses (overrides Allow list)
3537
SetDeny(deny []AddressCondition)
38+
// Clone returns a copy of the network restrictions.
39+
Clone() NetworkRestrictions
3640
}
3741

3842
// NewNetworkRestrictions creates a new NetworkRestrictions with the given name.
@@ -46,6 +50,11 @@ func NewNetworkRestrictions() NetworkRestrictions {
4650
}
4751
}
4852

53+
// Clone returns a copy of the network restrictions.
54+
func (r *NetworkRestrictionsV4) Clone() NetworkRestrictions {
55+
return utils.CloneProtoMsg(r)
56+
}
57+
4958
func (r *NetworkRestrictionsV4) setStaticFields() {
5059
if r.Version == "" {
5160
r.Version = V4

lib/cache/cache.go

-16
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,6 @@ type Cache struct {
504504
accessCache services.Access
505505
dynamicAccessCache services.DynamicAccessExt
506506
presenceCache services.Presence
507-
restrictionsCache services.Restrictions
508507
databaseObjectsCache *local.DatabaseObjectService
509508
dynamicWindowsDesktopsCache services.DynamicWindowsDesktops
510509
userGroupsCache services.UserGroups
@@ -1015,7 +1014,6 @@ func New(config Config) (*Cache, error) {
10151014
accessCache: local.NewAccessService(config.Backend),
10161015
dynamicAccessCache: local.NewDynamicAccessService(config.Backend),
10171016
presenceCache: local.NewPresenceService(config.Backend),
1018-
restrictionsCache: local.NewRestrictionsService(config.Backend),
10191017
dynamicWindowsDesktopsCache: dynamicDesktopsService,
10201018
userGroupsCache: userGroupsCache,
10211019
userTasksCache: userTasksCache,
@@ -1970,20 +1968,6 @@ func (c *Cache) ListDatabaseObjects(ctx context.Context, size int, pageToken str
19701968
return rg.reader.ListDatabaseObjects(ctx, size, pageToken)
19711969
}
19721970

1973-
// GetNetworkRestrictions gets the network restrictions.
1974-
func (c *Cache) GetNetworkRestrictions(ctx context.Context) (types.NetworkRestrictions, error) {
1975-
ctx, span := c.Tracer.Start(ctx, "cache/GetNetworkRestrictions")
1976-
defer span.End()
1977-
1978-
rg, err := readLegacyCollectionCache(c, c.legacyCacheCollections.networkRestrictions)
1979-
if err != nil {
1980-
return nil, trace.Wrap(err)
1981-
}
1982-
defer rg.Release()
1983-
1984-
return rg.reader.GetNetworkRestrictions(ctx)
1985-
}
1986-
19871971
// GetDynamicWindowsDesktop returns registered dynamic Windows desktop by name.
19881972
func (c *Cache) GetDynamicWindowsDesktop(ctx context.Context, name string) (types.DynamicWindowsDesktop, error) {
19891973
ctx, span := c.Tracer.Start(ctx, "cache/GetDynamicWindowsDesktop")

lib/cache/cert_authority_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ func TestNodeCAFiltering(t *testing.T) {
9393
Access: p.cache.accessCache,
9494
DynamicAccess: p.cache.dynamicAccessCache,
9595
Presence: p.cache.presenceCache,
96-
Restrictions: p.cache.restrictionsCache,
96+
Restrictions: p.cache.Restrictions,
9797
DynamicWindowsDesktops: p.cache.dynamicWindowsDesktopsCache,
9898
SAMLIdPServiceProviders: p.samlIDPServiceProviders,
9999
UserGroups: p.userGroups,

lib/cache/collections.go

+9
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ type collections struct {
111111
uiConfigs *collection[types.UIConfig, webUIConfigIndex]
112112
installers *collection[types.Installer, installerIndex]
113113
locks *collection[types.Lock, lockIndex]
114+
networkRestrictions *collection[types.NetworkRestrictions, networkingRestrictionIndex]
114115
}
115116

116117
// setupCollections ensures that the appropriate [collection] is
@@ -552,6 +553,14 @@ func setupCollections(c Config) (*collections, error) {
552553

553554
out.locks = collect
554555
out.byKind[resourceKind] = out.locks
556+
case types.KindNetworkRestrictions:
557+
collect, err := newNetworkingRestrictionCollection(c.Restrictions, watch)
558+
if err != nil {
559+
return nil, trace.Wrap(err)
560+
}
561+
562+
out.networkRestrictions = collect
563+
out.byKind[resourceKind] = out.networkRestrictions
555564
}
556565
}
557566

lib/cache/legacy_collections.go

-47
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,6 @@ type legacyCollections struct {
105105
userTasks collectionReader[userTasksGetter]
106106
kubeWaitingContainers collectionReader[kubernetesWaitingContainerGetter]
107107
staticHostUsers collectionReader[staticHostUserGetter]
108-
networkRestrictions collectionReader[networkRestrictionGetter]
109108
remoteClusters collectionReader[remoteClusterGetter]
110109
userLoginStates collectionReader[services.UserLoginStatesGetter]
111110
dynamicWindowsDesktops collectionReader[dynamicWindowsDesktopsGetter]
@@ -154,15 +153,6 @@ func setupLegacyCollections(c *Cache, watches []types.WatchKind) (*legacyCollect
154153
watch: watch,
155154
}
156155
collections.byKind[resourceKind] = collections.databaseObjects
157-
case types.KindNetworkRestrictions:
158-
if c.Restrictions == nil {
159-
return nil, trace.BadParameter("missing parameter Restrictions")
160-
}
161-
collections.networkRestrictions = &genericCollection[types.NetworkRestrictions, networkRestrictionGetter, networkRestrictionsExecutor]{
162-
cache: c,
163-
watch: watch,
164-
}
165-
collections.byKind[resourceKind] = collections.networkRestrictions
166156
case types.KindDynamicWindowsDesktop:
167157
if c.WindowsDesktops == nil {
168158
return nil, trace.BadParameter("missing parameter DynamicWindowsDesktops")
@@ -502,43 +492,6 @@ func (databaseObjectExecutor) getReader(cache *Cache, cacheOK bool) services.Dat
502492

503493
var _ executor[*dbobjectv1.DatabaseObject, services.DatabaseObjectsGetter] = databaseObjectExecutor{}
504494

505-
type networkRestrictionsExecutor struct{}
506-
507-
func (networkRestrictionsExecutor) getAll(ctx context.Context, cache *Cache, loadSecrets bool) ([]types.NetworkRestrictions, error) {
508-
restrictions, err := cache.Restrictions.GetNetworkRestrictions(ctx)
509-
if err != nil {
510-
return nil, trace.Wrap(err)
511-
}
512-
return []types.NetworkRestrictions{restrictions}, nil
513-
}
514-
515-
func (networkRestrictionsExecutor) upsert(ctx context.Context, cache *Cache, resource types.NetworkRestrictions) error {
516-
return cache.restrictionsCache.SetNetworkRestrictions(ctx, resource)
517-
}
518-
519-
func (networkRestrictionsExecutor) deleteAll(ctx context.Context, cache *Cache) error {
520-
return cache.restrictionsCache.DeleteNetworkRestrictions(ctx)
521-
}
522-
523-
func (networkRestrictionsExecutor) delete(ctx context.Context, cache *Cache, resource types.Resource) error {
524-
return cache.restrictionsCache.DeleteNetworkRestrictions(ctx)
525-
}
526-
527-
func (networkRestrictionsExecutor) isSingleton() bool { return true }
528-
529-
func (networkRestrictionsExecutor) getReader(cache *Cache, cacheOK bool) networkRestrictionGetter {
530-
if cacheOK {
531-
return cache.restrictionsCache
532-
}
533-
return cache.Config.Restrictions
534-
}
535-
536-
type networkRestrictionGetter interface {
537-
GetNetworkRestrictions(context.Context) (types.NetworkRestrictions, error)
538-
}
539-
540-
var _ executor[types.NetworkRestrictions, networkRestrictionGetter] = networkRestrictionsExecutor{}
541-
542495
type dynamicWindowsDesktopsExecutor struct{}
543496

544497
func (dynamicWindowsDesktopsExecutor) getAll(ctx context.Context, cache *Cache, loadSecrets bool) ([]types.DynamicWindowsDesktop, error) {

lib/cache/network_restrictions.go

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// Teleport
2+
// Copyright (C) 2025 Gravitational, Inc.
3+
//
4+
// This program is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU Affero General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// This program is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU Affero General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU Affero General Public License
15+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
17+
package cache
18+
19+
import (
20+
"context"
21+
22+
"github.com/gravitational/trace"
23+
24+
"github.com/gravitational/teleport/api/types"
25+
"github.com/gravitational/teleport/lib/services"
26+
)
27+
28+
type networkingRestrictionIndex string
29+
30+
const networkingRestrictionNameIndex networkingRestrictionIndex = "name"
31+
32+
func newNetworkingRestrictionCollection(upstream services.Restrictions, w types.WatchKind) (*collection[types.NetworkRestrictions, networkingRestrictionIndex], error) {
33+
if upstream == nil {
34+
return nil, trace.BadParameter("missing parameter Restrictions")
35+
}
36+
37+
return &collection[types.NetworkRestrictions, networkingRestrictionIndex]{
38+
store: newStore(map[networkingRestrictionIndex]func(types.NetworkRestrictions) string{
39+
networkingRestrictionNameIndex: types.NetworkRestrictions.GetName,
40+
}),
41+
fetcher: func(ctx context.Context, loadSecrets bool) ([]types.NetworkRestrictions, error) {
42+
restrictions, err := upstream.GetNetworkRestrictions(ctx)
43+
if err != nil {
44+
return nil, trace.Wrap(err)
45+
}
46+
return []types.NetworkRestrictions{restrictions}, nil
47+
},
48+
headerTransform: func(hdr *types.ResourceHeader) types.NetworkRestrictions {
49+
return &types.NetworkRestrictionsV4{
50+
Kind: hdr.Kind,
51+
Version: hdr.Version,
52+
Metadata: types.Metadata{
53+
Name: hdr.Metadata.Name,
54+
},
55+
}
56+
},
57+
watch: w,
58+
}, nil
59+
}
60+
61+
// GetNetworkRestrictions gets the network restrictions.
62+
func (c *Cache) GetNetworkRestrictions(ctx context.Context) (types.NetworkRestrictions, error) {
63+
ctx, span := c.Tracer.Start(ctx, "cache/GetNetworkRestrictions")
64+
defer span.End()
65+
66+
getter := genericGetter[types.NetworkRestrictions, networkingRestrictionIndex]{
67+
cache: c,
68+
collection: c.collections.networkRestrictions,
69+
index: networkingRestrictionNameIndex,
70+
upstreamGet: func(ctx context.Context, s string) (types.NetworkRestrictions, error) {
71+
restriction, err := c.Config.Restrictions.GetNetworkRestrictions(ctx)
72+
return restriction, trace.Wrap(err)
73+
},
74+
clone: types.NetworkRestrictions.Clone,
75+
}
76+
out, err := getter.get(ctx, types.MetaNameNetworkRestrictions)
77+
return out, trace.Wrap(err)
78+
}
+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Teleport
2+
// Copyright (C) 2025 Gravitational, Inc.
3+
//
4+
// This program is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU Affero General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// This program is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU Affero General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU Affero General Public License
15+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
17+
package cache
18+
19+
import (
20+
"context"
21+
"testing"
22+
23+
"github.com/gravitational/trace"
24+
25+
"github.com/gravitational/teleport/api/types"
26+
)
27+
28+
func TestNetworkRestrictions(t *testing.T) {
29+
t.Parallel()
30+
31+
p := newTestPack(t, ForAuth)
32+
t.Cleanup(p.Close)
33+
34+
testResources(t, p, testFuncs[types.NetworkRestrictions]{
35+
newResource: func(name string) (types.NetworkRestrictions, error) {
36+
return types.NewNetworkRestrictions(), nil
37+
},
38+
create: p.restrictions.SetNetworkRestrictions,
39+
list: func(ctx context.Context) ([]types.NetworkRestrictions, error) {
40+
restrictions, err := p.restrictions.GetNetworkRestrictions(ctx)
41+
return []types.NetworkRestrictions{restrictions}, trace.Wrap(err)
42+
},
43+
cacheList: func(ctx context.Context) ([]types.NetworkRestrictions, error) {
44+
restrictions, err := p.cache.GetNetworkRestrictions(ctx)
45+
if trace.IsNotFound(err) {
46+
return nil, nil
47+
}
48+
return []types.NetworkRestrictions{restrictions}, trace.Wrap(err)
49+
},
50+
deleteAll: p.restrictions.DeleteNetworkRestrictions,
51+
})
52+
}

lib/services/local/events.go

+1-6
Original file line numberDiff line numberDiff line change
@@ -1842,16 +1842,11 @@ func (p *networkRestrictionsParser) match(key backend.Key) bool {
18421842
func (p *networkRestrictionsParser) parse(event backend.Event) (types.Resource, error) {
18431843
switch event.Type {
18441844
case types.OpDelete:
1845-
name := event.Item.Key.TrimPrefix(backend.NewKey(restrictionsPrefix, network)).String()
1846-
if name == "" {
1847-
return nil, trace.NotFound("failed parsing %v", event.Item.Key.String())
1848-
}
1849-
18501845
return &types.ResourceHeader{
18511846
Kind: types.KindNetworkRestrictions,
18521847
Version: types.V1,
18531848
Metadata: types.Metadata{
1854-
Name: strings.TrimPrefix(name, backend.SeparatorString),
1849+
Name: types.MetaNameNetworkRestrictions,
18551850
Namespace: apidefaults.Namespace,
18561851
},
18571852
}, nil

0 commit comments

Comments
 (0)