mirror of
https://github.com/gravitational/teleport.git
synced 2026-10-12 02:15:01 +00:00
Remove the auth namespaces REST API (#50999)
Eliminates the namespace CRUD API as part of https://github.com/gravitational/teleport/issues/49509. The most notable change introduce here is with flushCache in the auth helpers. It was ironically using namespaces because they were deprecated, however, it has since been updated to use a role instead. The helpers.go file was also updated not to rely on testify in attempt to prevent it from being included in production builds. Updates https://github.com/gravitational/teleport/issues/6394.
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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{})
|
||||
|
||||
+37
-22
@@ -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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
|
||||
+25
-43
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Vendored
-42
@@ -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")
|
||||
|
||||
Vendored
-65
@@ -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},
|
||||
}
|
||||
|
||||
Vendored
-54
@@ -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
|
||||
|
||||
@@ -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. " +
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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]
|
||||
|
||||
|
||||
@@ -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},
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user