Skip to content

Commit

Permalink
Merge branch 'master' into joerger/sso-mfa-challenge
Browse files Browse the repository at this point in the history
  • Loading branch information
Joerger authored Oct 23, 2024
2 parents 15b110f + d82ee84 commit 99d7ee1
Show file tree
Hide file tree
Showing 11 changed files with 507 additions and 182 deletions.
7 changes: 7 additions & 0 deletions api/client/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,10 @@ func EventToGRPC(in types.Event) (*proto.Event, error) {
out.Resource = &proto.Event_WindowsDesktop{
WindowsDesktop: r,
}
case *types.DynamicWindowsDesktopV1:
out.Resource = &proto.Event_DynamicWindowsDesktop{
DynamicWindowsDesktop: r,
}
case *types.InstallerV1:
out.Resource = &proto.Event_Installer{
Installer: r,
Expand Down Expand Up @@ -444,6 +448,9 @@ func EventFromGRPC(in *proto.Event) (*types.Event, error) {
} else if r := in.GetWindowsDesktop(); r != nil {
out.Resource = r
return &out, nil
} else if r := in.GetDynamicWindowsDesktop(); r != nil {
out.Resource = r
return &out, nil
} else if r := in.GetKubernetesServer(); r != nil {
out.Resource = r
return &out, nil
Expand Down
371 changes: 193 additions & 178 deletions api/gen/proto/go/teleport/autoupdate/v1/autoupdate.pb.go

Large diffs are not rendered by default.

7 changes: 5 additions & 2 deletions api/proto/teleport/autoupdate/v1/autoupdate.proto
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ message AutoUpdateConfigSpec {
reserved 1;
reserved "tools_autoupdate"; // ToolsAutoupdate is replaced by tools.mode.
AutoUpdateConfigSpecTools tools = 2;
AutoUpdateConfigSpecAgents agents = 3;
}

// AutoUpdateConfigSpecTools encodes the parameters for client tools auto updates.
Expand All @@ -48,6 +49,8 @@ message AutoUpdateConfigSpecTools {

// AutoUpdateConfigSpecAgents encodes the parameters of automatic agent updates.
message AutoUpdateConfigSpecAgents {
reserved 5;
reserved "agent_schedules";
// mode specifies whether agent autoupdates are enabled, disabled, or paused.
string mode = 1;
// strategy to use for updating the agents.
Expand All @@ -56,8 +59,8 @@ message AutoUpdateConfigSpecAgents {
// Once the window is over, the group transitions to the done state. Existing agents won't be updated until the next
// maintenance window.
google.protobuf.Duration maintenance_window_duration = 3;
// agent_schedules specifies schedules for updates of grouped agents.
AgentAutoUpdateSchedules agent_schedules = 5;
// schedules specifies schedules for updates of grouped agents.
AgentAutoUpdateSchedules schedules = 6;
}

// AgentAutoUpdateSchedules specifies update scheduled for grouped agents.
Expand Down
6 changes: 6 additions & 0 deletions lib/auth/authclient/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -1088,6 +1088,12 @@ type Cache interface {
// GetWindowsDesktopService returns a windows desktop host by name.
GetWindowsDesktopService(ctx context.Context, name string) (types.WindowsDesktopService, error)

// GetDynamicWindowsDesktop returns registered dynamic Windows desktop by name.
GetDynamicWindowsDesktop(ctx context.Context, name string) (types.DynamicWindowsDesktop, error)

// ListDynamicWindowsDesktops returns all registered dynamic Windows desktop.
ListDynamicWindowsDesktops(ctx context.Context, pageSize int, pageToken string) ([]types.DynamicWindowsDesktop, string, error)

// GetStaticTokens gets the list of static tokens used to provision nodes.
GetStaticTokens() (types.StaticTokens, error)

Expand Down
3 changes: 1 addition & 2 deletions lib/auth/grpcserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -5149,8 +5149,7 @@ func NewGRPCServer(cfg GRPCServerConfig) (*GRPCServer, error) {
dynamicWindows, err := dynamicwindowsv1.NewService(dynamicwindowsv1.ServiceConfig{
Authorizer: cfg.Authorizer,
Backend: cfg.AuthServer.Services,
// TODO(probakowski): switch to cache when support is added
Cache: cfg.AuthServer.Services,
Cache: cfg.AuthServer.Cache,
})
if err != nil {
return nil, trace.Wrap(err)
Expand Down
39 changes: 39 additions & 0 deletions lib/cache/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ func ForAuth(cfg Config) Config {
{Kind: types.KindLock},
{Kind: types.KindWindowsDesktopService},
{Kind: types.KindWindowsDesktop},
{Kind: types.KindDynamicWindowsDesktop},
{Kind: types.KindKubeServer},
{Kind: types.KindInstaller},
{Kind: types.KindKubernetesCluster},
Expand Down Expand Up @@ -233,6 +234,7 @@ func ForProxy(cfg Config) Config {
{Kind: types.KindDatabase},
{Kind: types.KindWindowsDesktopService},
{Kind: types.KindWindowsDesktop},
{Kind: types.KindDynamicWindowsDesktop},
{Kind: types.KindKubeServer},
{Kind: types.KindInstaller},
{Kind: types.KindKubernetesCluster},
Expand Down Expand Up @@ -392,6 +394,7 @@ func ForWindowsDesktop(cfg Config) Config {
{Kind: types.KindNamespace, Name: apidefaults.Namespace},
{Kind: types.KindWindowsDesktopService},
{Kind: types.KindWindowsDesktop},
{Kind: types.KindDynamicWindowsDesktop},
}
cfg.QueueSize = defaults.WindowsDesktopQueueSize
return cfg
Expand Down Expand Up @@ -520,6 +523,7 @@ type Cache struct {
webSessionCache types.WebSessionInterface
webTokenCache types.WebTokenInterface
windowsDesktopsCache services.WindowsDesktops
dynamicWindowsDesktopsCache services.DynamicWindowsDesktops
samlIdPServiceProvidersCache services.SAMLIdPServiceProviders //nolint:revive // Because we want this to be IdP.
userGroupsCache services.UserGroups
oktaCache services.Okta
Expand Down Expand Up @@ -690,6 +694,8 @@ type Config struct {
WebToken types.WebTokenInterface
// WindowsDesktops is a windows desktop service.
WindowsDesktops services.WindowsDesktops
// DynamicWindowsDesktops is a dynamic Windows desktop service.
DynamicWindowsDesktops services.DynamicWindowsDesktops
// SAMLIdPServiceProviders is a SAML IdP service providers service.
SAMLIdPServiceProviders services.SAMLIdPServiceProviders
// UserGroups is a user groups service.
Expand Down Expand Up @@ -993,6 +999,12 @@ func New(config Config) (*Cache, error) {
return nil, trace.Wrap(err)
}

dynamicDesktopsService, err := local.NewDynamicWindowsDesktopService(config.Backend)
if err != nil {
cancel()
return nil, trace.Wrap(err)
}

cs := &Cache{
ctx: ctx,
cancel: cancel,
Expand All @@ -1019,6 +1031,7 @@ func New(config Config) (*Cache, error) {
webSessionCache: identityService.WebSessions(),
webTokenCache: identityService.WebTokens(),
windowsDesktopsCache: local.NewWindowsDesktopService(config.Backend),
dynamicWindowsDesktopsCache: dynamicDesktopsService,
accessMontoringRuleCache: accessMonitoringRuleCache,
samlIdPServiceProvidersCache: samlIdPServiceProvidersCache,
userGroupsCache: userGroupsCache,
Expand Down Expand Up @@ -2822,6 +2835,32 @@ func (c *Cache) ListWindowsDesktopServices(ctx context.Context, req types.ListWi
return rg.reader.ListWindowsDesktopServices(ctx, req)
}

// GetDynamicWindowsDesktop returns registered dynamic Windows desktop by name.
func (c *Cache) GetDynamicWindowsDesktop(ctx context.Context, name string) (types.DynamicWindowsDesktop, error) {
ctx, span := c.Tracer.Start(ctx, "cache/GetDynamicWindowsDesktop")
defer span.End()

rg, err := readCollectionCache(c, c.collections.dynamicWindowsDesktops)
if err != nil {
return nil, trace.Wrap(err)
}
defer rg.Release()
return rg.reader.GetDynamicWindowsDesktop(ctx, name)
}

// ListDynamicWindowsDesktops returns all registered dynamic Windows desktop.
func (c *Cache) ListDynamicWindowsDesktops(ctx context.Context, pageSize int, nextPage string) ([]types.DynamicWindowsDesktop, string, error) {
ctx, span := c.Tracer.Start(ctx, "cache/ListDynamicWindowsDesktops")
defer span.End()

rg, err := readCollectionCache(c, c.collections.dynamicWindowsDesktops)
if err != nil {
return nil, "", trace.Wrap(err)
}
defer rg.Release()
return rg.reader.ListDynamicWindowsDesktops(ctx, pageSize, nextPage)
}

// ListSAMLIdPServiceProviders returns a paginated list of SAML IdP service provider resources.
func (c *Cache) ListSAMLIdPServiceProviders(ctx context.Context, pageSize int, nextKey string) ([]types.SAMLIdPServiceProvider, string, error) {
ctx, span := c.Tracer.Start(ctx, "cache/ListSAMLIdPServiceProviders")
Expand Down
1 change: 1 addition & 0 deletions lib/cache/cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3424,6 +3424,7 @@ func TestCacheWatchKindExistsInEvents(t *testing.T) {
types.KindLock: &types.LockV2{},
types.KindWindowsDesktopService: &types.WindowsDesktopServiceV3{},
types.KindWindowsDesktop: &types.WindowsDesktopV3{},
types.KindDynamicWindowsDesktop: &types.DynamicWindowsDesktopV1{},
types.KindInstaller: &types.InstallerV1{},
types.KindKubernetesCluster: &types.KubernetesClusterV3{},
types.KindSAMLIdPServiceProvider: &types.SAMLIdPServiceProviderV1{},
Expand Down
59 changes: 59 additions & 0 deletions lib/cache/collections.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import (
"github.com/gravitational/teleport/api/types/discoveryconfig"
"github.com/gravitational/teleport/api/types/secreports"
"github.com/gravitational/teleport/api/types/userloginstate"
"github.com/gravitational/teleport/lib/defaults"
"github.com/gravitational/teleport/lib/services"
)

Expand Down Expand Up @@ -258,6 +259,7 @@ type cacheCollections struct {
webSessions collectionReader[webSessionGetter]
webTokens collectionReader[webTokenGetter]
windowsDesktops collectionReader[windowsDesktopsGetter]
dynamicWindowsDesktops collectionReader[dynamicWindowsDesktopsGetter]
windowsDesktopServices collectionReader[windowsDesktopServiceGetter]
userNotifications collectionReader[notificationGetter]
accessGraphSettings collectionReader[accessGraphSettingsGetter]
Expand Down Expand Up @@ -621,6 +623,15 @@ func setupCollections(c *Cache, watches []types.WatchKind) (*cacheCollections, e
watch: watch,
}
collections.byKind[resourceKind] = collections.windowsDesktops
case types.KindDynamicWindowsDesktop:
if c.WindowsDesktops == nil {
return nil, trace.BadParameter("missing parameter DynamicWindowsDesktops")
}
collections.dynamicWindowsDesktops = &genericCollection[types.DynamicWindowsDesktop, dynamicWindowsDesktopsGetter, dynamicWindowsDesktopsExecutor]{
cache: c,
watch: watch,
}
collections.byKind[resourceKind] = collections.dynamicWindowsDesktops
case types.KindSAMLIdPServiceProvider:
if c.SAMLIdPServiceProviders == nil {
return nil, trace.BadParameter("missing parameter SAMLIdPServiceProviders")
Expand Down Expand Up @@ -2318,6 +2329,54 @@ type windowsDesktopsGetter interface {

var _ executor[types.WindowsDesktop, windowsDesktopsGetter] = windowsDesktopsExecutor{}

type dynamicWindowsDesktopsExecutor struct{}

func (dynamicWindowsDesktopsExecutor) getAll(ctx context.Context, cache *Cache, loadSecrets bool) ([]types.DynamicWindowsDesktop, error) {
var desktops []types.DynamicWindowsDesktop
next := ""
for {
d, token, err := cache.dynamicWindowsDesktopsCache.ListDynamicWindowsDesktops(ctx, defaults.MaxIterationLimit, next)
if err != nil {
return nil, err
}
desktops = append(desktops, d...)
if token == "" {
break
}
next = token
}
return desktops, nil
}

func (dynamicWindowsDesktopsExecutor) upsert(ctx context.Context, cache *Cache, resource types.DynamicWindowsDesktop) error {
_, err := cache.dynamicWindowsDesktopsCache.UpsertDynamicWindowsDesktop(ctx, resource)
return err
}

func (dynamicWindowsDesktopsExecutor) deleteAll(ctx context.Context, cache *Cache) error {
return cache.dynamicWindowsDesktopsCache.DeleteAllDynamicWindowsDesktops(ctx)
}

func (dynamicWindowsDesktopsExecutor) delete(ctx context.Context, cache *Cache, resource types.Resource) error {
return cache.dynamicWindowsDesktopsCache.DeleteDynamicWindowsDesktop(ctx, resource.GetName())
}

func (dynamicWindowsDesktopsExecutor) isSingleton() bool { return false }

func (dynamicWindowsDesktopsExecutor) getReader(cache *Cache, cacheOK bool) dynamicWindowsDesktopsGetter {
if cacheOK {
return cache.dynamicWindowsDesktopsCache
}
return cache.Config.DynamicWindowsDesktops
}

type dynamicWindowsDesktopsGetter interface {
GetDynamicWindowsDesktop(ctx context.Context, name string) (types.DynamicWindowsDesktop, error)
ListDynamicWindowsDesktops(ctx context.Context, pageSize int, nextPage string) ([]types.DynamicWindowsDesktop, string, error)
}

var _ executor[types.DynamicWindowsDesktop, dynamicWindowsDesktopsGetter] = dynamicWindowsDesktopsExecutor{}

type kubeClusterExecutor struct{}

func (kubeClusterExecutor) getAll(ctx context.Context, cache *Cache, loadSecrets bool) ([]types.KubeCluster, error) {
Expand Down
1 change: 1 addition & 0 deletions lib/services/dynamic_desktop.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ type DynamicWindowsDesktops interface {
UpdateDynamicWindowsDesktop(context.Context, types.DynamicWindowsDesktop) (types.DynamicWindowsDesktop, error)
UpsertDynamicWindowsDesktop(context.Context, types.DynamicWindowsDesktop) (types.DynamicWindowsDesktop, error)
DeleteDynamicWindowsDesktop(ctx context.Context, name string) error
DeleteAllDynamicWindowsDesktops(ctx context.Context) error
ListDynamicWindowsDesktops(ctx context.Context, pageSize int, pageToken string) ([]types.DynamicWindowsDesktop, string, error)
}

Expand Down
39 changes: 39 additions & 0 deletions lib/services/local/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,8 @@ func (e *EventsService) NewWatcher(ctx context.Context, watch types.Watch) (type
parser = newWindowsDesktopServicesParser()
case types.KindWindowsDesktop:
parser = newWindowsDesktopsParser()
case types.KindDynamicWindowsDesktop:
parser = newDynamicWindowsDesktopsParser()
case types.KindInstaller:
parser = newInstallerParser()
case types.KindKubernetesCluster:
Expand Down Expand Up @@ -1851,6 +1853,43 @@ func (p *windowsDesktopServicesParser) parse(event backend.Event) (types.Resourc
}
}

func newDynamicWindowsDesktopsParser() *dynamicWindowsDesktopsParser {
return &dynamicWindowsDesktopsParser{
baseParser: newBaseParser(backend.NewKey(dynamicWindowsDesktopsPrefix, "")),
}
}

type dynamicWindowsDesktopsParser struct {
baseParser
}

func (p *dynamicWindowsDesktopsParser) parse(event backend.Event) (types.Resource, error) {
switch event.Type {
case types.OpDelete:
name := event.Item.Key.TrimPrefix(backend.NewKey(dynamicWindowsDesktopsPrefix, "")).String()
if name == "" {
return nil, trace.NotFound("failed parsing %v", event.Item.Key.String())
}

return &types.ResourceHeader{
Kind: types.KindDynamicWindowsDesktop,
Version: types.V1,
Metadata: types.Metadata{
Name: strings.TrimPrefix(name, backend.SeparatorString),
Namespace: apidefaults.Namespace,
},
}, nil
case types.OpPut:
return services.UnmarshalDynamicWindowsDesktop(
event.Item.Value,
services.WithExpires(event.Item.Expires),
services.WithRevision(event.Item.Revision),
)
default:
return nil, trace.BadParameter("event %v is not supported", event.Type)
}
}

func newWindowsDesktopsParser() *windowsDesktopsParser {
return &windowsDesktopsParser{
baseParser: newBaseParser(backend.NewKey(windowsDesktopsPrefix, "")),
Expand Down
Loading

0 comments on commit 99d7ee1

Please sign in to comment.