mirror of
https://github.com/gravitational/teleport
synced 2024-10-20 01:03:40 +00:00
Add tsh e2e tests with various security features enabled (#26862)
* * Refactor tool/tsh to enable tsh e2e tests outside of the tsh package. * Add tool/teleport/testenv to enable easier e2e tests from outside packages. * Skip all flaky test checks when * is provided.
This commit is contained in:
parent
724f6a1f76
commit
70c5ce7e8c
|
@ -169,7 +169,7 @@ func test(repoPath string, ref string, changedFiles []string) {
|
|||
}
|
||||
|
||||
for _, n := range r.New {
|
||||
if slices.Contains(testsToSkip, n.RefName) {
|
||||
if slices.Contains(testsToSkip, n.RefName) || slices.Contains(testsToSkip, "*") {
|
||||
log.Printf("-skipping %q (%s)\n", n.RefName, dir)
|
||||
continue
|
||||
}
|
||||
|
@ -182,7 +182,7 @@ func test(repoPath string, ref string, changedFiles []string) {
|
|||
}
|
||||
|
||||
for _, n := range r.Changed {
|
||||
if slices.Contains(testsToSkip, n.RefName) {
|
||||
if slices.Contains(testsToSkip, n.RefName) || slices.Contains(testsToSkip, "*") {
|
||||
log.Printf("-skipping %q (%s)\n", n.RefName, dir)
|
||||
continue
|
||||
}
|
||||
|
|
|
@ -430,6 +430,21 @@ type Config struct {
|
|||
|
||||
// PROXYSigner is used to sign PROXY headers for securely propagating client IP address
|
||||
PROXYSigner multiplexer.PROXYHeaderSigner
|
||||
|
||||
// DTAuthnRunCeremony allows tests to override the default device
|
||||
// authentication function.
|
||||
// Defaults to [dtauthn.NewCeremony().Run].
|
||||
DTAuthnRunCeremony DTAuthnRunCeremonyFunc
|
||||
|
||||
// dtAttemptLoginIgnorePing and dtAutoEnrollIgnorePing allow Device Trust
|
||||
// tests to ignore Ping responses.
|
||||
// Useful to force flows that only typically happen on Teleport Enterprise.
|
||||
dtAttemptLoginIgnorePing, dtAutoEnrollIgnorePing bool
|
||||
|
||||
// dtAutoEnroll allows tests to override the default device auto-enroll
|
||||
// function.
|
||||
// Defaults to [dtenroll.AutoEnroll].
|
||||
dtAutoEnroll dtAutoEnrollFunc
|
||||
}
|
||||
|
||||
// CachePolicy defines cache policy for local clients
|
||||
|
@ -942,8 +957,8 @@ func (c *Config) ResourceFilter(kind string) *proto.ListResourcesRequest {
|
|||
}
|
||||
}
|
||||
|
||||
// dtAuthnRunCeremonyFunc matches the signature of [dtauthn.RunCeremony].
|
||||
type dtAuthnRunCeremonyFunc func(context.Context, devicepb.DeviceTrustServiceClient, *devicepb.UserCertificates) (*devicepb.UserCertificates, error)
|
||||
// DTAuthnRunCeremonyFunc matches the signature of [dtauthn.RunCeremony].
|
||||
type DTAuthnRunCeremonyFunc func(context.Context, devicepb.DeviceTrustServiceClient, *devicepb.UserCertificates) (*devicepb.UserCertificates, error)
|
||||
|
||||
// dtAutoEnrollFunc matches the signature of [dtenroll.AutoEnroll].
|
||||
type dtAutoEnrollFunc func(context.Context, devicepb.DeviceTrustServiceClient) (*devicepb.Device, error)
|
||||
|
@ -966,21 +981,6 @@ type TeleportClient struct {
|
|||
// Note: there's no mutex guarding this or localAgent, making
|
||||
// TeleportClient NOT safe for concurrent use.
|
||||
lastPing *webclient.PingResponse
|
||||
|
||||
// dtAttemptLoginIgnorePing and dtAutoEnrollIgnorePing allow Device Trust
|
||||
// tests to ignore Ping responses.
|
||||
// Useful to force flows that only typically happen on Teleport Enterprise.
|
||||
dtAttemptLoginIgnorePing, dtAutoEnrollIgnorePing bool
|
||||
|
||||
// dtAuthnRunCeremony allows tests to override the default device
|
||||
// authentication function.
|
||||
// Defaults to [dtauthn.NewCeremony().Run].
|
||||
dtAuthnRunCeremony dtAuthnRunCeremonyFunc
|
||||
|
||||
// dtAutoEnroll allows tests to override the default device auto-enroll
|
||||
// function.
|
||||
// Defaults to [dtenroll.AutoEnroll].
|
||||
dtAutoEnroll dtAutoEnrollFunc
|
||||
}
|
||||
|
||||
// ShellCreatedCallback can be supplied for every teleport client. It will
|
||||
|
@ -3184,10 +3184,6 @@ func (tc *TeleportClient) WithoutJumpHosts(fn func(tcNoJump *TeleportClient) err
|
|||
OnShellCreated: tc.OnShellCreated,
|
||||
eventsCh: make(chan events.EventFields, 1024),
|
||||
lastPing: tc.lastPing,
|
||||
dtAttemptLoginIgnorePing: tc.dtAttemptLoginIgnorePing,
|
||||
dtAutoEnrollIgnorePing: tc.dtAutoEnrollIgnorePing,
|
||||
dtAuthnRunCeremony: tc.dtAuthnRunCeremony,
|
||||
dtAutoEnroll: tc.dtAutoEnroll,
|
||||
}
|
||||
tcNoJump.JumpHosts = nil
|
||||
|
||||
|
@ -3410,7 +3406,7 @@ func (tc *TeleportClient) DeviceLogin(ctx context.Context, certs *devicepb.UserC
|
|||
defer authClient.Close()
|
||||
|
||||
// Allow tests to override the default authn function.
|
||||
runCeremony := tc.dtAuthnRunCeremony
|
||||
runCeremony := tc.DTAuthnRunCeremony
|
||||
if runCeremony == nil {
|
||||
runCeremony = dtauthn.NewCeremony().Run
|
||||
}
|
||||
|
|
|
@ -24,8 +24,8 @@ func (tc *TeleportClient) SetDTAutoEnrollIgnorePing(val bool) {
|
|||
tc.dtAutoEnrollIgnorePing = val
|
||||
}
|
||||
|
||||
func (tc *TeleportClient) SetDTAuthnRunCeremony(fn dtAuthnRunCeremonyFunc) {
|
||||
tc.dtAuthnRunCeremony = fn
|
||||
func (tc *TeleportClient) SetDTAuthnRunCeremony(fn DTAuthnRunCeremonyFunc) {
|
||||
tc.DTAuthnRunCeremony = fn
|
||||
}
|
||||
|
||||
func (tc *TeleportClient) SetDTAutoEnroll(fn dtAutoEnrollFunc) {
|
||||
|
|
299
tool/teleport/testenv/test_server.go
Normal file
299
tool/teleport/testenv/test_server.go
Normal file
|
@ -0,0 +1,299 @@
|
|||
/*
|
||||
Copyright 2023 Gravitational, Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package testenv provides functions for creating test servers for testing.
|
||||
package testenv
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gravitational/trace"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/gravitational/teleport/api/breaker"
|
||||
apidefaults "github.com/gravitational/teleport/api/defaults"
|
||||
"github.com/gravitational/teleport/api/types"
|
||||
"github.com/gravitational/teleport/api/utils/keys"
|
||||
"github.com/gravitational/teleport/lib/backend"
|
||||
"github.com/gravitational/teleport/lib/cloud"
|
||||
"github.com/gravitational/teleport/lib/defaults"
|
||||
"github.com/gravitational/teleport/lib/modules"
|
||||
"github.com/gravitational/teleport/lib/service"
|
||||
"github.com/gravitational/teleport/lib/service/servicecfg"
|
||||
"github.com/gravitational/teleport/lib/services"
|
||||
"github.com/gravitational/teleport/lib/srv"
|
||||
"github.com/gravitational/teleport/lib/utils"
|
||||
"github.com/gravitational/teleport/tool/teleport/common"
|
||||
)
|
||||
|
||||
var ports utils.PortList
|
||||
|
||||
// used to easily join test services
|
||||
const staticToken = "test-static-token"
|
||||
|
||||
func init() {
|
||||
// If the test is re-executing itself, execute the command that comes over
|
||||
// the pipe. Used to test tsh ssh and tsh scp commands.
|
||||
if srv.IsReexec() {
|
||||
common.Run(common.Options{Args: os.Args[1:]})
|
||||
return
|
||||
}
|
||||
|
||||
var err error
|
||||
ports, err = utils.GetFreeTCPPorts(100)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("Failed to allocate tcp ports for tests: %v", err))
|
||||
}
|
||||
|
||||
modules.SetModules(&cliModules{})
|
||||
}
|
||||
|
||||
// MakeTestServer creates a Teleport Server for testing.
|
||||
func MakeTestServer(t *testing.T, opts ...TestServerOptFunc) (process *service.TeleportProcess) {
|
||||
t.Helper()
|
||||
|
||||
var options TestServersOpts
|
||||
for _, opt := range opts {
|
||||
opt(&options)
|
||||
}
|
||||
|
||||
// Set up a test auth server with default config.
|
||||
cfg := servicecfg.MakeDefaultConfig()
|
||||
cfg.CircuitBreakerConfig = breaker.NoopBreakerConfig()
|
||||
cfg.CachePolicy.Enabled = false
|
||||
// Disables cloud auto-imported labels when running tests in cloud envs
|
||||
// such as Github Actions.
|
||||
//
|
||||
// This is required otherwise Teleport will import cloud instance
|
||||
// labels, and use them for example as labels in Kubernetes Service and
|
||||
// cause some tests to fail because the output includes unexpected
|
||||
// labels.
|
||||
//
|
||||
// It is also found that Azure metadata client can throw "Too many
|
||||
// requests" during CI which fails services.NewTeleport.
|
||||
cfg.InstanceMetadataClient = cloud.NewDisabledIMDSClient()
|
||||
|
||||
cfg.Hostname = "server01"
|
||||
cfg.DataDir = t.TempDir()
|
||||
cfg.Log = utils.NewLoggerForTests()
|
||||
authAddr := utils.NetAddr{AddrNetwork: "tcp", Addr: net.JoinHostPort("127.0.0.1", ports.Pop())}
|
||||
cfg.SetToken(staticToken)
|
||||
cfg.SetAuthServerAddress(authAddr)
|
||||
|
||||
cfg.Auth.ListenAddr = authAddr
|
||||
cfg.Auth.BootstrapResources = options.Bootstrap
|
||||
cfg.Auth.StorageConfig.Params = backend.Params{defaults.BackendPath: filepath.Join(cfg.DataDir, defaults.BackendDir)}
|
||||
staticToken, err := types.NewStaticTokens(types.StaticTokensSpecV2{
|
||||
StaticTokens: []types.ProvisionTokenV1{{
|
||||
Roles: []types.SystemRole{types.RoleProxy, types.RoleDatabase, types.RoleTrustedCluster, types.RoleNode, types.RoleApp},
|
||||
Expires: time.Now().Add(time.Minute),
|
||||
Token: staticToken,
|
||||
}},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
cfg.Auth.StaticTokens = staticToken
|
||||
|
||||
cfg.Proxy.WebAddr = utils.NetAddr{AddrNetwork: "tcp", Addr: net.JoinHostPort("127.0.0.1", ports.Pop())}
|
||||
cfg.Proxy.SSHAddr = utils.NetAddr{AddrNetwork: "tcp", Addr: net.JoinHostPort("127.0.0.1", ports.Pop())}
|
||||
cfg.Proxy.ReverseTunnelListenAddr = utils.NetAddr{AddrNetwork: "tcp", Addr: net.JoinHostPort("127.0.0.1", ports.Pop())}
|
||||
cfg.Proxy.DisableWebInterface = true
|
||||
|
||||
cfg.SSH.Addr = utils.NetAddr{AddrNetwork: "tcp", Addr: net.JoinHostPort("127.0.0.1", ports.Pop())}
|
||||
cfg.SSH.DisableCreateHostUser = true
|
||||
|
||||
// Apply options
|
||||
for _, fn := range options.ConfigFuncs {
|
||||
fn(cfg)
|
||||
}
|
||||
|
||||
process, err = service.NewTeleport(cfg)
|
||||
require.NoError(t, err, trace.DebugReport(err))
|
||||
require.NoError(t, process.Start())
|
||||
t.Cleanup(func() {
|
||||
require.NoError(t, process.Close())
|
||||
require.NoError(t, process.Wait())
|
||||
})
|
||||
|
||||
waitForServices(t, process, cfg)
|
||||
|
||||
return process
|
||||
}
|
||||
|
||||
func waitForServices(t *testing.T, auth *service.TeleportProcess, cfg *servicecfg.Config) {
|
||||
var serviceReadyEvents []string
|
||||
if cfg.Proxy.Enabled {
|
||||
serviceReadyEvents = append(serviceReadyEvents, service.ProxyWebServerReady)
|
||||
}
|
||||
if cfg.SSH.Enabled {
|
||||
serviceReadyEvents = append(serviceReadyEvents, service.NodeSSHReady)
|
||||
}
|
||||
if cfg.Databases.Enabled {
|
||||
serviceReadyEvents = append(serviceReadyEvents, service.DatabasesReady)
|
||||
}
|
||||
if cfg.Apps.Enabled {
|
||||
serviceReadyEvents = append(serviceReadyEvents, service.AppsReady)
|
||||
}
|
||||
if cfg.Auth.Enabled {
|
||||
serviceReadyEvents = append(serviceReadyEvents, service.AuthTLSReady)
|
||||
}
|
||||
waitForEvents(t, auth, serviceReadyEvents...)
|
||||
|
||||
if cfg.Auth.Enabled && cfg.Databases.Enabled {
|
||||
waitForDatabases(t, auth, cfg.Databases.Databases)
|
||||
}
|
||||
}
|
||||
|
||||
func waitForEvents(t *testing.T, svc service.Supervisor, events ...string) {
|
||||
for _, event := range events {
|
||||
_, err := svc.WaitForEventTimeout(10*time.Second, event)
|
||||
require.NoError(t, err, "service server didn't receive %v event after 10s", event)
|
||||
}
|
||||
}
|
||||
|
||||
func waitForDatabases(t *testing.T, auth *service.TeleportProcess, dbs []servicecfg.Database) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
for {
|
||||
select {
|
||||
case <-time.After(500 * time.Millisecond):
|
||||
all, err := auth.GetAuthServer().GetDatabaseServers(ctx, apidefaults.Namespace)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Count how many input "dbs" are registered.
|
||||
var registered int
|
||||
for _, db := range dbs {
|
||||
for _, a := range all {
|
||||
if a.GetName() == db.Name {
|
||||
registered++
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if registered == len(dbs) {
|
||||
return
|
||||
}
|
||||
case <-ctx.Done():
|
||||
t.Fatal("Databases not registered after 10s")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type TestServersOpts struct {
|
||||
Bootstrap []types.Resource
|
||||
ConfigFuncs []func(cfg *servicecfg.Config)
|
||||
}
|
||||
|
||||
type TestServerOptFunc func(o *TestServersOpts)
|
||||
|
||||
func WithBootstrap(bootstrap ...types.Resource) TestServerOptFunc {
|
||||
return func(o *TestServersOpts) {
|
||||
o.Bootstrap = bootstrap
|
||||
}
|
||||
}
|
||||
|
||||
func WithConfig(fn func(cfg *servicecfg.Config)) TestServerOptFunc {
|
||||
return func(o *TestServersOpts) {
|
||||
o.ConfigFuncs = append(o.ConfigFuncs, fn)
|
||||
}
|
||||
}
|
||||
|
||||
func WithAuthConfig(fn func(*servicecfg.AuthConfig)) TestServerOptFunc {
|
||||
return WithConfig(func(cfg *servicecfg.Config) {
|
||||
fn(&cfg.Auth)
|
||||
})
|
||||
}
|
||||
|
||||
func WithClusterName(t *testing.T, n string) TestServerOptFunc {
|
||||
return WithAuthConfig(func(cfg *servicecfg.AuthConfig) {
|
||||
clusterName, err := services.NewClusterNameWithRandomID(
|
||||
types.ClusterNameSpecV2{
|
||||
ClusterName: n,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
cfg.ClusterName = clusterName
|
||||
})
|
||||
}
|
||||
|
||||
func WithHostname(hostname string) TestServerOptFunc {
|
||||
return WithConfig(func(cfg *servicecfg.Config) {
|
||||
cfg.Hostname = hostname
|
||||
})
|
||||
}
|
||||
|
||||
func WithSSHPublicAddrs(addrs ...string) TestServerOptFunc {
|
||||
return WithConfig(func(cfg *servicecfg.Config) {
|
||||
cfg.SSH.PublicAddrs = utils.MustParseAddrList(addrs...)
|
||||
})
|
||||
}
|
||||
|
||||
func WithSSHLabel(key, value string) TestServerOptFunc {
|
||||
return WithConfig(func(cfg *servicecfg.Config) {
|
||||
if cfg.SSH.Labels == nil {
|
||||
cfg.SSH.Labels = make(map[string]string)
|
||||
}
|
||||
cfg.SSH.Labels[key] = value
|
||||
})
|
||||
}
|
||||
|
||||
type cliModules struct{}
|
||||
|
||||
// BuildType returns build type.
|
||||
func (p *cliModules) BuildType() string {
|
||||
return "CLI"
|
||||
}
|
||||
|
||||
// PrintVersion prints the Teleport version.
|
||||
func (p *cliModules) PrintVersion() {
|
||||
fmt.Println("Teleport CLI")
|
||||
}
|
||||
|
||||
// Features returns supported features
|
||||
func (p *cliModules) Features() modules.Features {
|
||||
return modules.Features{
|
||||
Kubernetes: true,
|
||||
DB: true,
|
||||
App: true,
|
||||
AdvancedAccessWorkflows: true,
|
||||
AccessControls: true,
|
||||
}
|
||||
}
|
||||
|
||||
// IsBoringBinary checks if the binary was compiled with BoringCrypto.
|
||||
func (p *cliModules) IsBoringBinary() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// AttestHardwareKey attests a hardware key.
|
||||
func (p *cliModules) AttestHardwareKey(_ context.Context, _ interface{}, _ keys.PrivateKeyPolicy, _ *keys.AttestationStatement, _ crypto.PublicKey, _ time.Duration) (keys.PrivateKeyPolicy, error) {
|
||||
return keys.PrivateKeyPolicyNone, nil
|
||||
}
|
||||
|
||||
func (p *cliModules) EnableRecoveryCodes() {
|
||||
}
|
||||
|
||||
func (p *cliModules) EnablePlugins() {
|
||||
}
|
||||
|
||||
func (p *cliModules) SetFeatures(f modules.Features) {
|
||||
}
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
package common
|
||||
|
||||
import (
|
||||
"bytes"
|
|
@ -12,7 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package main
|
||||
package common
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
@ -41,7 +41,7 @@ type aliasRunner struct {
|
|||
aliases map[string]string
|
||||
|
||||
// runTshMain is a function to run tsh; for example Run().
|
||||
runTshMain func(ctx context.Context, args []string, opts ...cliOption) error
|
||||
runTshMain func(ctx context.Context, args []string, opts ...CliOption) error
|
||||
// runExternalCommand is a function to execute the command passed in as argument; outside of test, it should simply invoke the Run() method.
|
||||
runExternalCommand func(cmd *exec.Cmd) error
|
||||
}
|
|
@ -12,7 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package main
|
||||
package common
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
@ -34,7 +34,7 @@ func newTestAliasRunner(t *testing.T) *aliasRunner {
|
|||
t.Fatalf("calling uninitialized function 'setEnv(key=%q,value=%q)'", key, value)
|
||||
return nil
|
||||
},
|
||||
runTshMain: func(ctx context.Context, args []string, opts ...cliOption) error {
|
||||
runTshMain: func(ctx context.Context, args []string, opts ...CliOption) error {
|
||||
t.Fatalf("calling uninitialized function 'runTshMain(ctx=%v,args=%v,opts=%v)'", ctx, args, opts)
|
||||
return nil
|
||||
},
|
||||
|
@ -353,7 +353,7 @@ func Test_runAliasCommand(t *testing.T) {
|
|||
externalCalls := 0
|
||||
|
||||
ar := &aliasRunner{
|
||||
runTshMain: func(ctx context.Context, args []string, opts ...cliOption) error {
|
||||
runTshMain: func(ctx context.Context, args []string, opts ...CliOption) error {
|
||||
mainCalls++
|
||||
return nil
|
||||
},
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
package common
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
package common
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
@ -58,8 +58,8 @@ func TestAWS(t *testing.T) {
|
|||
// Log into Teleport cluster.
|
||||
err = Run(context.Background(), []string{
|
||||
"login", "--insecure", "--debug", "--auth", connector.GetName(), "--proxy", proxyAddr.String(),
|
||||
}, setHomePath(tmpHomePath), cliOption(func(cf *CLIConf) error {
|
||||
cf.mockSSOLogin = mockSSOLogin(t, authServer, user)
|
||||
}, setHomePath(tmpHomePath), CliOption(func(cf *CLIConf) error {
|
||||
cf.MockSSOLogin = mockSSOLogin(t, authServer, user)
|
||||
return nil
|
||||
}))
|
||||
require.NoError(t, err)
|
|
@ -12,7 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package main
|
||||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
package common
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
@ -57,10 +57,10 @@ func TestAzure(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
|
||||
// helper function
|
||||
run := func(args []string, opts ...cliOption) {
|
||||
run := func(args []string, opts ...CliOption) {
|
||||
opts = append(opts, setHomePath(tmpHomePath))
|
||||
opts = append(opts, func(cf *CLIConf) error {
|
||||
cf.mockSSOLogin = mockSSOLogin(t, authServer, user)
|
||||
cf.MockSSOLogin = mockSSOLogin(t, authServer, user)
|
||||
return nil
|
||||
})
|
||||
err := Run(context.Background(), args, opts...)
|
|
@ -12,7 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package main
|
||||
package common
|
||||
|
||||
import (
|
||||
"strings"
|
|
@ -12,7 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package main
|
||||
package common
|
||||
|
||||
import (
|
||||
"testing"
|
|
@ -12,7 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package main
|
||||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
|
@ -12,7 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package main
|
||||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
package common
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
@ -147,7 +147,7 @@ func TestAppLoginLeaf(t *testing.T) {
|
|||
getHelpers := func(t *testing.T) (func(cluster string) string, func(args ...string) string) {
|
||||
tmpHomePath := t.TempDir()
|
||||
|
||||
run := func(args []string, opts ...cliOption) string {
|
||||
run := func(args []string, opts ...CliOption) string {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
|
||||
defer cancel()
|
||||
|
||||
|
@ -169,7 +169,7 @@ func TestAppLoginLeaf(t *testing.T) {
|
|||
cluster}
|
||||
|
||||
opt := func(cf *CLIConf) error {
|
||||
cf.mockSSOLogin = mockSSOLogin(t, rootAuth.GetAuthServer(), alice)
|
||||
cf.MockSSOLogin = mockSSOLogin(t, rootAuth.GetAuthServer(), alice)
|
||||
return nil
|
||||
}
|
||||
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
package common
|
||||
|
||||
import (
|
||||
"strings"
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
package common
|
||||
|
||||
import (
|
||||
"context"
|
|
@ -15,7 +15,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package main
|
||||
package common
|
||||
|
||||
// onDaemonStop implements the "tsh daemon stop" command. It handles graceful shutdown of the daemon
|
||||
// on Windows, so it's a noop on other platforms. See daemonstop_windows.go for more details.
|
|
@ -15,7 +15,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package main
|
||||
package common
|
||||
|
||||
import (
|
||||
"syscall"
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
package common
|
||||
|
||||
import (
|
||||
"bytes"
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
package common
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
@ -115,8 +115,8 @@ func TestDatabaseLogin(t *testing.T) {
|
|||
// Log into Teleport cluster.
|
||||
err = Run(context.Background(), []string{
|
||||
"login", "--insecure", "--debug", "--auth", connector.GetName(), "--proxy", proxyAddr.String(),
|
||||
}, setHomePath(tmpHomePath), cliOption(func(cf *CLIConf) error {
|
||||
cf.mockSSOLogin = mockSSOLogin(t, authServer, alice)
|
||||
}, setHomePath(tmpHomePath), CliOption(func(cf *CLIConf) error {
|
||||
cf.MockSSOLogin = mockSSOLogin(t, authServer, alice)
|
||||
return nil
|
||||
}))
|
||||
require.NoError(t, err)
|
||||
|
@ -251,8 +251,8 @@ func TestLocalProxyRequirement(t *testing.T) {
|
|||
// Log into Teleport cluster.
|
||||
err = Run(context.Background(), []string{
|
||||
"login", "--insecure", "--debug", "--auth", connector.GetName(), "--proxy", proxyAddr.String(),
|
||||
}, setHomePath(tmpHomePath), cliOption(func(cf *CLIConf) error {
|
||||
cf.mockSSOLogin = mockSSOLogin(t, authServer, alice)
|
||||
}, setHomePath(tmpHomePath), CliOption(func(cf *CLIConf) error {
|
||||
cf.MockSSOLogin = mockSSOLogin(t, authServer, alice)
|
||||
return nil
|
||||
}))
|
||||
require.NoError(t, err)
|
||||
|
@ -372,6 +372,7 @@ func TestListDatabase(t *testing.T) {
|
|||
"--insecure",
|
||||
"--debug",
|
||||
}, setCopyStdout(captureStdout))
|
||||
|
||||
require.NoError(t, err)
|
||||
require.Contains(t, captureStdout.String(), "root-postgres")
|
||||
|
||||
|
@ -384,6 +385,7 @@ func TestListDatabase(t *testing.T) {
|
|||
"--insecure",
|
||||
"--debug",
|
||||
}, setCopyStdout(captureStdout))
|
||||
|
||||
require.NoError(t, err)
|
||||
require.Contains(t, captureStdout.String(), "leaf-postgres")
|
||||
}
|
|
@ -12,7 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package main
|
||||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
|
@ -12,7 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package main
|
||||
package common
|
||||
|
||||
import (
|
||||
"crypto/x509"
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
package common
|
||||
|
||||
const (
|
||||
// loginUsageFooter is printed at the bottom of `tsh help login` output
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
package common
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
@ -1398,8 +1398,8 @@ func updateKubeConfig(cf *CLIConf, tc *client.TeleportClient, path string, overr
|
|||
func getKubeConfigPath(cf *CLIConf, path string) string {
|
||||
// cf.kubeConfigPath is used in tests to allow Teleport to run tsh login commands
|
||||
// in parallel. If defined, it should take precedence over kubeconfig.PathFromEnv().
|
||||
if path == "" && cf.kubeConfigPath != "" {
|
||||
path = cf.kubeConfigPath
|
||||
if path == "" && cf.KubeConfigPath != "" {
|
||||
path = cf.KubeConfigPath
|
||||
} else if path == "" {
|
||||
path = kubeconfig.PathFromEnv()
|
||||
}
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
package common
|
||||
|
||||
import (
|
||||
"context"
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
package common
|
||||
|
||||
import (
|
||||
"context"
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
package common
|
||||
|
||||
import (
|
||||
"bytes"
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
package common
|
||||
|
||||
import (
|
||||
"bufio"
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
package common
|
||||
|
||||
import (
|
||||
"path"
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
package common
|
||||
|
||||
import (
|
||||
"context"
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
package common
|
||||
|
||||
import (
|
||||
"testing"
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
package common
|
||||
|
||||
import (
|
||||
"context"
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
package common
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
@ -290,7 +290,7 @@ func TestProxySSH(t *testing.T) {
|
|||
s.root.Config.Auth.ClusterName.GetClusterName(),
|
||||
s.root.Config.SSH.Addr.Port(defaults.SSHServerListenPort))
|
||||
|
||||
runProxySSH := func(proxyRequest string, opts ...cliOption) error {
|
||||
runProxySSH := func(proxyRequest string, opts ...CliOption) error {
|
||||
return Run(ctx, []string{
|
||||
"--insecure",
|
||||
"--proxy", s.root.Config.Proxy.WebAddr.Addr,
|
||||
|
@ -398,7 +398,7 @@ func TestProxySSHJumpHost(t *testing.T) {
|
|||
|
||||
s := newTestSuite(t, tc.opts...)
|
||||
|
||||
runProxySSHJump := func(opts ...cliOption) error {
|
||||
runProxySSHJump := func(opts ...CliOption) error {
|
||||
proxyRequest := fmt.Sprintf("%s:%d",
|
||||
s.leaf.Config.Proxy.SSHAddr.Host(),
|
||||
s.leaf.Config.SSH.Addr.Port(defaults.SSHServerListenPort))
|
||||
|
@ -733,9 +733,9 @@ func disableAgent(t *testing.T) {
|
|||
t.Setenv(teleport.SSHAuthSock, "")
|
||||
}
|
||||
|
||||
func setMockSSOLogin(t *testing.T, s *suite) cliOption {
|
||||
func setMockSSOLogin(t *testing.T, s *suite) CliOption {
|
||||
return func(cf *CLIConf) error {
|
||||
cf.mockSSOLogin = mockSSOLogin(t, s.root.GetAuthServer(), s.user)
|
||||
cf.MockSSOLogin = mockSSOLogin(t, s.root.GetAuthServer(), s.user)
|
||||
cf.AuthConnector = s.connector.GetName()
|
||||
return nil
|
||||
}
|
||||
|
@ -776,7 +776,7 @@ func mustLoginSetEnv(t *testing.T, s *suite, args ...string) string {
|
|||
return tshHome
|
||||
}
|
||||
|
||||
func mustLoginIdentity(t *testing.T, s *suite, opts ...cliOption) string {
|
||||
func mustLoginIdentity(t *testing.T, s *suite, opts ...CliOption) string {
|
||||
identityFile := path.Join(t.TempDir(), "identity.pem")
|
||||
mustLogin(t, s, "--out", identityFile)
|
||||
return identityFile
|
||||
|
@ -1132,7 +1132,7 @@ func TestPrintProxyAWSTemplate(t *testing.T) {
|
|||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
buf := new(bytes.Buffer)
|
||||
test.inputCLIConf.overrideStdout = buf
|
||||
test.inputCLIConf.OverrideStdout = buf
|
||||
require.NoError(t, printProxyAWSTemplate(test.inputCLIConf, test.inputAWSApp))
|
||||
for _, wantSnippet := range test.wantSnippets {
|
||||
require.Contains(t, buf.String(), wantSnippet)
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
package common
|
||||
|
||||
import (
|
||||
"bytes"
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
package common
|
||||
|
||||
import (
|
||||
"context"
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
package common
|
||||
|
||||
import (
|
||||
"context"
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
package common
|
||||
|
||||
import (
|
||||
"context"
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
package common
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
@ -54,8 +54,8 @@ func TestLoadConfigFromProfile(t *testing.T) {
|
|||
"--debug",
|
||||
"--auth", connector.GetName(),
|
||||
"--proxy", proxyAddr.String(),
|
||||
}, setHomePath(tmpHomePath), cliOption(func(cf *CLIConf) error {
|
||||
cf.mockSSOLogin = mockSSOLogin(t, authServer, alice)
|
||||
}, setHomePath(tmpHomePath), CliOption(func(cf *CLIConf) error {
|
||||
cf.MockSSOLogin = mockSSOLogin(t, authServer, alice)
|
||||
return nil
|
||||
}))
|
||||
require.NoError(t, err)
|
||||
|
@ -116,8 +116,8 @@ func TestRemoteTctlWithProfile(t *testing.T) {
|
|||
"--debug",
|
||||
"--auth", connector.GetName(),
|
||||
"--proxy", proxyAddr.String(),
|
||||
}, setHomePath(tmpHomePath), cliOption(func(cf *CLIConf) error {
|
||||
cf.mockSSOLogin = mockSSOLogin(t, authServer, alice)
|
||||
}, setHomePath(tmpHomePath), CliOption(func(cf *CLIConf) error {
|
||||
cf.MockSSOLogin = mockSSOLogin(t, authServer, alice)
|
||||
return nil
|
||||
}))
|
||||
require.NoError(t, err)
|
||||
|
@ -182,8 +182,8 @@ func TestSetAuthServerFlagWhileLoggedIn(t *testing.T) {
|
|||
"--debug",
|
||||
"--auth", connector.GetName(),
|
||||
"--proxy", proxyAddr.String(),
|
||||
}, setHomePath(tmpHomePath), cliOption(func(cf *CLIConf) error {
|
||||
cf.mockSSOLogin = mockSSOLogin(t, authServer, alice)
|
||||
}, setHomePath(tmpHomePath), CliOption(func(cf *CLIConf) error {
|
||||
cf.MockSSOLogin = mockSSOLogin(t, authServer, alice)
|
||||
return nil
|
||||
}))
|
||||
require.NoError(t, err)
|
|
@ -12,7 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package main
|
||||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
package common
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
@ -322,18 +322,18 @@ type CLIConf struct {
|
|||
// unsetEnvironment unsets Teleport related environment variables.
|
||||
unsetEnvironment bool
|
||||
|
||||
// overrideStdout allows to switch standard output source for resource command. Used in tests.
|
||||
overrideStdout io.Writer
|
||||
// OverrideStdout allows to switch standard output source for resource command. Used in tests.
|
||||
OverrideStdout io.Writer
|
||||
// overrideStderr allows to switch standard error source for resource command. Used in tests.
|
||||
overrideStderr io.Writer
|
||||
// overrideStdin allows to switch standard in source for resource command. Used in tests.
|
||||
overrideStdin io.Reader
|
||||
|
||||
// mockSSOLogin used in tests to override sso login handler in teleport client.
|
||||
mockSSOLogin client.SSOLoginFunc
|
||||
// MockSSOLogin used in tests to override sso login handler in teleport client.
|
||||
MockSSOLogin client.SSOLoginFunc
|
||||
|
||||
// mockHeadlessLogin used in tests to override Headless login handler in teleport client.
|
||||
mockHeadlessLogin client.SSHLoginFunc
|
||||
// MockHeadlessLogin used in tests to override Headless login handler in teleport client.
|
||||
MockHeadlessLogin client.SSHLoginFunc
|
||||
|
||||
// HomePath is where tsh stores profiles
|
||||
HomePath string
|
||||
|
@ -430,11 +430,11 @@ type CLIConf struct {
|
|||
// kubeAllNamespaces allows users to search for pods in every namespace.
|
||||
kubeAllNamespaces bool
|
||||
|
||||
// kubeConfigPath is the location of the Kubeconfig for the current test.
|
||||
// KubeConfigPath is the location of the Kubeconfig for the current test.
|
||||
// Setting this value allows Teleport tests to run `tsh login` commands in
|
||||
// parallel.
|
||||
// It shouldn't be used outside testing.
|
||||
kubeConfigPath string
|
||||
KubeConfigPath string
|
||||
|
||||
// Client only version display. Skips checking proxy version.
|
||||
clientOnlyVersionCheck bool
|
||||
|
@ -451,12 +451,17 @@ type CLIConf struct {
|
|||
|
||||
// HeadlessAuthenticationID is the ID of a headless authentication.
|
||||
HeadlessAuthenticationID string
|
||||
|
||||
// DTAuthnRunCeremony allows tests to override the default device
|
||||
// authentication function.
|
||||
// Defaults to [dtauthn.NewCeremony().Run].
|
||||
DTAuthnRunCeremony client.DTAuthnRunCeremonyFunc
|
||||
}
|
||||
|
||||
// Stdout returns the stdout writer.
|
||||
func (c *CLIConf) Stdout() io.Writer {
|
||||
if c.overrideStdout != nil {
|
||||
return c.overrideStdout
|
||||
if c.OverrideStdout != nil {
|
||||
return c.OverrideStdout
|
||||
}
|
||||
return os.Stdout
|
||||
}
|
||||
|
@ -490,7 +495,7 @@ func (c *CLIConf) RunCommand(cmd *exec.Cmd) error {
|
|||
return trace.Wrap(cmd.Run())
|
||||
}
|
||||
|
||||
func main() {
|
||||
func Main() {
|
||||
cmdLineOrig := os.Args[1:]
|
||||
var cmdLine []string
|
||||
|
||||
|
@ -567,8 +572,8 @@ const (
|
|||
// env vars that tsh status will check to provide hints about active env vars to a user.
|
||||
var tshStatusEnvVars = [...]string{proxyEnvVar, clusterEnvVar, siteEnvVar, kubeClusterEnvVar, teleport.EnvKubeConfig}
|
||||
|
||||
// cliOption is used in tests to inject/override configuration within Run
|
||||
type cliOption func(*CLIConf) error
|
||||
// CliOption is used in tests to inject/override configuration within Run
|
||||
type CliOption func(*CLIConf) error
|
||||
|
||||
// initLogger initializes the logger taking into account --debug and TELEPORT_DEBUG. If TELEPORT_DEBUG is set, it will also enable CLIConf.Debug.
|
||||
func initLogger(cf *CLIConf) {
|
||||
|
@ -582,7 +587,7 @@ func initLogger(cf *CLIConf) {
|
|||
}
|
||||
|
||||
// Run executes TSH client. same as main() but easier to test
|
||||
func Run(ctx context.Context, args []string, opts ...cliOption) error {
|
||||
func Run(ctx context.Context, args []string, opts ...CliOption) error {
|
||||
cf := CLIConf{
|
||||
Context: ctx,
|
||||
TracingProvider: tracing.NoopProvider(),
|
||||
|
@ -3586,9 +3591,10 @@ func loadClientConfigFromCLIConf(cf *CLIConf, proxy string) (*client.Config, err
|
|||
|
||||
c.EnableEscapeSequences = cf.EnableEscapeSequences
|
||||
|
||||
// pass along mock sso login if provided (only used in tests)
|
||||
c.MockSSOLogin = cf.mockSSOLogin
|
||||
c.MockHeadlessLogin = cf.mockHeadlessLogin
|
||||
// pass along mock functions if provided (only used in tests)
|
||||
c.MockSSOLogin = cf.MockSSOLogin
|
||||
c.MockHeadlessLogin = cf.MockHeadlessLogin
|
||||
c.DTAuthnRunCeremony = cf.DTAuthnRunCeremony
|
||||
|
||||
// Set tsh home directory
|
||||
c.HomePath = cf.HomePath
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
package common
|
||||
|
||||
import (
|
||||
"context"
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
package common
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
|
@ -94,7 +94,7 @@ func init() {
|
|||
// Needed for tests that generate OpenSSH config by tsh config command where
|
||||
// tsh proxy ssh command is used as ProxyCommand.
|
||||
if os.Getenv(tshBinMainTestEnv) != "" {
|
||||
main()
|
||||
Main()
|
||||
// main will only exit if there is an error.
|
||||
// since we are here, there was no error, so we must do so ourselves.
|
||||
os.Exit(0)
|
||||
|
@ -313,7 +313,7 @@ func TestFailedLogin(t *testing.T) {
|
|||
"--auth", connector.GetName(),
|
||||
"--proxy", proxyAddr.String(),
|
||||
}, setHomePath(tmpHomePath), func(cf *CLIConf) error {
|
||||
cf.mockSSOLogin = ssoLogin
|
||||
cf.MockSSOLogin = ssoLogin
|
||||
return nil
|
||||
})
|
||||
require.ErrorIs(t, err, loginFailed)
|
||||
|
@ -407,7 +407,7 @@ func TestOIDCLogin(t *testing.T) {
|
|||
"--proxy", proxyAddr.String(),
|
||||
"--user", "alice", // explicitly use wrong name
|
||||
}, setHomePath(tmpHomePath), func(cf *CLIConf) error {
|
||||
cf.mockSSOLogin = mockSSOLogin(t, authServer, alice)
|
||||
cf.MockSSOLogin = mockSSOLogin(t, authServer, alice)
|
||||
cf.SiteName = "localhost"
|
||||
cf.overrideStderr = buf
|
||||
return nil
|
||||
|
@ -523,7 +523,7 @@ func TestLoginIdentityOut(t *testing.T) {
|
|||
"--proxy", proxyAddr.String(),
|
||||
"--out", identPath,
|
||||
}, tt.extraArgs...), setHomePath(tmpHomePath), func(cf *CLIConf) error {
|
||||
cf.mockSSOLogin = mockSSOLogin(t, authServer, alice)
|
||||
cf.MockSSOLogin = mockSSOLogin(t, authServer, alice)
|
||||
return nil
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
@ -581,7 +581,7 @@ func TestRelogin(t *testing.T) {
|
|||
"--auth", connector.GetName(),
|
||||
"--proxy", proxyAddr.String(),
|
||||
}, setHomePath(tmpHomePath), func(cf *CLIConf) error {
|
||||
cf.mockSSOLogin = mockSSOLogin(t, authServer, alice)
|
||||
cf.MockSSOLogin = mockSSOLogin(t, authServer, alice)
|
||||
cf.overrideStderr = buf
|
||||
return nil
|
||||
})
|
||||
|
@ -596,7 +596,7 @@ func TestRelogin(t *testing.T) {
|
|||
"localhost",
|
||||
}, setHomePath(tmpHomePath),
|
||||
func(cf *CLIConf) error {
|
||||
cf.mockSSOLogin = mockSSOLogin(t, authServer, alice)
|
||||
cf.MockSSOLogin = mockSSOLogin(t, authServer, alice)
|
||||
cf.overrideStderr = buf
|
||||
return nil
|
||||
})
|
||||
|
@ -618,7 +618,7 @@ func TestRelogin(t *testing.T) {
|
|||
"--proxy", proxyAddr.String(),
|
||||
"localhost",
|
||||
}, setHomePath(tmpHomePath), func(cf *CLIConf) error {
|
||||
cf.mockSSOLogin = mockSSOLogin(t, authServer, alice)
|
||||
cf.MockSSOLogin = mockSSOLogin(t, authServer, alice)
|
||||
cf.overrideStderr = buf
|
||||
return nil
|
||||
})
|
||||
|
@ -667,7 +667,7 @@ func TestSwitchingProxies(t *testing.T) {
|
|||
"--auth", connector.GetName(),
|
||||
"--proxy", proxyAddr1.String(),
|
||||
}, setHomePath(tmpHomePath), func(cf *CLIConf) error {
|
||||
cf.mockSSOLogin = mockSSOLogin(t, authServer1, alice)
|
||||
cf.MockSSOLogin = mockSSOLogin(t, authServer1, alice)
|
||||
return nil
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
@ -680,7 +680,7 @@ func TestSwitchingProxies(t *testing.T) {
|
|||
"--proxy", proxyAddr2.String(),
|
||||
}, setHomePath(tmpHomePath),
|
||||
func(cf *CLIConf) error {
|
||||
cf.mockSSOLogin = mockSSOLogin(t, authServer2, alice)
|
||||
cf.MockSSOLogin = mockSSOLogin(t, authServer2, alice)
|
||||
return nil
|
||||
})
|
||||
|
||||
|
@ -875,7 +875,7 @@ func TestMakeClient(t *testing.T) {
|
|||
// makeClient should call Ping on the proxy to fetch SSHProxyAddr
|
||||
conf = CLIConf{
|
||||
Proxy: proxyWebAddr.String(),
|
||||
IdentityFileIn: "../../fixtures/certs/identities/tls.pem",
|
||||
IdentityFileIn: "../../../fixtures/certs/identities/tls.pem",
|
||||
Context: context.Background(),
|
||||
InsecureSkipVerify: true,
|
||||
}
|
||||
|
@ -1494,7 +1494,7 @@ func TestSSHOnMultipleNodes(t *testing.T) {
|
|||
tt.cluster,
|
||||
}, setHomePath(tmpHomePath),
|
||||
func(cf *CLIConf) error {
|
||||
cf.mockSSOLogin = mockSSOLogin(t, tt.auth, alice)
|
||||
cf.MockSSOLogin = mockSSOLogin(t, tt.auth, alice)
|
||||
return nil
|
||||
},
|
||||
)
|
||||
|
@ -1516,8 +1516,8 @@ func TestSSHOnMultipleNodes(t *testing.T) {
|
|||
setHomePath(tmpHomePath),
|
||||
func(conf *CLIConf) error {
|
||||
conf.overrideStdin = &bytes.Buffer{}
|
||||
conf.overrideStdout = stdout
|
||||
conf.mockHeadlessLogin = mockHeadlessLogin(t, tt.auth, alice)
|
||||
conf.OverrideStdout = stdout
|
||||
conf.MockHeadlessLogin = mockHeadlessLogin(t, tt.auth, alice)
|
||||
return nil
|
||||
},
|
||||
)
|
||||
|
@ -1632,8 +1632,8 @@ func TestSSHAccessRequest(t *testing.T) {
|
|||
"--auth", connector.GetName(),
|
||||
"--proxy", proxyAddr.String(),
|
||||
"--user", "alice",
|
||||
}, setHomePath(tmpHomePath), cliOption(func(cf *CLIConf) error {
|
||||
cf.mockSSOLogin = mockSSOLogin(t, rootAuth.GetAuthServer(), alice)
|
||||
}, setHomePath(tmpHomePath), CliOption(func(cf *CLIConf) error {
|
||||
cf.MockSSOLogin = mockSSOLogin(t, rootAuth.GetAuthServer(), alice)
|
||||
return nil
|
||||
}))
|
||||
require.NoError(t, err)
|
||||
|
@ -1729,8 +1729,8 @@ func TestSSHAccessRequest(t *testing.T) {
|
|||
"--auth", connector.GetName(),
|
||||
"--proxy", proxyAddr.String(),
|
||||
"--user", "alice",
|
||||
}, setHomePath(tmpHomePath), cliOption(func(cf *CLIConf) error {
|
||||
cf.mockSSOLogin = mockSSOLogin(t, rootAuth.GetAuthServer(), alice)
|
||||
}, setHomePath(tmpHomePath), CliOption(func(cf *CLIConf) error {
|
||||
cf.MockSSOLogin = mockSSOLogin(t, rootAuth.GetAuthServer(), alice)
|
||||
return nil
|
||||
}))
|
||||
require.NoError(t, err)
|
||||
|
@ -1847,7 +1847,7 @@ func TestAccessRequestOnLeaf(t *testing.T) {
|
|||
"--auth", connector.GetName(),
|
||||
"--proxy", rootProxyAddr.String(),
|
||||
}, setHomePath(tmpHomePath), func(cf *CLIConf) error {
|
||||
cf.mockSSOLogin = mockSSOLogin(t, rootAuthServer, alice)
|
||||
cf.MockSSOLogin = mockSSOLogin(t, rootAuthServer, alice)
|
||||
return nil
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
@ -2006,7 +2006,7 @@ func TestKubeCredentialsLock(t *testing.T) {
|
|||
"--auth", connector.GetName(),
|
||||
"--proxy", proxyAddr.String(),
|
||||
}, setHomePath(tmpHomePath), func(cf *CLIConf) error {
|
||||
cf.mockSSOLogin = ssoFunc
|
||||
cf.MockSSOLogin = ssoFunc
|
||||
return nil
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
@ -2067,7 +2067,7 @@ iUK/veLmZ6XoouiWLCdU1VJz/1Fcwe/IEamg6ETfofvsqOCgcNYJ
|
|||
"--teleport-cluster", teleportClusterName.GetClusterName(),
|
||||
"--kube-cluster", kubeClusterName,
|
||||
}, setHomePath(tmpHomePath), func(cf *CLIConf) error {
|
||||
cf.mockSSOLogin = ssoFunc
|
||||
cf.MockSSOLogin = ssoFunc
|
||||
return nil
|
||||
})
|
||||
errChan <- credErr
|
||||
|
@ -2209,9 +2209,9 @@ func TestSSHHeadless(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
bob.SetRoles([]string{"requester"})
|
||||
|
||||
sshHostName := "test-ssh-host"
|
||||
sshHostname := "test-ssh-host"
|
||||
rootAuth, rootProxy := makeTestServers(t, withBootstrap(nodeAccess, alice, requester, bob), withConfig(func(cfg *servicecfg.Config) {
|
||||
cfg.Hostname = sshHostName
|
||||
cfg.Hostname = sshHostname
|
||||
cfg.SSH.Enabled = true
|
||||
cfg.SSH.Addr = utils.NetAddr{AddrNetwork: "tcp", Addr: net.JoinHostPort("127.0.0.1", ports.Pop())}
|
||||
}))
|
||||
|
@ -2262,12 +2262,12 @@ func TestSSHHeadless(t *testing.T) {
|
|||
"--proxy", proxyAddr.String(),
|
||||
}, tc.args...)
|
||||
args = append(args,
|
||||
fmt.Sprintf("%s@%s", user.Username, sshHostName),
|
||||
fmt.Sprintf("%s@%s", user.Username, sshHostname),
|
||||
"echo", "test",
|
||||
)
|
||||
|
||||
err := Run(ctx, args, cliOption(func(cf *CLIConf) error {
|
||||
cf.mockHeadlessLogin = mockHeadlessLogin(t, rootAuth.GetAuthServer(), alice)
|
||||
err := Run(ctx, args, CliOption(func(cf *CLIConf) error {
|
||||
cf.MockHeadlessLogin = mockHeadlessLogin(t, rootAuth.GetAuthServer(), alice)
|
||||
return nil
|
||||
}))
|
||||
tc.assertErr(t, err)
|
||||
|
@ -2943,7 +2943,7 @@ func TestAuthClientFromTSHProfile(t *testing.T) {
|
|||
"--auth", connector.GetName(),
|
||||
"--proxy", proxyAddr.String(),
|
||||
}, setHomePath(tmpHomePath), func(cf *CLIConf) error {
|
||||
cf.mockSSOLogin = mockSSOLogin(t, authServer, alice)
|
||||
cf.MockSSOLogin = mockSSOLogin(t, authServer, alice)
|
||||
return nil
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
@ -3189,39 +3189,39 @@ func mockHeadlessLogin(t *testing.T, authServer *auth.Server, user types.User) c
|
|||
}
|
||||
}
|
||||
|
||||
func setOverrideStdout(stdout io.Writer) cliOption {
|
||||
func setOverrideStdout(stdout io.Writer) CliOption {
|
||||
return func(cf *CLIConf) error {
|
||||
cf.overrideStdout = stdout
|
||||
cf.OverrideStdout = stdout
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func setCopyStdout(stdout io.Writer) cliOption {
|
||||
func setCopyStdout(stdout io.Writer) CliOption {
|
||||
return setOverrideStdout(io.MultiWriter(os.Stdout, stdout))
|
||||
}
|
||||
|
||||
func setHomePath(path string) cliOption {
|
||||
func setHomePath(path string) CliOption {
|
||||
return func(cf *CLIConf) error {
|
||||
cf.HomePath = path
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func setKubeConfigPath(path string) cliOption {
|
||||
func setKubeConfigPath(path string) CliOption {
|
||||
return func(cf *CLIConf) error {
|
||||
cf.kubeConfigPath = path
|
||||
cf.KubeConfigPath = path
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func setIdentity(path string) cliOption {
|
||||
func setIdentity(path string) CliOption {
|
||||
return func(cf *CLIConf) error {
|
||||
cf.IdentityFileIn = path
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func setCmdRunner(cmdRunner func(*exec.Cmd) error) cliOption {
|
||||
func setCmdRunner(cmdRunner func(*exec.Cmd) error) CliOption {
|
||||
return func(cf *CLIConf) error {
|
||||
cf.cmdRunner = cmdRunner
|
||||
return nil
|
||||
|
@ -4304,7 +4304,7 @@ func TestForwardingTraces(t *testing.T) {
|
|||
"--proxy", proxyAddr.String(),
|
||||
"--trace",
|
||||
}, setHomePath(tmpHomePath), func(cf *CLIConf) error {
|
||||
cf.mockSSOLogin = mockSSOLogin(t, authServer, alice)
|
||||
cf.MockSSOLogin = mockSSOLogin(t, authServer, alice)
|
||||
return nil
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
@ -4423,7 +4423,7 @@ func TestExportingTraces(t *testing.T) {
|
|||
"--trace",
|
||||
"--trace-exporter", tshCollector.GRPCAddr(),
|
||||
}, setHomePath(tmpHomePath), func(cf *CLIConf) error {
|
||||
cf.mockSSOLogin = mockSSOLogin(t, authServer, alice)
|
||||
cf.MockSSOLogin = mockSSOLogin(t, authServer, alice)
|
||||
return nil
|
||||
})
|
||||
require.NoError(t, err)
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
package common
|
||||
|
||||
import (
|
||||
"errors"
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
package common
|
||||
|
||||
import (
|
||||
"os"
|
|
@ -12,7 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package main
|
||||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
25
tool/tsh/main.go
Normal file
25
tool/tsh/main.go
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
Copyright 2016-2021 Gravitational, Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
tshcommon "github.com/gravitational/teleport/tool/tsh/common"
|
||||
)
|
||||
|
||||
func main() {
|
||||
tshcommon.Main()
|
||||
}
|
Loading…
Reference in a new issue