diff --git a/lib/auth/auth.go b/lib/auth/auth.go index 120bc03fb751d..e904471985972 100644 --- a/lib/auth/auth.go +++ b/lib/auth/auth.go @@ -3817,9 +3817,26 @@ func (a *Server) UpsertNode(ctx context.Context, server types.Server) (*types.Ke return lease, nil } +// enforceLicense checks if the license allows the given resource type to be +// created. +func enforceLicense(t string) error { + switch t { + case types.KindKubeServer, types.KindKubernetesCluster: + if !modules.GetModules().Features().Kubernetes { + return trace.AccessDenied( + "this Teleport cluster is not licensed for Kubernetes, please contact the cluster administrator") + } + } + return nil +} + // UpsertKubernetesServer implements [services.Presence] by delegating to // [Server.Services] and then potentially emitting a [usagereporter] event. func (a *Server) UpsertKubernetesServer(ctx context.Context, server types.KubeServer) (*types.KeepAlive, error) { + if err := enforceLicense(types.KindKubeServer); err != nil { + return nil, trace.Wrap(err) + } + k, err := a.Services.UpsertKubernetesServer(ctx, server) if err != nil { return nil, trace.Wrap(err) @@ -4242,6 +4259,9 @@ func (a *Server) ListResources(ctx context.Context, req proto.ListResourcesReque // CreateKubernetesCluster creates a new kubernetes cluster resource. func (a *Server) CreateKubernetesCluster(ctx context.Context, kubeCluster types.KubeCluster) error { + if err := enforceLicense(types.KindKubernetesCluster); err != nil { + return trace.Wrap(err) + } if err := a.Services.CreateKubernetesCluster(ctx, kubeCluster); err != nil { return trace.Wrap(err) } @@ -4266,6 +4286,9 @@ func (a *Server) CreateKubernetesCluster(ctx context.Context, kubeCluster types. // UpdateKubernetesCluster updates an existing kubernetes cluster resource. func (a *Server) UpdateKubernetesCluster(ctx context.Context, kubeCluster types.KubeCluster) error { + if err := enforceLicense(types.KindKubernetesCluster); err != nil { + return trace.Wrap(err) + } if err := a.Kubernetes.UpdateKubernetesCluster(ctx, kubeCluster); err != nil { return trace.Wrap(err) } diff --git a/lib/auth/auth_with_roles.go b/lib/auth/auth_with_roles.go index d6cabbce49db6..bfa15f4b5628f 100644 --- a/lib/auth/auth_with_roles.go +++ b/lib/auth/auth_with_roles.go @@ -1389,6 +1389,17 @@ func (a *ServerWithRoles) ListResources(ctx context.Context, req proto.ListResou if req.ResourceType == kubeService { return &types.ListResourcesResponse{}, nil } + + // Check if auth server has a license for this resource type but only return an + // error if the user is not a builtin proxy or kube role. + // Builtin proxy and kube roles are allowed to list resources to avoid crashes + // even if the license is missing. + // Users with other roles will get an error if the license is missing so they + // can request a license with the correct features. + if err := enforceLicense(req.ResourceType); err != nil && !a.hasBuiltinRole(types.RoleProxy, types.RoleKube) { + return nil, trace.Wrap(err) + } + if req.UseSearchAsRoles || req.UsePreviewAsRoles { var extraRoles []string if req.UseSearchAsRoles { diff --git a/lib/auth/kube.go b/lib/auth/kube.go index 0a843b1049989..b3b9c56d36805 100644 --- a/lib/auth/kube.go +++ b/lib/auth/kube.go @@ -25,7 +25,6 @@ import ( "github.com/gravitational/teleport" apidefaults "github.com/gravitational/teleport/api/defaults" "github.com/gravitational/teleport/api/types" - "github.com/gravitational/teleport/lib/modules" "github.com/gravitational/teleport/lib/services" "github.com/gravitational/teleport/lib/tlsca" ) @@ -64,9 +63,8 @@ type KubeCSRResponse struct { // signed certificate if successful. func (s *Server) ProcessKubeCSR(req KubeCSR) (*KubeCSRResponse, error) { ctx := context.TODO() - if !modules.GetModules().Features().Kubernetes { - return nil, trace.AccessDenied( - "this Teleport cluster is not licensed for Kubernetes, please contact the cluster administrator") + if err := enforceLicense(types.KindKubernetesCluster); err != nil { + return nil, trace.Wrap(err) } if err := req.CheckAndSetDefaults(); err != nil { return nil, trace.Wrap(err) diff --git a/lib/kube/proxy/moderated_sessions_test.go b/lib/kube/proxy/moderated_sessions_test.go index 49603000d7efb..ecc047c4770e9 100644 --- a/lib/kube/proxy/moderated_sessions_test.go +++ b/lib/kube/proxy/moderated_sessions_test.go @@ -44,7 +44,7 @@ import ( func TestModeratedSessions(t *testing.T) { // enable enterprise features to have access to ModeratedSessions. - modules.SetTestModules(t, &modules.TestModules{TestBuildType: modules.BuildEnterprise}) + modules.SetTestModules(t, &modules.TestModules{TestBuildType: modules.BuildEnterprise, TestFeatures: modules.Features{Kubernetes: true}}) const ( moderatorUsername = "moderator_user" moderatorRoleName = "mod_role"