Skip to content

Commit 5e643bf

Browse files
committed
Add PluginsGetter to auth Cache
1 parent d44ef0b commit 5e643bf

File tree

4 files changed

+87
-6
lines changed

4 files changed

+87
-6
lines changed

lib/auth/authclient/api.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1356,6 +1356,9 @@ type Cache interface {
13561356
// GetPluginStaticCredentialsByLabels will get a list of plugin static credentials resource by matching labels.
13571357
GetPluginStaticCredentialsByLabels(ctx context.Context, labels map[string]string) ([]types.PluginStaticCredentials, error)
13581358

1359+
// PluginGetter defines methods for fetching plugins.
1360+
services.PluginGetter
1361+
13591362
// GitServerGetter defines methods for fetching Git servers.
13601363
services.GitServerGetter
13611364

lib/cache/plugins.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,31 @@ func (c *Cache) ListPlugins(ctx context.Context, limit int, startKey string, wit
165165
return plugins, nextKey, nil
166166
}
167167

168+
// HasPluginType will return true if a plugin of the given type is registered.
169+
func (c *Cache) HasPluginType(ctx context.Context, pluginType types.PluginType) (bool, error) {
170+
_, span := c.Tracer.Start(ctx, "cache/HasPluginType")
171+
defer span.End()
172+
173+
rg, err := acquireReadGuard(c, c.collections.plugins)
174+
if err != nil {
175+
return false, trace.Wrap(err)
176+
}
177+
defer rg.Release()
178+
179+
if !rg.ReadCache() {
180+
// Cache is currently not available; check for the plugin type existence upstream.
181+
ok, err := c.Config.Plugin.HasPluginType(ctx, pluginType)
182+
return ok, trace.Wrap(err)
183+
}
184+
185+
for plugin := range rg.store.resources(pluginNameIndex, "", "") {
186+
if plugin.GetType() == pluginType {
187+
return true, nil
188+
}
189+
}
190+
return false, nil
191+
}
192+
168193
// stripPluginSecrets returns a cloned plugin, optionally removing secrets.
169194
// This allows conditional filtering based on the `withSecrets` flag.
170195
func stripAndClonePluginSecrets(in types.Plugin, withSecrets bool) types.Plugin {

lib/cache/plugins_test.go

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,16 @@ package cache
1919
import (
2020
"context"
2121
"testing"
22+
"time"
2223

2324
"github.com/gravitational/trace"
25+
"github.com/stretchr/testify/assert"
26+
"github.com/stretchr/testify/require"
2427

2528
"github.com/gravitational/teleport/api/types"
2629
)
2730

28-
func newPlugin(name string) types.Plugin {
31+
func newPlugin(name string) *types.PluginV1 {
2932
return &types.PluginV1{
3033
Metadata: types.Metadata{Name: name},
3134
Spec: types.PluginSpecV1{
@@ -38,7 +41,7 @@ func newPlugin(name string) types.Plugin {
3841
}
3942
}
4043

41-
func newPluginWithCreds(name string) types.Plugin {
44+
func newPluginWithCreds(name string) *types.PluginV1 {
4245
item := newPlugin(name)
4346
creds := types.PluginCredentialsV1{
4447
Credentials: &types.PluginCredentialsV1_StaticCredentialsRef{
@@ -142,3 +145,49 @@ func TestPlugin(t *testing.T) {
142145
})
143146
})
144147
}
148+
149+
func TestPlugin_HasPluginType(t *testing.T) {
150+
t.Parallel()
151+
ctx := t.Context()
152+
153+
p := newTestPack(t, ForAuth)
154+
t.Cleanup(p.Close)
155+
156+
slackPlugin := newPlugin("test_slack_1")
157+
slackPlugin.Spec.Settings = &types.PluginSpecV1_SlackAccessPlugin{
158+
SlackAccessPlugin: &types.PluginSlackAccessSettings{
159+
FallbackChannel: "#foo",
160+
},
161+
}
162+
scimPlugin := newPlugin("test_scim_1")
163+
scimPlugin.Spec.Settings = &types.PluginSpecV1_Scim{
164+
Scim: &types.PluginSCIMSettings{
165+
SamlConnectorName: "example-saml-connector",
166+
},
167+
}
168+
169+
err := p.plugin.CreatePlugin(ctx, slackPlugin)
170+
require.NoError(t, err)
171+
172+
err = p.plugin.CreatePlugin(ctx, scimPlugin)
173+
require.NoError(t, err)
174+
175+
// Wait for cache propagation.
176+
require.EventuallyWithT(t, func(t *assert.CollectT) {
177+
plugins, _, err := p.cache.ListPlugins(ctx, 0, "", false)
178+
require.NoError(t, err)
179+
require.Len(t, plugins, 2)
180+
}, 15*time.Second, 100*time.Millisecond)
181+
182+
has, err := p.cache.HasPluginType(ctx, types.PluginTypeSlack)
183+
require.NoError(t, err)
184+
require.True(t, has)
185+
186+
has, err = p.cache.HasPluginType(ctx, types.PluginTypeSCIM)
187+
require.NoError(t, err)
188+
require.True(t, has)
189+
190+
has, err = p.cache.HasPluginType(ctx, types.PluginTypeOkta)
191+
require.NoError(t, err)
192+
require.False(t, has)
193+
}

lib/services/plugins.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,20 @@ import (
2929
"github.com/gravitational/teleport/lib/utils"
3030
)
3131

32+
type PluginGetter interface {
33+
GetPlugin(ctx context.Context, name string, withSecrets bool) (types.Plugin, error)
34+
GetPlugins(ctx context.Context, withSecrets bool) ([]types.Plugin, error)
35+
ListPlugins(ctx context.Context, limit int, startKey string, withSecrets bool) ([]types.Plugin, string, error)
36+
HasPluginType(ctx context.Context, pluginType types.PluginType) (bool, error)
37+
}
38+
3239
// Plugins is the plugin service
3340
type Plugins interface {
41+
PluginGetter
3442
CreatePlugin(ctx context.Context, plugin types.Plugin) error
3543
UpdatePlugin(ctx context.Context, plugin types.Plugin) (types.Plugin, error)
3644
DeleteAllPlugins(ctx context.Context) error
3745
DeletePlugin(ctx context.Context, name string) error
38-
GetPlugin(ctx context.Context, name string, withSecrets bool) (types.Plugin, error)
39-
GetPlugins(ctx context.Context, withSecrets bool) ([]types.Plugin, error)
40-
ListPlugins(ctx context.Context, limit int, startKey string, withSecrets bool) ([]types.Plugin, string, error)
41-
HasPluginType(ctx context.Context, pluginType types.PluginType) (bool, error)
4246
SetPluginCredentials(ctx context.Context, name string, creds types.PluginCredentials) error
4347
SetPluginStatus(ctx context.Context, name string, creds types.PluginStatus) error
4448
}

0 commit comments

Comments
 (0)