From f71301e43a030990a493fd62debf99378705ca19 Mon Sep 17 00:00:00 2001 From: Tim Ross Date: Mon, 18 Oct 2021 14:54:34 -0400 Subject: [PATCH] fully refactor out auth.AccessPoint and auth.ReadAccessPoint --- lib/auth/api.go | 462 +++++++++++++++--------------- lib/auth/auth.go | 26 +- lib/cache/cache.go | 30 +- lib/client/api.go | 12 - lib/client/client.go | 6 +- lib/reversetunnel/localsite.go | 2 +- lib/reversetunnel/srv.go | 8 +- lib/service/service.go | 106 +++++-- lib/srv/ctx.go | 4 +- lib/srv/forward/sshserver.go | 2 +- lib/srv/regular/sshserver_test.go | 2 +- lib/web/apiserver_test.go | 2 +- 12 files changed, 352 insertions(+), 310 deletions(-) diff --git a/lib/auth/api.go b/lib/auth/api.go index a4b2bc8515b8f..62293e8594a99 100644 --- a/lib/auth/api.go +++ b/lib/auth/api.go @@ -22,11 +22,8 @@ import ( "github.com/gravitational/teleport/api/client/proto" "github.com/gravitational/teleport/api/types" - apievents "github.com/gravitational/teleport/api/types/events" "github.com/gravitational/teleport/lib/events" "github.com/gravitational/teleport/lib/services" - "github.com/gravitational/teleport/lib/session" - "github.com/gravitational/trace" ) @@ -71,144 +68,6 @@ type Announcer interface { UpdateWindowsDesktop(context.Context, types.WindowsDesktop) error } -// ReadAccessPoint is a read only API interface implemented by a certificate authority (CA). -// -// NOTE: This should not be used directly. The component specific interfaces should be used instead. -type ReadAccessPoint interface { - // Closer closes all the resources - io.Closer - - // NewWatcher returns a new event watcher. - NewWatcher(ctx context.Context, watch types.Watch) (types.Watcher, error) - - // GetReverseTunnels returns a list of reverse tunnels - GetReverseTunnels(opts ...services.MarshalOption) ([]types.ReverseTunnel, error) - - // GetClusterName returns cluster name - GetClusterName(opts ...services.MarshalOption) (types.ClusterName, error) - - // GetClusterAuditConfig returns cluster audit configuration. - GetClusterAuditConfig(ctx context.Context, opts ...services.MarshalOption) (types.ClusterAuditConfig, error) - - // GetClusterNetworkingConfig returns cluster networking configuration. - GetClusterNetworkingConfig(ctx context.Context, opts ...services.MarshalOption) (types.ClusterNetworkingConfig, error) - - // GetAuthPreference returns the cluster authentication configuration. - GetAuthPreference(ctx context.Context) (types.AuthPreference, error) - - // GetSessionRecordingConfig returns session recording configuration. - GetSessionRecordingConfig(ctx context.Context, opts ...services.MarshalOption) (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) - - // GetNodes returns a list of registered servers for this cluster. - GetNodes(ctx context.Context, namespace string, opts ...services.MarshalOption) ([]types.Server, error) - - // ListNodes returns a paginated list of registered servers for this cluster. - ListNodes(ctx context.Context, req proto.ListNodesRequest) (nodes []types.Server, nextKey string, err error) - - // GetProxies returns a list of proxy servers registered in the cluster - GetProxies() ([]types.Server, error) - - // GetAuthServers returns a list of auth servers registered in the cluster - GetAuthServers() ([]types.Server, error) - - // GetCertAuthority returns cert authority by id - GetCertAuthority(id types.CertAuthID, loadKeys bool, opts ...services.MarshalOption) (types.CertAuthority, error) - - // GetCertAuthorities returns a list of cert authorities - GetCertAuthorities(caType types.CertAuthType, loadKeys bool, opts ...services.MarshalOption) ([]types.CertAuthority, error) - - // GetUser returns a services.User for this cluster. - GetUser(name string, withSecrets bool) (types.User, error) - - // GetUsers returns a list of local users registered with this domain - GetUsers(withSecrets bool) ([]types.User, error) - - // GetRole returns role by name - GetRole(ctx context.Context, name string) (types.Role, error) - - // GetRoles returns a list of roles - GetRoles(ctx context.Context) ([]types.Role, error) - - // GetAllTunnelConnections returns all tunnel connections - GetAllTunnelConnections(opts ...services.MarshalOption) ([]types.TunnelConnection, error) - - // GetTunnelConnections returns tunnel connections for a given cluster - GetTunnelConnections(clusterName string, opts ...services.MarshalOption) ([]types.TunnelConnection, error) - - // GetAppServers gets all application servers. - // - // DELETE IN 9.0. Deprecated, use GetApplicationServers. - GetAppServers(ctx context.Context, namespace string, opts ...services.MarshalOption) ([]types.Server, error) - - // GetApps returns all application resources. - GetApps(ctx context.Context) ([]types.Application, error) - - // GetApp returns the specified application resource. - GetApp(ctx context.Context, name string) (types.Application, error) - - // GetApplicationServers returns all registered application servers. - GetApplicationServers(ctx context.Context, namespace string) ([]types.AppServer, error) - - // GetAppSession gets an application web session. - GetAppSession(context.Context, types.GetAppSessionRequest) (types.WebSession, error) - - // GetWebSession gets a web session for the given request - GetWebSession(context.Context, types.GetWebSessionRequest) (types.WebSession, error) - - // GetWebToken gets a web token for the given request - GetWebToken(context.Context, types.GetWebTokenRequest) (types.WebToken, error) - - // GetRemoteClusters returns a list of remote clusters - GetRemoteClusters(opts ...services.MarshalOption) ([]types.RemoteCluster, error) - - // GetRemoteCluster returns a remote cluster by name - GetRemoteCluster(clusterName string) (types.RemoteCluster, error) - - // GetKubeServices returns a list of kubernetes services registered in the cluster - GetKubeServices(context.Context) ([]types.Server, error) - - // GetDatabaseServers returns all registered database proxy servers. - GetDatabaseServers(ctx context.Context, namespace string, opts ...services.MarshalOption) ([]types.DatabaseServer, error) - - // GetDatabases returns all database resources. - GetDatabases(ctx context.Context) ([]types.Database, error) - - // GetDatabase returns the specified database resource. - GetDatabase(ctx context.Context, name string) (types.Database, error) - - // GetNetworkRestrictions returns networking restrictions for restricted shell to enforce - GetNetworkRestrictions(ctx context.Context) (types.NetworkRestrictions, error) - - // GetWindowsDesktops returns windows desktop hosts. - GetWindowsDesktops(ctx context.Context) ([]types.WindowsDesktop, error) - - // GetWindowsDesktop returns a named windows desktop host. - GetWindowsDesktop(ctx context.Context, name string) (types.WindowsDesktop, error) - - // GetWindowsDesktopServices returns windows desktop hosts. - GetWindowsDesktopServices(ctx context.Context) ([]types.WindowsDesktopService, error) -} - -// AccessPoint is an API interface implemented by a certificate authority (CA) -// -// NOTE: This should not be used directly. The component specific interfaces should be used instead. -type AccessPoint interface { - // ReadAccessPoint provides methods to read data - ReadAccessPoint - - // accessPoint provides common access point functionality - accessPoint -} - // accessPoint is an API interface implemented by a certificate authority (CA) type accessPoint interface { // Announcer adds methods used to announce presence @@ -801,7 +660,127 @@ type AccessCache interface { // Cache is a subset of the auth interface handling // access to the discovery API and static tokens type Cache interface { - ReadAccessPoint + // Closer closes all the resources + io.Closer + + // NewWatcher returns a new event watcher. + NewWatcher(ctx context.Context, watch types.Watch) (types.Watcher, error) + + // GetReverseTunnels returns a list of reverse tunnels + GetReverseTunnels(opts ...services.MarshalOption) ([]types.ReverseTunnel, error) + + // GetClusterName returns cluster name + GetClusterName(opts ...services.MarshalOption) (types.ClusterName, error) + + // GetClusterAuditConfig returns cluster audit configuration. + GetClusterAuditConfig(ctx context.Context, opts ...services.MarshalOption) (types.ClusterAuditConfig, error) + + // GetClusterNetworkingConfig returns cluster networking configuration. + GetClusterNetworkingConfig(ctx context.Context, opts ...services.MarshalOption) (types.ClusterNetworkingConfig, error) + + // GetAuthPreference returns the cluster authentication configuration. + GetAuthPreference(ctx context.Context) (types.AuthPreference, error) + + // GetSessionRecordingConfig returns session recording configuration. + GetSessionRecordingConfig(ctx context.Context, opts ...services.MarshalOption) (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) + + // GetNodes returns a list of registered servers for this cluster. + GetNodes(ctx context.Context, namespace string, opts ...services.MarshalOption) ([]types.Server, error) + + // ListNodes returns a paginated list of registered servers for this cluster. + ListNodes(ctx context.Context, namespace string, limit int, startKey string) (nodes []types.Server, nextKey string, err error) + + // GetProxies returns a list of proxy servers registered in the cluster + GetProxies() ([]types.Server, error) + + // GetAuthServers returns a list of auth servers registered in the cluster + GetAuthServers() ([]types.Server, error) + + // GetCertAuthority returns cert authority by id + GetCertAuthority(id types.CertAuthID, loadKeys bool, opts ...services.MarshalOption) (types.CertAuthority, error) + + // GetCertAuthorities returns a list of cert authorities + GetCertAuthorities(caType types.CertAuthType, loadKeys bool, opts ...services.MarshalOption) ([]types.CertAuthority, error) + + // GetUser returns a services.User for this cluster. + GetUser(name string, withSecrets bool) (types.User, error) + + // GetUsers returns a list of local users registered with this domain + GetUsers(withSecrets bool) ([]types.User, error) + + // GetRole returns role by name + GetRole(ctx context.Context, name string) (types.Role, error) + + // GetRoles returns a list of roles + GetRoles(ctx context.Context) ([]types.Role, error) + + // GetAllTunnelConnections returns all tunnel connections + GetAllTunnelConnections(opts ...services.MarshalOption) ([]types.TunnelConnection, error) + + // GetTunnelConnections returns tunnel connections for a given cluster + GetTunnelConnections(clusterName string, opts ...services.MarshalOption) ([]types.TunnelConnection, error) + + // GetAppServers gets all application servers. + // + // DELETE IN 9.0. Deprecated, use GetApplicationServers. + GetAppServers(ctx context.Context, namespace string, opts ...services.MarshalOption) ([]types.Server, error) + + // GetApps returns all application resources. + GetApps(ctx context.Context) ([]types.Application, error) + + // GetApp returns the specified application resource. + GetApp(ctx context.Context, name string) (types.Application, error) + + // GetApplicationServers returns all registered application servers. + GetApplicationServers(ctx context.Context, namespace string) ([]types.AppServer, error) + + // GetAppSession gets an application web session. + GetAppSession(context.Context, types.GetAppSessionRequest) (types.WebSession, error) + + // GetWebSession gets a web session for the given request + GetWebSession(context.Context, types.GetWebSessionRequest) (types.WebSession, error) + + // GetWebToken gets a web token for the given request + GetWebToken(context.Context, types.GetWebTokenRequest) (types.WebToken, error) + + // GetRemoteClusters returns a list of remote clusters + GetRemoteClusters(opts ...services.MarshalOption) ([]types.RemoteCluster, error) + + // GetRemoteCluster returns a remote cluster by name + GetRemoteCluster(clusterName string) (types.RemoteCluster, error) + + // GetKubeServices returns a list of kubernetes services registered in the cluster + GetKubeServices(context.Context) ([]types.Server, error) + + // GetDatabaseServers returns all registered database proxy servers. + GetDatabaseServers(ctx context.Context, namespace string, opts ...services.MarshalOption) ([]types.DatabaseServer, error) + + // GetDatabases returns all database resources. + GetDatabases(ctx context.Context) ([]types.Database, error) + + // GetDatabase returns the specified database resource. + GetDatabase(ctx context.Context, name string) (types.Database, error) + + // GetNetworkRestrictions returns networking restrictions for restricted shell to enforce + GetNetworkRestrictions(ctx context.Context) (types.NetworkRestrictions, error) + + // GetWindowsDesktops returns windows desktop hosts. + GetWindowsDesktops(ctx context.Context) ([]types.WindowsDesktop, error) + + // GetWindowsDesktop returns a named windows desktop host. + GetWindowsDesktop(ctx context.Context, name string) (types.WindowsDesktop, error) + + // GetWindowsDesktopServices returns windows desktop hosts. + GetWindowsDesktopServices(ctx context.Context) ([]types.WindowsDesktopService, error) // GetStaticTokens gets the list of static tokens used to provision nodes. GetStaticTokens() (types.StaticTokens, error) @@ -824,149 +803,158 @@ type Cache interface { // cache, the other Teleport components should make use of // services.LockWatcher that provides the necessary freshness guarantees. GetLocks(ctx context.Context, inForceOnly bool, targets ...types.LockTarget) ([]types.Lock, error) - - // NewWatcher returns a new event watcher - NewWatcher(ctx context.Context, watch types.Watch) (types.Watcher, error) -} - -// NewWrapper returns new access point wrapper -func NewWrapper(base AccessPoint, cache ReadAccessPoint) AccessPoint { - return &Wrapper{ - NoCache: base, - ReadAccessPoint: cache, - } } -// Wrapper wraps access point and auth cache in one client -// so that reads of cached values can be intercepted. -type Wrapper struct { - ReadAccessPoint - NoCache AccessPoint -} - -// ResumeAuditStream resumes existing audit stream -func (w *Wrapper) ResumeAuditStream(ctx context.Context, sid session.ID, uploadID string) (apievents.Stream, error) { - return w.NoCache.ResumeAuditStream(ctx, sid, uploadID) +type NodeWrapper struct { + ReadNodeAccessPoint + accessPoint + NoCache NodeAccessPoint } -// CreateAuditStream creates new audit stream -func (w *Wrapper) CreateAuditStream(ctx context.Context, sid session.ID) (apievents.Stream, error) { - return w.NoCache.CreateAuditStream(ctx, sid) +func NewNodeWrapper(base NodeAccessPoint, cache ReadNodeAccessPoint) NodeAccessPoint { + return &NodeWrapper{ + NoCache: base, + accessPoint: base, + ReadNodeAccessPoint: cache, + } } // Close closes all associated resources -func (w *Wrapper) Close() error { +func (w *NodeWrapper) Close() error { err := w.NoCache.Close() - err2 := w.ReadAccessPoint.Close() + err2 := w.ReadNodeAccessPoint.Close() return trace.NewAggregate(err, err2) } -// UpsertNode is part of auth.AccessPoint implementation -func (w *Wrapper) UpsertNode(ctx context.Context, s types.Server) (*types.KeepAlive, error) { - return w.NoCache.UpsertNode(ctx, s) -} - -// UpsertAuthServer is part of auth.AccessPoint implementation -func (w *Wrapper) UpsertAuthServer(s types.Server) error { - return w.NoCache.UpsertAuthServer(s) +type ProxyWrapper struct { + ReadProxyAccessPoint + accessPoint + NoCache ProxyAccessPoint } -// NewKeepAliver returns a new instance of keep aliver -func (w *Wrapper) NewKeepAliver(ctx context.Context) (types.KeepAliver, error) { - return w.NoCache.NewKeepAliver(ctx) +func NewProxyWrapper(base ProxyAccessPoint, cache ReadProxyAccessPoint) ProxyAccessPoint { + return &ProxyWrapper{ + NoCache: base, + accessPoint: base, + ReadProxyAccessPoint: cache, + } } -// UpsertProxy is part of auth.AccessPoint implementation -func (w *Wrapper) UpsertProxy(s types.Server) error { - return w.NoCache.UpsertProxy(s) +// Close closes all associated resources +func (w *ProxyWrapper) Close() error { + err := w.NoCache.Close() + err2 := w.ReadProxyAccessPoint.Close() + return trace.NewAggregate(err, err2) } -// UpsertTunnelConnection is a part of auth.AccessPoint implementation -func (w *Wrapper) UpsertTunnelConnection(conn types.TunnelConnection) error { - return w.NoCache.UpsertTunnelConnection(conn) +type RemoteProxyWrapper struct { + ReadRemoteProxyAccessPoint + accessPoint + NoCache RemoteProxyAccessPoint } -// DeleteTunnelConnection is a part of auth.AccessPoint implementation -func (w *Wrapper) DeleteTunnelConnection(clusterName, connName string) error { - return w.NoCache.DeleteTunnelConnection(clusterName, connName) +func NewRemoteProxyWrapper(base RemoteProxyAccessPoint, cache ReadRemoteProxyAccessPoint) RemoteProxyAccessPoint { + return &RemoteProxyWrapper{ + NoCache: base, + accessPoint: base, + ReadRemoteProxyAccessPoint: cache, + } } -// AcquireSemaphore acquires lease with requested resources from semaphore -func (w *Wrapper) AcquireSemaphore(ctx context.Context, params types.AcquireSemaphoreRequest) (*types.SemaphoreLease, error) { - return w.NoCache.AcquireSemaphore(ctx, params) +// Close closes all associated resources +func (w *RemoteProxyWrapper) Close() error { + err := w.NoCache.Close() + err2 := w.ReadRemoteProxyAccessPoint.Close() + return trace.NewAggregate(err, err2) } -// KeepAliveSemaphoreLease updates semaphore lease -func (w *Wrapper) KeepAliveSemaphoreLease(ctx context.Context, lease types.SemaphoreLease) error { - return w.NoCache.KeepAliveSemaphoreLease(ctx, lease) +type KubernetesWrapper struct { + ReadKubernetesAccessPoint + accessPoint + NoCache KubernetesAccessPoint } -// CancelSemaphoreLease cancels semaphore lease early -func (w *Wrapper) CancelSemaphoreLease(ctx context.Context, lease types.SemaphoreLease) error { - return w.NoCache.CancelSemaphoreLease(ctx, lease) +func NewKubernetesWrapper(base KubernetesAccessPoint, cache ReadKubernetesAccessPoint) KubernetesAccessPoint { + return &KubernetesWrapper{ + NoCache: base, + accessPoint: base, + ReadKubernetesAccessPoint: cache, + } } -// GetSemaphores returns a list of semaphores matching supplied filter. -func (w *Wrapper) GetSemaphores(ctx context.Context, filter types.SemaphoreFilter) ([]types.Semaphore, error) { - return w.NoCache.GetSemaphores(ctx, filter) +// Close closes all associated resources +func (w *KubernetesWrapper) Close() error { + err := w.NoCache.Close() + err2 := w.ReadKubernetesAccessPoint.Close() + return trace.NewAggregate(err, err2) } -// DeleteSemaphore deletes a semaphore matching supplied filter. -func (w *Wrapper) DeleteSemaphore(ctx context.Context, filter types.SemaphoreFilter) error { - return w.NoCache.DeleteSemaphore(ctx, filter) +type DatabaseWrapper struct { + ReadDatabaseAccessPoint + accessPoint + NoCache DatabaseAccessPoint } -// UpsertKubeService is part of auth.AccessPoint implementation -func (w *Wrapper) UpsertKubeService(ctx context.Context, s types.Server) error { - return w.NoCache.UpsertKubeService(ctx, s) +func NewDatabaseWrapper(base DatabaseAccessPoint, cache ReadDatabaseAccessPoint) DatabaseAccessPoint { + return &DatabaseWrapper{ + NoCache: base, + accessPoint: base, + ReadDatabaseAccessPoint: cache, + } } -// UpsertAppServer adds an application server. -// -// DELETE IN 9.0. Deprecated, use UpsertAppServer. -func (w *Wrapper) UpsertAppServer(ctx context.Context, server types.Server) (*types.KeepAlive, error) { - return w.NoCache.UpsertAppServer(ctx, server) +// Close closes all associated resources +func (w *DatabaseWrapper) Close() error { + err := w.NoCache.Close() + err2 := w.ReadDatabaseAccessPoint.Close() + return trace.NewAggregate(err, err2) } -// UpsertApplicationServer registers an application server. -func (w *Wrapper) UpsertApplicationServer(ctx context.Context, server types.AppServer) (*types.KeepAlive, error) { - return w.NoCache.UpsertApplicationServer(ctx, server) +type AppsWrapper struct { + ReadAppsAccessPoint + accessPoint + NoCache AppsAccessPoint } -// UpsertDatabaseServer registers a database proxy server. -func (w *Wrapper) UpsertDatabaseServer(ctx context.Context, server types.DatabaseServer) (*types.KeepAlive, error) { - return w.NoCache.UpsertDatabaseServer(ctx, server) +func NewAppsWrapper(base AppsAccessPoint, cache ReadAppsAccessPoint) AppsAccessPoint { + return &AppsWrapper{ + NoCache: base, + accessPoint: base, + ReadAppsAccessPoint: cache, + } } -// UpsertWindowsDesktopService registers a Windows desktop service. -func (w *Wrapper) UpsertWindowsDesktopService(ctx context.Context, s types.WindowsDesktopService) (*types.KeepAlive, error) { - return w.NoCache.UpsertWindowsDesktopService(ctx, s) +// Close closes all associated resources +func (w *AppsWrapper) Close() error { + err := w.NoCache.Close() + err2 := w.ReadAppsAccessPoint.Close() + return trace.NewAggregate(err, err2) } -// CreateWindowsDesktop registers a Windows desktop host. -func (w *Wrapper) CreateWindowsDesktop(ctx context.Context, d types.WindowsDesktop) error { - return w.NoCache.CreateWindowsDesktop(ctx, d) +type WindowsDesktopWrapper struct { + ReadWindowsDesktopAccessPoint + accessPoint + NoCache WindowsDesktopAccessPoint } -// UpdateWindowsDesktop updates a Windows desktop host. -func (w *Wrapper) UpdateWindowsDesktop(ctx context.Context, d types.WindowsDesktop) error { - return w.NoCache.UpdateWindowsDesktop(ctx, d) +func NewWindowsDesktopWrapper(base WindowsDesktopAccessPoint, cache ReadWindowsDesktopAccessPoint) WindowsDesktopAccessPoint { + return &WindowsDesktopWrapper{ + NoCache: base, + accessPoint: base, + ReadWindowsDesktopAccessPoint: cache, + } } -// GenerateCertAuthorityCRL generates an empty CRL for a CA. -func (w *Wrapper) GenerateCertAuthorityCRL(ctx context.Context, caType types.CertAuthType) ([]byte, error) { - crl, err := w.NoCache.GenerateCertAuthorityCRL(ctx, caType) - return crl, trace.Wrap(err) +// Close closes all associated resources +func (w *WindowsDesktopWrapper) Close() error { + err := w.NoCache.Close() + err2 := w.ReadWindowsDesktopAccessPoint.Close() + return trace.NewAggregate(err, err2) } -// NewCachingAccessPoint returns new caching access point using +// NewRemoteProxyCachingAccessPoint returns new caching access point using // access point policy -type NewCachingAccessPoint func(clt ClientI, cacheName []string) (RemoteProxyAccessPoint, error) - -// NoCache is a no cache used for access point -func NoCache(clt ClientI, cacheName []string) (AccessPoint, error) { - return clt, nil -} +type NewRemoteProxyCachingAccessPoint func(clt ClientI, cacheName []string) (RemoteProxyAccessPoint, error) // notImplementedMessage is the message to return for endpoints that are not // implemented. This is due to how service interfaces are used with Teleport. diff --git a/lib/auth/auth.go b/lib/auth/auth.go index c04b9d6e13ba4..ea0341cdaac00 100644 --- a/lib/auth/auth.go +++ b/lib/auth/auth.go @@ -2688,32 +2688,32 @@ func (a *Server) GetToken(ctx context.Context, token string) (types.ProvisionTok return a.GetCache().GetToken(ctx, token) } -// GetRoles is a part of auth.AccessPoint implementation +// GetRoles returns roles from the cache func (a *Server) GetRoles(ctx context.Context) ([]types.Role, error) { return a.GetCache().GetRoles(ctx) } -// GetRole is a part of auth.AccessPoint implementation +// GetRole returns a role from the cache func (a *Server) GetRole(ctx context.Context, name string) (types.Role, error) { return a.GetCache().GetRole(ctx, name) } -// GetNamespace returns namespace +// GetNamespace returns a namespace from the cache func (a *Server) GetNamespace(name string) (*types.Namespace, error) { return a.GetCache().GetNamespace(name) } -// GetNamespaces is a part of auth.AccessPoint implementation +// GetNamespaces returns namespaces from the cache func (a *Server) GetNamespaces() ([]types.Namespace, error) { return a.GetCache().GetNamespaces() } -// GetNodes is a part of auth.AccessPoint implementation +// GetNodes returns nodes from the cache func (a *Server) GetNodes(ctx context.Context, namespace string, opts ...services.MarshalOption) ([]types.Server, error) { return a.GetCache().GetNodes(ctx, namespace, opts...) } -// ListNodes is a part of auth.AccessPoint implementation +// ListNodes lists nodes from the cache func (a *Server) ListNodes(ctx context.Context, req proto.ListNodesRequest) ([]types.Server, string, error) { return a.GetCache().ListNodes(ctx, req) } @@ -2744,34 +2744,32 @@ func (a *Server) IterateNodePages(ctx context.Context, req proto.ListNodesReques } } -// GetReverseTunnels is a part of auth.AccessPoint implementation +// GetReverseTunnels returns reverse tunnels from the cache func (a *Server) GetReverseTunnels(opts ...services.MarshalOption) ([]types.ReverseTunnel, error) { return a.GetCache().GetReverseTunnels(opts...) } -// GetProxies is a part of auth.AccessPoint implementation +// GetProxies returns proxies from the cache func (a *Server) GetProxies() ([]types.Server, error) { return a.GetCache().GetProxies() } -// GetUser is a part of auth.AccessPoint implementation. +// GetUser returns a user from the cache func (a *Server) GetUser(name string, withSecrets bool) (user types.User, err error) { return a.GetCache().GetUser(name, withSecrets) } -// GetUsers is a part of auth.AccessPoint implementation +// GetUsers returns users from the cache func (a *Server) GetUsers(withSecrets bool) (users []types.User, err error) { return a.GetCache().GetUsers(withSecrets) } -// GetTunnelConnections is a part of auth.AccessPoint implementation // GetTunnelConnections are not using recent cache as they are designed // to be called periodically and always return fresh data func (a *Server) GetTunnelConnections(clusterName string, opts ...services.MarshalOption) ([]types.TunnelConnection, error) { return a.GetCache().GetTunnelConnections(clusterName, opts...) } -// GetAllTunnelConnections is a part of auth.AccessPoint implementation // GetAllTunnelConnections are not using recent cache, as they are designed // to be called periodically and always return fresh data func (a *Server) GetAllTunnelConnections(opts ...services.MarshalOption) (conns []types.TunnelConnection, err error) { @@ -2814,12 +2812,12 @@ func (a *Server) modeStreamer(ctx context.Context) (events.Streamer, error) { return a.streamer, nil } -// GetAppServers is a part of the auth.AccessPoint implementation. +// GetAppServers returns app servers from the cache func (a *Server) GetAppServers(ctx context.Context, namespace string, opts ...services.MarshalOption) ([]types.Server, error) { return a.GetCache().GetAppServers(ctx, namespace, opts...) } -// GetAppSession is a part of the auth.AccessPoint implementation. +// GetAppSession returns app sessions from the cache func (a *Server) GetAppSession(ctx context.Context, req types.GetAppSessionRequest) (types.WebSession, error) { return a.GetCache().GetAppSession(ctx, req) } diff --git a/lib/cache/cache.go b/lib/cache/cache.go index 71c3955b5074d..e957547b49a6d 100644 --- a/lib/cache/cache.go +++ b/lib/cache/cache.go @@ -281,7 +281,7 @@ func ForWindowsDesktop(cfg Config) Config { // for cache type SetupConfigFn func(c Config) Config -// Cache implements auth.AccessPoint interface and remembers +// Cache implements auth.Cache interface and remembers // the previously returned upstream value for each API call. // // This which can be used if the upstream AccessPoint goes offline @@ -1196,7 +1196,7 @@ func (c *Cache) GetClusterName(opts ...services.MarshalOption) (types.ClusterNam return rg.clusterConfig.GetClusterName(opts...) } -// GetRoles is a part of auth.AccessPoint implementation +// GetRoles is a part of auth.Cache implementation func (c *Cache) GetRoles(ctx context.Context) ([]types.Role, error) { rg, err := c.read() if err != nil { @@ -1206,7 +1206,7 @@ func (c *Cache) GetRoles(ctx context.Context) ([]types.Role, error) { return rg.access.GetRoles(ctx) } -// GetRole is a part of auth.AccessPoint implementation +// GetRole is a part of auth.Cache implementation func (c *Cache) GetRole(ctx context.Context, name string) (types.Role, error) { rg, err := c.read() if err != nil { @@ -1236,7 +1236,7 @@ func (c *Cache) GetNamespace(name string) (*types.Namespace, error) { return rg.presence.GetNamespace(name) } -// GetNamespaces is a part of auth.AccessPoint implementation +// GetNamespaces is a part of auth.Cache implementation func (c *Cache) GetNamespaces() ([]types.Namespace, error) { rg, err := c.read() if err != nil { @@ -1262,7 +1262,7 @@ type getNodesCacheKey struct { var _ map[getNodesCacheKey]struct{} // compile-time hashability check -// GetNodes is a part of auth.AccessPoint implementation +// GetNodes is a part of auth.Cache implementation func (c *Cache) GetNodes(ctx context.Context, namespace string, opts ...services.MarshalOption) ([]types.Server, error) { rg, err := c.read() if err != nil { @@ -1294,7 +1294,7 @@ func (c *Cache) GetNodes(ctx context.Context, namespace string, opts ...services return rg.presence.GetNodes(ctx, namespace, opts...) } -// ListNodes is a part of auth.AccessPoint implementation +// ListNodes is a part of auth.Cache implementation func (c *Cache) ListNodes(ctx context.Context, req proto.ListNodesRequest) ([]types.Server, string, error) { // NOTE: we "fake" the ListNodes API here in order to take advantage of TTL-based caching of // the GetNodes endpoint, since performing TTL-based caching on a paginated endpoint is nightmarish. @@ -1352,7 +1352,7 @@ func (c *Cache) GetAuthServers() ([]types.Server, error) { return rg.presence.GetAuthServers() } -// GetReverseTunnels is a part of auth.AccessPoint implementation +// GetReverseTunnels is a part of auth.Cache implementation func (c *Cache) GetReverseTunnels(opts ...services.MarshalOption) ([]types.ReverseTunnel, error) { rg, err := c.read() if err != nil { @@ -1362,7 +1362,7 @@ func (c *Cache) GetReverseTunnels(opts ...services.MarshalOption) ([]types.Rever return rg.presence.GetReverseTunnels(opts...) } -// GetProxies is a part of auth.AccessPoint implementation +// GetProxies is a part of auth.Cache implementation func (c *Cache) GetProxies() ([]types.Server, error) { rg, err := c.read() if err != nil { @@ -1430,7 +1430,7 @@ func (c *Cache) GetRemoteCluster(clusterName string) (types.RemoteCluster, error return rg.presence.GetRemoteCluster(clusterName) } -// GetUser is a part of auth.AccessPoint implementation. +// GetUser is a part of auth.Cache implementation. func (c *Cache) GetUser(name string, withSecrets bool) (user types.User, err error) { if withSecrets { // cache never tracks user secrets return c.Config.Users.GetUser(name, withSecrets) @@ -1454,7 +1454,7 @@ func (c *Cache) GetUser(name string, withSecrets bool) (user types.User, err err return user, trace.Wrap(err) } -// GetUsers is a part of auth.AccessPoint implementation +// GetUsers is a part of auth.Cache implementation func (c *Cache) GetUsers(withSecrets bool) (users []types.User, err error) { if withSecrets { // cache never tracks user secrets return c.Users.GetUsers(withSecrets) @@ -1467,9 +1467,7 @@ func (c *Cache) GetUsers(withSecrets bool) (users []types.User, err error) { return rg.users.GetUsers(withSecrets) } -// GetTunnelConnections is a part of auth.AccessPoint implementation -// GetTunnelConnections are not using recent cache as they are designed -// to be called periodically and always return fresh data +// GetTunnelConnections is a part of auth.Cache implementation func (c *Cache) GetTunnelConnections(clusterName string, opts ...services.MarshalOption) ([]types.TunnelConnection, error) { rg, err := c.read() if err != nil { @@ -1479,9 +1477,7 @@ func (c *Cache) GetTunnelConnections(clusterName string, opts ...services.Marsha return rg.presence.GetTunnelConnections(clusterName, opts...) } -// GetAllTunnelConnections is a part of auth.AccessPoint implementation -// GetAllTunnelConnections are not using recent cache, as they are designed -// to be called periodically and always return fresh data +// GetAllTunnelConnections is a part of auth.Cache implementation func (c *Cache) GetAllTunnelConnections(opts ...services.MarshalOption) (conns []types.TunnelConnection, err error) { rg, err := c.read() if err != nil { @@ -1491,7 +1487,7 @@ func (c *Cache) GetAllTunnelConnections(opts ...services.MarshalOption) (conns [ return rg.presence.GetAllTunnelConnections(opts...) } -// GetKubeServices is a part of auth.AccessPoint implementation +// GetKubeServices is a part of auth.Cache implementation func (c *Cache) GetKubeServices(ctx context.Context) ([]types.Server, error) { rg, err := c.read() if err != nil { diff --git a/lib/client/api.go b/lib/client/api.go index 7fafbda89721f..dffb9025e27b8 100644 --- a/lib/client/api.go +++ b/lib/client/api.go @@ -1167,18 +1167,6 @@ func (tc *TeleportClient) LoadKeyForClusterWithReissue(ctx context.Context, clus return nil } -// accessPoint returns access point based on the cache policy -func (tc *TeleportClient) accessPoint(clt auth.AccessPoint, proxyHostPort string, clusterName string) (auth.AccessPoint, error) { - // If no caching policy was set or on Windows (where Teleport does not - // support file locking at the moment), return direct access to the access - // point. - if tc.CachePolicy == nil || runtime.GOOS == constants.WindowsOS { - log.Debugf("not using caching access point") - return clt, nil - } - return clt, nil -} - // LocalAgent is a getter function for the client's local agent func (tc *TeleportClient) LocalAgent() *LocalKeyAgent { return tc.localAgent diff --git a/lib/client/client.go b/lib/client/client.go index 269bb78cf77db..a31dbd4fa8802 100644 --- a/lib/client/client.go +++ b/lib/client/client.go @@ -622,7 +622,7 @@ func (proxy *ProxyClient) GetDatabaseServers(ctx context.Context, namespace stri // CurrentClusterAccessPoint returns cluster access point to the currently // selected cluster and is used for discovery // and could be cached based on the access policy -func (proxy *ProxyClient) CurrentClusterAccessPoint(ctx context.Context, quiet bool) (auth.AccessPoint, error) { +func (proxy *ProxyClient) CurrentClusterAccessPoint(ctx context.Context, quiet bool) (auth.ClientI, error) { // get the current cluster: cluster, err := proxy.currentCluster() if err != nil { @@ -633,7 +633,7 @@ func (proxy *ProxyClient) CurrentClusterAccessPoint(ctx context.Context, quiet b // ClusterAccessPoint returns cluster access point used for discovery // and could be cached based on the access policy -func (proxy *ProxyClient) ClusterAccessPoint(ctx context.Context, clusterName string, quiet bool) (auth.AccessPoint, error) { +func (proxy *ProxyClient) ClusterAccessPoint(ctx context.Context, clusterName string, quiet bool) (auth.ClientI, error) { if clusterName == "" { return nil, trace.BadParameter("parameter clusterName is missing") } @@ -641,7 +641,7 @@ func (proxy *ProxyClient) ClusterAccessPoint(ctx context.Context, clusterName st if err != nil { return nil, trace.Wrap(err) } - return proxy.teleportClient.accessPoint(clt, proxy.proxyAddress, clusterName) + return clt, nil } // ConnectToCurrentCluster connects to the auth server of the currently selected diff --git a/lib/reversetunnel/localsite.go b/lib/reversetunnel/localsite.go index 4f47201403c35..8ca862e00b5bd 100644 --- a/lib/reversetunnel/localsite.go +++ b/lib/reversetunnel/localsite.go @@ -123,7 +123,7 @@ func (s *localSite) GetTunnelsCount() int { return len(s.remoteConns) } -// CachingAccessPoint returns a auth.AccessPoint for this cluster. +// CachingAccessPoint returns an auth.RemoteProxyAccessPoint for this cluster. func (s *localSite) CachingAccessPoint() (auth.RemoteProxyAccessPoint, error) { return s.accessPoint, nil } diff --git a/lib/reversetunnel/srv.go b/lib/reversetunnel/srv.go index babfbadbe4a92..bc4e17128aa9e 100644 --- a/lib/reversetunnel/srv.go +++ b/lib/reversetunnel/srv.go @@ -96,7 +96,7 @@ type server struct { clusterPeers map[string]*clusterPeers // newAccessPoint returns new caching access point - newAccessPoint auth.NewCachingAccessPoint + newAccessPoint auth.NewRemoteProxyCachingAccessPoint // cancel function will cancel the cancel context.CancelFunc @@ -148,7 +148,7 @@ type Config struct { LocalAccessPoint auth.ProxyAccessPoint // NewCachingAccessPoint returns new caching access points // per remote cluster - NewCachingAccessPoint auth.NewCachingAccessPoint + NewCachingAccessPoint auth.NewRemoteProxyCachingAccessPoint // DirectClusters is a list of clusters accessed directly DirectClusters []DirectCluster // Context is a signalling context @@ -198,7 +198,7 @@ type Config struct { // NewCachingAccessPointOldProxy is an access point that can be configured // with the old access point policy until all clusters are migrated to 7.0.0 // and above. - NewCachingAccessPointOldProxy auth.NewCachingAccessPoint + NewCachingAccessPointOldProxy auth.NewRemoteProxyCachingAccessPoint // LockWatcher is a lock watcher. LockWatcher *services.LockWatcher @@ -1040,7 +1040,7 @@ func newRemoteSite(srv *server, domainName string, sconn ssh.Conn) (*remoteSite, // don't assume the newer organization of cluster configuration resources // (RFD 28) because older proxy servers will reject that causing the cache // to go into a re-sync loop. - var accessPointFunc auth.NewCachingAccessPoint + var accessPointFunc auth.NewRemoteProxyCachingAccessPoint ok, err := isPreV8Cluster(closeContext, sconn) if err != nil { return nil, trace.Wrap(err) diff --git a/lib/service/service.go b/lib/service/service.go index a6f34eff3a696..9618c4732f114 100644 --- a/lib/service/service.go +++ b/lib/service/service.go @@ -1600,27 +1600,77 @@ func (process *TeleportProcess) newAccessCache(cfg accessCacheConfig) (*cache.Ca // newLocalCacheForNode returns new instance of access point configured for a local proxy. func (process *TeleportProcess) newLocalCacheForNode(clt auth.ClientI, cacheName []string) (auth.NodeAccessPoint, error) { - return process.newLocalCache(clt, cache.ForNode, cacheName) + // if caching is disabled, return access point + if !process.Config.CachePolicy.Enabled { + return clt, nil + } + + cache, err := process.newLocalCache(clt, cache.ForNode, cacheName) + if err != nil { + return nil, trace.Wrap(err) + } + + return auth.NewNodeWrapper(clt, cache), nil } // newLocalCacheForKubernetes returns new instance of access point configured for a kubernetes service. func (process *TeleportProcess) newLocalCacheForKubernetes(clt auth.ClientI, cacheName []string) (auth.KubernetesAccessPoint, error) { - return process.newLocalCache(clt, cache.ForKubernetes, cacheName) + // if caching is disabled, return access point + if !process.Config.CachePolicy.Enabled { + return clt, nil + } + + cache, err := process.newLocalCache(clt, cache.ForKubernetes, cacheName) + if err != nil { + return nil, trace.Wrap(err) + } + + return auth.NewKubernetesWrapper(clt, cache), nil } // newLocalCacheForDatabase returns new instance of access point configured for a database service. func (process *TeleportProcess) newLocalCacheForDatabase(clt auth.ClientI, cacheName []string) (auth.DatabaseAccessPoint, error) { - return process.newLocalCache(clt, cache.ForDatabases, cacheName) + // if caching is disabled, return access point + if !process.Config.CachePolicy.Enabled { + return clt, nil + } + + cache, err := process.newLocalCache(clt, cache.ForDatabases, cacheName) + if err != nil { + return nil, trace.Wrap(err) + } + + return auth.NewDatabaseWrapper(clt, cache), nil } // newLocalCacheForProxy returns new instance of access point configured for a local proxy. func (process *TeleportProcess) newLocalCacheForProxy(clt auth.ClientI, cacheName []string) (auth.ProxyAccessPoint, error) { - return process.newLocalCache(clt, cache.ForProxy, cacheName) + // if caching is disabled, return access point + if !process.Config.CachePolicy.Enabled { + return clt, nil + } + + cache, err := process.newLocalCache(clt, cache.ForProxy, cacheName) + if err != nil { + return nil, trace.Wrap(err) + } + + return auth.NewProxyWrapper(clt, cache), nil } // newLocalCacheForRemoteProxy returns new instance of access point configured for a remote proxy. func (process *TeleportProcess) newLocalCacheForRemoteProxy(clt auth.ClientI, cacheName []string) (auth.RemoteProxyAccessPoint, error) { - return process.newLocalCache(clt, cache.ForRemoteProxy, cacheName) + // if caching is disabled, return access point + if !process.Config.CachePolicy.Enabled { + return clt, nil + } + + cache, err := process.newLocalCache(clt, cache.ForRemoteProxy, cacheName) + if err != nil { + return nil, trace.Wrap(err) + } + + return auth.NewRemoteProxyWrapper(clt, cache), nil } // DELETE IN: 8.0.0 @@ -1628,35 +1678,57 @@ func (process *TeleportProcess) newLocalCacheForRemoteProxy(clt auth.ClientI, ca // newLocalCacheForOldRemoteProxy returns new instance of access point // configured for an old remote proxy. func (process *TeleportProcess) newLocalCacheForOldRemoteProxy(clt auth.ClientI, cacheName []string) (auth.RemoteProxyAccessPoint, error) { - return process.newLocalCache(clt, cache.ForOldRemoteProxy, cacheName) + // if caching is disabled, return access point + if !process.Config.CachePolicy.Enabled { + return clt, nil + } + + cache, err := process.newLocalCache(clt, cache.ForOldRemoteProxy, cacheName) + if err != nil { + return nil, trace.Wrap(err) + } + + return auth.NewRemoteProxyWrapper(clt, cache), nil } // newLocalCacheForApps returns new instance of access point configured for a remote proxy. func (process *TeleportProcess) newLocalCacheForApps(clt auth.ClientI, cacheName []string) (auth.AppsAccessPoint, error) { - return process.newLocalCache(clt, cache.ForApps, cacheName) + // if caching is disabled, return access point + if !process.Config.CachePolicy.Enabled { + return clt, nil + } + + cache, err := process.newLocalCache(clt, cache.ForApps, cacheName) + if err != nil { + return nil, trace.Wrap(err) + } + + return auth.NewAppsWrapper(clt, cache), nil } // newLocalCacheForApps returns new instance of access point configured for a windows desktop service. func (process *TeleportProcess) newLocalCacheForWindowsDesktop(clt auth.ClientI, cacheName []string) (auth.WindowsDesktopAccessPoint, error) { - return process.newLocalCache(clt, cache.ForWindowsDesktop, cacheName) -} - -// newLocalCache returns new instance of access point -func (process *TeleportProcess) newLocalCache(clt auth.ClientI, setupConfig cache.SetupConfigFn, cacheName []string) (auth.AccessPoint, error) { // if caching is disabled, return access point if !process.Config.CachePolicy.Enabled { return clt, nil } - cache, err := process.newAccessCache(accessCacheConfig{ + + cache, err := process.newLocalCache(clt, cache.ForWindowsDesktop, cacheName) + if err != nil { + return nil, trace.Wrap(err) + } + + return auth.NewWindowsDesktopWrapper(clt, cache), nil +} + +// newLocalCache returns new instance of access point +func (process *TeleportProcess) newLocalCache(clt auth.ClientI, setupConfig cache.SetupConfigFn, cacheName []string) (*cache.Cache, error) { + return process.newAccessCache(accessCacheConfig{ inMemory: process.Config.CachePolicy.Type == memory.GetName(), services: clt, setup: setupConfig, cacheName: cacheName, }) - if err != nil { - return nil, trace.Wrap(err) - } - return auth.NewWrapper(clt, cache), nil } func (process *TeleportProcess) getRotation(role types.SystemRole) (*types.Rotation, error) { diff --git a/lib/srv/ctx.go b/lib/srv/ctx.go index 355f6470eb6d5..d1360079bdca4 100644 --- a/lib/srv/ctx.go +++ b/lib/srv/ctx.go @@ -73,7 +73,7 @@ func init() { prometheus.MustRegister(serverRX) } -//AccessPoint is the access point contract required by a Server +// AccessPoint is the access point contract required by a Server type AccessPoint interface { // Announcer adds methods used to announce presence auth.Announcer @@ -126,7 +126,7 @@ type Server interface { // startup is allowed. PermitUserEnvironment() bool - // GetAccessPoint returns an auth.AccessPoint for this cluster. + // GetAccessPoint returns an AccessPoint for this cluster. GetAccessPoint() AccessPoint // GetSessionServer returns a session server. diff --git a/lib/srv/forward/sshserver.go b/lib/srv/forward/sshserver.go index c385946658bb1..b3861053aecdc 100644 --- a/lib/srv/forward/sshserver.go +++ b/lib/srv/forward/sshserver.go @@ -372,7 +372,7 @@ func (s *Server) PermitUserEnvironment() bool { return false } -// GetAccessPoint returns an auth.AccessPoint for this cluster. +// GetAccessPoint returns a srv.AccessPoint for this cluster. func (s *Server) GetAccessPoint() srv.AccessPoint { return s.authService } diff --git a/lib/srv/regular/sshserver_test.go b/lib/srv/regular/sshserver_test.go index c8d3f630baab1..e433a99913f34 100644 --- a/lib/srv/regular/sshserver_test.go +++ b/lib/srv/regular/sshserver_test.go @@ -936,7 +936,7 @@ func mustListen(t *testing.T) (net.Listener, utils.NetAddr) { } func noCache(clt auth.ClientI, cacheName []string) (auth.RemoteProxyAccessPoint, error) { - return auth.NoCache(clt, cacheName) + return clt, nil } func TestProxyReverseTunnel(t *testing.T) { diff --git a/lib/web/apiserver_test.go b/lib/web/apiserver_test.go index f32d212c351a3..8af35f7412a08 100644 --- a/lib/web/apiserver_test.go +++ b/lib/web/apiserver_test.go @@ -145,7 +145,7 @@ func (s *WebSuite) SetUpSuite(c *C) { } func noCache(clt auth.ClientI, cacheName []string) (auth.RemoteProxyAccessPoint, error) { - return auth.NoCache(clt, cacheName) + return clt, nil } func (s *WebSuite) SetUpTest(c *C) {