Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
d278306
Update type for targetSubresourceName on DocumentGateway
ravicious Jan 2, 2025
83d9248
Use "local port" instead of "port" in DocumentGatewapApp
ravicious Jan 2, 2025
615aeec
Rewrite gateway FieldInputs to use styled components
ravicious Jan 2, 2025
99f2a3a
Update comments in protos
ravicious Jan 2, 2025
0762ce7
useGateway: Stabilize useAsync functions of ports
ravicious Jan 2, 2025
b34d93b
Add padding to menu label if it's first child
ravicious Jan 2, 2025
d6617c3
Add support for required prop to Input and FieldInput
ravicious Jan 2, 2025
e9bcf63
Add UI for changing target port
ravicious Jan 2, 2025
00665a3
ActionButtons: Show ports of multi-port apps when VNet is not supported
ravicious Jan 2, 2025
7d359a5
Add RWMutex to gateways
ravicious Jan 2, 2025
819ecbb
Clear app gateway cert on target port change
ravicious Jan 2, 2025
596b62d
Remove gateways/app.LocalProxyURL
ravicious Jan 2, 2025
53b1061
TestTCP: Close connections when test ends
ravicious Jan 2, 2025
34f5c85
Create context with timeout in testGatewayCertRenewal
ravicious Jan 2, 2025
d3c8122
Add tests for changing the target port of a TCP gateway
ravicious Jan 2, 2025
415cd92
Parallelize app gateway tests within MFA/non-MFA groups
ravicious Jan 2, 2025
4b3cb94
Make testGatewayConnection take ctx as first arg
ravicious Jan 2, 2025
41646e1
Validate target port of app gateways
ravicious Jan 2, 2025
4ffb482
Increase timeouts in app gateway tests
ravicious Jan 10, 2025
e3c849f
Change icons from medium to small
ravicious Jan 13, 2025
0048d41
Use consistent spacing in AppGateway
ravicious Jan 13, 2025
1dd43af
Add godoc for ValidateTargetPort
ravicious Jan 13, 2025
41b1f2e
Add retry with relogin to change target port
ravicious Jan 13, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions gen/proto/go/teleport/lib/teleterm/v1/gateway.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions gen/proto/ts/teleport/lib/teleterm/v1/gateway_pb.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions integration/appaccess/appaccess_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -831,6 +831,7 @@ func TestTCP(t *testing.T) {

conn, err := net.Dial("tcp", localProxyAddress)
require.NoError(t, err)
defer conn.Close()

buf := make([]byte, 1024)
n, err := conn.Read(buf)
Expand Down
56 changes: 56 additions & 0 deletions integration/appaccess/pack.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,34 @@ func (p *Pack) RootAppPublicAddr() string {
return p.rootAppPublicAddr
}

func (p *Pack) RootTCPAppName() string {
return p.rootTCPAppName
}

func (p *Pack) RootTCPMessage() string {
return p.rootTCPMessage
}

func (p *Pack) RootTCPMultiPortAppName() string {
return p.rootTCPMultiPortAppName
}

func (p *Pack) RootTCPMultiPortAppPortAlpha() int {
return p.rootTCPMultiPortAppPortAlpha
}

func (p *Pack) RootTCPMultiPortMessageAlpha() string {
return p.rootTCPMultiPortMessageAlpha
}

func (p *Pack) RootTCPMultiPortAppPortBeta() int {
return p.rootTCPMultiPortAppPortBeta
}

func (p *Pack) RootTCPMultiPortMessageBeta() string {
return p.rootTCPMultiPortMessageBeta
}

func (p *Pack) RootAuthServer() *auth.Server {
return p.rootCluster.Process.GetAuthServer()
}
Expand All @@ -200,6 +228,34 @@ func (p *Pack) LeafAppPublicAddr() string {
return p.leafAppPublicAddr
}

func (p *Pack) LeafTCPAppName() string {
return p.leafTCPAppName
}

func (p *Pack) LeafTCPMessage() string {
return p.leafTCPMessage
}

func (p *Pack) LeafTCPMultiPortAppName() string {
return p.leafTCPMultiPortAppName
}

func (p *Pack) LeafTCPMultiPortAppPortAlpha() int {
return p.leafTCPMultiPortAppPortAlpha
}

func (p *Pack) LeafTCPMultiPortMessageAlpha() string {
return p.leafTCPMultiPortMessageAlpha
}

func (p *Pack) LeafTCPMultiPortAppPortBeta() int {
return p.leafTCPMultiPortAppPortBeta
}

func (p *Pack) LeafTCPMultiPortMessageBeta() string {
return p.leafTCPMultiPortMessageBeta
}

func (p *Pack) LeafAuthServer() *auth.Server {
return p.leafCluster.Process.GetAuthServer()
}
Expand Down
53 changes: 46 additions & 7 deletions integration/proxy/proxy_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"net/http"
"net/url"
"path/filepath"
"strconv"
"strings"
"testing"
"time"
Expand Down Expand Up @@ -684,7 +685,7 @@ func mustFindKubePod(t *testing.T, tc *client.TeleportClient) {
require.Equal(t, types.KindKubePod, response.Resources[0].Kind)
}

func mustConnectDatabaseGateway(t *testing.T, _ *daemon.Service, gw gateway.Gateway) {
func mustConnectDatabaseGateway(ctx context.Context, t *testing.T, _ *daemon.Service, gw gateway.Gateway) {
t.Helper()

dbGateway, err := gateway.AsDatabase(gw)
Expand All @@ -705,15 +706,15 @@ func mustConnectDatabaseGateway(t *testing.T, _ *daemon.Service, gw gateway.Gate
require.NoError(t, client.Close())
}

// mustConnectAppGateway verifies that the gateway acts as an unauthenticated proxy that forwards
// requests to the app behind it.
func mustConnectAppGateway(t *testing.T, _ *daemon.Service, gw gateway.Gateway) {
// mustConnectWebAppGateway verifies that the gateway acts as an unauthenticated proxy that forwards
// requests to the web app behind it.
func mustConnectWebAppGateway(ctx context.Context, t *testing.T, _ *daemon.Service, gw gateway.Gateway) {
t.Helper()

appGw, err := gateway.AsApp(gw)
require.NoError(t, err)
gatewayAddress := net.JoinHostPort(gw.LocalAddress(), gw.LocalPort())
gatewayURL := fmt.Sprintf("http://%s", gatewayAddress)

req, err := http.NewRequest(http.MethodGet, appGw.LocalProxyURL(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, gatewayURL, nil)
require.NoError(t, err)

client := &http.Client{}
Expand All @@ -724,6 +725,44 @@ func mustConnectAppGateway(t *testing.T, _ *daemon.Service, gw gateway.Gateway)
require.Equal(t, http.StatusOK, resp.StatusCode)
}

func makeMustConnectMultiPortTCPAppGateway(wantMessage string, otherTargetPort int, otherWantMessage string) testGatewayConnectionFunc {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI @ravicious, this change breaks the build. proxy_helpers.go (a "production" file) depends on testGatewayConnectionFunc, which is declared in teleterm_test.go (a test file).

It also looks like we don't build integration/ outside of tests, so this wrongly passes CI (but breaks elsewhere - for example https://github.com/gravitational/teleport.e/actions/runs/12765303605/job/35579282485).

return func(ctx context.Context, t *testing.T, d *daemon.Service, gw gateway.Gateway) {
t.Helper()

gwURI := gw.URI().String()
originalTargetPort := gw.TargetSubresourceName()
makeMustConnectTCPAppGateway(wantMessage)(ctx, t, d, gw)

_, err := d.SetGatewayTargetSubresourceName(ctx, gwURI, strconv.Itoa(otherTargetPort))
require.NoError(t, err)
makeMustConnectTCPAppGateway(otherWantMessage)(ctx, t, d, gw)

// Restore the original port, so that the next time the test calls this function after certs
// expire, wantMessage is going to match the port that the gateway points to.
_, err = d.SetGatewayTargetSubresourceName(ctx, gwURI, originalTargetPort)
require.NoError(t, err)
makeMustConnectTCPAppGateway(wantMessage)(ctx, t, d, gw)
}
}

func makeMustConnectTCPAppGateway(wantMessage string) testGatewayConnectionFunc {
return func(ctx context.Context, t *testing.T, _ *daemon.Service, gw gateway.Gateway) {
t.Helper()

gatewayAddress := net.JoinHostPort(gw.LocalAddress(), gw.LocalPort())
conn, err := net.Dial("tcp", gatewayAddress)
require.NoError(t, err)
defer conn.Close()

buf := make([]byte, 1024)
n, err := conn.Read(buf)
require.NoError(t, err)

resp := strings.TrimSpace(string(buf[:n]))
require.Equal(t, wantMessage, resp)
}
}

func kubeClientForLocalProxy(t *testing.T, kubeconfigPath, teleportCluster, kubeCluster string) *kubernetes.Clientset {
t.Helper()

Expand Down
30 changes: 21 additions & 9 deletions integration/proxy/proxy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ import (
"github.com/gravitational/teleport/lib"
"github.com/gravitational/teleport/lib/auth/testauthority"
libclient "github.com/gravitational/teleport/lib/client"
"github.com/gravitational/teleport/lib/client/mfa"
"github.com/gravitational/teleport/lib/defaults"
"github.com/gravitational/teleport/lib/modules"
"github.com/gravitational/teleport/lib/multiplexer"
Expand Down Expand Up @@ -1315,18 +1316,29 @@ func TestALPNSNIProxyAppAccess(t *testing.T) {
})

t.Run("teleterm app gateways cert renewal", func(t *testing.T) {
user, _ := pack.CreateUser(t)
tc := pack.MakeTeleportClient(t, user.GetName())

// test without per session MFA.
testTeletermAppGateway(t, pack, tc)
t.Run("without per-session MFA", func(t *testing.T) {
makeTC := func(t *testing.T) (*libclient.TeleportClient, mfa.WebauthnLoginFunc) {
user, _ := pack.CreateUser(t)
tc := pack.MakeTeleportClient(t, user.GetName())
return tc, nil
}
testTeletermAppGateway(t, pack, makeTC)
testTeletermAppGatewayTargetPortValidation(t, pack, makeTC)
})

t.Run("per session MFA", func(t *testing.T) {
// They update user's authentication to Webauthn so they must run after tests which do not use MFA.
t.Run("per-session MFA", func(t *testing.T) {
// They update clusters authentication to Webauthn so they must run after tests which do not use MFA.
requireSessionMFAAuthPref(ctx, t, pack.RootAuthServer(), "127.0.0.1")
requireSessionMFAAuthPref(ctx, t, pack.LeafAuthServer(), "127.0.0.1")
tc.WebauthnLogin = setupUserMFA(ctx, t, pack.RootAuthServer(), user.GetName(), "127.0.0.1")
testTeletermAppGateway(t, pack, tc)
makeTCAndWebauthnLogin := func(t *testing.T) (*libclient.TeleportClient, mfa.WebauthnLoginFunc) {
// Create a separate user for each tests to enable parallel tests that use per-session MFA.
// See the comment for webauthnLogin in setupUserMFA for more details.
user, _ := pack.CreateUser(t)
tc := pack.MakeTeleportClient(t, user.GetName())
webauthnLogin := setupUserMFA(ctx, t, pack.RootAuthServer(), user.GetName(), "127.0.0.1")
return tc, webauthnLogin
}
testTeletermAppGateway(t, pack, makeTCAndWebauthnLogin)
})
})
}
Expand Down
Loading