Add manual tracing instrumentation to tsh (#13204)

Create spans for all public facing TeleportClient,
ProxyClient, and NodeClient methods. This makes
correlating spans easier to reason about when
looking at `tsh` traces. As a result of creating
spans, some additional context propagation is
required as well to ensure that spans are linked
properly.

This also removes the unused `quiet` argument from
`ConnectToCluster`. It's usage was not consistent
by existing callers, and it was ignored, so in order
to avoid confusion in future calls, it was removed.

#12241
This commit is contained in:
rosstimothy 2022-06-11 11:34:40 -04:00 committed by GitHub
parent d08c95d40d
commit e5c745f331
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
27 changed files with 756 additions and 132 deletions

View file

@ -501,6 +501,8 @@ type Config struct {
ALPNSNIAuthDialClusterName string
// CircuitBreakerConfig defines how the circuit breaker should behave.
CircuitBreakerConfig breaker.Config
// Context is the base context to use for dialing. If not provided context.Background is used
Context context.Context
}
// CheckAndSetDefaults checks and sets default config values.
@ -522,6 +524,10 @@ func (c *Config) CheckAndSetDefaults() error {
c.CircuitBreakerConfig = breaker.DefaultBreakerConfig(clockwork.NewRealClock())
}
if c.Context == nil {
c.Context = context.Background()
}
c.DialOpts = append(c.DialOpts, grpc.WithKeepaliveParams(keepalive.ClientParameters{
Time: c.KeepAlivePeriod,
Timeout: c.KeepAlivePeriod * time.Duration(c.KeepAliveCount),

View file

@ -37,11 +37,6 @@ import (
"time"
"github.com/gravitational/teleport/api/breaker"
"golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh/agent"
"github.com/stretchr/testify/require"
apiclient "github.com/gravitational/teleport/api/client"
"github.com/gravitational/teleport/api/client/proto"
"github.com/gravitational/teleport/api/constants"
@ -56,6 +51,7 @@ import (
"github.com/gravitational/teleport/lib/defaults"
"github.com/gravitational/teleport/lib/events"
"github.com/gravitational/teleport/lib/kube/kubeconfig"
"github.com/gravitational/teleport/lib/observability/tracing"
"github.com/gravitational/teleport/lib/reversetunnel"
"github.com/gravitational/teleport/lib/service"
"github.com/gravitational/teleport/lib/services"
@ -64,11 +60,13 @@ import (
"github.com/gravitational/teleport/lib/tlsca"
"github.com/gravitational/teleport/lib/utils"
authztypes "k8s.io/client-go/kubernetes/typed/authorization/v1"
"github.com/gravitational/trace"
"github.com/jonboulle/clockwork"
log "github.com/sirupsen/logrus"
"github.com/stretchr/testify/require"
"golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh/agent"
authztypes "k8s.io/client-go/kubernetes/typed/authorization/v1"
)
const (
@ -424,7 +422,7 @@ func SetupUserCreds(tc *client.TeleportClient, proxyHost string, creds UserCreds
if err != nil {
return trace.Wrap(err)
}
err = tc.AddTrustedCA(creds.HostCA)
err = tc.AddTrustedCA(context.Background(), creds.HostCA)
if err != nil {
return trace.Wrap(err)
}
@ -1377,6 +1375,7 @@ func (i *TeleInstance) NewUnauthenticatedClient(cfg ClientConfig) (tc *client.Te
SSHProxyAddr: sshProxyAddr,
Interactive: cfg.Interactive,
TLSRoutingEnabled: i.isSinglePortSetup,
Tracer: tracing.NoopProvider().Tracer("test"),
}
// JumpHost turns on jump host mode
@ -1419,7 +1418,7 @@ func (i *TeleInstance) NewClient(cfg ClientConfig) (*client.TeleportClient, erro
return nil, trace.Wrap(err)
}
for _, ca := range cas {
err = tc.AddTrustedCA(ca)
err = tc.AddTrustedCA(context.Background(), ca)
if err != nil {
return nil, trace.Wrap(err)
}

View file

@ -41,10 +41,10 @@ import (
"testing"
"time"
"github.com/gravitational/teleport/api/breaker"
"golang.org/x/crypto/ssh"
"github.com/gravitational/teleport"
"github.com/gravitational/teleport/api/breaker"
"github.com/gravitational/teleport/api/client/proto"
"github.com/gravitational/teleport/api/constants"
apidefaults "github.com/gravitational/teleport/api/defaults"
@ -2434,7 +2434,7 @@ func trustedClusters(t *testing.T, suite *integrationTestSuite, test trustedClus
auxCAS, err := aux.Secrets.GetCAs()
require.NoError(t, err)
for _, auxCA := range auxCAS {
err = tc.AddTrustedCA(auxCA)
err = tc.AddTrustedCA(ctx, auxCA)
require.NoError(t, err)
}
@ -6167,7 +6167,7 @@ func testKubeAgentFiltering(t *testing.T, suite *integrationTestSuite) {
proxy, err := cl.ConnectToProxy(ctx)
require.NoError(t, err)
userSite, err := proxy.ConnectToCluster(ctx, Site, false)
userSite, err := proxy.ConnectToCluster(ctx, Site)
require.NoError(t, err)
services, err := userSite.GetKubeServices(ctx)
@ -6283,7 +6283,7 @@ func createTrustedClusterPair(t *testing.T, suite *integrationTestSuite, extraSe
leafCAs, err := leaf.Secrets.GetCAs()
require.NoError(t, err)
for _, leafCA := range leafCAs {
require.NoError(t, tc.AddTrustedCA(leafCA))
require.NoError(t, tc.AddTrustedCA(context.Background(), leafCA))
}
return tc

View file

@ -88,7 +88,11 @@ var _ ClientI = &Client{}
// functionality that hasn't been ported to the new client yet.
func NewClient(cfg client.Config, params ...roundtrip.ClientParam) (*Client, error) {
cfg.DialInBackground = true
apiClient, err := client.New(context.TODO(), cfg)
if err := cfg.CheckAndSetDefaults(); err != nil {
return nil, trace.Wrap(err)
}
apiClient, err := client.New(cfg.Context, cfg)
if err != nil {
return nil, trace.Wrap(err)
}

View file

@ -30,6 +30,7 @@ import (
"github.com/gravitational/teleport/api/profile"
"github.com/gravitational/teleport/lib/client"
"github.com/gravitational/teleport/lib/observability/tracing"
"github.com/gravitational/teleport/lib/utils"
"github.com/HdrHistogram/hdrhistogram-go"
@ -270,7 +271,10 @@ func execute(m benchMeasure) error {
// makeTeleportClient creates an instance of a teleport client
func makeTeleportClient(host, login, proxy string) (*client.TeleportClient, error) {
c := client.Config{Host: host}
c := client.Config{
Host: host,
Tracer: tracing.NoopProvider().Tracer("test"),
}
path := profile.FullProfilePath("")
if login != "" {
c.HostLogin = login

View file

@ -44,7 +44,7 @@ import (
"github.com/gravitational/teleport/api/client/webclient"
"github.com/gravitational/teleport/api/constants"
apidefaults "github.com/gravitational/teleport/api/defaults"
"github.com/gravitational/teleport/api/observability/tracing"
apitracing "github.com/gravitational/teleport/api/observability/tracing"
tracessh "github.com/gravitational/teleport/api/observability/tracing/ssh"
"github.com/gravitational/teleport/api/profile"
"github.com/gravitational/teleport/api/types"
@ -59,6 +59,7 @@ import (
"github.com/gravitational/teleport/lib/events"
kubeutils "github.com/gravitational/teleport/lib/kube/utils"
"github.com/gravitational/teleport/lib/modules"
"github.com/gravitational/teleport/lib/observability/tracing"
"github.com/gravitational/teleport/lib/services"
"github.com/gravitational/teleport/lib/session"
"github.com/gravitational/teleport/lib/shell"
@ -74,6 +75,8 @@ import (
"github.com/gravitational/trace"
"github.com/jonboulle/clockwork"
"github.com/sirupsen/logrus"
"go.opentelemetry.io/otel/attribute"
oteltrace "go.opentelemetry.io/otel/trace"
"golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh/agent"
)
@ -387,6 +390,9 @@ type Config struct {
// about and is often a source of bugs.
// Do not set this options unless you deeply understand what you are doing.
AllowStdinHijack bool
// Tracer is the tracer to create spans with
Tracer oteltrace.Tracer
}
// CachePolicy defines cache policy for local clients
@ -405,6 +411,7 @@ func MakeDefaultConfig() *Config {
Stdin: os.Stdin,
AddKeysToAgent: AddKeysToAgentAuto,
EnableEscapeSequences: true,
Tracer: tracing.NoopProvider().Tracer("TeleportClient"),
}
}
@ -1401,7 +1408,13 @@ func NewClient(c *Config) (tc *TeleportClient, err error) {
}
c.Namespace = types.ProcessNamespace(c.Namespace)
tc = &TeleportClient{Config: *c}
if c.Tracer == nil {
c.Tracer = tracing.NoopProvider().Tracer(teleport.ComponentTeleport)
}
tc = &TeleportClient{
Config: *c,
}
if tc.Stdout == nil {
tc.Stdout = os.Stdout
@ -1505,9 +1518,17 @@ func (tc *TeleportClient) LoadKeyForCluster(clusterName string) error {
return nil
}
// LoadKeyForCluster fetches a cluster-specific SSH key and loads it into the
// LoadKeyForClusterWithReissue fetches a cluster-specific SSH key and loads it into the
// SSH agent. If the key is not found, it is requested to be reissued.
func (tc *TeleportClient) LoadKeyForClusterWithReissue(ctx context.Context, clusterName string) error {
ctx, span := tc.Tracer.Start(
ctx,
"teleportClient/LoadKeyForClusterWithReissue",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
oteltrace.WithAttributes(attribute.String("cluster", clusterName)),
)
defer span.End()
err := tc.LoadKeyForCluster(clusterName)
if err == nil {
return nil
@ -1529,7 +1550,14 @@ func (tc *TeleportClient) LocalAgent() *LocalKeyAgent {
}
// RootClusterName returns root cluster name.
func (tc *TeleportClient) RootClusterName() (string, error) {
func (tc *TeleportClient) RootClusterName(ctx context.Context) (string, error) {
_, span := tc.Tracer.Start(
ctx,
"teleportClient/RootClusterName",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
)
defer span.End()
key, err := tc.LocalAgent().GetCoreKey()
if err != nil {
return "", trace.Wrap(err)
@ -1586,6 +1614,13 @@ func (tc *TeleportClient) getTargetNodes(ctx context.Context, proxy *ProxyClient
// ReissueUserCerts issues new user certs based on params and stores them in
// the local key agent (usually on disk in ~/.tsh).
func (tc *TeleportClient) ReissueUserCerts(ctx context.Context, cachePolicy CertCachePolicy, params ReissueParams) error {
ctx, span := tc.Tracer.Start(
ctx,
"teleportClient/ReissueUserCerts",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
)
defer span.End()
proxyClient, err := tc.ConnectToProxy(ctx)
if err != nil {
return trace.Wrap(err)
@ -1605,6 +1640,13 @@ func (tc *TeleportClient) ReissueUserCerts(ctx context.Context, cachePolicy Cert
// - for SSH certs, return the existing Key from the keystore.
// - for TLS certs, fall back to ReissueUserCerts.
func (tc *TeleportClient) IssueUserCertsWithMFA(ctx context.Context, params ReissueParams) (*Key, error) {
ctx, span := tc.Tracer.Start(
ctx,
"teleportClient/IssueUserCertsWithMFA",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
)
defer span.End()
proxyClient, err := tc.ConnectToProxy(ctx)
if err != nil {
return nil, trace.Wrap(err)
@ -1620,6 +1662,15 @@ func (tc *TeleportClient) IssueUserCertsWithMFA(ctx context.Context, params Reis
// CreateAccessRequest registers a new access request with the auth server.
func (tc *TeleportClient) CreateAccessRequest(ctx context.Context, req types.AccessRequest) error {
ctx, span := tc.Tracer.Start(
ctx,
"teleportClient/CreateAccessRequest",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
oteltrace.WithAttributes(attribute.String("request", req.GetName())),
)
defer span.End()
proxyClient, err := tc.ConnectToProxy(ctx)
if err != nil {
return trace.Wrap(err)
@ -1631,6 +1682,17 @@ func (tc *TeleportClient) CreateAccessRequest(ctx context.Context, req types.Acc
// GetAccessRequests loads all access requests matching the supplied filter.
func (tc *TeleportClient) GetAccessRequests(ctx context.Context, filter types.AccessRequestFilter) ([]types.AccessRequest, error) {
ctx, span := tc.Tracer.Start(
ctx,
"teleportClient/GetAccessRequests",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
oteltrace.WithAttributes(
attribute.String("id", filter.ID),
attribute.String("user", filter.User),
),
)
defer span.End()
proxyClient, err := tc.ConnectToProxy(ctx)
if err != nil {
return nil, trace.Wrap(err)
@ -1642,6 +1704,16 @@ func (tc *TeleportClient) GetAccessRequests(ctx context.Context, filter types.Ac
// GetRole loads a role resource by name.
func (tc *TeleportClient) GetRole(ctx context.Context, name string) (types.Role, error) {
ctx, span := tc.Tracer.Start(
ctx,
"teleportClient/GetRole",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
oteltrace.WithAttributes(
attribute.String("role", name),
),
)
defer span.End()
proxyClient, err := tc.ConnectToProxy(ctx)
if err != nil {
return nil, trace.Wrap(err)
@ -1665,6 +1737,16 @@ func (w watchCloser) Close() error {
// NewWatcher sets up a new event watcher.
func (tc *TeleportClient) NewWatcher(ctx context.Context, watch types.Watch) (types.Watcher, error) {
ctx, span := tc.Tracer.Start(
ctx,
"teleportClient/NewWatcher",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
oteltrace.WithAttributes(
attribute.String("name", watch.Name),
),
)
defer span.End()
proxyClient, err := tc.ConnectToProxy(ctx)
if err != nil {
return nil, trace.Wrap(err)
@ -1685,13 +1767,20 @@ func (tc *TeleportClient) NewWatcher(ctx context.Context, watch types.Watch) (ty
// WithRootClusterClient provides a functional interface for making calls
// against the root cluster's auth server.
func (tc *TeleportClient) WithRootClusterClient(ctx context.Context, do func(clt auth.ClientI) error) error {
ctx, span := tc.Tracer.Start(
ctx,
"teleportClient/WithRootClusterClient",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
)
defer span.End()
proxyClient, err := tc.ConnectToProxy(ctx)
if err != nil {
return trace.Wrap(err)
}
defer proxyClient.Close()
clt, err := proxyClient.ConnectToRootCluster(ctx, false)
clt, err := proxyClient.ConnectToRootCluster(ctx)
if err != nil {
return trace.Wrap(err)
}
@ -1703,7 +1792,7 @@ func (tc *TeleportClient) WithRootClusterClient(ctx context.Context, do func(clt
// NewTracingClient provides a tracing client that will forward spans on to
// the current clusters auth server. The auth server will then forward along to the configured
// telemetry backend.
func (tc *TeleportClient) NewTracingClient(ctx context.Context) (*tracing.Client, error) {
func (tc *TeleportClient) NewTracingClient(ctx context.Context) (*apitracing.Client, error) {
proxyClient, err := tc.ConnectToProxy(ctx)
if err != nil {
return nil, trace.Wrap(err)
@ -1727,6 +1816,16 @@ func (tc *TeleportClient) NewTracingClient(ctx context.Context) (*tracing.Client
//
// Returns nil if successful, or (possibly) *exec.ExitError
func (tc *TeleportClient) SSH(ctx context.Context, command []string, runLocally bool) error {
ctx, span := tc.Tracer.Start(
ctx,
"teleportClient/SSH",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
oteltrace.WithAttributes(
attribute.String("proxy", tc.Config.WebProxyAddr),
),
)
defer span.End()
// connect to proxy first:
if !tc.Config.ProxySpecified() {
return trace.BadParameter("proxy server is not specified")
@ -1753,7 +1852,7 @@ func (tc *TeleportClient) SSH(ctx context.Context, command []string, runLocally
ctx,
NodeAddr{Addr: nodeAddrs[0], Namespace: tc.Namespace, Cluster: siteInfo.Name},
tc.Config.HostLogin,
false)
)
if err != nil {
tc.ExitStatus = 1
return trace.Wrap(err)
@ -1829,6 +1928,17 @@ func (tc *TeleportClient) startPortForwarding(ctx context.Context, nodeClient *N
// Join connects to the existing/active SSH session
func (tc *TeleportClient) Join(ctx context.Context, mode types.SessionParticipantMode, namespace string, sessionID session.ID, input io.Reader) (err error) {
ctx, span := tc.Tracer.Start(
ctx,
"teleportClient/Join",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
oteltrace.WithAttributes(
attribute.String("session", sessionID.String()),
attribute.String("mode", string(mode)),
),
)
defer span.End()
if namespace == "" {
return trace.BadParameter(auth.MissingNamespaceError)
}
@ -1847,7 +1957,7 @@ func (tc *TeleportClient) Join(ctx context.Context, mode types.SessionParticipan
return trace.Wrap(err)
}
defer proxyClient.Close()
site, err := proxyClient.ConnectToCurrentCluster(ctx, false)
site, err := proxyClient.ConnectToCurrentCluster(ctx)
if err != nil {
return trace.Wrap(err)
}
@ -1866,7 +1976,7 @@ func (tc *TeleportClient) Join(ctx context.Context, mode types.SessionParticipan
Addr: session.GetAddress() + ":0",
Namespace: tc.Namespace,
Cluster: tc.SiteName,
}, tc.Config.HostLogin, false)
}, tc.Config.HostLogin)
if err != nil {
return trace.Wrap(err)
}
@ -1894,6 +2004,16 @@ func (tc *TeleportClient) Join(ctx context.Context, mode types.SessionParticipan
// Play replays the recorded session
func (tc *TeleportClient) Play(ctx context.Context, namespace, sessionID string) (err error) {
ctx, span := tc.Tracer.Start(
ctx,
"teleportClient/Play",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
oteltrace.WithAttributes(
attribute.String("session", sessionID),
),
)
defer span.End()
var sessionEvents []events.EventFields
var stream []byte
if namespace == "" {
@ -1910,7 +2030,7 @@ func (tc *TeleportClient) Play(ctx context.Context, namespace, sessionID string)
}
defer proxyClient.Close()
site, err := proxyClient.ConnectToCurrentCluster(ctx, false)
site, err := proxyClient.ConnectToCurrentCluster(ctx)
if err != nil {
return trace.Wrap(err)
}
@ -1936,6 +2056,16 @@ func (tc *TeleportClient) Play(ctx context.Context, namespace, sessionID string)
}
func (tc *TeleportClient) GetSessionEvents(ctx context.Context, namespace, sessionID string) ([]events.EventFields, error) {
ctx, span := tc.Tracer.Start(
ctx,
"teleportClient/GetSessionEvents",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
oteltrace.WithAttributes(
attribute.String("session", sessionID),
),
)
defer span.End()
if namespace == "" {
return nil, trace.BadParameter(auth.MissingNamespaceError)
}
@ -1950,7 +2080,7 @@ func (tc *TeleportClient) GetSessionEvents(ctx context.Context, namespace, sessi
}
defer proxyClient.Close()
site, err := proxyClient.ConnectToCurrentCluster(ctx, false)
site, err := proxyClient.ConnectToCurrentCluster(ctx)
if err != nil {
return nil, trace.Wrap(err)
}
@ -1990,6 +2120,13 @@ func PlayFile(ctx context.Context, tarFile io.Reader, sid string) error {
// ExecuteSCP executes SCP command. It executes scp.Command using
// lower-level API integrations that mimic SCP CLI command behavior
func (tc *TeleportClient) ExecuteSCP(ctx context.Context, cmd scp.Command) (err error) {
ctx, span := tc.Tracer.Start(
ctx,
"teleportClient/ExecuteSCP",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
)
defer span.End()
// connect to proxy first:
if !tc.Config.ProxySpecified() {
return trace.BadParameter("proxy server is not specified")
@ -2019,7 +2156,7 @@ func (tc *TeleportClient) ExecuteSCP(ctx context.Context, cmd scp.Command) (err
ctx,
NodeAddr{Addr: nodeAddrs[0], Namespace: tc.Namespace, Cluster: clusterInfo.Name},
tc.Config.HostLogin,
false)
)
if err != nil {
tc.ExitStatus = 1
return trace.Wrap(err)
@ -2041,6 +2178,13 @@ func (tc *TeleportClient) ExecuteSCP(ctx context.Context, cmd scp.Command) (err
// SCP securely copies file(s) from one SSH server to another
func (tc *TeleportClient) SCP(ctx context.Context, args []string, port int, flags scp.Flags, quiet bool) (err error) {
ctx, span := tc.Tracer.Start(
ctx,
"teleportClient/SCP",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
)
defer span.End()
if len(args) < 2 {
return trace.Errorf("need at least two arguments for scp")
}
@ -2079,7 +2223,7 @@ func (tc *TeleportClient) SCP(ctx context.Context, args []string, port int, flag
}
return proxyClient.ConnectToNode(ctx,
NodeAddr{Addr: addr, Namespace: tc.Namespace, Cluster: siteInfo.Name},
hostLogin, false)
hostLogin)
}
// gets called to convert SSH error code to tc.ExitStatus
@ -2196,6 +2340,13 @@ func isRemoteDest(name string) bool {
// ListNodesWithFilters returns a list of nodes connected to a proxy
func (tc *TeleportClient) ListNodesWithFilters(ctx context.Context) ([]types.Server, error) {
ctx, span := tc.Tracer.Start(
ctx,
"teleportClient/ListNodesWithFilters",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
)
defer span.End()
// connect to the proxy and ask it to return a full list of servers
proxyClient, err := tc.ConnectToProxy(ctx)
if err != nil {
@ -2246,6 +2397,13 @@ func (tc *TeleportClient) ListNodesWithFiltersAllClusters(ctx context.Context) (
// ListAppServersWithFilters returns a list of application servers.
func (tc *TeleportClient) ListAppServersWithFilters(ctx context.Context, customFilter *proto.ListResourcesRequest) ([]types.AppServer, error) {
ctx, span := tc.Tracer.Start(
ctx,
"teleportClient/ListAppServersWithFilters",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
)
defer span.End()
proxyClient, err := tc.ConnectToProxy(ctx)
if err != nil {
return nil, trace.Wrap(err)
@ -2305,6 +2463,13 @@ func (tc *TeleportClient) listAppServersWithFiltersAllClusters(ctx context.Conte
// ListApps returns all registered applications.
func (tc *TeleportClient) ListApps(ctx context.Context, customFilter *proto.ListResourcesRequest) ([]types.Application, error) {
ctx, span := tc.Tracer.Start(
ctx,
"teleportClient/ListApps",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
)
defer span.End()
servers, err := tc.ListAppServersWithFilters(ctx, customFilter)
if err != nil {
return nil, trace.Wrap(err)
@ -2335,6 +2500,13 @@ func (tc *TeleportClient) ListAppsAllClusters(ctx context.Context, customFilter
// CreateAppSession creates a new application access session.
func (tc *TeleportClient) CreateAppSession(ctx context.Context, req types.CreateAppSessionRequest) (types.WebSession, error) {
ctx, span := tc.Tracer.Start(
ctx,
"teleportClient/CreateAppSession",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
)
defer span.End()
proxyClient, err := tc.ConnectToProxy(ctx)
if err != nil {
return nil, trace.Wrap(err)
@ -2345,6 +2517,13 @@ func (tc *TeleportClient) CreateAppSession(ctx context.Context, req types.Create
// DeleteAppSession removes the specified application access session.
func (tc *TeleportClient) DeleteAppSession(ctx context.Context, sessionID string) error {
ctx, span := tc.Tracer.Start(
ctx,
"teleportClient/DeleteAppSession",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
)
defer span.End()
proxyClient, err := tc.ConnectToProxy(ctx)
if err != nil {
return trace.Wrap(err)
@ -2355,6 +2534,13 @@ func (tc *TeleportClient) DeleteAppSession(ctx context.Context, sessionID string
// ListDatabaseServersWithFilters returns all registered database proxy servers.
func (tc *TeleportClient) ListDatabaseServersWithFilters(ctx context.Context, customFilter *proto.ListResourcesRequest) ([]types.DatabaseServer, error) {
ctx, span := tc.Tracer.Start(
ctx,
"teleportClient/ListDatabaseServersWithFilters",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
)
defer span.End()
proxyClient, err := tc.ConnectToProxy(ctx)
if err != nil {
return nil, trace.Wrap(err)
@ -2414,6 +2600,13 @@ func (tc *TeleportClient) listDatabaseServersWithFiltersAllClusters(ctx context.
// ListDatabases returns all registered databases.
func (tc *TeleportClient) ListDatabases(ctx context.Context, customFilter *proto.ListResourcesRequest) ([]types.Database, error) {
ctx, span := tc.Tracer.Start(
ctx,
"teleportClient/ListDatabases",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
)
defer span.End()
servers, err := tc.ListDatabaseServersWithFilters(ctx, customFilter)
if err != nil {
return nil, trace.Wrap(err)
@ -2444,6 +2637,13 @@ func (tc *TeleportClient) ListDatabasesAllClusters(ctx context.Context, customFi
// ListAllNodes is the same as ListNodes except that it ignores labels.
func (tc *TeleportClient) ListAllNodes(ctx context.Context) ([]types.Server, error) {
ctx, span := tc.Tracer.Start(
ctx,
"teleportClient/ListAllNodes",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
)
defer span.End()
proxyClient, err := tc.ConnectToProxy(ctx)
if err != nil {
return nil, trace.Wrap(err)
@ -2467,7 +2667,7 @@ func (tc *TeleportClient) ListKubeClustersWithFiltersAllClusters(ctx context.Con
}
kubeClusters := make(map[string][]*types.KubernetesCluster, 0)
for _, cluster := range clusters {
ac, err := pc.ConnectToCluster(ctx, cluster.Name, true)
ac, err := pc.ConnectToCluster(ctx, cluster.Name)
if err != nil {
return nil, trace.Wrap(err)
}
@ -2497,7 +2697,7 @@ func (tc *TeleportClient) runCommandOnNodes(
var nodeClient *NodeClient
nodeClient, err = proxyClient.ConnectToNode(ctx,
NodeAddr{Addr: address, Namespace: tc.Namespace, Cluster: siteName},
tc.Config.HostLogin, false)
tc.Config.HostLogin)
if err != nil {
// err is passed to resultsC in the defer above.
fmt.Fprintln(tc.Stderr, err)
@ -2521,7 +2721,7 @@ func (tc *TeleportClient) runCommandOnNodes(
// runCommand executes a given bash command on an established NodeClient.
func (tc *TeleportClient) runCommand(ctx context.Context, nodeClient *NodeClient, command []string) error {
nodeSession, err := newSession(nodeClient, nil, tc.Config.Env, tc.Stdin, tc.Stdout, tc.Stderr, tc.EnableEscapeSequences)
nodeSession, err := newSession(ctx, nodeClient, nil, tc.Config.Env, tc.Stdin, tc.Stdout, tc.Stderr, tc.EnableEscapeSequences)
if err != nil {
return trace.Wrap(err)
}
@ -2563,7 +2763,7 @@ func (tc *TeleportClient) runShell(ctx context.Context, nodeClient *NodeClient,
env[key] = value
}
nodeSession, err := newSession(nodeClient, sessToJoin, env, tc.Stdin, tc.Stdout, tc.Stderr, tc.EnableEscapeSequences)
nodeSession, err := newSession(ctx, nodeClient, sessToJoin, env, tc.Stdin, tc.Stdout, tc.Stderr, tc.EnableEscapeSequences)
if err != nil {
return trace.Wrap(err)
}
@ -2613,12 +2813,22 @@ func (tc *TeleportClient) getProxySSHPrincipal() string {
// successful. If the passed in context is canceled, this function will return
// a trace.ConnectionProblem right away.
func (tc *TeleportClient) ConnectToProxy(ctx context.Context) (*ProxyClient, error) {
ctx, span := tc.Tracer.Start(
ctx,
"teleportClient/ConnectToProxy",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
oteltrace.WithAttributes(
attribute.String("proxy", tc.Config.WebProxyAddr),
),
)
defer span.End()
var err error
var proxyClient *ProxyClient
// Use connectContext and the cancel function to signal when a response is
// returned from connectToProxy.
connectContext, cancel := context.WithCancel(context.Background())
connectContext, cancel := context.WithCancel(ctx)
go func() {
defer cancel()
proxyClient, err = tc.connectToProxy(ctx)
@ -2716,6 +2926,7 @@ func (tc *TeleportClient) connectToProxy(ctx context.Context) (*ProxyClient, err
hostLogin: tc.HostLogin,
siteName: clusterName(),
clientAddr: tc.ClientAddr,
Tracer: tc.Tracer,
}, nil
}
@ -2908,6 +3119,13 @@ func (tc *TeleportClient) LogoutAll() error {
// PingAndShowMOTD pings the Teleport Proxy and displays the Message Of The Day if it's available.
func (tc *TeleportClient) PingAndShowMOTD(ctx context.Context) (*webclient.PingResponse, error) {
ctx, span := tc.Tracer.Start(
ctx,
"teleportClient/PingAndShowMOTD",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
)
defer span.End()
pr, err := tc.Ping(ctx)
if err != nil {
return nil, trace.Wrap(err)
@ -2922,8 +3140,15 @@ func (tc *TeleportClient) PingAndShowMOTD(ctx context.Context) (*webclient.PingR
return pr, nil
}
// GetWebConfig retreives Teleport proxy web config
// GetWebConfig retrieves Teleport proxy web config
func (tc *TeleportClient) GetWebConfig(ctx context.Context) (*webclient.WebConfig, error) {
ctx, span := tc.Tracer.Start(
ctx,
"teleportClient/GetWebConfig",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
)
defer span.End()
cfg, err := GetWebConfig(ctx, tc.WebProxyAddr, tc.InsecureSkipVerify)
if err != nil {
return nil, trace.Wrap(err)
@ -2936,6 +3161,13 @@ func (tc *TeleportClient) GetWebConfig(ctx context.Context) (*webclient.WebConfi
// The returned Key should typically be passed to ActivateKey in order to
// update local agent state.
func (tc *TeleportClient) Login(ctx context.Context) (*Key, error) {
ctx, span := tc.Tracer.Start(
ctx,
"teleportClient/Login",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
)
defer span.End()
// Ping the endpoint to see if it's up and find the type of authentication
// supported, also show the message of the day if available.
pr, err := tc.PingAndShowMOTD(ctx)
@ -3208,6 +3440,13 @@ func (tc *TeleportClient) ssoLogin(ctx context.Context, connectorID string, pub
// ActivateKey saves the target session cert into the local
// keystore (and into the ssh-agent) for future use.
func (tc *TeleportClient) ActivateKey(ctx context.Context, key *Key) error {
ctx, span := tc.Tracer.Start(
ctx,
"teleportClient/ActivateKey",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
)
defer span.End()
if tc.localAgent == nil {
// skip activation if no local agent is present
return nil
@ -3257,6 +3496,13 @@ func (tc *TeleportClient) ActivateKey(ctx context.Context, key *Key) error {
// Ping can be called for its side-effect of applying the proxy-provided
// settings (such as various listening addresses).
func (tc *TeleportClient) Ping(ctx context.Context) (*webclient.PingResponse, error) {
ctx, span := tc.Tracer.Start(
ctx,
"teleportClient/Ping",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
)
defer span.End()
// If, at some point, there's a need to bypass this caching, consider
// adding a bool argument. At the time of writing this we always want to
// cache.
@ -3300,6 +3546,13 @@ func (tc *TeleportClient) Ping(ctx context.Context) (*webclient.PingResponse, er
// ShowMOTD fetches the cluster MotD, displays it (if any) and waits for
// confirmation from the user.
func (tc *TeleportClient) ShowMOTD(ctx context.Context) error {
ctx, span := tc.Tracer.Start(
ctx,
"teleportClient/ShowMOTD",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
)
defer span.End()
motd, err := webclient.GetMOTD(
&webclient.Config{
Context: ctx,
@ -3354,6 +3607,14 @@ func (tc *TeleportClient) UpdateKnownHosts(ctx context.Context, proxyHost, clust
// GetTrustedCA returns a list of host certificate authorities
// trusted by the cluster client is authenticated with.
func (tc *TeleportClient) GetTrustedCA(ctx context.Context, clusterName string) ([]types.CertAuthority, error) {
ctx, span := tc.Tracer.Start(
ctx,
"teleportClient/GetTrustedCA",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
oteltrace.WithAttributes(attribute.String("cluster", clusterName)),
)
defer span.End()
// Connect to the proxy.
if !tc.Config.ProxySpecified() {
return nil, trace.BadParameter("proxy server is not specified")
@ -3365,7 +3626,7 @@ func (tc *TeleportClient) GetTrustedCA(ctx context.Context, clusterName string)
defer proxyClient.Close()
// Get a client to the Auth Server.
clt, err := proxyClient.ClusterAccessPoint(ctx, clusterName, true)
clt, err := proxyClient.ClusterAccessPoint(ctx, clusterName)
if err != nil {
return nil, trace.Wrap(err)
}
@ -3377,6 +3638,14 @@ func (tc *TeleportClient) GetTrustedCA(ctx context.Context, clusterName string)
// UpdateTrustedCA connects to the Auth Server and fetches all host certificates
// and updates ~/.tsh/keys/proxy/certs.pem and ~/.tsh/known_hosts.
func (tc *TeleportClient) UpdateTrustedCA(ctx context.Context, clusterName string) error {
ctx, span := tc.Tracer.Start(
ctx,
"teleportClient/UpdateTrustedCA",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
oteltrace.WithAttributes(attribute.String("cluster", clusterName)),
)
defer span.End()
if tc.localAgent == nil {
return trace.BadParameter("TeleportClient.UpdateTrustedCA called on a client without localAgent")
}
@ -3556,7 +3825,14 @@ func (tc *TeleportClient) applyProxySettings(proxySettings webclient.ProxySettin
}
// AddTrustedCA adds a new CA as trusted CA for this client, used in tests
func (tc *TeleportClient) AddTrustedCA(ca types.CertAuthority) error {
func (tc *TeleportClient) AddTrustedCA(ctx context.Context, ca types.CertAuthority) error {
_, span := tc.Tracer.Start(
ctx,
"teleportClient/AddTrustedCA",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
)
defer span.End()
if tc.localAgent == nil {
return trace.BadParameter("TeleportClient.AddTrustedCA called on a client without localAgent")
}

View file

@ -26,13 +26,14 @@ import (
"testing"
"time"
"github.com/google/uuid"
"github.com/gravitational/teleport/api/breaker"
"github.com/gravitational/teleport/api/client/proto"
"github.com/gravitational/teleport/api/constants"
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/lib/auth"
"github.com/gravitational/teleport/lib/auth/mocku2f"
wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
wancli "github.com/gravitational/teleport/lib/auth/webauthncli"
"github.com/gravitational/teleport/lib/backend"
"github.com/gravitational/teleport/lib/client"
"github.com/gravitational/teleport/lib/defaults"
@ -40,13 +41,12 @@ import (
"github.com/gravitational/teleport/lib/services"
"github.com/gravitational/teleport/lib/utils"
"github.com/gravitational/teleport/lib/utils/prompt"
"github.com/google/uuid"
"github.com/jonboulle/clockwork"
"github.com/pquerna/otp/totp"
"github.com/stretchr/testify/require"
wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
wancli "github.com/gravitational/teleport/lib/auth/webauthncli"
log "github.com/sirupsen/logrus"
"github.com/stretchr/testify/require"
)
func TestTeleportClient_Login_local(t *testing.T) {

View file

@ -21,14 +21,16 @@ import (
"os"
"testing"
"github.com/gravitational/teleport/api/client/webclient"
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/lib/defaults"
"github.com/gravitational/teleport/lib/utils"
"github.com/gravitational/trace"
"golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh/agent"
"github.com/gravitational/teleport/api/client/webclient"
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/lib/defaults"
"github.com/gravitational/teleport/lib/observability/tracing"
"github.com/gravitational/teleport/lib/utils"
"github.com/stretchr/testify/require"
"gopkg.in/check.v1"
)
@ -191,6 +193,7 @@ func (s *APITestSuite) TestNew(c *check.C) {
KeysDir: "/tmp",
Username: "localuser",
SiteName: "site",
Tracer: tracing.NoopProvider().Tracer("test"),
}
err := conf.ParseProxyHost("proxy")
c.Assert(err, check.IsNil)
@ -539,6 +542,7 @@ func TestNewClient_UseKeyPrincipals(t *testing.T) {
UseKeyPrincipals: true, // causes VALID to be returned, as key was used
Agent: &mockAgent{ValidPrincipals: []string{"VALID"}},
AuthMethods: []ssh.AuthMethod{ssh.Password("xyz") /* placeholder authmethod */},
Tracer: tracing.NoopProvider().Tracer("test"),
}
client, err := NewClient(cfg)
require.NoError(t, err)

View file

@ -48,6 +48,8 @@ import (
"github.com/gravitational/trace"
"github.com/moby/term"
"go.opentelemetry.io/otel/attribute"
oteltrace "go.opentelemetry.io/otel/trace"
"golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh/agent"
)
@ -57,6 +59,7 @@ import (
type ProxyClient struct {
teleportClient *TeleportClient
Client *tracessh.Client
Tracer oteltrace.Tracer
hostLogin string
proxyAddress string
proxyPrincipal string
@ -70,6 +73,7 @@ type ProxyClient struct {
// NodeClient can run shell and commands or upload and download files.
type NodeClient struct {
Namespace string
Tracer oteltrace.Tracer
Client *tracessh.Client
Proxy *ProxyClient
TC *TeleportClient
@ -80,6 +84,16 @@ type NodeClient struct {
// Each site is returned as an instance of its auth server
//
func (proxy *ProxyClient) GetSites(ctx context.Context) ([]types.Site, error) {
ctx, span := proxy.Tracer.Start(
ctx,
"proxyClient/GetSites",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
oteltrace.WithAttributes(
attribute.String("cluster", proxy.siteName),
),
)
defer span.End()
proxySession, err := proxy.Client.NewSession(ctx)
if err != nil {
return nil, trace.Wrap(err)
@ -121,7 +135,17 @@ func (proxy *ProxyClient) GetSites(ctx context.Context) ([]types.Site, error) {
// GetLeafClusters returns the leaf/remote clusters.
func (proxy *ProxyClient) GetLeafClusters(ctx context.Context) ([]types.RemoteCluster, error) {
clt, err := proxy.ConnectToRootCluster(ctx, false)
ctx, span := proxy.Tracer.Start(
ctx,
"proxyClient/GetLeafClusters",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
oteltrace.WithAttributes(
attribute.String("cluster", proxy.siteName),
),
)
defer span.End()
clt, err := proxy.ConnectToRootCluster(ctx)
if err != nil {
return nil, trace.Wrap(err)
}
@ -218,6 +242,16 @@ const (
// ReissueUserCerts generates certificates for the user
// that have a metadata instructing server to route the requests to the cluster
func (proxy *ProxyClient) ReissueUserCerts(ctx context.Context, cachePolicy CertCachePolicy, params ReissueParams) error {
ctx, span := proxy.Tracer.Start(
ctx,
"proxyClient/ReissueUserCerts",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
oteltrace.WithAttributes(
attribute.String("cluster", proxy.siteName),
),
)
defer span.End()
key, err := proxy.reissueUserCerts(ctx, cachePolicy, params)
if err != nil {
return trace.Wrap(err)
@ -261,7 +295,7 @@ func (proxy *ProxyClient) reissueUserCerts(ctx context.Context, cachePolicy Cert
return nil, trace.Wrap(err)
}
clt, err := proxy.ConnectToRootCluster(ctx, true)
clt, err := proxy.ConnectToRootCluster(ctx)
if err != nil {
return nil, trace.Wrap(err)
}
@ -327,6 +361,16 @@ type PromptMFAChallengeHandler func(ctx context.Context, proxyAddr string, c *pr
// IssueUserCertsWithMFA generates a single-use certificate for the user.
func (proxy *ProxyClient) IssueUserCertsWithMFA(ctx context.Context, params ReissueParams, promptMFAChallenge PromptMFAChallengeHandler) (*Key, error) {
ctx, span := proxy.Tracer.Start(
ctx,
"proxyClient/IssueUserCertsWithMFA",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
oteltrace.WithAttributes(
attribute.String("cluster", proxy.siteName),
),
)
defer span.End()
if params.RouteToCluster == "" {
params.RouteToCluster = proxy.siteName
}
@ -341,7 +385,7 @@ func (proxy *ProxyClient) IssueUserCertsWithMFA(ctx context.Context, params Reis
// Connect to the target cluster (root or leaf) to check whether MFA is
// required.
clt, err := proxy.ConnectToCluster(ctx, params.RouteToCluster, true)
clt, err := proxy.ConnectToCluster(ctx, params.RouteToCluster)
if err != nil {
return nil, trace.Wrap(err)
}
@ -380,7 +424,7 @@ func (proxy *ProxyClient) IssueUserCertsWithMFA(ctx context.Context, params Reis
}
if params.RouteToCluster != rootClusterName {
clt.Close()
clt, err = proxy.ConnectToCluster(ctx, rootClusterName, true)
clt, err = proxy.ConnectToCluster(ctx, rootClusterName)
if err != nil {
return nil, trace.Wrap(err)
}
@ -497,7 +541,14 @@ func (proxy *ProxyClient) prepareUserCertsRequest(params ReissueParams, key *Key
}
// RootClusterName returns name of the current cluster
func (proxy *ProxyClient) RootClusterName() (string, error) {
func (proxy *ProxyClient) RootClusterName(ctx context.Context) (string, error) {
_, span := proxy.Tracer.Start(
ctx,
"proxyClient/RootClusterName",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
)
defer span.End()
tlsKey, err := proxy.localAgent().GetCoreKey()
if err != nil {
if trace.IsNotFound(err) {
@ -524,16 +575,35 @@ func (proxy *ProxyClient) RootClusterName() (string, error) {
// CreateAccessRequest registers a new access request with the auth server.
func (proxy *ProxyClient) CreateAccessRequest(ctx context.Context, req types.AccessRequest) error {
site, err := proxy.ConnectToCurrentCluster(ctx, false)
ctx, span := proxy.Tracer.Start(
ctx,
"proxyClient/CreateAccessRequest",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
oteltrace.WithAttributes(attribute.String("request", req.GetName())),
)
defer span.End()
site, err := proxy.ConnectToCurrentCluster(ctx)
if err != nil {
return trace.Wrap(err)
}
return site.CreateAccessRequest(ctx, req)
}
// GetAccessRequests loads all access requests matching the spupplied filter.
// GetAccessRequests loads all access requests matching the supplied filter.
func (proxy *ProxyClient) GetAccessRequests(ctx context.Context, filter types.AccessRequestFilter) ([]types.AccessRequest, error) {
site, err := proxy.ConnectToCurrentCluster(ctx, false)
ctx, span := proxy.Tracer.Start(
ctx,
"proxyClient/GetAccessRequests",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
oteltrace.WithAttributes(
attribute.String("id", filter.ID),
attribute.String("user", filter.User),
),
)
defer span.End()
site, err := proxy.ConnectToCurrentCluster(ctx)
if err != nil {
return nil, trace.Wrap(err)
}
@ -546,7 +616,17 @@ func (proxy *ProxyClient) GetAccessRequests(ctx context.Context, filter types.Ac
// GetRole loads a role resource by name.
func (proxy *ProxyClient) GetRole(ctx context.Context, name string) (types.Role, error) {
site, err := proxy.ConnectToCurrentCluster(ctx, false)
ctx, span := proxy.Tracer.Start(
ctx,
"proxyClient/GetRole",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
oteltrace.WithAttributes(
attribute.String("role", name),
),
)
defer span.End()
site, err := proxy.ConnectToCurrentCluster(ctx)
if err != nil {
return nil, trace.Wrap(err)
}
@ -559,7 +639,17 @@ func (proxy *ProxyClient) GetRole(ctx context.Context, name string) (types.Role,
// NewWatcher sets up a new event watcher.
func (proxy *ProxyClient) NewWatcher(ctx context.Context, watch types.Watch) (types.Watcher, error) {
site, err := proxy.ConnectToCurrentCluster(ctx, false)
ctx, span := proxy.Tracer.Start(
ctx,
"proxyClient/NewWatcher",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
oteltrace.WithAttributes(
attribute.String("name", watch.Name),
),
)
defer span.End()
site, err := proxy.ConnectToCurrentCluster(ctx)
if err != nil {
return nil, trace.Wrap(err)
}
@ -572,7 +662,7 @@ func (proxy *ProxyClient) NewWatcher(ctx context.Context, watch types.Watch) (ty
// isAuthBoring checks whether or not the auth server for the current cluster was compiled with BoringCrypto.
func (proxy *ProxyClient) isAuthBoring(ctx context.Context) (bool, error) {
site, err := proxy.ConnectToCurrentCluster(ctx, false)
site, err := proxy.ConnectToCurrentCluster(ctx)
if err != nil {
return false, trace.Wrap(err)
}
@ -582,6 +672,19 @@ func (proxy *ProxyClient) isAuthBoring(ctx context.Context) (bool, error) {
// FindNodesByFilters returns list of the nodes which have filters matched.
func (proxy *ProxyClient) FindNodesByFilters(ctx context.Context, req proto.ListResourcesRequest) ([]types.Server, error) {
ctx, span := proxy.Tracer.Start(
ctx,
"proxyClient/FindNodesByFilters",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
oteltrace.WithAttributes(
attribute.String("resource", req.ResourceType),
attribute.Int("limit", int(req.Limit)),
attribute.String("predicate", req.PredicateExpression),
attribute.StringSlice("keywords", req.SearchKeywords),
),
)
defer span.End()
cluster, err := proxy.currentCluster(ctx)
if err != nil {
return nil, trace.Wrap(err)
@ -592,9 +695,23 @@ func (proxy *ProxyClient) FindNodesByFilters(ctx context.Context, req proto.List
// FindNodesByFiltersForCluster returns list of the nodes in a specified cluster which have filters matched.
func (proxy *ProxyClient) FindNodesByFiltersForCluster(ctx context.Context, req proto.ListResourcesRequest, cluster string) ([]types.Server, error) {
ctx, span := proxy.Tracer.Start(
ctx,
"proxyClient/FindNodesByFiltersForCluster",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
oteltrace.WithAttributes(
attribute.String("cluster", cluster),
attribute.String("resource", req.ResourceType),
attribute.Int("limit", int(req.Limit)),
attribute.String("predicate", req.PredicateExpression),
attribute.StringSlice("keywords", req.SearchKeywords),
),
)
defer span.End()
req.ResourceType = types.KindNode
site, err := proxy.ClusterAccessPoint(ctx, cluster, false)
site, err := proxy.ClusterAccessPoint(ctx, cluster)
if err != nil {
return nil, trace.Wrap(err)
}
@ -614,6 +731,19 @@ func (proxy *ProxyClient) FindNodesByFiltersForCluster(ctx context.Context, req
// FindAppServersByFilters returns a list of application servers in the current cluster which have filters matched.
func (proxy *ProxyClient) FindAppServersByFilters(ctx context.Context, req proto.ListResourcesRequest) ([]types.AppServer, error) {
ctx, span := proxy.Tracer.Start(
ctx,
"proxyClient/FindAppServersByFilters",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
oteltrace.WithAttributes(
attribute.String("resource", req.ResourceType),
attribute.Int("limit", int(req.Limit)),
attribute.String("predicate", req.PredicateExpression),
attribute.StringSlice("keywords", req.SearchKeywords),
),
)
defer span.End()
cluster, err := proxy.currentCluster(ctx)
if err != nil {
return nil, trace.Wrap(err)
@ -624,8 +754,22 @@ func (proxy *ProxyClient) FindAppServersByFilters(ctx context.Context, req proto
// FindAppServersByFiltersForCluster returns a list of application servers for a given cluster which have filters matched.
func (proxy *ProxyClient) FindAppServersByFiltersForCluster(ctx context.Context, req proto.ListResourcesRequest, cluster string) ([]types.AppServer, error) {
ctx, span := proxy.Tracer.Start(
ctx,
"proxyClient/FindAppServersByFiltersForCluster",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
oteltrace.WithAttributes(
attribute.String("cluster", cluster),
attribute.String("resource", req.ResourceType),
attribute.Int("limit", int(req.Limit)),
attribute.String("predicate", req.PredicateExpression),
attribute.StringSlice("keywords", req.SearchKeywords),
),
)
defer span.End()
req.ResourceType = types.KindAppServer
authClient, err := proxy.ClusterAccessPoint(ctx, cluster, false)
authClient, err := proxy.ClusterAccessPoint(ctx, cluster)
if err != nil {
return nil, trace.Wrap(err)
}
@ -657,11 +801,22 @@ func (proxy *ProxyClient) FindAppServersByFiltersForCluster(ctx context.Context,
// CreateAppSession creates a new application access session.
func (proxy *ProxyClient) CreateAppSession(ctx context.Context, req types.CreateAppSessionRequest) (types.WebSession, error) {
clusterName, err := proxy.RootClusterName()
ctx, span := proxy.Tracer.Start(
ctx,
"proxyClient/CreateAppSession",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
oteltrace.WithAttributes(
attribute.String("username", req.Username),
attribute.String("cluster", req.ClusterName),
),
)
defer span.End()
clusterName, err := proxy.RootClusterName(ctx)
if err != nil {
return nil, trace.Wrap(err)
}
authClient, err := proxy.ConnectToCluster(ctx, clusterName, true)
authClient, err := proxy.ConnectToCluster(ctx, clusterName)
if err != nil {
return nil, trace.Wrap(err)
}
@ -670,7 +825,7 @@ func (proxy *ProxyClient) CreateAppSession(ctx context.Context, req types.Create
return nil, trace.Wrap(err)
}
// Make sure to wait for the created app session to propagate through the cache.
accessPoint, err := proxy.ClusterAccessPoint(ctx, clusterName, true)
accessPoint, err := proxy.ClusterAccessPoint(ctx, clusterName)
if err != nil {
return nil, trace.Wrap(err)
}
@ -683,7 +838,17 @@ func (proxy *ProxyClient) CreateAppSession(ctx context.Context, req types.Create
// DeleteAppSession removes the specified application access session.
func (proxy *ProxyClient) DeleteAppSession(ctx context.Context, sessionID string) error {
authClient, err := proxy.ConnectToRootCluster(ctx, true)
ctx, span := proxy.Tracer.Start(
ctx,
"proxyClient/DeleteAppSession",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
oteltrace.WithAttributes(
attribute.String("session", sessionID),
),
)
defer span.End()
authClient, err := proxy.ConnectToRootCluster(ctx)
if err != nil {
return trace.Wrap(err)
}
@ -696,7 +861,17 @@ func (proxy *ProxyClient) DeleteAppSession(ctx context.Context, sessionID string
// DeleteUserAppSessions removes user's all application web sessions.
func (proxy *ProxyClient) DeleteUserAppSessions(ctx context.Context, req *proto.DeleteUserAppSessionsRequest) error {
authClient, err := proxy.ConnectToRootCluster(ctx, true)
ctx, span := proxy.Tracer.Start(
ctx,
"proxyClient/DeleteUserAppSessions",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
oteltrace.WithAttributes(
attribute.String("username", req.Username),
),
)
defer span.End()
authClient, err := proxy.ConnectToRootCluster(ctx)
if err != nil {
return trace.Wrap(err)
}
@ -709,6 +884,19 @@ func (proxy *ProxyClient) DeleteUserAppSessions(ctx context.Context, req *proto.
// FindDatabaseServersByFilters returns registered database proxy servers that match the provided filter.
func (proxy *ProxyClient) FindDatabaseServersByFilters(ctx context.Context, req proto.ListResourcesRequest) ([]types.DatabaseServer, error) {
ctx, span := proxy.Tracer.Start(
ctx,
"proxyClient/FindDatabaseServersByFilters",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
oteltrace.WithAttributes(
attribute.String("resource", req.ResourceType),
attribute.Int("limit", int(req.Limit)),
attribute.String("predicate", req.PredicateExpression),
attribute.StringSlice("keywords", req.SearchKeywords),
),
)
defer span.End()
cluster, err := proxy.currentCluster(ctx)
if err != nil {
return nil, trace.Wrap(err)
@ -719,8 +907,22 @@ func (proxy *ProxyClient) FindDatabaseServersByFilters(ctx context.Context, req
// FindDatabaseServersByFiltersForCluster returns all registered database proxy servers in the current cluster.
func (proxy *ProxyClient) FindDatabaseServersByFiltersForCluster(ctx context.Context, req proto.ListResourcesRequest, cluster string) ([]types.DatabaseServer, error) {
ctx, span := proxy.Tracer.Start(
ctx,
"proxyClient/FindDatabaseServersByFiltersForCluster",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
oteltrace.WithAttributes(
attribute.String("cluster", cluster),
attribute.String("resource", req.ResourceType),
attribute.Int("limit", int(req.Limit)),
attribute.String("predicate", req.PredicateExpression),
attribute.StringSlice("keywords", req.SearchKeywords),
),
)
defer span.End()
req.ResourceType = types.KindDatabaseServer
authClient, err := proxy.ClusterAccessPoint(ctx, cluster, false)
authClient, err := proxy.ClusterAccessPoint(ctx, cluster)
if err != nil {
return nil, trace.Wrap(err)
}
@ -751,7 +953,18 @@ func (proxy *ProxyClient) FindDatabaseServersByFiltersForCluster(ctx context.Con
// ListResources returns a paginated list of resources.
func (proxy *ProxyClient) ListResources(ctx context.Context, namespace, resource, startKey string, limit int) ([]types.ResourceWithLabels, string, error) {
authClient, err := proxy.CurrentClusterAccessPoint(ctx, false)
ctx, span := proxy.Tracer.Start(
ctx,
"proxyClient/ListResources",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
oteltrace.WithAttributes(
attribute.String("resource", resource),
attribute.Int("limit", limit),
),
)
defer span.End()
authClient, err := proxy.CurrentClusterAccessPoint(ctx)
if err != nil {
return nil, "", trace.Wrap(err)
}
@ -770,22 +983,39 @@ func (proxy *ProxyClient) ListResources(ctx context.Context, namespace, resource
// 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.ClientI, error) {
func (proxy *ProxyClient) CurrentClusterAccessPoint(ctx context.Context) (auth.ClientI, error) {
ctx, span := proxy.Tracer.Start(
ctx,
"proxyClient/CurrentClusterAccessPoint",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
)
defer span.End()
// get the current cluster:
cluster, err := proxy.currentCluster(ctx)
if err != nil {
return nil, trace.Wrap(err)
}
return proxy.ClusterAccessPoint(ctx, cluster.Name, quiet)
return proxy.ClusterAccessPoint(ctx, cluster.Name)
}
// 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.ClientI, error) {
func (proxy *ProxyClient) ClusterAccessPoint(ctx context.Context, clusterName string) (auth.ClientI, error) {
ctx, span := proxy.Tracer.Start(
ctx,
"proxyClient/ClusterAccessPoint",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
oteltrace.WithAttributes(
attribute.String("cluster", clusterName),
),
)
defer span.End()
if clusterName == "" {
return nil, trace.BadParameter("parameter clusterName is missing")
}
clt, err := proxy.ConnectToCluster(ctx, clusterName, quiet)
clt, err := proxy.ConnectToCluster(ctx, clusterName)
if err != nil {
return nil, trace.Wrap(err)
}
@ -797,25 +1027,39 @@ func (proxy *ProxyClient) ClusterAccessPoint(ctx context.Context, clusterName st
//
// if 'quiet' is set to true, no errors will be printed to stdout, otherwise
// any connection errors are visible to a user.
func (proxy *ProxyClient) ConnectToCurrentCluster(ctx context.Context, quiet bool) (auth.ClientI, error) {
func (proxy *ProxyClient) ConnectToCurrentCluster(ctx context.Context) (auth.ClientI, error) {
ctx, span := proxy.Tracer.Start(
ctx,
"proxyClient/ConnectToCurrentCluster",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
)
defer span.End()
cluster, err := proxy.currentCluster(ctx)
if err != nil {
return nil, trace.Wrap(err)
}
return proxy.ConnectToCluster(ctx, cluster.Name, quiet)
return proxy.ConnectToCluster(ctx, cluster.Name)
}
// ConnectToRootCluster connects to the auth server of the root cluster
// cluster via proxy. It returns connected and authenticated auth server client
// via proxy. It returns connected and authenticated auth server client
//
// if 'quiet' is set to true, no errors will be printed to stdout, otherwise
// any connection errors are visible to a user.
func (proxy *ProxyClient) ConnectToRootCluster(ctx context.Context, quiet bool) (auth.ClientI, error) {
clusterName, err := proxy.RootClusterName()
func (proxy *ProxyClient) ConnectToRootCluster(ctx context.Context) (auth.ClientI, error) {
ctx, span := proxy.Tracer.Start(
ctx,
"proxyClient/ConnectToRootCluster",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
)
defer span.End()
clusterName, err := proxy.RootClusterName(ctx)
if err != nil {
return nil, trace.Wrap(err)
}
return proxy.ConnectToCluster(ctx, clusterName, quiet)
return proxy.ConnectToCluster(ctx, clusterName)
}
func (proxy *ProxyClient) loadTLS(clusterName string) (*tls.Config, error) {
@ -844,7 +1088,8 @@ func (proxy *ProxyClient) ConnectToAuthServiceThroughALPNSNIProxy(ctx context.Co
}
tlsConfig.InsecureSkipVerify = proxy.teleportClient.InsecureSkipVerify
clt, err := auth.NewClient(client.Config{
Addrs: []string{proxy.teleportClient.WebProxyAddr},
Context: ctx,
Addrs: []string{proxy.teleportClient.WebProxyAddr},
Credentials: []client.Credentials{
client.LoadTLS(tlsConfig),
},
@ -859,10 +1104,17 @@ func (proxy *ProxyClient) ConnectToAuthServiceThroughALPNSNIProxy(ctx context.Co
// ConnectToCluster connects to the auth server of the given cluster via proxy.
// It returns connected and authenticated auth server client
//
// if 'quiet' is set to true, no errors will be printed to stdout, otherwise
// any connection errors are visible to a user.
func (proxy *ProxyClient) ConnectToCluster(ctx context.Context, clusterName string, quiet bool) (auth.ClientI, error) {
func (proxy *ProxyClient) ConnectToCluster(ctx context.Context, clusterName string) (auth.ClientI, error) {
ctx, span := proxy.Tracer.Start(
ctx,
"proxyClient/ConnectToCluster",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
oteltrace.WithAttributes(
attribute.String("cluster", clusterName),
),
)
defer span.End()
// If proxy supports multiplex listener mode dial root/leaf cluster auth service via ALPN Proxy
// directly without using SSH tunnels.
if proxy.teleportClient.TLSRoutingEnabled {
@ -874,12 +1126,17 @@ func (proxy *ProxyClient) ConnectToCluster(ctx context.Context, clusterName stri
}
dialer := client.ContextDialerFunc(func(ctx context.Context, network, _ string) (net.Conn, error) {
// link the span created dialing the auth server to the one created above. grpc dialing
// passes in a context.Background() during dial which causes these two spans to be in
// different traces.
ctx = oteltrace.ContextWithSpan(ctx, span)
return proxy.dialAuthServer(ctx, clusterName)
})
if proxy.teleportClient.SkipLocalAuth {
return auth.NewClient(client.Config{
Dialer: dialer,
Context: ctx,
Dialer: dialer,
Credentials: []client.Credentials{
client.LoadTLS(proxy.teleportClient.TLS),
},
@ -897,7 +1154,8 @@ func (proxy *ProxyClient) ConnectToCluster(ctx context.Context, clusterName stri
}
tlsConfig.InsecureSkipVerify = proxy.teleportClient.InsecureSkipVerify
clt, err := auth.NewClient(client.Config{
Dialer: dialer,
Context: ctx,
Dialer: dialer,
Credentials: []client.Credentials{
client.LoadTLS(tlsConfig),
},
@ -1034,6 +1292,16 @@ func (proxy *ProxyClient) isRecordingProxy() (bool, error) {
// dialAuthServer returns auth server connection forwarded via proxy
func (proxy *ProxyClient) dialAuthServer(ctx context.Context, clusterName string) (net.Conn, error) {
ctx, span := proxy.Tracer.Start(
ctx,
"proxyClient/dialAuthServer",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
oteltrace.WithAttributes(
attribute.String("cluster", clusterName),
),
)
defer span.End()
log.Debugf("Client %v is connecting to auth server on cluster %q.", proxy.clientAddr, clusterName)
address := "@" + clusterName
@ -1138,10 +1406,22 @@ func requestSubsystem(ctx context.Context, session *ssh.Session, name string) er
// ConnectToNode connects to the ssh server via Proxy.
// It returns connected and authenticated NodeClient
func (proxy *ProxyClient) ConnectToNode(ctx context.Context, nodeAddress NodeAddr, user string, quiet bool) (*NodeClient, error) {
func (proxy *ProxyClient) ConnectToNode(ctx context.Context, nodeAddress NodeAddr, user string) (*NodeClient, error) {
ctx, span := proxy.Tracer.Start(
ctx,
"proxyClient/ConnectToNode",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
oteltrace.WithAttributes(
attribute.String("node", nodeAddress.Addr),
attribute.String("cluster", nodeAddress.Cluster),
attribute.String("user", user),
),
)
defer span.End()
log.Infof("Client=%v connecting to node=%v", proxy.clientAddr, nodeAddress)
if len(proxy.teleportClient.JumpHosts) > 0 {
return proxy.PortForwardToNode(ctx, nodeAddress, user, quiet)
return proxy.PortForwardToNode(ctx, nodeAddress, user)
}
authMethods, err := proxy.sessionSSHCertificate(ctx, nodeAddress)
@ -1256,6 +1536,7 @@ func (proxy *ProxyClient) ConnectToNode(ctx context.Context, nodeAddress NodeAdd
Proxy: proxy,
Namespace: apidefaults.Namespace,
TC: proxy.teleportClient,
Tracer: proxy.Tracer,
}
// Start a goroutine that will run for the duration of the client to process
@ -1268,7 +1549,19 @@ func (proxy *ProxyClient) ConnectToNode(ctx context.Context, nodeAddress NodeAdd
// PortForwardToNode connects to the ssh server via Proxy
// It returns connected and authenticated NodeClient
func (proxy *ProxyClient) PortForwardToNode(ctx context.Context, nodeAddress NodeAddr, user string, quiet bool) (*NodeClient, error) {
func (proxy *ProxyClient) PortForwardToNode(ctx context.Context, nodeAddress NodeAddr, user string) (*NodeClient, error) {
ctx, span := proxy.Tracer.Start(
ctx,
"proxyClient/PortForwardToNode",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
oteltrace.WithAttributes(
attribute.String("node", nodeAddress.Addr),
attribute.String("cluster", nodeAddress.Cluster),
attribute.String("user", user),
),
)
defer span.End()
log.Infof("Client=%v jumping to node=%s", proxy.clientAddr, nodeAddress)
authMethods, err := proxy.sessionSSHCertificate(ctx, nodeAddress)
@ -1326,6 +1619,7 @@ func (proxy *ProxyClient) PortForwardToNode(ctx context.Context, nodeAddress Nod
Proxy: proxy,
Namespace: apidefaults.Namespace,
TC: proxy.teleportClient,
Tracer: proxy.Tracer,
}
// Start a goroutine that will run for the duration of the client to process
@ -1426,6 +1720,13 @@ func (proxy *ProxyClient) Close() error {
// ExecuteSCP runs remote scp command(shellCmd) on the remote server and
// runs local scp handler using SCP Command
func (c *NodeClient) ExecuteSCP(ctx context.Context, cmd scp.Command) error {
ctx, span := c.Tracer.Start(
ctx,
"nodeClient/ExecuteSCP",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
)
defer span.End()
shellCmd, err := cmd.GetRemoteShellCmd()
if err != nil {
return trace.Wrap(err)
@ -1663,7 +1964,15 @@ func (c *NodeClient) dynamicListenAndForward(ctx context.Context, ln net.Listene
}
// GetRemoteTerminalSize fetches the terminal size of a given SSH session.
func (c *NodeClient) GetRemoteTerminalSize(sessionID string) (*term.Winsize, error) {
func (c *NodeClient) GetRemoteTerminalSize(ctx context.Context, sessionID string) (*term.Winsize, error) {
_, span := c.Tracer.Start(
ctx,
"nodeClient/GetRemoteTerminalSize",
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
oteltrace.WithAttributes(attribute.String("session", sessionID)),
)
defer span.End()
ok, payload, err := c.Client.SendRequest(teleport.TerminalSizeRequest, true, []byte(sessionID))
if err != nil {
return nil, trace.Wrap(err)

View file

@ -26,10 +26,11 @@ import (
"time"
tracessh "github.com/gravitational/teleport/api/observability/tracing/ssh"
"github.com/gravitational/teleport/lib/observability/tracing"
"github.com/gravitational/teleport/lib/sshutils"
"github.com/gravitational/trace"
"golang.org/x/crypto/ssh"
"gopkg.in/check.v1"
)
@ -48,6 +49,7 @@ func (s *ClientTestSuite) SetUpSuite(c *check.C) {
// create the client:
config := &Config{
KeysDir: c.MkDir(),
Tracer: tracing.NoopProvider().Tracer("test"),
}
err := config.ParseProxyHost("localhost")
c.Assert(err, check.IsNil)
@ -60,10 +62,12 @@ func (s *ClientTestSuite) SetUpSuite(c *check.C) {
func (s *ClientTestSuite) TestNewSession(c *check.C) {
nc := &NodeClient{
Namespace: "blue",
Tracer: tracing.NoopProvider().Tracer("test"),
}
ctx := context.Background()
// defaults:
ses, err := newSession(nc, nil, nil, nil, nil, nil, true)
ses, err := newSession(ctx, nc, nil, nil, nil, nil, nil, true)
c.Assert(err, check.IsNil)
c.Assert(ses, check.NotNil)
c.Assert(ses.NodeClient(), check.Equals, nc)
@ -77,7 +81,7 @@ func (s *ClientTestSuite) TestNewSession(c *check.C) {
env := map[string]string{
sshutils.SessionEnvVar: "session-id",
}
ses, err = newSession(nc, nil, env, nil, nil, nil, true)
ses, err = newSession(ctx, nc, nil, env, nil, nil, nil, true)
c.Assert(err, check.IsNil)
c.Assert(ses, check.NotNil)
c.Assert(ses.env, check.DeepEquals, env)
@ -191,6 +195,7 @@ func (s *ClientTestSuite) TestListenAndForwardCancel(c *check.C) {
Conn: &fakeSSHConn{},
},
},
Tracer: tracing.NoopProvider().Tracer("test"),
}
// Create two anchors. An "accept" anchor that unblocks once the listener has

View file

@ -24,6 +24,7 @@ import (
"github.com/gravitational/teleport/lib/client"
"github.com/gravitational/teleport/lib/defaults"
"github.com/gravitational/teleport/lib/fixtures"
"github.com/gravitational/teleport/lib/observability/tracing"
"github.com/gravitational/teleport/lib/tlsca"
"github.com/gravitational/teleport/lib/utils"
@ -95,6 +96,7 @@ func TestCLICommandBuilderGetConnectCommand(t *testing.T) {
Host: "localhost",
WebProxyAddr: "localhost",
SiteName: "db.example.com",
Tracer: tracing.NoopProvider().Tracer("test"),
}
tc, err := client.NewClient(conf)
@ -522,6 +524,7 @@ func TestGetConnectCommandNoAbsPathConvertsAbsolutePathToRelative(t *testing.T)
Host: "localhost",
WebProxyAddr: "localhost",
SiteName: "db.example.com",
Tracer: tracing.NoopProvider().Tracer("test"),
}
tc, err := client.NewClient(conf)
@ -560,6 +563,7 @@ func TestGetConnectCommandNoAbsPathIsNoopWhenGivenRelativePath(t *testing.T) {
Host: "localhost",
WebProxyAddr: "localhost",
SiteName: "db.example.com",
Tracer: tracing.NoopProvider().Tracer("test"),
}
tc, err := client.NewClient(conf)

View file

@ -25,6 +25,7 @@ limitations under the License.
package db
import (
"context"
"fmt"
"github.com/gravitational/teleport/lib/client"
@ -38,7 +39,7 @@ import (
)
// Add updates database connection profile file.
func Add(tc *client.TeleportClient, db tlsca.RouteToDatabase, clientProfile client.ProfileStatus) error {
func Add(ctx context.Context, tc *client.TeleportClient, db tlsca.RouteToDatabase, clientProfile client.ProfileStatus) error {
// Out of supported databases, only Postgres and MySQL have a concept
// of the connection options file.
switch db.Protocol {
@ -51,7 +52,7 @@ func Add(tc *client.TeleportClient, db tlsca.RouteToDatabase, clientProfile clie
return trace.Wrap(err)
}
rootClusterName, err := tc.RootClusterName()
rootClusterName, err := tc.RootClusterName(ctx)
if err != nil {
return trace.Wrap(err)
}

View file

@ -22,6 +22,7 @@ import (
"github.com/gravitational/teleport/lib/client"
"github.com/gravitational/teleport/lib/client/db/profile"
"github.com/gravitational/teleport/lib/defaults"
"github.com/gravitational/teleport/lib/observability/tracing"
"github.com/gravitational/teleport/lib/tlsca"
"github.com/gravitational/trace"
@ -95,6 +96,7 @@ func TestAddProfile(t *testing.T) {
WebProxyAddr: test.webProxyAddrIn,
PostgresProxyAddr: test.postgresProxyAddrIn,
MySQLProxyAddr: test.mysqlProxyAddrIn,
Tracer: tracing.NoopProvider().Tracer("test"),
},
}
db := tlsca.RouteToDatabase{

View file

@ -24,11 +24,12 @@ import (
"sync"
"time"
"github.com/gorilla/websocket"
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/lib/client/terminal"
"github.com/gravitational/teleport/lib/kube/proxy/streamproto"
"github.com/gravitational/teleport/lib/utils"
"github.com/gorilla/websocket"
"github.com/gravitational/trace"
"k8s.io/client-go/tools/remotecommand"
)
@ -166,7 +167,7 @@ func (s *KubeSession) handleMFA(ctx context.Context, tc *TeleportClient, mode ty
return trace.Wrap(err)
}
auth, err := proxy.ConnectToCluster(ctx, s.meta.GetClusterName(), false)
auth, err := proxy.ConnectToCluster(ctx, s.meta.GetClusterName())
if err != nil {
return trace.Wrap(err)
}

View file

@ -28,9 +28,6 @@ import (
"syscall"
"time"
"golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh/agent"
"github.com/gravitational/teleport"
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/lib/client/escape"
@ -41,7 +38,10 @@ import (
"github.com/gravitational/teleport/lib/sshutils"
"github.com/gravitational/teleport/lib/sshutils/x11"
"github.com/gravitational/teleport/lib/utils"
"github.com/gravitational/trace"
"golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh/agent"
)
const (
@ -96,7 +96,8 @@ type NodeSession struct {
// newSession creates a new Teleport session with the given remote node
// if 'joinSessin' is given, the session will join the existing session
// of another user
func newSession(client *NodeClient,
func newSession(ctx context.Context,
client *NodeClient,
joinSession types.SessionTracker,
env map[string]string,
stdin io.Reader,
@ -129,7 +130,7 @@ func newSession(client *NodeClient,
// existing/current terminal size:
if joinSession != nil {
sessionID := joinSession.GetSessionID()
terminalSize, err := client.GetRemoteTerminalSize(sessionID)
terminalSize, err := client.GetRemoteTerminalSize(ctx, sessionID)
if err != nil {
return nil, trace.Wrap(err)
}
@ -158,7 +159,7 @@ func newSession(client *NodeClient,
// Determine if terminal should clear on exit.
ns.shouldClearOnExit = isFIPS()
if client.Proxy != nil {
boring, err := client.Proxy.isAuthBoring(context.TODO())
boring, err := client.Proxy.isAuthBoring(ctx)
if err != nil {
return nil, trace.Wrap(err)
}

View file

@ -930,7 +930,8 @@ func (process *TeleportProcess) newClientThroughTunnel(authServers []utils.NetAd
return nil, trace.Wrap(err)
}
clt, err := auth.NewClient(apiclient.Config{
Dialer: dialer,
Context: process.ExitContext(),
Dialer: dialer,
Credentials: []apiclient.Credentials{
apiclient.LoadTLS(tlsConfig),
},
@ -972,7 +973,8 @@ func (process *TeleportProcess) newClientDirect(authServers []utils.NetAddr, tls
}
clt, err := auth.NewClient(apiclient.Config{
Addrs: utils.NetAddrsToStrings(authServers),
Context: process.ExitContext(),
Addrs: utils.NetAddrsToStrings(authServers),
Credentials: []apiclient.Credentials{
apiclient.LoadTLS(tlsConfig),
},

View file

@ -137,7 +137,7 @@ func (c *Cluster) ReissueDBCerts(ctx context.Context, user, dbName string, db ty
}
// Update the database-specific connection profile file.
err = dbprofile.Add(c.clusterClient, tlsca.RouteToDatabase{
err = dbprofile.Add(ctx, c.clusterClient, tlsca.RouteToDatabase{
ServiceName: db.GetName(),
Protocol: db.GetProtocol(),
Username: user,

View file

@ -44,7 +44,7 @@ func (c *Cluster) GetKubes(ctx context.Context) ([]Kube, error) {
}
defer proxyClient.Close()
authClient, err = proxyClient.ConnectToCluster(ctx, c.clusterClient.SiteName, true)
authClient, err = proxyClient.ConnectToCluster(ctx, c.clusterClient.SiteName)
if err != nil {
return trace.Wrap(err)
}

View file

@ -52,6 +52,7 @@ import (
"github.com/gravitational/teleport/lib/httplib/csrf"
"github.com/gravitational/teleport/lib/jwt"
"github.com/gravitational/teleport/lib/limiter"
"github.com/gravitational/teleport/lib/observability/tracing"
"github.com/gravitational/teleport/lib/plugin"
"github.com/gravitational/teleport/lib/reversetunnel"
"github.com/gravitational/teleport/lib/secret"
@ -2788,6 +2789,7 @@ func makeTeleportClientConfig(ctx context.Context, sesCtx *SessionContext) (*cli
DefaultPrincipal: cert.ValidPrincipals[0],
HostKeyCallback: callback,
TLSRoutingEnabled: proxyListenerMode == types.ProxyListenerMode_Multiplex,
Tracer: tracing.NoopProvider().Tracer("test"),
}
return config, nil

View file

@ -23,7 +23,6 @@ import (
"strings"
"time"
"github.com/ghodss/yaml"
"github.com/gravitational/teleport"
"github.com/gravitational/teleport/api/client"
"github.com/gravitational/teleport/api/client/proto"
@ -34,6 +33,7 @@ import (
"github.com/gravitational/teleport/lib/services"
"github.com/gravitational/teleport/lib/utils"
"github.com/ghodss/yaml"
"github.com/gravitational/trace"
)
@ -366,7 +366,7 @@ func onRequestSearch(cf *CLIConf) error {
}
defer proxyClient.Close()
authClient, err := proxyClient.CurrentClusterAccessPoint(cf.Context, false /* quiet */)
authClient, err := proxyClient.CurrentClusterAccessPoint(cf.Context)
if err != nil {
return trace.Wrap(err)
}

View file

@ -26,7 +26,6 @@ import (
"text/template"
"time"
"github.com/ghodss/yaml"
"github.com/gravitational/teleport"
"github.com/gravitational/teleport/api/client/proto"
"github.com/gravitational/teleport/api/types"
@ -35,6 +34,7 @@ import (
"github.com/gravitational/teleport/lib/tlsca"
"github.com/gravitational/teleport/lib/utils"
"github.com/ghodss/yaml"
"github.com/gravitational/trace"
)
@ -53,7 +53,7 @@ func onAppLogin(cf *CLIConf) error {
return trace.Wrap(err)
}
rootCluster, err := tc.RootClusterName()
rootCluster, err := tc.RootClusterName(cf.Context)
if err != nil {
return trace.Wrap(err)
}

View file

@ -103,7 +103,7 @@ func onConfig(cf *CLIConf) error {
}
defer proxyClient.Close()
rootClusterName, rootErr := proxyClient.RootClusterName()
rootClusterName, rootErr := proxyClient.RootClusterName(cf.Context)
leafClusters, leafErr := proxyClient.GetLeafClusters(cf.Context)
if err := trace.NewAggregate(rootErr, leafErr); err != nil {
return trace.Wrap(err)

View file

@ -24,7 +24,6 @@ import (
"sort"
"strings"
"github.com/ghodss/yaml"
"github.com/gravitational/teleport"
"github.com/gravitational/teleport/api/client/proto"
"github.com/gravitational/teleport/api/types"
@ -36,6 +35,8 @@ import (
"github.com/gravitational/teleport/lib/srv/alpnproxy/common"
"github.com/gravitational/teleport/lib/tlsca"
"github.com/gravitational/teleport/lib/utils"
"github.com/ghodss/yaml"
"github.com/gravitational/trace"
)
@ -65,7 +66,7 @@ func onListDatabases(cf *CLIConf) error {
return trace.Wrap(err)
}
cluster, err := proxy.ConnectToCurrentCluster(cf.Context, false)
cluster, err := proxy.ConnectToCurrentCluster(cf.Context)
if err != nil {
return trace.Wrap(err)
}
@ -154,7 +155,7 @@ func listDatabasesAllClusters(cf *CLIConf) error {
}
var errors []error
for clusterName, databases := range result {
cluster, err := proxy.ConnectToCluster(cf.Context, clusterName, false)
cluster, err := proxy.ConnectToCluster(cf.Context, clusterName)
if err != nil {
errors = append(errors, err)
continue
@ -279,7 +280,7 @@ func databaseLogin(cf *CLIConf, tc *client.TeleportClient, db tlsca.RouteToDatab
return trace.Wrap(err)
}
// Update the database-specific connection profile file.
err = dbprofile.Add(tc, db, *profile)
err = dbprofile.Add(cf.Context, tc, db, *profile)
if err != nil {
return trace.Wrap(err)
}
@ -415,7 +416,7 @@ func onDatabaseConfig(cf *CLIConf) error {
if err != nil {
return trace.Wrap(err)
}
rootCluster, err := tc.RootClusterName()
rootCluster, err := tc.RootClusterName(cf.Context)
if err != nil {
return trace.Wrap(err)
}
@ -808,7 +809,7 @@ func isMFADatabaseAccessRequired(cf *CLIConf, tc *client.TeleportClient, databas
if err != nil {
return false, trace.Wrap(err)
}
cluster, err := proxy.ConnectToCluster(cf.Context, tc.SiteName, true)
cluster, err := proxy.ConnectToCluster(cf.Context, tc.SiteName)
if err != nil {
return false, trace.Wrap(err)
}

View file

@ -28,11 +28,7 @@ import (
"strings"
"time"
"github.com/ghodss/yaml"
"github.com/gravitational/kingpin"
"github.com/gravitational/teleport"
"github.com/gravitational/trace"
"github.com/gravitational/teleport/api/client/proto"
"github.com/gravitational/teleport/api/constants"
"github.com/gravitational/teleport/api/profile"
@ -45,6 +41,9 @@ import (
kubeutils "github.com/gravitational/teleport/lib/kube/utils"
"github.com/gravitational/teleport/lib/utils"
"github.com/ghodss/yaml"
"github.com/gravitational/kingpin"
"github.com/gravitational/trace"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
@ -110,7 +109,7 @@ func (c *kubeJoinCommand) getSessionMeta(ctx context.Context, tc *client.Telepor
return nil, trace.Wrap(err)
}
site, err := proxy.ConnectToCurrentCluster(ctx, false)
site, err := proxy.ConnectToCurrentCluster(ctx)
if err != nil {
return nil, trace.Wrap(err)
}
@ -493,7 +492,7 @@ func (c *kubeSessionsCommand) run(cf *CLIConf) error {
return trace.Wrap(err)
}
site, err := proxy.ConnectToCurrentCluster(cf.Context, true)
site, err := proxy.ConnectToCurrentCluster(cf.Context)
if err != nil {
return trace.Wrap(err)
}
@ -928,7 +927,7 @@ func fetchKubeClusters(ctx context.Context, tc *client.TeleportClient) (teleport
return trace.Wrap(err)
}
defer pc.Close()
ac, err := pc.ConnectToCurrentCluster(ctx, true)
ac, err := pc.ConnectToCurrentCluster(ctx)
if err != nil {
return trace.Wrap(err)
}

View file

@ -28,23 +28,23 @@ import (
"strings"
"time"
"github.com/ghodss/yaml"
"github.com/gravitational/kingpin"
"github.com/gravitational/teleport"
"github.com/gravitational/teleport/api/client/proto"
"github.com/gravitational/teleport/api/constants"
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/lib/asciitable"
"github.com/gravitational/teleport/lib/auth/touchid"
wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
wancli "github.com/gravitational/teleport/lib/auth/webauthncli"
"github.com/gravitational/teleport/lib/client"
"github.com/gravitational/teleport/lib/utils"
"github.com/gravitational/teleport/lib/utils/prompt"
"github.com/ghodss/yaml"
"github.com/gravitational/kingpin"
"github.com/gravitational/trace"
"github.com/pquerna/otp"
"github.com/pquerna/otp/totp"
wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
wancli "github.com/gravitational/teleport/lib/auth/webauthncli"
)
const (
@ -111,7 +111,7 @@ func (c *mfaLSCommand) run(cf *CLIConf) error {
return trace.Wrap(err)
}
defer pc.Close()
aci, err := pc.ConnectToRootCluster(cf.Context, false)
aci, err := pc.ConnectToRootCluster(cf.Context)
if err != nil {
return trace.Wrap(err)
}
@ -312,7 +312,7 @@ func (c *mfaAddCommand) addDeviceRPC(ctx context.Context, tc *client.TeleportCli
return trace.Wrap(err)
}
defer pc.Close()
aci, err := pc.ConnectToRootCluster(ctx, false)
aci, err := pc.ConnectToRootCluster(ctx)
if err != nil {
return trace.Wrap(err)
}
@ -567,7 +567,7 @@ func (c *mfaRemoveCommand) run(cf *CLIConf) error {
return trace.Wrap(err)
}
defer pc.Close()
aci, err := pc.ConnectToRootCluster(cf.Context, false)
aci, err := pc.ConnectToRootCluster(cf.Context)
if err != nil {
return trace.Wrap(err)
}

View file

@ -245,7 +245,7 @@ func onProxyCommandDB(cf *CLIConf) error {
return trace.BadParameter("Snowflake proxy works only in the tunnel mode. Please add --tunnel flag to enable it")
}
rootCluster, err := client.RootClusterName()
rootCluster, err := client.RootClusterName(cf.Context)
if err != nil {
return trace.Wrap(err)
}

View file

@ -2251,7 +2251,7 @@ func onListClusters(cf *CLIConf) error {
defer proxyClient.Close()
var rootErr, leafErr error
rootClusterName, rootErr = proxyClient.RootClusterName()
rootClusterName, rootErr = proxyClient.RootClusterName(cf.Context)
leafClusters, leafErr = proxyClient.GetLeafClusters(cf.Context)
return trace.NewAggregate(rootErr, leafErr)
})
@ -2677,6 +2677,10 @@ func makeClientForProxy(cf *CLIConf, proxy string, useProfileLogin bool) (*clien
// 1: start with the defaults
c := client.MakeDefaultConfig()
c.Host = cf.UserHost
if cf.TracingProvider == nil {
cf.TracingProvider = tracing.NoopProvider()
}
c.Tracer = cf.TracingProvider.Tracer(teleport.ComponentTSH)
// ProxyJump is an alias of Proxy flag
if cf.ProxyJump != "" {
@ -3358,7 +3362,7 @@ func (w *accessRequestWatcher) initialize(ctx context.Context, tc *client.Telepo
}
w.closers = append(w.closers, proxyClient)
rootClient, err := proxyClient.ConnectToRootCluster(ctx, false)
rootClient, err := proxyClient.ConnectToRootCluster(ctx)
if err != nil {
return trace.Wrap(err)
}