mirror of
https://github.com/gravitational/teleport
synced 2024-10-22 10:13:21 +00:00
743ea57f87
This commit refactor discovery protocol to make it less dependent on the database and scale better on large numbers of tunnels. Reverse tunnel is now always sending back the list of all proxies registered in the cluster in the form of discovery requests. Before this commit, reverse tunnel server was comparing existing TunnelConnection with the Proxies and sending back the list of proxies that were not discovered. This required nodes to register tunnel connections in the database and servers poll the connections. On 10K clusters this is not scalable. Instead, the change assumes that there is not a lot of proxies so it's OK to send the information about them back to all connected agents. Agent pools can make up their own mind about what to do with the information - they can ignore the request as long as they observe all agents connected to the requested proxies. At the same time, to avoid using too much traffic, reverse tunnel server only sends the discovery requests after the first agent heartbeat and in case if proxy list changes. To make it possible reverse tunnel sets up a watch on the proxies.
217 lines
6.7 KiB
Go
217 lines
6.7 KiB
Go
/*
|
|
Copyright 2015 Gravitational, Inc.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package services
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"github.com/gravitational/teleport/lib/defaults"
|
|
"github.com/gravitational/trace"
|
|
)
|
|
|
|
// ProxyGetter is an service that gets proxies
|
|
type ProxyGetter interface {
|
|
// GetProxies returns a list of registered proxies
|
|
GetProxies() ([]Server, error)
|
|
}
|
|
|
|
// Presence records and reports the presence of all components
|
|
// of the cluster - Nodes, Proxies and SSH nodes
|
|
type Presence interface {
|
|
// UpsertLocalClusterName upserts local domain
|
|
UpsertLocalClusterName(name string) error
|
|
|
|
// GetLocalClusterName upserts local domain
|
|
GetLocalClusterName() (string, error)
|
|
|
|
// GetNodes returns a list of registered servers. Schema validation can be
|
|
// skipped to improve performance.
|
|
GetNodes(namespace string, opts ...MarshalOption) ([]Server, error)
|
|
|
|
// DeleteAllNodes deletes all nodes in a namespace.
|
|
DeleteAllNodes(namespace string) error
|
|
|
|
// DeleteNode deletes node in a namespace
|
|
DeleteNode(namespace, name string) error
|
|
|
|
// UpsertNode registers node presence, permanently if TTL is 0 or for the
|
|
// specified duration with second resolution if it's >= 1 second.
|
|
UpsertNode(server Server) (*KeepAlive, error)
|
|
|
|
// UpsertNodes bulk inserts nodes.
|
|
UpsertNodes(namespace string, servers []Server) error
|
|
|
|
// KeepAliveNode updates node TTL in the storage
|
|
KeepAliveNode(ctx context.Context, h KeepAlive) error
|
|
|
|
// GetAuthServers returns a list of registered servers
|
|
GetAuthServers() ([]Server, error)
|
|
|
|
// UpsertAuthServer registers auth server presence, permanently if ttl is 0 or
|
|
// for the specified duration with second resolution if it's >= 1 second
|
|
UpsertAuthServer(server Server) error
|
|
|
|
// DeleteAuthServer deletes auth server by name
|
|
DeleteAuthServer(name string) error
|
|
|
|
// DeleteAllAuthServers deletes all auth servers
|
|
DeleteAllAuthServers() error
|
|
|
|
// UpsertProxy registers proxy server presence, permanently if ttl is 0 or
|
|
// for the specified duration with second resolution if it's >= 1 second
|
|
UpsertProxy(server Server) error
|
|
|
|
// ProxyGetter gets a list of proxies
|
|
ProxyGetter
|
|
|
|
// DeleteProxy deletes proxy by name
|
|
DeleteProxy(name string) error
|
|
|
|
// DeleteAllProxies deletes all proxies
|
|
DeleteAllProxies() error
|
|
|
|
// UpsertReverseTunnel upserts reverse tunnel entry temporarily or permanently
|
|
UpsertReverseTunnel(tunnel ReverseTunnel) error
|
|
|
|
// GetReverseTunnel returns reverse tunnel by name
|
|
GetReverseTunnel(name string, opts ...MarshalOption) (ReverseTunnel, error)
|
|
|
|
// GetReverseTunnels returns a list of registered servers
|
|
GetReverseTunnels(opts ...MarshalOption) ([]ReverseTunnel, error)
|
|
|
|
// DeleteReverseTunnel deletes reverse tunnel by it's domain name
|
|
DeleteReverseTunnel(domainName string) error
|
|
|
|
// DeleteAllReverseTunnels deletes all reverse tunnels
|
|
DeleteAllReverseTunnels() error
|
|
|
|
// GetNamespaces returns a list of namespaces
|
|
GetNamespaces() ([]Namespace, error)
|
|
|
|
// GetNamespace returns namespace by name
|
|
GetNamespace(name string) (*Namespace, error)
|
|
|
|
// DeleteAllNamespaces deletes all namespaces
|
|
DeleteAllNamespaces() error
|
|
|
|
// UpsertNamespace upserts namespace
|
|
UpsertNamespace(Namespace) error
|
|
|
|
// DeleteNamespace deletes namespace by name
|
|
DeleteNamespace(name string) error
|
|
|
|
// UpsertTrustedCluster creates or updates a TrustedCluster in the backend.
|
|
UpsertTrustedCluster(TrustedCluster) (TrustedCluster, error)
|
|
|
|
// GetTrustedCluster returns a single TrustedCluster by name.
|
|
GetTrustedCluster(string) (TrustedCluster, error)
|
|
|
|
// GetTrustedClusters returns all TrustedClusters in the backend.
|
|
GetTrustedClusters() ([]TrustedCluster, error)
|
|
|
|
// DeleteTrustedCluster removes a TrustedCluster from the backend by name.
|
|
DeleteTrustedCluster(string) error
|
|
|
|
// UpsertTunnelConnection upserts tunnel connection
|
|
UpsertTunnelConnection(TunnelConnection) error
|
|
|
|
// GetTunnelConnections returns tunnel connections for a given cluster
|
|
GetTunnelConnections(clusterName string, opts ...MarshalOption) ([]TunnelConnection, error)
|
|
|
|
// GetAllTunnelConnections returns all tunnel connections
|
|
GetAllTunnelConnections(opts ...MarshalOption) ([]TunnelConnection, error)
|
|
|
|
// DeleteTunnelConnection deletes tunnel connection by name
|
|
DeleteTunnelConnection(clusterName string, connName string) error
|
|
|
|
// DeleteTunnelConnections deletes all tunnel connections for cluster
|
|
DeleteTunnelConnections(clusterName string) error
|
|
|
|
// DeleteAllTunnelConnections deletes all tunnel connections for cluster
|
|
DeleteAllTunnelConnections() error
|
|
|
|
// CreateRemoteCluster creates a remote cluster
|
|
CreateRemoteCluster(RemoteCluster) error
|
|
|
|
// GetRemoteClusters returns a list of remote clusters
|
|
GetRemoteClusters(opts ...MarshalOption) ([]RemoteCluster, error)
|
|
|
|
// GetRemoteCluster returns a remote cluster by name
|
|
GetRemoteCluster(clusterName string) (RemoteCluster, error)
|
|
|
|
// DeleteRemoteCluster deletes remote cluster by name
|
|
DeleteRemoteCluster(clusterName string) error
|
|
|
|
// DeleteAllRemoteClusters deletes all remote clusters
|
|
DeleteAllRemoteClusters() error
|
|
}
|
|
|
|
// NewNamespace returns new namespace
|
|
func NewNamespace(name string) Namespace {
|
|
return Namespace{
|
|
Kind: KindNamespace,
|
|
Version: V2,
|
|
Metadata: Metadata{
|
|
Name: name,
|
|
},
|
|
}
|
|
}
|
|
|
|
// Site represents a cluster of teleport nodes who collectively trust the same
|
|
// certificate authority (CA) and have a common name.
|
|
//
|
|
// The CA is represented by an auth server (or multiple auth servers, if running
|
|
// in HA mode)
|
|
type Site struct {
|
|
Name string `json:"name"`
|
|
LastConnected time.Time `json:"lastconnected"`
|
|
Status string `json:"status"`
|
|
}
|
|
|
|
// IsEmpty returns true if keepalive is empty,
|
|
// used to indicate that keepalive is not supported
|
|
func (s *KeepAlive) IsEmpty() bool {
|
|
return s.LeaseID == 0 && s.ServerName == ""
|
|
}
|
|
|
|
func (s *KeepAlive) CheckAndSetDefaults() error {
|
|
if s.IsEmpty() {
|
|
return trace.BadParameter("no lease ID or server name is specified")
|
|
}
|
|
if s.Namespace == "" {
|
|
s.Namespace = defaults.Namespace
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// KeepAliver keeps object alive
|
|
type KeepAliver interface {
|
|
// KeepAlives allows to receive keep alives
|
|
KeepAlives() chan<- KeepAlive
|
|
|
|
// Done returns the channel signalling the closure
|
|
Done() <-chan struct{}
|
|
|
|
// Close closes the watcher and releases
|
|
// all associated resources
|
|
Close() error
|
|
|
|
// Error returns error associated with keep aliver if any
|
|
Error() error
|
|
}
|