mirror of
https://github.com/gravitational/teleport.git
synced 2026-10-11 22:49:54 +00:00
Remove dead heartbeatv1 code for v19 (#68399)
* Remove HeartbeatV1 fallback for services which have supported HeartbeatV2 since v17. * Remove heartbeatv1 implementation for services that haven't used it since v17. * Fix accessPoint interface; Remove dead constants; Add delete in TODO. * Add inventory control handler to tests. * Update lib/auth/auth.go Co-authored-by: rosstimothy <[email protected]> * Add old Announcer field and comment. * Fix TestRootUTMPEntryExists. --------- Co-authored-by: rosstimothy <[email protected]>
This commit is contained in:
co-authored by
rosstimothy
parent
7309862f42
commit
08c06437fc
@@ -49,6 +49,7 @@ import (
|
||||
"github.com/gravitational/teleport/lib/authz"
|
||||
"github.com/gravitational/teleport/lib/bpf"
|
||||
"github.com/gravitational/teleport/lib/cryptosuites"
|
||||
"github.com/gravitational/teleport/lib/inventory"
|
||||
"github.com/gravitational/teleport/lib/reversetunnel"
|
||||
"github.com/gravitational/teleport/lib/services"
|
||||
"github.com/gravitational/teleport/lib/srv"
|
||||
@@ -333,6 +334,18 @@ func newSrvCtx(ctx context.Context, t *testing.T) *SrvCtx {
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
inventoryHandle, err := inventory.NewDownstreamHandle(s.nodeClient.InventoryControlStream,
|
||||
func(_ context.Context) (*proto.UpstreamInventoryHello, error) {
|
||||
return proto.UpstreamInventoryHello_builder{
|
||||
ServerID: s.nodeID,
|
||||
Version: teleport.Version,
|
||||
Services: []string{string(types.RoleNode)},
|
||||
Hostname: "test",
|
||||
}.Build(), nil
|
||||
})
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() { require.NoError(t, inventoryHandle.Close()) })
|
||||
|
||||
nodeDir := t.TempDir()
|
||||
srv, err := regular.New(
|
||||
ctx,
|
||||
@@ -363,6 +376,7 @@ func newSrvCtx(ctx context.Context, t *testing.T) *SrvCtx {
|
||||
regular.SetLockWatcher(lockWatcher),
|
||||
regular.SetSessionController(nodeSessionController),
|
||||
regular.SetConnectedProxyGetter(reversetunnel.NewConnectedProxyGetter()),
|
||||
regular.SetInventoryControlHandle(inventoryHandle),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
s.srv = srv
|
||||
|
||||
@@ -56,10 +56,6 @@ import (
|
||||
|
||||
// Announcer specifies interface responsible for announcing presence
|
||||
type Announcer interface {
|
||||
// UpsertNode registers node presence, permanently if ttl is 0 or
|
||||
// for the specified duration with second resolution if it's >= 1 second
|
||||
UpsertNode(ctx context.Context, s types.Server) (*types.KeepAlive, error)
|
||||
|
||||
// UpsertProxyServerWithoutReturn registers proxy presence, permanently if
|
||||
// ttl is 0 or for the specified duration with second resolution if it's
|
||||
// >= 1 second. The upserted server is not returned because the HTTP
|
||||
@@ -73,18 +69,9 @@ type Announcer interface {
|
||||
// for the specified duration with second resolution if it's >= 1 second
|
||||
UpsertAuthServer(ctx context.Context, s types.Server) error
|
||||
|
||||
// UpsertKubernetesServer registers a kubernetes server
|
||||
UpsertKubernetesServer(context.Context, types.KubeServer) (*types.KeepAlive, error)
|
||||
|
||||
// NewKeepAliver returns a new instance of keep aliver
|
||||
NewKeepAliver(ctx context.Context) (types.KeepAliver, error)
|
||||
|
||||
// UpsertApplicationServer registers an application server.
|
||||
UpsertApplicationServer(context.Context, types.AppServer) (*types.KeepAlive, error)
|
||||
|
||||
// UpsertDatabaseServer registers a database proxy server.
|
||||
UpsertDatabaseServer(context.Context, types.DatabaseServer) (*types.KeepAlive, error)
|
||||
|
||||
// UpsertWindowsDesktopService registers a Windows desktop service.
|
||||
UpsertWindowsDesktopService(context.Context, types.WindowsDesktopService) (*types.KeepAlive, error)
|
||||
|
||||
@@ -116,6 +103,13 @@ type accessPoint interface {
|
||||
|
||||
// ConnectionDiagnosticTraceAppender adds a method to append traces into ConnectionDiagnostics.
|
||||
services.ConnectionDiagnosticTraceAppender
|
||||
|
||||
// UpsertNode registers node presence, permanently if ttl is 0 or
|
||||
// for the specified duration with second resolution if it's >= 1 second
|
||||
UpsertNode(ctx context.Context, s types.Server) (*types.KeepAlive, error)
|
||||
|
||||
// UpsertApplicationServer registers an application server.
|
||||
UpsertApplicationServer(context.Context, types.AppServer) (*types.KeepAlive, error)
|
||||
}
|
||||
|
||||
// ReadNodeAccessPoint is a read only API interface implemented by a certificate authority (CA) to be
|
||||
|
||||
@@ -696,7 +696,6 @@ func (t *TLSServer) getKubeClusterWithServiceLabels(name string) (*types.Kuberne
|
||||
func (t *TLSServer) startHeartbeat(name string) error {
|
||||
heartbeat, err := srv.NewKubernetesServerHeartbeat(srv.HeartbeatV2Config[*types.KubernetesServerV3]{
|
||||
InventoryHandle: t.InventoryHandle,
|
||||
Announcer: t.TLSServerConfig.AuthClient,
|
||||
GetResource: func(context.Context) (*types.KubernetesServerV3, error) { return t.GetServerInfo(name) },
|
||||
OnHeartbeat: t.TLSServerConfig.OnHeartbeat,
|
||||
})
|
||||
|
||||
@@ -407,11 +407,6 @@ func (process *TeleportProcess) runRelayService() error {
|
||||
GetResource: func(context.Context) (*presencev1.RelayServer, error) {
|
||||
return relayServer.Load(), nil
|
||||
},
|
||||
|
||||
// there's no fallback announce mode, the relay service only works with
|
||||
// clusters recent enough to support relay heartbeats through the ICS
|
||||
Announcer: nil,
|
||||
|
||||
OnHeartbeat: process.OnHeartbeat(teleport.ComponentRelay),
|
||||
}, sublogger("heartbeat"))
|
||||
if err != nil {
|
||||
|
||||
+2
-113
@@ -88,7 +88,7 @@ type HeartbeatMode int
|
||||
// CheckAndSetDefaults checks values and sets defaults
|
||||
func (h HeartbeatMode) CheckAndSetDefaults() error {
|
||||
switch h {
|
||||
case HeartbeatModeNode, HeartbeatModeProxy, HeartbeatModeAuth, HeartbeatModeKube, HeartbeatModeApp, HeartbeatModeDB, HeartbeatModeDatabaseService, HeartbeatModeWindowsDesktopService, HeartbeatModeWindowsDesktop:
|
||||
case HeartbeatModeProxy, HeartbeatModeAuth, HeartbeatModeDatabaseService, HeartbeatModeWindowsDesktopService, HeartbeatModeWindowsDesktop:
|
||||
return nil
|
||||
default:
|
||||
return trace.BadParameter("unrecognized mode")
|
||||
@@ -98,18 +98,10 @@ func (h HeartbeatMode) CheckAndSetDefaults() error {
|
||||
// String returns user-friendly representation of the mode
|
||||
func (h HeartbeatMode) String() string {
|
||||
switch h {
|
||||
case HeartbeatModeNode:
|
||||
return "Node"
|
||||
case HeartbeatModeProxy:
|
||||
return "Proxy"
|
||||
case HeartbeatModeAuth:
|
||||
return "Auth"
|
||||
case HeartbeatModeKube:
|
||||
return "Kube"
|
||||
case HeartbeatModeApp:
|
||||
return "App"
|
||||
case HeartbeatModeDB:
|
||||
return "Database"
|
||||
case HeartbeatModeDatabaseService:
|
||||
return "DatabaseService"
|
||||
case HeartbeatModeWindowsDesktopService:
|
||||
@@ -122,21 +114,12 @@ func (h HeartbeatMode) String() string {
|
||||
}
|
||||
|
||||
const (
|
||||
// HeartbeatModeNode sets heartbeat to node
|
||||
// updates that support keep alives
|
||||
HeartbeatModeNode HeartbeatMode = iota
|
||||
// HeartbeatModeProxy sets heartbeat to proxy
|
||||
// that does not support keep alives
|
||||
HeartbeatModeProxy
|
||||
HeartbeatModeProxy HeartbeatMode = iota
|
||||
// HeartbeatModeAuth sets heartbeat to auth
|
||||
// that does not support keep alives
|
||||
HeartbeatModeAuth
|
||||
// HeartbeatModeKube is a mode for kubernetes service heartbeats.
|
||||
HeartbeatModeKube
|
||||
// HeartbeatModeApp sets heartbeat to apps and will use keep alives.
|
||||
HeartbeatModeApp
|
||||
// HeartbeatModeDB sets heartbeat to db
|
||||
HeartbeatModeDB
|
||||
// HeartbeatModeDatabaseService sets heartbeat mode to DatabaseService.
|
||||
HeartbeatModeDatabaseService
|
||||
// HeartbeatModeWindowsDesktopService sets heartbeat mode to windows desktop
|
||||
@@ -438,100 +421,6 @@ func (h *Heartbeat) announce() (doneSomething bool, _ error) {
|
||||
h.notifySend()
|
||||
h.setState(HeartbeatStateAnnounceWait)
|
||||
return true, nil
|
||||
case HeartbeatModeNode:
|
||||
node, ok := h.current.(types.Server)
|
||||
if !ok {
|
||||
return false, trace.BadParameter("expected services.Server, got %#v", h.current)
|
||||
}
|
||||
keepAlive, err := h.Announcer.UpsertNode(h.cancelCtx, node)
|
||||
if err != nil {
|
||||
return false, trace.Wrap(err)
|
||||
}
|
||||
h.notifySend()
|
||||
keepAliver, err := h.Announcer.NewKeepAliver(h.cancelCtx)
|
||||
if err != nil {
|
||||
h.reset(HeartbeatStateInit)
|
||||
return false, trace.Wrap(err)
|
||||
}
|
||||
h.nextAnnounce = h.Clock.Now().UTC().Add(h.AnnouncePeriod)
|
||||
h.nextKeepAlive = h.Clock.Now().UTC().Add(h.KeepAlivePeriod)
|
||||
h.keepAlive = keepAlive
|
||||
h.keepAliver = keepAliver
|
||||
h.setState(HeartbeatStateKeepAliveWait)
|
||||
return true, nil
|
||||
case HeartbeatModeKube:
|
||||
var (
|
||||
keepAlive *types.KeepAlive
|
||||
err error
|
||||
)
|
||||
|
||||
switch current := h.current.(type) {
|
||||
case types.KubeServer:
|
||||
keepAlive, err = h.Announcer.UpsertKubernetesServer(h.cancelCtx, current)
|
||||
if err != nil {
|
||||
return false, trace.Wrap(err)
|
||||
}
|
||||
default:
|
||||
return false, trace.BadParameter("expected types.KubeServer, got %#v", h.current)
|
||||
}
|
||||
|
||||
h.notifySend()
|
||||
keepAliver, err := h.Announcer.NewKeepAliver(h.cancelCtx)
|
||||
if err != nil {
|
||||
h.reset(HeartbeatStateInit)
|
||||
return false, trace.Wrap(err)
|
||||
}
|
||||
h.nextAnnounce = h.Clock.Now().UTC().Add(h.AnnouncePeriod)
|
||||
h.nextKeepAlive = h.Clock.Now().UTC().Add(h.KeepAlivePeriod)
|
||||
h.keepAlive = keepAlive
|
||||
h.keepAliver = keepAliver
|
||||
h.setState(HeartbeatStateKeepAliveWait)
|
||||
return true, nil
|
||||
case HeartbeatModeApp:
|
||||
var keepAlive *types.KeepAlive
|
||||
var err error
|
||||
switch current := h.current.(type) {
|
||||
case types.AppServer:
|
||||
keepAlive, err = h.Announcer.UpsertApplicationServer(h.cancelCtx, current)
|
||||
default:
|
||||
return false, trace.BadParameter("expected types.AppServer, got %#v", h.current)
|
||||
}
|
||||
if err != nil {
|
||||
return false, trace.Wrap(err)
|
||||
}
|
||||
h.notifySend()
|
||||
keepAliver, err := h.Announcer.NewKeepAliver(h.cancelCtx)
|
||||
if err != nil {
|
||||
h.reset(HeartbeatStateInit)
|
||||
return false, trace.Wrap(err)
|
||||
}
|
||||
h.nextAnnounce = h.Clock.Now().UTC().Add(h.AnnouncePeriod)
|
||||
h.nextKeepAlive = h.Clock.Now().UTC().Add(h.KeepAlivePeriod)
|
||||
h.keepAlive = keepAlive
|
||||
h.keepAliver = keepAliver
|
||||
h.setState(HeartbeatStateKeepAliveWait)
|
||||
return true, nil
|
||||
case HeartbeatModeDB:
|
||||
db, ok := h.current.(types.DatabaseServer)
|
||||
if !ok {
|
||||
return false, trace.BadParameter("expected services.DatabaseServer, got %#v", h.current)
|
||||
}
|
||||
keepAlive, err := h.Announcer.UpsertDatabaseServer(h.cancelCtx, db)
|
||||
if err != nil {
|
||||
return false, trace.Wrap(err)
|
||||
}
|
||||
h.notifySend()
|
||||
keepAliver, err := h.Announcer.NewKeepAliver(h.cancelCtx)
|
||||
if err != nil {
|
||||
h.reset(HeartbeatStateInit)
|
||||
return false, trace.Wrap(err)
|
||||
}
|
||||
h.nextAnnounce = h.Clock.Now().UTC().Add(h.AnnouncePeriod)
|
||||
h.nextKeepAlive = h.Clock.Now().UTC().Add(h.KeepAlivePeriod)
|
||||
h.keepAlive = keepAlive
|
||||
h.keepAliver = keepAliver
|
||||
h.setState(HeartbeatStateKeepAliveWait)
|
||||
return true, nil
|
||||
case HeartbeatModeWindowsDesktopService:
|
||||
wd, ok := h.current.(types.WindowsDesktopService)
|
||||
if !ok {
|
||||
|
||||
+22
-102
@@ -29,10 +29,10 @@ import (
|
||||
|
||||
apidefaults "github.com/gravitational/teleport/api/defaults"
|
||||
"github.com/gravitational/teleport/api/types"
|
||||
"github.com/gravitational/teleport/lib/defaults"
|
||||
)
|
||||
|
||||
// TestHeartbeatKeepAlive tests keep alive cycle used for nodes and apps.
|
||||
// TestHeartbeatKeepAlive tests keep alive cycle used for database services and
|
||||
// windows desktop services.
|
||||
func TestHeartbeatKeepAlive(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -41,60 +41,6 @@ func TestHeartbeatKeepAlive(t *testing.T) {
|
||||
mode HeartbeatMode
|
||||
makeServer func() types.Resource
|
||||
}{
|
||||
{
|
||||
name: "keep alive node",
|
||||
mode: HeartbeatModeNode,
|
||||
makeServer: func() types.Resource {
|
||||
return &types.ServerV2{
|
||||
Kind: types.KindNode,
|
||||
Version: types.V2,
|
||||
Metadata: types.Metadata{
|
||||
Namespace: apidefaults.Namespace,
|
||||
Name: "1",
|
||||
},
|
||||
Spec: types.ServerSpecV2{
|
||||
Addr: "127.0.0.1:1234",
|
||||
Hostname: "2",
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "keep alive app server",
|
||||
mode: HeartbeatModeApp,
|
||||
makeServer: func() types.Resource {
|
||||
return &types.AppServerV3{
|
||||
Kind: types.KindAppServer,
|
||||
Version: types.V3,
|
||||
Metadata: types.Metadata{
|
||||
Namespace: apidefaults.Namespace,
|
||||
Name: "1",
|
||||
},
|
||||
Spec: types.AppServerSpecV3{
|
||||
App: &types.AppV3{},
|
||||
Hostname: "2",
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "keep alive database server",
|
||||
mode: HeartbeatModeDB,
|
||||
makeServer: func() types.Resource {
|
||||
return &types.DatabaseServerV3{
|
||||
Kind: types.KindDatabaseServer,
|
||||
Version: types.V3,
|
||||
Metadata: types.Metadata{
|
||||
Namespace: apidefaults.Namespace,
|
||||
Name: "db-1",
|
||||
},
|
||||
Spec: types.DatabaseServerSpecV3{
|
||||
Database: mustCreateDatabase(t, "db-1", defaults.ProtocolPostgres, "127.0.0.1:1234"),
|
||||
Hostname: "2",
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "keep alive database service",
|
||||
mode: HeartbeatModeDatabaseService,
|
||||
@@ -116,6 +62,26 @@ func TestHeartbeatKeepAlive(t *testing.T) {
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "keep alive windows desktop service",
|
||||
mode: HeartbeatModeWindowsDesktopService,
|
||||
makeServer: func() types.Resource {
|
||||
return &types.WindowsDesktopServiceV3{
|
||||
ResourceHeader: types.ResourceHeader{
|
||||
Kind: types.KindWindowsDesktopService,
|
||||
Version: types.V3,
|
||||
Metadata: types.Metadata{
|
||||
Name: "1",
|
||||
Namespace: apidefaults.Namespace,
|
||||
},
|
||||
},
|
||||
Spec: types.WindowsDesktopServiceSpecV3{
|
||||
Addr: "127.0.0.1:1234",
|
||||
TeleportVersion: "1.2.3",
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
@@ -217,20 +183,6 @@ func TestHeartbeatKeepAlive(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func mustCreateDatabase(t *testing.T, name, protocol, uri string) *types.DatabaseV3 {
|
||||
database, err := types.NewDatabaseV3(
|
||||
types.Metadata{
|
||||
Name: name,
|
||||
},
|
||||
types.DatabaseSpecV3{
|
||||
Protocol: protocol,
|
||||
URI: uri,
|
||||
},
|
||||
)
|
||||
require.NoError(t, err)
|
||||
return database
|
||||
}
|
||||
|
||||
// TestHeartbeatAnnounce tests announce cycles used for proxies and auth servers
|
||||
func TestHeartbeatAnnounce(t *testing.T) {
|
||||
t.Parallel()
|
||||
@@ -352,30 +304,6 @@ type fakeAnnouncer struct {
|
||||
keepAlivesC chan<- types.KeepAlive
|
||||
}
|
||||
|
||||
func (f *fakeAnnouncer) UpsertApplicationServer(ctx context.Context, s types.AppServer) (*types.KeepAlive, error) {
|
||||
f.upsertCalls[HeartbeatModeApp]++
|
||||
if f.err != nil {
|
||||
return nil, f.err
|
||||
}
|
||||
return &types.KeepAlive{}, nil
|
||||
}
|
||||
|
||||
func (f *fakeAnnouncer) UpsertDatabaseServer(ctx context.Context, s types.DatabaseServer) (*types.KeepAlive, error) {
|
||||
f.upsertCalls[HeartbeatModeDB]++
|
||||
if f.err != nil {
|
||||
return nil, f.err
|
||||
}
|
||||
return &types.KeepAlive{}, nil
|
||||
}
|
||||
|
||||
func (f *fakeAnnouncer) UpsertNode(ctx context.Context, s types.Server) (*types.KeepAlive, error) {
|
||||
f.upsertCalls[HeartbeatModeNode]++
|
||||
if f.err != nil {
|
||||
return nil, f.err
|
||||
}
|
||||
return &types.KeepAlive{}, nil
|
||||
}
|
||||
|
||||
func (f *fakeAnnouncer) UpsertProxyServerWithoutReturn(ctx context.Context, s types.Server) error {
|
||||
f.upsertCalls[HeartbeatModeProxy]++
|
||||
return f.err
|
||||
@@ -386,14 +314,6 @@ func (f *fakeAnnouncer) UpsertAuthServer(ctx context.Context, s types.Server) er
|
||||
return f.err
|
||||
}
|
||||
|
||||
func (f *fakeAnnouncer) UpsertKubernetesServer(ctx context.Context, s types.KubeServer) (*types.KeepAlive, error) {
|
||||
f.upsertCalls[HeartbeatModeKube]++
|
||||
if f.err != nil {
|
||||
return nil, f.err
|
||||
}
|
||||
return &types.KeepAlive{}, f.err
|
||||
}
|
||||
|
||||
func (f *fakeAnnouncer) UpsertWindowsDesktopService(ctx context.Context, s types.WindowsDesktopService) (*types.KeepAlive, error) {
|
||||
f.upsertCalls[HeartbeatModeWindowsDesktopService]++
|
||||
if f.err != nil {
|
||||
|
||||
+13
-112
@@ -56,7 +56,11 @@ type HeartbeatV2Config[T any] struct {
|
||||
// Announcer is a fallback used to perform basic upsert-style heartbeats
|
||||
// if the control stream is unavailable.
|
||||
//
|
||||
// DELETE IN: 11.0 (only exists for back-compat with v9 auth servers)
|
||||
// This field is currently unused as all services migrated to heartbeatV2
|
||||
// have deprecated V1 support. Future heartbeatV2 service migrations would
|
||||
// need to set this field and use it to implement `SupportsFallback` and
|
||||
// `FallbackAnnounce`. See git history prior to this change for exact
|
||||
// code examples.
|
||||
Announcer authclient.Announcer
|
||||
// OnHeartbeat is a per-attempt callback (optional).
|
||||
OnHeartbeat func(error)
|
||||
@@ -88,7 +92,6 @@ func NewSSHServerHeartbeat(cfg HeartbeatV2Config[*types.ServerV2]) (*HeartbeatV2
|
||||
|
||||
inner := &sshServerHeartbeatV2{
|
||||
getMetadata: metadata.Get,
|
||||
announcer: cfg.Announcer,
|
||||
}
|
||||
inner.getServer = func(ctx context.Context) (*types.ServerV2, error) {
|
||||
server, err := cfg.GetResource(ctx)
|
||||
@@ -124,7 +127,6 @@ func NewAppServerHeartbeat(cfg HeartbeatV2Config[*types.AppServerV3]) (*Heartbea
|
||||
|
||||
inner := &appServerHeartbeatV2{
|
||||
getServer: cfg.GetResource,
|
||||
announcer: cfg.Announcer,
|
||||
}
|
||||
|
||||
return newHeartbeatV2(cfg.InventoryHandle, inner, heartbeatV2Config{
|
||||
@@ -144,7 +146,6 @@ func NewDatabaseServerHeartbeat(cfg HeartbeatV2Config[*types.DatabaseServerV3])
|
||||
|
||||
inner := &dbServerHeartbeatV2{
|
||||
getServer: cfg.GetResource,
|
||||
announcer: cfg.Announcer,
|
||||
}
|
||||
|
||||
return newHeartbeatV2(cfg.InventoryHandle, inner, heartbeatV2Config{
|
||||
@@ -164,7 +165,6 @@ func NewKubernetesServerHeartbeat(cfg HeartbeatV2Config[*types.KubernetesServerV
|
||||
|
||||
inner := &kubeServerHeartbeatV2{
|
||||
getServer: cfg.GetResource,
|
||||
announcer: cfg.Announcer,
|
||||
}
|
||||
|
||||
return newHeartbeatV2(cfg.InventoryHandle, inner, heartbeatV2Config{
|
||||
@@ -595,7 +595,6 @@ type metadataGetter func(ctx context.Context) (*metadata.Metadata, error)
|
||||
type sshServerHeartbeatV2 struct {
|
||||
getServer func(ctx context.Context) (*types.ServerV2, error)
|
||||
getMetadata metadataGetter
|
||||
announcer authclient.Announcer
|
||||
prev *types.ServerV2
|
||||
}
|
||||
|
||||
@@ -613,26 +612,11 @@ func (h *sshServerHeartbeatV2) Poll(ctx context.Context) (changed bool) {
|
||||
}
|
||||
|
||||
func (h *sshServerHeartbeatV2) SupportsFallback() bool {
|
||||
return h.announcer != nil
|
||||
return false
|
||||
}
|
||||
|
||||
func (h *sshServerHeartbeatV2) FallbackAnnounce(ctx context.Context) (ok bool) {
|
||||
if h.announcer == nil {
|
||||
return false
|
||||
}
|
||||
server, err := h.getServer(ctx)
|
||||
if err != nil {
|
||||
slog.WarnContext(ctx, "Failed to perform fallback heartbeat for ssh server", "error", err)
|
||||
return false
|
||||
}
|
||||
|
||||
if _, err := h.announcer.UpsertNode(ctx, server); err != nil {
|
||||
slog.WarnContext(ctx, "Failed to perform fallback heartbeat for ssh server", "error", err)
|
||||
return false
|
||||
}
|
||||
|
||||
h.prev = server
|
||||
return true
|
||||
return false
|
||||
}
|
||||
|
||||
func (h *sshServerHeartbeatV2) Announce(ctx context.Context, sender inventory.DownstreamSender) (ok bool) {
|
||||
@@ -653,7 +637,6 @@ func (h *sshServerHeartbeatV2) Announce(ctx context.Context, sender inventory.Do
|
||||
// appServerHeartbeatV2 is the heartbeatV2 implementation for app servers.
|
||||
type appServerHeartbeatV2 struct {
|
||||
getServer func(ctx context.Context) (*types.AppServerV3, error)
|
||||
announcer authclient.Announcer
|
||||
prev *types.AppServerV3
|
||||
}
|
||||
|
||||
@@ -671,41 +654,14 @@ func (h *appServerHeartbeatV2) Poll(ctx context.Context) (changed bool) {
|
||||
}
|
||||
|
||||
func (h *appServerHeartbeatV2) SupportsFallback() bool {
|
||||
return h.announcer != nil
|
||||
return false
|
||||
}
|
||||
|
||||
func (h *appServerHeartbeatV2) FallbackAnnounce(ctx context.Context) (ok bool) {
|
||||
if h.announcer == nil {
|
||||
return false
|
||||
}
|
||||
server, err := h.getServer(ctx)
|
||||
if err != nil {
|
||||
slog.WarnContext(ctx, "Failed to perform fallback heartbeat for app server", "error", err)
|
||||
return false
|
||||
}
|
||||
|
||||
if _, err := h.announcer.UpsertApplicationServer(ctx, server); err != nil {
|
||||
if !errors.Is(err, context.Canceled) && status.Code(err) != codes.Canceled {
|
||||
slog.WarnContext(ctx, "Failed to perform fallback heartbeat for app server", "error", err)
|
||||
}
|
||||
return false
|
||||
}
|
||||
h.prev = server
|
||||
return true
|
||||
return false
|
||||
}
|
||||
|
||||
func (h *appServerHeartbeatV2) Announce(ctx context.Context, sender inventory.DownstreamSender) (ok bool) {
|
||||
// AppServer heartbeats via inventory control stream were not introduced in a major version,
|
||||
// so there is a chance that the Auth server is unable to process the request via the inventory
|
||||
// control stream. If the Auth server capabilities indicate as such, then use the fallback mechanism.
|
||||
hello := sender.Hello()
|
||||
switch {
|
||||
case !hello.HasCapabilities():
|
||||
return h.FallbackAnnounce(ctx)
|
||||
case hello.HasCapabilities() && !hello.GetCapabilities().GetAppHeartbeats():
|
||||
return h.FallbackAnnounce(ctx)
|
||||
}
|
||||
|
||||
server, err := h.getServer(ctx)
|
||||
if err != nil {
|
||||
slog.WarnContext(ctx, "Failed to perform inventory heartbeat for app server", "error", err)
|
||||
@@ -726,7 +682,6 @@ func (h *appServerHeartbeatV2) Announce(ctx context.Context, sender inventory.Do
|
||||
// dbServerHeartbeatV2 is the heartbeatV2 implementation for db servers.
|
||||
type dbServerHeartbeatV2 struct {
|
||||
getServer func(ctx context.Context) (*types.DatabaseServerV3, error)
|
||||
announcer authclient.Announcer
|
||||
prev *types.DatabaseServerV3
|
||||
}
|
||||
|
||||
@@ -744,40 +699,14 @@ func (h *dbServerHeartbeatV2) Poll(ctx context.Context) (changed bool) {
|
||||
}
|
||||
|
||||
func (h *dbServerHeartbeatV2) SupportsFallback() bool {
|
||||
return h.announcer != nil
|
||||
return false
|
||||
}
|
||||
|
||||
func (h *dbServerHeartbeatV2) FallbackAnnounce(ctx context.Context) (ok bool) {
|
||||
if h.announcer == nil {
|
||||
return false
|
||||
}
|
||||
server, err := h.getServer(ctx)
|
||||
if err != nil {
|
||||
slog.WarnContext(ctx, "Failed to perform fallback heartbeat for database server", "error", err)
|
||||
return false
|
||||
}
|
||||
if _, err := h.announcer.UpsertDatabaseServer(ctx, server); err != nil {
|
||||
if !errors.Is(err, context.Canceled) && status.Code(err) != codes.Canceled {
|
||||
slog.WarnContext(ctx, "Failed to perform fallback heartbeat for database server", "error", err)
|
||||
}
|
||||
return false
|
||||
}
|
||||
h.prev = server
|
||||
return true
|
||||
return false
|
||||
}
|
||||
|
||||
func (h *dbServerHeartbeatV2) Announce(ctx context.Context, sender inventory.DownstreamSender) (ok bool) {
|
||||
// DatabaseServer heartbeats via inventory control stream were not introduced in a major version,
|
||||
// so there is a chance that the Auth server is unable to process the request via the inventory
|
||||
// control stream. If the Auth server capabilities indicate as such, then use the fallback mechanism.
|
||||
hello := sender.Hello()
|
||||
switch {
|
||||
case !hello.HasCapabilities():
|
||||
return h.FallbackAnnounce(ctx)
|
||||
case hello.HasCapabilities() && !hello.GetCapabilities().GetDatabaseHeartbeats():
|
||||
return h.FallbackAnnounce(ctx)
|
||||
}
|
||||
|
||||
server, err := h.getServer(ctx)
|
||||
if err != nil {
|
||||
slog.WarnContext(ctx, "Failed to perform inventory heartbeat for database server", "error", err)
|
||||
@@ -797,7 +726,6 @@ func (h *dbServerHeartbeatV2) Announce(ctx context.Context, sender inventory.Dow
|
||||
// kubeServerHeartbeatV2 is the heartbeatV2 implementation for kubernetes servers.
|
||||
type kubeServerHeartbeatV2 struct {
|
||||
getServer func(ctx context.Context) (*types.KubernetesServerV3, error)
|
||||
announcer authclient.Announcer
|
||||
prev *types.KubernetesServerV3
|
||||
}
|
||||
|
||||
@@ -815,41 +743,14 @@ func (h *kubeServerHeartbeatV2) Poll(ctx context.Context) (changed bool) {
|
||||
}
|
||||
|
||||
func (h *kubeServerHeartbeatV2) SupportsFallback() bool {
|
||||
return h.announcer != nil
|
||||
return false
|
||||
}
|
||||
|
||||
func (h *kubeServerHeartbeatV2) FallbackAnnounce(ctx context.Context) (ok bool) {
|
||||
if h.announcer == nil {
|
||||
return false
|
||||
}
|
||||
server, err := h.getServer(ctx)
|
||||
if err != nil {
|
||||
slog.WarnContext(ctx, "Failed to perform fallback heartbeat for kubernetes server", "error", err)
|
||||
return false
|
||||
}
|
||||
|
||||
if _, err := h.announcer.UpsertKubernetesServer(ctx, apiutils.CloneProtoMsg(server)); err != nil {
|
||||
if !errors.Is(err, context.Canceled) && status.Code(err) != codes.Canceled {
|
||||
slog.WarnContext(ctx, "Failed to perform fallback heartbeat for kubernetes server", "error", err)
|
||||
}
|
||||
return false
|
||||
}
|
||||
h.prev = server
|
||||
return true
|
||||
return false
|
||||
}
|
||||
|
||||
func (h *kubeServerHeartbeatV2) Announce(ctx context.Context, sender inventory.DownstreamSender) (ok bool) {
|
||||
// KubernetesServer heartbeats via inventory control stream were not introduced in a major version,
|
||||
// so there is a chance that the Auth server is unable to process the request via the inventory
|
||||
// control stream. If the Auth server capabilities indicate as such, then use the fallback mechanism.
|
||||
hello := sender.Hello()
|
||||
switch {
|
||||
case !hello.HasCapabilities():
|
||||
return h.FallbackAnnounce(ctx)
|
||||
case hello.HasCapabilities() && !hello.GetCapabilities().GetKubernetesHeartbeats():
|
||||
return h.FallbackAnnounce(ctx)
|
||||
}
|
||||
|
||||
server, err := h.getServer(ctx)
|
||||
if err != nil {
|
||||
slog.WarnContext(ctx, "Failed to perform inventory heartbeat for kubernetes server", "error", err)
|
||||
|
||||
@@ -1042,15 +1042,11 @@ func New(
|
||||
}
|
||||
}
|
||||
|
||||
var heartbeatMode srv.HeartbeatMode
|
||||
if s.proxyMode {
|
||||
heartbeatMode = srv.HeartbeatModeProxy
|
||||
} else {
|
||||
heartbeatMode = srv.HeartbeatModeNode
|
||||
}
|
||||
|
||||
var heartbeat srv.HeartbeatI
|
||||
if heartbeatMode == srv.HeartbeatModeNode && s.inventoryHandle != nil {
|
||||
if !s.proxyMode {
|
||||
if s.inventoryHandle == nil {
|
||||
return nil, trace.BadParameter("inventoryHandle must not be nil")
|
||||
}
|
||||
s.logger.DebugContext(ctx, "starting control-stream based heartbeat")
|
||||
heartbeat, err = srv.NewSSHServerHeartbeat(srv.HeartbeatV2Config[*types.ServerV2]{
|
||||
InventoryHandle: s.inventoryHandle,
|
||||
@@ -1060,7 +1056,7 @@ func New(
|
||||
} else {
|
||||
s.logger.DebugContext(ctx, "starting legacy heartbeat")
|
||||
heartbeat, err = srv.NewHeartbeat(srv.HeartbeatConfig{
|
||||
Mode: heartbeatMode,
|
||||
Mode: srv.HeartbeatModeProxy,
|
||||
Context: ctx,
|
||||
Component: component,
|
||||
Announcer: s.authService,
|
||||
|
||||
@@ -73,6 +73,7 @@ import (
|
||||
"github.com/gravitational/teleport/lib/cryptosuites"
|
||||
"github.com/gravitational/teleport/lib/events"
|
||||
"github.com/gravitational/teleport/lib/events/eventstest"
|
||||
"github.com/gravitational/teleport/lib/inventory"
|
||||
"github.com/gravitational/teleport/lib/limiter"
|
||||
"github.com/gravitational/teleport/lib/modules"
|
||||
"github.com/gravitational/teleport/lib/observability/tracing"
|
||||
@@ -196,6 +197,22 @@ func (f *sshTestFixture) newSSHClient(ctx context.Context, t testing.TB, user *u
|
||||
return client
|
||||
}
|
||||
|
||||
func newTestInventoryHandle(t testing.TB, clt *authclient.Client, hostID string, role types.SystemRole) inventory.DownstreamHandle {
|
||||
t.Helper()
|
||||
handle, err := inventory.NewDownstreamHandle(clt.InventoryControlStream,
|
||||
func(_ context.Context) (*proto.UpstreamInventoryHello, error) {
|
||||
return proto.UpstreamInventoryHello_builder{
|
||||
ServerID: hostID,
|
||||
Version: teleport.Version,
|
||||
Services: types.SystemRoles{role}.StringSlice(),
|
||||
Hostname: "test",
|
||||
}.Build(), nil
|
||||
})
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() { require.NoError(t, handle.Close()) })
|
||||
return handle
|
||||
}
|
||||
|
||||
func setChildLogConfigForTest() ServerOption {
|
||||
return func(s *Server) error {
|
||||
s.childLogConfig = &srv.ChildLogConfig{
|
||||
@@ -266,6 +283,7 @@ func newCustomFixture(t testing.TB, mutateCfg func(*authtest.ServerConfig), sshO
|
||||
SetSessionController(sessionController),
|
||||
SetStoragePresenceService(testServer.AuthServer.AuthServer.PresenceInternal),
|
||||
SetConnectedProxyGetter(reversetunnel.NewConnectedProxyGetter()),
|
||||
SetInventoryControlHandle(newTestInventoryHandle(t, nodeClient, nodeID, types.RoleNode)),
|
||||
setChildLogConfigForTest(),
|
||||
}
|
||||
|
||||
@@ -2423,7 +2441,7 @@ func TestLimiter(t *testing.T) {
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
nodeClient, _ := newNodeClient(t, f.testSrv)
|
||||
nodeClient, nodeID := newNodeClient(t, f.testSrv)
|
||||
|
||||
lockWatcher := newLockWatcher(ctx, t, nodeClient)
|
||||
|
||||
@@ -2458,6 +2476,7 @@ func TestLimiter(t *testing.T) {
|
||||
SetLockWatcher(lockWatcher),
|
||||
SetSessionController(sessionController),
|
||||
SetConnectedProxyGetter(reversetunnel.NewConnectedProxyGetter()),
|
||||
SetInventoryControlHandle(newTestInventoryHandle(t, nodeClient, nodeID, types.RoleNode)),
|
||||
setChildLogConfigForTest(),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
@@ -3338,6 +3357,7 @@ func TestEventMetadata(t *testing.T) {
|
||||
SetX11ForwardingConfig(&x11.ServerConfig{}),
|
||||
SetSessionController(sessionController),
|
||||
SetConnectedProxyGetter(reversetunnel.NewConnectedProxyGetter()),
|
||||
SetInventoryControlHandle(newTestInventoryHandle(t, nodeClient, nodeID, types.RoleNode)),
|
||||
setChildLogConfigForTest(),
|
||||
}
|
||||
|
||||
@@ -4034,6 +4054,9 @@ func TestGetServerInfoHeartbeat(t *testing.T) {
|
||||
SetSessionController(sessionController),
|
||||
SetConnectedProxyGetter(reversetunnel.NewConnectedProxyGetter()),
|
||||
}
|
||||
if role == types.RoleNode {
|
||||
opts = append(opts, SetInventoryControlHandle(newTestInventoryHandle(t, client, serverID, role)))
|
||||
}
|
||||
opts = append(opts, extraOpts...)
|
||||
|
||||
s, err := New(
|
||||
|
||||
@@ -224,6 +224,22 @@ func noHistoryShell(t *testing.T) string {
|
||||
return shell
|
||||
}
|
||||
|
||||
func newTestInventoryHandle(t *testing.T, clt *authclient.Client, hostID string, role types.SystemRole) inventory.DownstreamHandle {
|
||||
t.Helper()
|
||||
handle, err := inventory.NewDownstreamHandle(clt.InventoryControlStream,
|
||||
func(_ context.Context) (*authproto.UpstreamInventoryHello, error) {
|
||||
return authproto.UpstreamInventoryHello_builder{
|
||||
ServerID: hostID,
|
||||
Version: teleport.Version,
|
||||
Services: types.SystemRoles{role}.StringSlice(),
|
||||
Hostname: "test",
|
||||
}.Build(), nil
|
||||
})
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() { require.NoError(t, handle.Close()) })
|
||||
return handle
|
||||
}
|
||||
|
||||
func newWebSuite(t *testing.T) *WebSuite {
|
||||
return newWebSuiteWithConfig(t, webSuiteConfig{})
|
||||
}
|
||||
@@ -403,6 +419,7 @@ func newWebSuiteWithConfig(t *testing.T, cfg webSuiteConfig) *WebSuite {
|
||||
|
||||
// create SSH service:
|
||||
nodeDataDir := t.TempDir()
|
||||
inventoryHandle := newTestInventoryHandle(t, nodeClient, nodeID, types.RoleNode)
|
||||
node, err := regular.New(
|
||||
ctx,
|
||||
utils.NetAddr{AddrNetwork: "tcp", Addr: "127.0.0.1:0"},
|
||||
@@ -423,6 +440,7 @@ func newWebSuiteWithConfig(t *testing.T, cfg webSuiteConfig) *WebSuite {
|
||||
regular.SetLockWatcher(nodeLockWatcher),
|
||||
regular.SetSessionController(nodeSessionController),
|
||||
regular.SetConnectedProxyGetter(reversetunnel.NewConnectedProxyGetter()),
|
||||
regular.SetInventoryControlHandle(inventoryHandle),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
s.node = node
|
||||
@@ -680,6 +698,9 @@ func newWebSuiteWithConfig(t *testing.T, cfg webSuiteConfig) *WebSuite {
|
||||
if err := s.node.Close(); err != nil {
|
||||
errors = append(errors, err)
|
||||
}
|
||||
// Close the inventory handle so its control stream doesn't block
|
||||
// s.server.Shutdown's graceful stop below.
|
||||
inventoryHandle.Close()
|
||||
s.webServer.Close()
|
||||
if err := s.proxy.Close(); err != nil {
|
||||
errors = append(errors, err)
|
||||
@@ -763,6 +784,7 @@ func (s *WebSuite) addNode(t *testing.T, uuid string, hostname string, address s
|
||||
regular.SetLockWatcher(nodeLockWatcher),
|
||||
regular.SetSessionController(nodeSessionController),
|
||||
regular.SetConnectedProxyGetter(reversetunnel.NewConnectedProxyGetter()),
|
||||
regular.SetInventoryControlHandle(newTestInventoryHandle(t, nodeClient, uuid, types.RoleNode)),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, node.Start())
|
||||
@@ -9133,6 +9155,7 @@ func newWebPack(t *testing.T, numProxies int, opts ...webPackOptions) *webPack {
|
||||
regular.SetLockWatcher(nodeLockWatcher),
|
||||
regular.SetSessionController(nodeSessionController),
|
||||
regular.SetConnectedProxyGetter(reversetunnel.NewConnectedProxyGetter()),
|
||||
regular.SetInventoryControlHandle(newTestInventoryHandle(t, nodeClient, nodeID, types.RoleNode)),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user