diff --git a/lib/auth/apiserver.go b/lib/auth/apiserver.go index 6c05b49041d..0e220f0b8c8 100644 --- a/lib/auth/apiserver.go +++ b/lib/auth/apiserver.go @@ -144,12 +144,6 @@ func NewAPIServer(config *APIConfig) (http.Handler, error) { // TODO(strideynet): REMOVE IN 18.0.0 - this method is now gRPC srv.POST("/:version/tokens/register", srv.WithAuth(srv.registerUsingToken)) - // Namespaces - srv.POST("/:version/namespaces", srv.WithAuth(srv.upsertNamespace)) - srv.GET("/:version/namespaces", srv.WithAuth(srv.getNamespaces)) - srv.GET("/:version/namespaces/:namespace", srv.WithAuth(srv.getNamespace)) - srv.DELETE("/:version/namespaces/:namespace", srv.WithAuth(srv.deleteNamespace)) - // cluster configuration srv.GET("/:version/configuration/name", srv.WithAuth(srv.getClusterName)) srv.POST("/:version/configuration/name", srv.WithAuth(srv.setClusterName)) @@ -669,55 +663,6 @@ func (s *APIServer) searchSessionEvents(auth *ServerWithRoles, w http.ResponseWr return eventsList, nil } -type upsertNamespaceReq struct { - Namespace types.Namespace `json:"namespace"` -} - -func (s *APIServer) upsertNamespace(auth *ServerWithRoles, w http.ResponseWriter, r *http.Request, p httprouter.Params, version string) (interface{}, error) { - var req *upsertNamespaceReq - if err := httplib.ReadJSON(r, &req); err != nil { - return nil, trace.Wrap(err) - } - if err := auth.UpsertNamespace(req.Namespace); err != nil { - return nil, trace.Wrap(err) - } - return message("ok"), nil -} - -func (s *APIServer) getNamespaces(auth *ServerWithRoles, w http.ResponseWriter, r *http.Request, p httprouter.Params, version string) (interface{}, error) { - namespaces, err := auth.GetNamespaces() - if err != nil { - return nil, trace.Wrap(err) - } - return namespaces, nil -} - -func (s *APIServer) getNamespace(auth *ServerWithRoles, w http.ResponseWriter, r *http.Request, p httprouter.Params, version string) (interface{}, error) { - name := p.ByName("namespace") - if !types.IsValidNamespace(name) { - return nil, trace.BadParameter("invalid namespace %q", name) - } - - namespace, err := auth.GetNamespace(name) - if err != nil { - return nil, trace.Wrap(err) - } - return namespace, nil -} - -func (s *APIServer) deleteNamespace(auth *ServerWithRoles, w http.ResponseWriter, r *http.Request, p httprouter.Params, version string) (interface{}, error) { - name := p.ByName("namespace") - if !types.IsValidNamespace(name) { - return nil, trace.BadParameter("invalid namespace %q", name) - } - - err := auth.DeleteNamespace(name) - if err != nil { - return nil, trace.Wrap(err) - } - return message("ok"), nil -} - func (s *APIServer) getClusterName(auth *ServerWithRoles, w http.ResponseWriter, r *http.Request, p httprouter.Params, version string) (interface{}, error) { cn, err := auth.GetClusterName() if err != nil { diff --git a/lib/auth/auth.go b/lib/auth/auth.go index 641d9e8c0cd..b2375a57159 100644 --- a/lib/auth/auth.go +++ b/lib/auth/auth.go @@ -5065,21 +5065,6 @@ func (a *Server) GetWebSessionInfo(ctx context.Context, user, sessionID string) return sess.WithoutSecrets(), nil } -func (a *Server) DeleteNamespace(namespace string) error { - ctx := context.TODO() - if namespace == apidefaults.Namespace { - return trace.AccessDenied("can't delete default namespace") - } - nodes, err := a.GetNodes(ctx, namespace) - if err != nil { - return trace.Wrap(err) - } - if len(nodes) != 0 { - return trace.BadParameter("can't delete namespace %v that has %v registered nodes", namespace, len(nodes)) - } - return a.Services.DeleteNamespace(namespace) -} - // IterateRoles is a helper used to read a page of roles with a custom matcher, used by access-control logic to handle // per-resource read permissions. func (a *Server) IterateRoles(ctx context.Context, req *proto.ListRolesRequest, match func(*types.RoleV6) (bool, error)) ([]*types.RoleV6, string, error) { diff --git a/lib/auth/auth_test.go b/lib/auth/auth_test.go index b9e9eb0a5aa..6c750684ce1 100644 --- a/lib/auth/auth_test.go +++ b/lib/auth/auth_test.go @@ -194,10 +194,6 @@ func newTestPack( return p, trace.Wrap(err) } - if err := p.a.UpsertNamespace(types.DefaultNamespace()); err != nil { - return p, trace.Wrap(err) - } - return p, nil } diff --git a/lib/auth/auth_with_roles.go b/lib/auth/auth_with_roles.go index 850f99f71bc..fd3fe03e1fd 100644 --- a/lib/auth/auth_with_roles.go +++ b/lib/auth/auth_with_roles.go @@ -4346,38 +4346,6 @@ func (a *ServerWithRoles) findSessionEndEvent(ctx context.Context, sid session.I return nil, trace.NotFound("session end event not found for session ID %q", sid) } -// GetNamespaces returns a list of namespaces -func (a *ServerWithRoles) GetNamespaces() ([]types.Namespace, error) { - if err := a.action(types.KindNamespace, types.VerbList, types.VerbRead); err != nil { - return nil, trace.Wrap(err) - } - return a.authServer.GetNamespaces() -} - -// GetNamespace returns namespace by name -func (a *ServerWithRoles) GetNamespace(name string) (*types.Namespace, error) { - if err := a.action(types.KindNamespace, types.VerbRead); err != nil { - return nil, trace.Wrap(err) - } - return a.authServer.GetNamespace(name) -} - -// UpsertNamespace upserts namespace -func (a *ServerWithRoles) UpsertNamespace(ns types.Namespace) error { - if err := a.action(types.KindNamespace, types.VerbCreate, types.VerbUpdate); err != nil { - return trace.Wrap(err) - } - return a.authServer.UpsertNamespace(ns) -} - -// DeleteNamespace deletes namespace by name -func (a *ServerWithRoles) DeleteNamespace(name string) error { - if err := a.action(types.KindNamespace, types.VerbDelete); err != nil { - return trace.Wrap(err) - } - return a.authServer.DeleteNamespace(name) -} - // GetRoles returns a list of roles func (a *ServerWithRoles) GetRoles(ctx context.Context) ([]types.Role, error) { // delegate all access-control logic to ListRoles, which will eventually diff --git a/lib/auth/authclient/api.go b/lib/auth/authclient/api.go index c59bb595a2a..1776165eaea 100644 --- a/lib/auth/authclient/api.go +++ b/lib/auth/authclient/api.go @@ -145,12 +145,6 @@ type ReadNodeAccessPoint interface { // GetRoles returns a list of roles GetRoles(ctx context.Context) ([]types.Role, error) - // GetNamespaces returns a list of namespaces - GetNamespaces() ([]types.Namespace, error) - - // GetNamespace returns namespace by name - GetNamespace(name string) (*types.Namespace, error) - // GetNetworkRestrictions returns networking restrictions for restricted shell to enforce GetNetworkRestrictions(ctx context.Context) (types.NetworkRestrictions, error) } @@ -209,12 +203,6 @@ type ReadProxyAccessPoint interface { // GetUser returns a services.User for this cluster. GetUser(ctx context.Context, name string, withSecrets bool) (types.User, error) - // GetNamespaces returns a list of namespaces - GetNamespaces() ([]types.Namespace, error) - - // GetNamespace returns namespace by name - GetNamespace(name string) (*types.Namespace, error) - // GetNode returns a node by name and namespace. GetNode(ctx context.Context, namespace, name string) (types.Server, error) @@ -382,12 +370,6 @@ type ReadRemoteProxyAccessPoint interface { // GetRoles returns a list of roles GetRoles(ctx context.Context) ([]types.Role, error) - // GetNamespaces returns a list of namespaces - GetNamespaces() ([]types.Namespace, error) - - // GetNamespace returns namespace by name - GetNamespace(name string) (*types.Namespace, error) - // GetNode returns a node by name and namespace. GetNode(ctx context.Context, namespace, name string) (types.Server, error) @@ -476,12 +458,6 @@ type ReadKubernetesAccessPoint interface { // GetRoles returns a list of roles GetRoles(ctx context.Context) ([]types.Role, error) - // GetNamespaces returns a list of namespaces - GetNamespaces() ([]types.Namespace, error) - - // GetNamespace returns namespace by name - GetNamespace(name string) (*types.Namespace, error) - // GetKubernetesServers returns a list of kubernetes servers registered in the cluster GetKubernetesServers(context.Context) ([]types.KubeServer, error) @@ -555,12 +531,6 @@ type ReadAppsAccessPoint interface { // GetProxies returns a list of proxy servers registered in the cluster GetProxies() ([]types.Server, error) - // GetNamespaces returns a list of namespaces - GetNamespaces() ([]types.Namespace, error) - - // GetNamespace returns namespace by name - GetNamespace(name string) (*types.Namespace, error) - // GetApps returns all application resources. GetApps(ctx context.Context) ([]types.Application, error) @@ -622,12 +592,6 @@ type ReadDatabaseAccessPoint interface { // GetProxies returns a list of proxy servers registered in the cluster GetProxies() ([]types.Server, error) - // GetNamespaces returns a list of namespaces - GetNamespaces() ([]types.Namespace, error) - - // GetNamespace returns namespace by name - GetNamespace(name string) (*types.Namespace, error) - // GetDatabases returns all database resources. GetDatabases(ctx context.Context) ([]types.Database, error) @@ -686,12 +650,6 @@ type ReadWindowsDesktopAccessPoint interface { // GetRoles returns a list of roles GetRoles(ctx context.Context) ([]types.Role, error) - // GetNamespaces returns a list of namespaces - GetNamespaces() ([]types.Namespace, error) - - // GetNamespace returns namespace by name - GetNamespace(name string) (*types.Namespace, error) - // GetWindowsDesktops returns windows desktop hosts. GetWindowsDesktops(ctx context.Context, filter types.WindowsDesktopFilter) ([]types.WindowsDesktop, error) @@ -732,12 +690,6 @@ type ReadDiscoveryAccessPoint interface { // GetClusterName gets the name of the cluster from the backend. GetClusterName(opts ...services.MarshalOption) (types.ClusterName, error) - // GetNamespaces returns a list of namespaces - GetNamespaces() ([]types.Namespace, error) - - // GetNamespace returns namespace by name - GetNamespace(name string) (*types.Namespace, error) - // GetNodes returns a list of registered servers for this cluster. GetNodes(ctx context.Context, namespace string) ([]types.Server, error) // GetKubernetesCluster returns a kubernetes cluster resource identified by name. @@ -998,12 +950,6 @@ type Cache interface { // GetSessionRecordingConfig returns session recording configuration. GetSessionRecordingConfig(ctx context.Context) (types.SessionRecordingConfig, error) - // GetNamespaces returns a list of namespaces - GetNamespaces() ([]types.Namespace, error) - - // GetNamespace returns namespace by name - GetNamespace(name string) (*types.Namespace, error) - // GetNode returns a node by name and namespace. GetNode(ctx context.Context, namespace, name string) (types.Server, error) diff --git a/lib/auth/authclient/http_client.go b/lib/auth/authclient/http_client.go index 5845c6f2022..502fa4f6a8c 100644 --- a/lib/auth/authclient/http_client.go +++ b/lib/auth/authclient/http_client.go @@ -40,7 +40,6 @@ import ( "github.com/gravitational/teleport/lib/defaults" "github.com/gravitational/teleport/lib/httplib" "github.com/gravitational/teleport/lib/services" - "github.com/gravitational/teleport/lib/utils" ) // HTTPClientConfig contains configuration for an HTTP client. @@ -797,47 +796,6 @@ func (c *HTTPClient) ValidateGithubAuthCallback(ctx context.Context, q url.Value return &response, nil } -// GetNamespaces returns a list of namespaces -func (c *HTTPClient) GetNamespaces() ([]types.Namespace, error) { - out, err := c.Get(context.TODO(), c.Endpoint("namespaces"), url.Values{}) - if err != nil { - return nil, trace.Wrap(err) - } - var re []types.Namespace - if err := utils.FastUnmarshal(out.Bytes(), &re); err != nil { - return nil, trace.Wrap(err) - } - return re, nil -} - -// GetNamespace returns namespace by name -func (c *HTTPClient) GetNamespace(name string) (*types.Namespace, error) { - if name == "" { - return nil, trace.BadParameter("missing namespace name") - } - out, err := c.Get(context.TODO(), c.Endpoint("namespaces", name), url.Values{}) - if err != nil { - return nil, trace.Wrap(err) - } - return services.UnmarshalNamespace(out.Bytes()) -} - -type upsertNamespaceReq struct { - Namespace types.Namespace `json:"namespace"` -} - -// UpsertNamespace upserts namespace -func (c *HTTPClient) UpsertNamespace(ns types.Namespace) error { - _, err := c.PostJSON(context.TODO(), c.Endpoint("namespaces"), upsertNamespaceReq{Namespace: ns}) - return trace.Wrap(err) -} - -// DeleteNamespace deletes namespace by name -func (c *HTTPClient) DeleteNamespace(name string) error { - _, err := c.Delete(context.TODO(), c.Endpoint("namespaces", name)) - return trace.Wrap(err) -} - // GetClusterName returns a cluster name func (c *HTTPClient) GetClusterName(opts ...services.MarshalOption) (types.ClusterName, error) { out, err := c.Get(context.TODO(), c.Endpoint("configuration", "name"), url.Values{}) diff --git a/lib/auth/helpers.go b/lib/auth/helpers.go index 58079d47453..8b216f63337 100644 --- a/lib/auth/helpers.go +++ b/lib/auth/helpers.go @@ -31,7 +31,6 @@ import ( "github.com/google/uuid" "github.com/gravitational/trace" "github.com/jonboulle/clockwork" - "github.com/stretchr/testify/require" "go.opentelemetry.io/otel/exporters/otlp/otlptrace" "golang.org/x/crypto/bcrypt" "golang.org/x/crypto/ssh" @@ -1113,11 +1112,11 @@ func (t *TestTLSServer) CloneClient(tt *testing.T, clt *authclient.Client) *auth }, CircuitBreakerConfig: breaker.NoopBreakerConfig(), }) - require.NoError(tt, err) + if err != nil { + tt.Fatalf("error creating auth client: %v", err.Error()) + } - tt.Cleanup(func() { - require.NoError(tt, newClient.Close()) - }) + tt.Cleanup(func() { _ = newClient.Close() }) return newClient } @@ -1458,12 +1457,12 @@ func CreateUserAndRoleWithoutRoles(clt clt, username string, allowedLogins []str // flushClt is the set of methods expected by the flushCache helper. type flushClt interface { - // GetNamespace returns namespace by name - GetNamespace(name string) (*types.Namespace, error) - // UpsertNamespace upserts namespace - UpsertNamespace(types.Namespace) error - // DeleteNamespace deletes namespace by name - DeleteNamespace(name string) error + // GetRole returns role by name + GetRole(ctx context.Context, name string) (types.Role, error) + // CreateRole creates a new role. + CreateRole(context.Context, types.Role) (types.Role, error) + // DeleteRole deletes the role by name. + DeleteRole(ctx context.Context, name string) error } // flushCache is a helper for waiting until preceding changes have propagated to the @@ -1473,19 +1472,35 @@ type flushClt interface { // write events for different keys show up in the order in which the writes were performed, which // is not necessarily true for all backends. func flushCache(t *testing.T, clt flushClt) { + ctx := context.Background() + // the pattern of writing a resource and then waiting for it to appear - // works for any resource type (when using memory backend). we use namespaces - // here because namespaces are deprecated and therefore unlikely to interfer - // with tests. + // works for any resource type (when using memory backend). name := strings.ReplaceAll(uuid.NewString(), "-", "") - defer clt.DeleteNamespace(name) + defer clt.DeleteRole(ctx, name) - ns, err := types.NewNamespace(name) - require.NoError(t, err) + role, err := types.NewRole(name, types.RoleSpecV6{}) + if err != nil { + t.Fatalf("Failed to instantiate new role: %v", err) + } - require.NoError(t, clt.UpsertNamespace(ns)) - require.Eventually(t, func() bool { - _, err := clt.GetNamespace(name) - return err == nil - }, time.Second*20, time.Millisecond*200) + role, err = clt.CreateRole(ctx, role) + if err != nil { + t.Fatalf("Failed to create new role: %v", err) + } + + ctx, cancel := context.WithTimeout(ctx, 20*time.Second) + defer cancel() + for { + r, err := clt.GetRole(ctx, name) + if err == nil && r.GetRevision() == role.GetRevision() { + return + } + + select { + case <-time.After(200 * time.Millisecond): + case <-ctx.Done(): + t.Fatal("Time out waiting for role to be replicated") + } + } } diff --git a/lib/auth/init.go b/lib/auth/init.go index b9fd40f1ed5..3ee5625cf46 100644 --- a/lib/auth/init.go +++ b/lib/auth/init.go @@ -43,7 +43,6 @@ import ( "github.com/gravitational/teleport" "github.com/gravitational/teleport/api/client/proto" - apidefaults "github.com/gravitational/teleport/api/defaults" clusterconfigpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/clusterconfig/v1" dbobjectimportrulev1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/dbobjectimportrule/v1" machineidv1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/machineid/v1" @@ -501,13 +500,6 @@ func initCluster(ctx context.Context, cfg InitConfig, asrv *Server) error { return trace.Wrap(asrv.SetStaticTokens(cfg.StaticTokens)) }) - g.Go(func() error { - _, span := cfg.Tracer.Start(gctx, "auth/SetClusterNamespace") - defer span.End() - asrv.logger.InfoContext(ctx, "Creating namespace", "namespace", apidefaults.Namespace) - return trace.Wrap(asrv.UpsertNamespace(types.DefaultNamespace())) - }) - var cn types.ClusterName g.Go(func() error { _, span := cfg.Tracer.Start(gctx, "auth/SetClusterName") diff --git a/lib/auth/join_ec2.go b/lib/auth/join_ec2.go index ee4ee567b74..376ff47d4c9 100644 --- a/lib/auth/join_ec2.go +++ b/lib/auth/join_ec2.go @@ -40,6 +40,7 @@ import ( "github.com/jonboulle/clockwork" "go.opentelemetry.io/otel" + "github.com/gravitational/teleport/api/defaults" "github.com/gravitational/teleport/api/types" "github.com/gravitational/teleport/lib/services" "github.com/gravitational/teleport/lib/utils" @@ -179,21 +180,15 @@ func checkPendingTime(iid *imds.InstanceIdentityDocument, provisionToken types.P } func nodeExists(ctx context.Context, presence services.Presence, hostID string) (bool, error) { - namespaces, err := presence.GetNamespaces() - if err != nil { + _, err := presence.GetNode(ctx, defaults.Namespace, hostID) + switch { + case trace.IsNotFound(err): + return false, nil + case err != nil: return false, trace.Wrap(err) + default: + return true, nil } - for _, namespace := range namespaces { - _, err := presence.GetNode(ctx, namespace.GetName(), hostID) - if trace.IsNotFound(err) { - continue - } else if err != nil { - return false, trace.Wrap(err) - } else { - return true, nil - } - } - return false, nil } func proxyExists(ctx context.Context, presence services.Presence, hostID string) (bool, error) { @@ -223,59 +218,46 @@ func kubeExists(ctx context.Context, presence services.Presence, hostID string) } func appExists(ctx context.Context, presence services.Presence, hostID string) (bool, error) { - namespaces, err := presence.GetNamespaces() + apps, err := presence.GetApplicationServers(ctx, defaults.Namespace) if err != nil { return false, trace.Wrap(err) } - for _, namespace := range namespaces { - apps, err := presence.GetApplicationServers(ctx, namespace.GetName()) - if err != nil { - return false, trace.Wrap(err) - } - for _, app := range apps { - if app.GetName() == hostID { - return true, nil - } + + for _, app := range apps { + if app.GetName() == hostID { + return true, nil } } + return false, nil } func dbExists(ctx context.Context, presence services.Presence, hostID string) (bool, error) { - namespaces, err := presence.GetNamespaces() + dbs, err := presence.GetDatabaseServers(ctx, defaults.Namespace) if err != nil { return false, trace.Wrap(err) } - for _, namespace := range namespaces { - dbs, err := presence.GetDatabaseServers(ctx, namespace.GetName()) - if err != nil { - return false, trace.Wrap(err) - } - for _, db := range dbs { - if db.GetName() == hostID { - return true, nil - } + + for _, db := range dbs { + if db.GetName() == hostID { + return true, nil } } + return false, nil } func oktaExists(ctx context.Context, presence services.Presence, hostID string) (bool, error) { - namespaces, err := presence.GetNamespaces() + apps, err := presence.GetApplicationServers(ctx, defaults.Namespace) if err != nil { return false, trace.Wrap(err) } - for _, namespace := range namespaces { - apps, err := presence.GetApplicationServers(ctx, namespace.GetName()) - if err != nil { - return false, trace.Wrap(err) - } - for _, app := range apps { - if app.GetName() == hostID && app.Origin() == types.OriginOkta { - return true, nil - } + for _, app := range apps { + if app.GetName() == hostID && app.Origin() == types.OriginOkta { + return true, nil } } + return false, nil } diff --git a/lib/auth/join_ec2_test.go b/lib/auth/join_ec2_test.go index 3bd1e63a566..b396f0c9c77 100644 --- a/lib/auth/join_ec2_test.go +++ b/lib/auth/join_ec2_test.go @@ -805,7 +805,7 @@ func TestHostUniqueCheck(t *testing.T) { // request should fail _, err = a.RegisterUsingToken(ctx, &request) expectedErr := &trace.AccessDeniedError{} - require.ErrorAs(t, err, &expectedErr) + require.ErrorAs(t, err, &expectedErr, err) } }) } diff --git a/lib/cache/cache.go b/lib/cache/cache.go index 1ae68be9715..bd953d4254a 100644 --- a/lib/cache/cache.go +++ b/lib/cache/cache.go @@ -142,7 +142,6 @@ func ForAuth(cfg Config) Config { {Kind: types.KindToken}, {Kind: types.KindUser}, {Kind: types.KindRole}, - {Kind: types.KindNamespace}, {Kind: types.KindNode}, {Kind: types.KindProxy}, {Kind: types.KindAuthServer}, @@ -225,7 +224,6 @@ func ForProxy(cfg Config) Config { {Kind: types.KindUIConfig}, {Kind: types.KindUser}, {Kind: types.KindRole}, - {Kind: types.KindNamespace}, {Kind: types.KindNode}, {Kind: types.KindProxy}, {Kind: types.KindAuthServer}, @@ -277,7 +275,6 @@ func ForRemoteProxy(cfg Config) Config { {Kind: types.KindSessionRecordingConfig}, {Kind: types.KindUser}, {Kind: types.KindRole}, - {Kind: types.KindNamespace}, {Kind: types.KindNode}, {Kind: types.KindProxy}, {Kind: types.KindAuthServer}, @@ -315,10 +312,6 @@ func ForNode(cfg Config) Config { {Kind: types.KindClusterAuthPreference}, {Kind: types.KindSessionRecordingConfig}, {Kind: types.KindRole}, - // Node only needs to "know" about default - // namespace events to avoid matching too much - // data about other namespaces or node events - {Kind: types.KindNamespace, Name: apidefaults.Namespace}, {Kind: types.KindNetworkRestrictions}, {Kind: types.KindStaticHostUser}, } @@ -339,7 +332,6 @@ func ForKubernetes(cfg Config) Config { {Kind: types.KindSessionRecordingConfig}, {Kind: types.KindUser}, {Kind: types.KindRole}, - {Kind: types.KindNamespace, Name: apidefaults.Namespace}, {Kind: types.KindKubeServer}, {Kind: types.KindKubernetesCluster}, {Kind: types.KindKubeWaitingContainer}, @@ -361,9 +353,6 @@ func ForApps(cfg Config) Config { {Kind: types.KindUser}, {Kind: types.KindRole}, {Kind: types.KindProxy}, - // Applications only need to "know" about default namespace events to avoid - // matching too much data about other namespaces or events. - {Kind: types.KindNamespace, Name: apidefaults.Namespace}, {Kind: types.KindApp}, } cfg.QueueSize = defaults.AppsQueueSize @@ -383,9 +372,6 @@ func ForDatabases(cfg Config) Config { {Kind: types.KindUser}, {Kind: types.KindRole}, {Kind: types.KindProxy}, - // Databases only need to "know" about default namespace events to - // avoid matching too much data about other namespaces or events. - {Kind: types.KindNamespace, Name: apidefaults.Namespace}, {Kind: types.KindDatabase}, } cfg.QueueSize = defaults.DatabasesQueueSize @@ -404,7 +390,6 @@ func ForWindowsDesktop(cfg Config) Config { {Kind: types.KindSessionRecordingConfig}, {Kind: types.KindUser}, {Kind: types.KindRole}, - {Kind: types.KindNamespace, Name: apidefaults.Namespace}, {Kind: types.KindWindowsDesktopService}, {Kind: types.KindWindowsDesktop}, {Kind: types.KindDynamicWindowsDesktop}, @@ -419,7 +404,6 @@ func ForDiscovery(cfg Config) Config { cfg.Watches = []types.WatchKind{ {Kind: types.KindCertAuthority, LoadSecrets: false, Filter: makeAllKnownCAsFilter().IntoMap()}, {Kind: types.KindClusterName}, - {Kind: types.KindNamespace, Name: apidefaults.Namespace}, {Kind: types.KindNode}, {Kind: types.KindKubernetesCluster}, {Kind: types.KindKubeServer}, @@ -2178,32 +2162,6 @@ func (c *Cache) GetRole(ctx context.Context, name string) (types.Role, error) { return role, err } -// GetNamespace returns namespace -func (c *Cache) GetNamespace(name string) (*types.Namespace, error) { - _, span := c.Tracer.Start(context.TODO(), "cache/GetNamespace") - defer span.End() - - rg, err := readCollectionCache(c, c.collections.namespaces) - if err != nil { - return nil, trace.Wrap(err) - } - defer rg.Release() - return rg.reader.GetNamespace(name) -} - -// GetNamespaces is a part of auth.Cache implementation -func (c *Cache) GetNamespaces() ([]types.Namespace, error) { - _, span := c.Tracer.Start(context.TODO(), "cache/GetNamespaces") - defer span.End() - - rg, err := readCollectionCache(c, c.collections.namespaces) - if err != nil { - return nil, trace.Wrap(err) - } - defer rg.Release() - return rg.reader.GetNamespaces() -} - // GetNode finds and returns a node by name and namespace. func (c *Cache) GetNode(ctx context.Context, namespace, name string) (types.Server, error) { ctx, span := c.Tracer.Start(ctx, "cache/GetNode") diff --git a/lib/cache/cache_test.go b/lib/cache/cache_test.go index 6819e8742fb..fa37fed634e 100644 --- a/lib/cache/cache_test.go +++ b/lib/cache/cache_test.go @@ -187,10 +187,6 @@ func newPackForAuth(t *testing.T) *testPack { return newTestPack(t, ForAuth) } -func newPackForProxy(t *testing.T) *testPack { - return newTestPack(t, ForProxy) -} - func newTestPack(t *testing.T, setupConfig SetupConfigFn) *testPack { pack, err := newPack(t.TempDir(), setupConfig) require.NoError(t, err) @@ -1604,66 +1600,6 @@ func TestClusterName(t *testing.T) { require.Empty(t, cmp.Diff(outName, clusterName, cmpopts.IgnoreFields(types.Metadata{}, "Revision"))) } -// TestNamespaces tests caching of namespaces -func TestNamespaces(t *testing.T) { - t.Parallel() - - p := newPackForProxy(t) - t.Cleanup(p.Close) - - v, err := types.NewNamespace("universe") - require.NoError(t, err) - ns := &v - err = p.presenceS.UpsertNamespace(*ns) - require.NoError(t, err) - - ns, err = p.presenceS.GetNamespace(ns.GetName()) - require.NoError(t, err) - - select { - case event := <-p.eventsC: - require.Equal(t, EventProcessed, event.Type) - case <-time.After(time.Second): - t.Fatalf("timeout waiting for event") - } - - out, err := p.cache.GetNamespace(ns.GetName()) - require.NoError(t, err) - require.Empty(t, cmp.Diff(ns, out, cmpopts.IgnoreFields(types.Metadata{}, "Revision"))) - - // update namespace metadata - ns.Metadata.Labels = map[string]string{"a": "b"} - require.NoError(t, err) - err = p.presenceS.UpsertNamespace(*ns) - require.NoError(t, err) - - ns, err = p.presenceS.GetNamespace(ns.GetName()) - require.NoError(t, err) - - select { - case event := <-p.eventsC: - require.Equal(t, EventProcessed, event.Type) - case <-time.After(time.Second): - t.Fatalf("timeout waiting for event") - } - - out, err = p.cache.GetNamespace(ns.GetName()) - require.NoError(t, err) - require.Empty(t, cmp.Diff(ns, out, cmpopts.IgnoreFields(types.Metadata{}, "Revision"))) - - err = p.presenceS.DeleteNamespace(ns.GetName()) - require.NoError(t, err) - - select { - case <-p.eventsC: - case <-time.After(time.Second): - t.Fatalf("timeout waiting for event") - } - - _, err = p.cache.GetNamespace(ns.GetName()) - require.True(t, trace.IsNotFound(err)) -} - // TestUsers tests caching of users func TestUsers(t *testing.T) { t.Parallel() @@ -3279,7 +3215,6 @@ func TestRelativeExpiryOnlyForAuth(t *testing.T) { c.Clock = clock c.target = "llama" c.Watches = []types.WatchKind{ - {Kind: types.KindNamespace}, {Kind: types.KindNode}, {Kind: types.KindCertAuthority}, } diff --git a/lib/cache/collections.go b/lib/cache/collections.go index 1af1b2d86d3..a54d23823e3 100644 --- a/lib/cache/collections.go +++ b/lib/cache/collections.go @@ -142,7 +142,6 @@ type cacheCollections struct { staticHostUsers collectionReader[staticHostUserGetter] kubeServers collectionReader[kubeServerGetter] locks collectionReader[services.LockGetter] - namespaces collectionReader[namespaceGetter] networkRestrictions collectionReader[networkRestrictionGetter] oktaAssignments collectionReader[oktaAssignmentGetter] oktaImportRules collectionReader[oktaImportRuleGetter] @@ -302,15 +301,6 @@ func setupCollections(c *Cache, watches []types.WatchKind) (*cacheCollections, e watch: watch, } collections.byKind[resourceKind] = collections.roles - case types.KindNamespace: - if c.Presence == nil { - return nil, trace.BadParameter("missing parameter Presence") - } - collections.namespaces = &genericCollection[*types.Namespace, namespaceGetter, namespaceExecutor]{ - cache: c, - watch: watch, - } - collections.byKind[resourceKind] = collections.namespaces case types.KindNode: if c.Presence == nil { return nil, trace.BadParameter("missing parameter Presence") @@ -1073,50 +1063,6 @@ type nodeGetter interface { var _ executor[types.Server, nodeGetter] = nodeExecutor{} -type namespaceExecutor struct{} - -func (namespaceExecutor) getAll(ctx context.Context, cache *Cache, loadSecrets bool) ([]*types.Namespace, error) { - namespaces, err := cache.Presence.GetNamespaces() - if err != nil { - return nil, trace.Wrap(err) - } - - derefNamespaces := make([]*types.Namespace, len(namespaces)) - for i := range namespaces { - ns := namespaces[i] - derefNamespaces[i] = &ns - } - return derefNamespaces, nil -} - -func (namespaceExecutor) upsert(ctx context.Context, cache *Cache, resource *types.Namespace) error { - return cache.presenceCache.UpsertNamespace(*resource) -} - -func (namespaceExecutor) deleteAll(ctx context.Context, cache *Cache) error { - return cache.presenceCache.DeleteAllNamespaces() -} - -func (namespaceExecutor) delete(ctx context.Context, cache *Cache, resource types.Resource) error { - return cache.presenceCache.DeleteNamespace(resource.GetName()) -} - -func (namespaceExecutor) isSingleton() bool { return false } - -func (namespaceExecutor) getReader(cache *Cache, cacheOK bool) namespaceGetter { - if cacheOK { - return cache.presenceCache - } - return cache.Config.Presence -} - -type namespaceGetter interface { - GetNamespaces() ([]types.Namespace, error) - GetNamespace(name string) (*types.Namespace, error) -} - -var _ executor[*types.Namespace, namespaceGetter] = namespaceExecutor{} - type certAuthorityExecutor struct { // extracted from watch.Filter, to avoid rebuilding on every event filter types.CertAuthorityFilter diff --git a/lib/service/service.go b/lib/service/service.go index 26de170be5d..4d70c019c77 100644 --- a/lib/service/service.go +++ b/lib/service/service.go @@ -2960,14 +2960,6 @@ func (process *TeleportProcess) initSSH() error { "use builtin namespace %q, or omit the 'namespace' config option.", ns, apidefaults.Namespace) } namespace := types.ProcessNamespace(cfg.SSH.Namespace) - _, err = authClient.GetNamespace(namespace) - if err != nil { - if trace.IsNotFound(err) { - return trace.NotFound( - "namespace %v is not found, ask your system administrator to create this namespace so you can register nodes there.", namespace) - } - return trace.Wrap(err) - } if auditd.IsLoginUIDSet() { const warn = "Login UID is set, but it shouldn't be. Incorrect login UID breaks session ID when using auditd. " + diff --git a/lib/services/local/presence.go b/lib/services/local/presence.go index 520eae0f33c..3c24cbecf42 100644 --- a/lib/services/local/presence.go +++ b/lib/services/local/presence.go @@ -62,91 +62,6 @@ func NewPresenceService(b backend.Backend) *PresenceService { } } -// DeleteAllNamespaces deletes all namespaces -func (s *PresenceService) DeleteAllNamespaces() error { - startKey := backend.ExactKey(namespacesPrefix) - endKey := backend.RangeEnd(startKey) - return s.DeleteRange(context.TODO(), startKey, endKey) -} - -// GetNamespaces returns a list of namespaces -func (s *PresenceService) GetNamespaces() ([]types.Namespace, error) { - startKey := backend.ExactKey(namespacesPrefix) - endKey := backend.RangeEnd(startKey) - result, err := s.GetRange(context.TODO(), startKey, endKey, backend.NoLimit) - if err != nil { - return nil, trace.Wrap(err) - } - out := make([]types.Namespace, 0, len(result.Items)) - for _, item := range result.Items { - if !item.Key.HasSuffix(backend.NewKey(paramsPrefix)) { - continue - } - ns, err := services.UnmarshalNamespace( - item.Value, services.WithExpires(item.Expires), services.WithRevision(item.Revision)) - if err != nil { - return nil, trace.Wrap(err) - } - out = append(out, *ns) - } - sort.Sort(types.SortedNamespaces(out)) - return out, nil -} - -// UpsertNamespace upserts namespace -func (s *PresenceService) UpsertNamespace(n types.Namespace) error { - if err := n.CheckAndSetDefaults(); err != nil { - return trace.Wrap(err) - } - rev := n.GetRevision() - value, err := services.MarshalNamespace(n) - if err != nil { - return trace.Wrap(err) - } - item := backend.Item{ - Key: backend.NewKey(namespacesPrefix, n.Metadata.Name, paramsPrefix), - Value: value, - Expires: n.Metadata.Expiry(), - Revision: rev, - } - - _, err = s.Put(context.TODO(), item) - if err != nil { - return trace.Wrap(err) - } - return nil -} - -// GetNamespace returns a namespace by name -func (s *PresenceService) GetNamespace(name string) (*types.Namespace, error) { - if name == "" { - return nil, trace.BadParameter("missing namespace name") - } - item, err := s.Get(context.TODO(), backend.NewKey(namespacesPrefix, name, paramsPrefix)) - if err != nil { - if trace.IsNotFound(err) { - return nil, trace.NotFound("namespace %q is not found", name) - } - return nil, trace.Wrap(err) - } - return services.UnmarshalNamespace( - item.Value, services.WithExpires(item.Expires), services.WithRevision(item.Revision)) -} - -// DeleteNamespace deletes a namespace with all the keys from the backend -func (s *PresenceService) DeleteNamespace(namespace string) error { - if namespace == "" { - return trace.BadParameter("missing namespace name") - } - err := s.Delete(context.TODO(), backend.NewKey(namespacesPrefix, namespace, paramsPrefix)) - if err != nil { - if trace.IsNotFound(err) { - return trace.NotFound("namespace %q is not found", namespace) - } - } - return trace.Wrap(err) -} - // GetServerInfos returns a stream of ServerInfos. func (s *PresenceService) GetServerInfos(ctx context.Context) stream.Stream[types.ServerInfo] { startKey := backend.ExactKey(serverInfoPrefix) diff --git a/lib/services/presence.go b/lib/services/presence.go index 83bf8aa211d..ea760f31aa8 100644 --- a/lib/services/presence.go +++ b/lib/services/presence.go @@ -126,21 +126,6 @@ type Presence interface { // ListReverseTunnels returns a page of ReverseTunnels. ListReverseTunnels(ctx context.Context, pageSize int, pageToken string) ([]types.ReverseTunnel, string, error) - // GetNamespaces returns a list of namespaces - GetNamespaces() ([]types.Namespace, error) - - // GetNamespace returns namespace by name - GetNamespace(name string) (*types.Namespace, error) - - // DeleteAllNamespaces deletes all namespaces - DeleteAllNamespaces() error - - // UpsertNamespace upserts namespace - UpsertNamespace(types.Namespace) error - - // DeleteNamespace deletes namespace by name - DeleteNamespace(name string) error - // GetServerInfos returns a stream of ServerInfos. GetServerInfos(ctx context.Context) stream.Stream[types.ServerInfo] diff --git a/lib/services/suite/suite.go b/lib/services/suite/suite.go index 3c1a4454801..b94881b5942 100644 --- a/lib/services/suite/suite.go +++ b/lib/services/suite/suite.go @@ -833,32 +833,6 @@ func (s *ServicesTestSuite) RolesCRUD(t *testing.T) { require.True(t, trace.IsNotFound(err)) } -func (s *ServicesTestSuite) NamespacesCRUD(t *testing.T) { - out, err := s.PresenceS.GetNamespaces() - require.NoError(t, err) - require.Empty(t, out) - - ns := types.Namespace{ - Kind: types.KindNamespace, - Version: types.V2, - Metadata: types.Metadata{ - Name: apidefaults.Namespace, - Namespace: apidefaults.Namespace, - }, - } - err = s.PresenceS.UpsertNamespace(ns) - require.NoError(t, err) - nsout, err := s.PresenceS.GetNamespace(ns.Metadata.Name) - require.NoError(t, err) - require.Empty(t, cmp.Diff(nsout, &ns)) - - err = s.PresenceS.DeleteNamespace(ns.Metadata.Name) - require.NoError(t, err) - - _, err = s.PresenceS.GetNamespace(ns.Metadata.Name) - require.True(t, trace.IsNotFound(err)) -} - func (s *ServicesTestSuite) SAMLCRUD(t *testing.T) { ctx := context.Background() connector := &types.SAMLConnectorV2{ @@ -1714,32 +1688,6 @@ func (s *ServicesTestSuite) Events(t *testing.T) { return token }, }, - { - name: "Namespace", - kind: types.WatchKind{ - Kind: types.KindNamespace, - }, - crud: func(context.Context) types.Resource { - ns := types.Namespace{ - Kind: types.KindNamespace, - Version: types.V2, - Metadata: types.Metadata{ - Name: "testnamespace", - Namespace: apidefaults.Namespace, - }, - } - err := s.PresenceS.UpsertNamespace(ns) - require.NoError(t, err) - - out, err := s.PresenceS.GetNamespace(ns.Metadata.Name) - require.NoError(t, err) - - err = s.PresenceS.DeleteNamespace(ns.Metadata.Name) - require.NoError(t, err) - - return out - }, - }, { name: "Static tokens", kind: types.WatchKind{ @@ -1927,38 +1875,6 @@ func (s *ServicesTestSuite) Events(t *testing.T) { AllowPartialSuccess: true, }) - // Namespace with a name - testCases = []eventTest{ - { - name: "Namespace with a name", - kind: types.WatchKind{ - Kind: types.KindNamespace, - Name: "shmest", - }, - crud: func(context.Context) types.Resource { - ns := types.Namespace{ - Kind: types.KindNamespace, - Version: types.V2, - Metadata: types.Metadata{ - Name: "shmest", - Namespace: apidefaults.Namespace, - }, - } - err := s.PresenceS.UpsertNamespace(ns) - require.NoError(t, err) - - out, err := s.PresenceS.GetNamespace(ns.Metadata.Name) - require.NoError(t, err) - - err = s.PresenceS.DeleteNamespace(ns.Metadata.Name) - require.NoError(t, err) - - return out - }, - }, - } - s.runEventsTests(t, testCases, types.Watch{Kinds: eventsTestKinds(testCases)}) - // tests that a watch fails given an unknown kind when the partial success mode is not enabled s.runUnknownEventsTest(t, types.Watch{Kinds: []types.WatchKind{ {Kind: types.KindNamespace}, diff --git a/lib/web/apiserver.go b/lib/web/apiserver.go index ae9196bcc1e..9a80c33c2e4 100644 --- a/lib/web/apiserver.go +++ b/lib/web/apiserver.go @@ -2954,16 +2954,8 @@ type getSiteNamespacesResponse struct { // // {"namespaces": [{..namespace resource...}]} func (h *Handler) getSiteNamespaces(w http.ResponseWriter, r *http.Request, _ httprouter.Params, c *SessionContext, site reversetunnelclient.RemoteSite) (interface{}, error) { - clt, err := site.GetClient() - if err != nil { - return nil, trace.Wrap(err) - } - namespaces, err := clt.GetNamespaces() - if err != nil { - return nil, trace.Wrap(err) - } return getSiteNamespacesResponse{ - Namespaces: namespaces, + Namespaces: []types.Namespace{types.DefaultNamespace()}, }, nil } diff --git a/tool/tctl/common/resource_command.go b/tool/tctl/common/resource_command.go index 14d08bd9712..6229be8fc6b 100644 --- a/tool/tctl/common/resource_command.go +++ b/tool/tctl/common/resource_command.go @@ -2360,18 +2360,7 @@ func (rc *ResourceCommand) getCollection(ctx context.Context, client *authclient warnAboutDynamicLabelsInDenyRule(ctx, rc.config.Logger, role) return &roleCollection{roles: []types.Role{role}}, nil case types.KindNamespace: - if rc.ref.Name == "" { - namespaces, err := client.GetNamespaces() - if err != nil { - return nil, trace.Wrap(err) - } - return &namespaceCollection{namespaces: namespaces}, nil - } - ns, err := client.GetNamespace(rc.ref.Name) - if err != nil { - return nil, trace.Wrap(err) - } - return &namespaceCollection{namespaces: []types.Namespace{*ns}}, nil + return &namespaceCollection{namespaces: []types.Namespace{types.DefaultNamespace()}}, nil case types.KindTrustedCluster: if rc.ref.Name == "" { trustedClusters, err := client.GetTrustedClusters(ctx)