Skip to content

Commit

Permalink
Merge branch 'master' into ami-auto-branch-1729706368
Browse files Browse the repository at this point in the history
  • Loading branch information
zmb3 authored Oct 23, 2024
2 parents 6689570 + cca0f19 commit dc7ac54
Show file tree
Hide file tree
Showing 21 changed files with 751 additions and 43 deletions.
6 changes: 5 additions & 1 deletion .github/ISSUE_TEMPLATE/test-plan-docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,15 @@ to determine the rollout date.
git submodule add https://github.com/gravitational/teleport content/<VERSION>.x
```

## Is the docs site up to date with the new release?
## Is the docs site content up to date with the new release?

- [ ] Verify that Teleport version variables are correct and reflect the upcoming
release. Check `docs/config.json` for this.

- [ ] Ensure that redirects (as configured in `docs/config.json`) only exist for
the default version of the docs site, and have been removed from other
versions.

- [ ] Remove version warnings in the docs that mention a version we no longer
support _except_ for the last EOL version. E.g., if we no longer support
version 10, remove messages saying "You need at least version n to use this
Expand Down
2 changes: 1 addition & 1 deletion api/client/dynamicwindows/dynamicwindows.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func (c *Client) GetDynamicWindowsDesktop(ctx context.Context, name string) (typ
return desktop, trace.Wrap(err)
}

func (c *Client) ListDynamicWindowsDesktop(ctx context.Context, pageSize int, pageToken string) ([]types.DynamicWindowsDesktop, string, error) {
func (c *Client) ListDynamicWindowsDesktops(ctx context.Context, pageSize int, pageToken string) ([]types.DynamicWindowsDesktop, string, error) {
resp, err := c.grpcClient.ListDynamicWindowsDesktops(ctx, &dynamicwindows.ListDynamicWindowsDesktopsRequest{
PageSize: int32(pageSize),
PageToken: pageToken,
Expand Down
6 changes: 6 additions & 0 deletions api/types/common/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ const (
// OriginEntraID indicates that the resource was imported
// from the Entra ID directory.
OriginEntraID = "entra-id"

// OriginAWSIdentityCenter indicates that the resource was
// imported from the AWS Identity Center or created from
// the AWS Identity Center plugin.
OriginAWSIdentityCenter = "aws-identity-center"
)

// OriginValues lists all possible origin values.
Expand All @@ -82,4 +87,5 @@ var OriginValues = []string{
OriginSCIM,
OriginDiscoveryKubernetes,
OriginEntraID,
OriginAWSIdentityCenter,
}
3 changes: 3 additions & 0 deletions api/types/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ var AllPluginTypes = []PluginType{
PluginTypeEntraID,
PluginTypeSCIM,
PluginTypeDatadog,
PluginTypeAWSIdentityCenter,
}

const (
Expand Down Expand Up @@ -75,6 +76,8 @@ const (
PluginTypeSCIM = "scim"
// PluginTypeDatadog indicates the Datadog Incident Management plugin
PluginTypeDatadog = "datadog"
// PluginTypeAWSIdentityCenter indicates AWS Identity Center plugin
PluginTypeAWSIdentityCenter = "aws-identity-center"
)

// PluginSubkind represents the type of the plugin, e.g., access request, MDM etc.
Expand Down
2 changes: 1 addition & 1 deletion api/types/saml_idp_service_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ func (am *SAMLAttributeMapping) CheckAndSetDefaults() error {
// preset can be either empty or one of the supported type.
func (s *SAMLIdPServiceProviderV1) checkAndSetPresetDefaults(preset string) bool {
switch preset {
case "", samlsp.Unspecified:
case "", samlsp.Unspecified, samlsp.AWSIdentityCenter:
return true
case samlsp.GCPWorkforce:
if s.GetRelayState() == "" {
Expand Down
9 changes: 9 additions & 0 deletions api/types/saml_idp_service_provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,15 @@ func TestNewSAMLIdPServiceProvider(t *testing.T) {
errAssertion: require.NoError,
preset: samlsp.Unspecified,
},
{
name: "aws-identity-center preset",
entityDescriptor: "",
entityID: "IAMShowcase",
acsURL: acsURL,
expectedEntityID: "IAMShowcase",
errAssertion: require.NoError,
preset: samlsp.AWSIdentityCenter,
},
{
name: "unsupported preset value",
entityDescriptor: "",
Expand Down
3 changes: 3 additions & 0 deletions api/types/samlsp/samlsp.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ const (
// Unspecified preset type is used in the Web UI to denote a generic SAML service
// provider preset.
Unspecified = "unspecified"
// AWSIdentityCenter is a SAML service provider preset name for AWS
// Identity Center.
AWSIdentityCenter = "aws-identity-center"
)

const (
Expand Down
17 changes: 0 additions & 17 deletions docs/pages/admin-guides/access-controls/guides/impersonation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,6 @@ spec:
users: ['jenkins']
roles: ['jenkins']

# The deny section uses the identical format as the 'allow' section.
# The deny rules always override allow rules.
deny:
node_labels:
'*': '*'
```

Create the `role` resource:
Expand Down Expand Up @@ -207,12 +202,6 @@ spec:
where: >
equals(impersonate_role.metadata.labels["group"], "security") &&
equals(impersonate_user.metadata.labels["group"], "security")
# The deny section uses the identical format as the 'allow' section.
# The deny rules always override allow rules.
deny:
node_labels:
'*': '*'
```
Create the resources:
Expand Down Expand Up @@ -285,12 +274,6 @@ spec:
where: >
contains(user.spec.traits["group"], impersonate_role.metadata.labels["group"]) &&
contains(user.spec.traits["group"], impersonate_user.metadata.labels["group"])
# The deny section uses the identical format as the 'allow' section.
# The deny rules always override allow rules.
deny:
node_labels:
'*': '*'
```

While user traits typically come from an external identity provider, we can test
Expand Down
2 changes: 1 addition & 1 deletion e
Submodule e updated from e4f948 to b5db15
3 changes: 3 additions & 0 deletions lib/auth/authclient/clt.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (
"github.com/gravitational/teleport/api/client"
"github.com/gravitational/teleport/api/client/crownjewel"
"github.com/gravitational/teleport/api/client/databaseobject"
"github.com/gravitational/teleport/api/client/dynamicwindows"
"github.com/gravitational/teleport/api/client/externalauditstorage"
"github.com/gravitational/teleport/api/client/proto"
"github.com/gravitational/teleport/api/client/secreport"
Expand Down Expand Up @@ -1600,6 +1601,8 @@ type ClientI interface {
types.WebSessionsGetter
types.WebTokensGetter

DynamicDesktopClient() *dynamicwindows.Client

// TrustClient returns a client to the Trust service.
TrustClient() trustpb.TrustServiceClient

Expand Down
90 changes: 90 additions & 0 deletions lib/srv/desktop/discovery.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"errors"
"fmt"
"log/slog"
"maps"
"net"
"net/netip"
"strings"
Expand All @@ -32,6 +33,7 @@ import (
"github.com/go-ldap/ldap/v3"
"github.com/gravitational/trace"

"github.com/gravitational/teleport"
apidefaults "github.com/gravitational/teleport/api/defaults"
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/lib/auth/windows"
Expand Down Expand Up @@ -306,3 +308,91 @@ func (s *WindowsService) ldapEntryToWindowsDesktop(ctx context.Context, entry *l
desktop.SetExpiry(s.cfg.Clock.Now().UTC().Add(apidefaults.ServerAnnounceTTL * 3))
return desktop, nil
}

// startDynamicReconciler starts resource watcher and reconciler that registers/unregisters Windows desktops
// according to the up-to-date list of dynamic Windows desktops resources.
func (s *WindowsService) startDynamicReconciler(ctx context.Context) (*services.DynamicWindowsDesktopWatcher, error) {
if len(s.cfg.ResourceMatchers) == 0 {
s.cfg.Logger.DebugContext(ctx, "Not starting dynamic desktop resource watcher.")
return nil, nil
}
s.cfg.Logger.DebugContext(ctx, "Starting dynamic desktop resource watcher.")
dynamicDesktopClient := s.cfg.AuthClient.DynamicDesktopClient()
watcher, err := services.NewDynamicWindowsDesktopWatcher(ctx, services.DynamicWindowsDesktopWatcherConfig{
DynamicWindowsDesktopGetter: dynamicDesktopClient,
ResourceWatcherConfig: services.ResourceWatcherConfig{
Component: teleport.ComponentWindowsDesktop,
Client: s.cfg.AccessPoint,
},
})
if err != nil {
return nil, trace.Wrap(err)
}

currentResources := make(map[string]types.WindowsDesktop)
var newResources map[string]types.WindowsDesktop

reconciler, err := services.NewReconciler(services.ReconcilerConfig[types.WindowsDesktop]{
Matcher: func(desktop types.WindowsDesktop) bool {
return services.MatchResourceLabels(s.cfg.ResourceMatchers, desktop.GetAllLabels())
},
GetCurrentResources: func() map[string]types.WindowsDesktop {
return currentResources
},
GetNewResources: func() map[string]types.WindowsDesktop {
return newResources
},
OnCreate: s.upsertDesktop,
OnUpdate: s.updateDesktop,
OnDelete: s.deleteDesktop,
})
if err != nil {
return nil, trace.Wrap(err)
}
go func() {
defer s.cfg.Logger.DebugContext(ctx, "DynamicWindowsDesktop resource watcher done.")
defer watcher.Close()
for {
select {
case desktops := <-watcher.DynamicWindowsDesktopsC:
newResources = make(map[string]types.WindowsDesktop)
for _, dynamicDesktop := range desktops {
desktop, err := s.toWindowsDesktop(dynamicDesktop)
if err != nil {
s.cfg.Logger.WarnContext(ctx, "Can't create desktop resource", "error", err)
continue
}
newResources[dynamicDesktop.GetName()] = desktop
}
if err := reconciler.Reconcile(ctx); err != nil {
s.cfg.Logger.WarnContext(ctx, "Reconciliation failed, will retry", "error", err)
continue
}
currentResources = newResources
case <-watcher.Done():
return
case <-ctx.Done():
return
}
}
}()
return watcher, nil
}

func (s *WindowsService) toWindowsDesktop(dynamicDesktop types.DynamicWindowsDesktop) (*types.WindowsDesktopV3, error) {
width, height := dynamicDesktop.GetScreenSize()
desktopLabels := dynamicDesktop.GetAllLabels()
labels := make(map[string]string, len(desktopLabels)+1)
maps.Copy(labels, desktopLabels)
labels[types.OriginLabel] = types.OriginDynamic
return types.NewWindowsDesktopV3(dynamicDesktop.GetName(), labels, types.WindowsDesktopSpecV3{
Addr: dynamicDesktop.GetAddr(),
Domain: dynamicDesktop.GetDomain(),
HostID: s.cfg.Heartbeat.HostUUID,
NonAD: dynamicDesktop.NonAD(),
ScreenSize: &types.Resolution{
Width: width,
Height: height,
},
})
}
Loading

0 comments on commit dc7ac54

Please sign in to comment.