mirror of
https://github.com/gravitational/teleport.git
synced 2026-10-30 18:29:21 +08:00
Support AWS Console for US GovCloud Partition (#13442)
This commit is contained in:
@@ -126,6 +126,13 @@ const (
|
||||
|
||||
// AWSConsoleURL is the URL of AWS management console.
|
||||
AWSConsoleURL = "https://console.aws.amazon.com"
|
||||
// AWSUSGovConsoleURL is the URL of AWS management console for AWS GovCloud
|
||||
// (US) Partition.
|
||||
AWSUSGovConsoleURL = "https://console.amazonaws-us-gov.com"
|
||||
// AWSCNConsoleURL is the URL of AWS management console for AWS China
|
||||
// Partition.
|
||||
AWSCNConsoleURL = "https://console.amazonaws.cn"
|
||||
|
||||
// AWSAccountIDLabel is the key of the label containing AWS account ID.
|
||||
AWSAccountIDLabel = "aws_account_id"
|
||||
|
||||
|
||||
+12
-1
@@ -237,7 +237,18 @@ func (a *AppV3) GetRewrite() *Rewrite {
|
||||
|
||||
// IsAWSConsole returns true if this app is AWS management console.
|
||||
func (a *AppV3) IsAWSConsole() bool {
|
||||
return strings.HasPrefix(a.Spec.URI, constants.AWSConsoleURL)
|
||||
// TODO(greedy52) support region based console URL like:
|
||||
// https://us-east-1.console.aws.amazon.com/
|
||||
for _, consoleURL := range []string{
|
||||
constants.AWSConsoleURL,
|
||||
constants.AWSUSGovConsoleURL,
|
||||
constants.AWSCNConsoleURL,
|
||||
} {
|
||||
if strings.HasPrefix(a.Spec.URI, consoleURL) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsTCP returns true if this app represents a TCP endpoint.
|
||||
|
||||
@@ -167,6 +167,53 @@ func TestAppServerSorter(t *testing.T) {
|
||||
require.True(t, trace.IsNotImplemented(AppServers(servers).SortByCustom(sortBy)))
|
||||
}
|
||||
|
||||
func TestAppIsAWSConsole(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
uri string
|
||||
assertIsAWSConsole require.BoolAssertionFunc
|
||||
}{
|
||||
{
|
||||
name: "AWS Standard",
|
||||
uri: "https://console.aws.amazon.com/ec2/v2/home",
|
||||
assertIsAWSConsole: require.True,
|
||||
},
|
||||
{
|
||||
name: "AWS China",
|
||||
uri: "https://console.amazonaws.cn/console/home",
|
||||
assertIsAWSConsole: require.True,
|
||||
},
|
||||
{
|
||||
name: "AWS GovCloud (US)",
|
||||
uri: "https://console.amazonaws-us-gov.com/console/home",
|
||||
assertIsAWSConsole: require.True,
|
||||
},
|
||||
{
|
||||
name: "Region based not supported yet",
|
||||
uri: "https://us-west-1.console.aws.amazon.com",
|
||||
assertIsAWSConsole: require.False,
|
||||
},
|
||||
{
|
||||
name: "Not an AWS Console URL",
|
||||
uri: "https://hello.world",
|
||||
assertIsAWSConsole: require.False,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
app, err := NewAppV3(Metadata{
|
||||
Name: "aws",
|
||||
}, AppSpecV3{
|
||||
URI: test.uri,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
test.assertIsAWSConsole(t, app.IsAWSConsole())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestApplicationGetAWSExternalID(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
||||
+26
-5
@@ -22,8 +22,10 @@ import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gravitational/teleport/api/constants"
|
||||
"github.com/gravitational/teleport/lib/tlsca"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
@@ -67,7 +69,7 @@ func (r *AWSSigninRequest) CheckAndSetDefaults() error {
|
||||
return trace.Wrap(err)
|
||||
}
|
||||
if r.TargetURL == "" {
|
||||
r.TargetURL = consoleURL
|
||||
return trace.BadParameter("missing TargetURL")
|
||||
}
|
||||
if r.Issuer == "" {
|
||||
return trace.BadParameter("missing Issuer")
|
||||
@@ -131,6 +133,7 @@ func (c *cloud) GetAWSSigninURL(req AWSSigninRequest) (*AWSSigninResponse, error
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
|
||||
federationURL := getFederationURL(req.TargetURL)
|
||||
signinToken, err := c.getAWSSigninToken(&req, federationURL)
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
@@ -333,11 +336,29 @@ type federationResponse struct {
|
||||
SigninToken string `json:"SigninToken"`
|
||||
}
|
||||
|
||||
// getFederationURL picks the AWS federation endpoint based on the AWS
|
||||
// partition of the target URL.
|
||||
//
|
||||
// https://docs.aws.amazon.com/general/latest/gr/signin-service.html
|
||||
// https://docs.amazonaws.cn/en_us/aws/latest/userguide/endpoints-Beijing.html
|
||||
func getFederationURL(targetURL string) string {
|
||||
// TODO(greedy52) support region based sign-in.
|
||||
switch {
|
||||
// AWS GovCloud (US) Partition.
|
||||
case strings.HasPrefix(targetURL, constants.AWSUSGovConsoleURL):
|
||||
return "https://signin.amazonaws-us-gov.com/federation"
|
||||
|
||||
// AWS China Partition.
|
||||
case strings.HasPrefix(targetURL, constants.AWSCNConsoleURL):
|
||||
return "https://signin.amazonaws.cn/federation"
|
||||
|
||||
// AWS Standard Partition.
|
||||
default:
|
||||
return "https://signin.aws.amazon.com/federation"
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
// federationURL is the AWS federation endpoint.
|
||||
federationURL = "https://signin.aws.amazon.com/federation"
|
||||
// consoleURL is the default AWS console destination.
|
||||
consoleURL = "https://console.aws.amazon.com/ec2/v2/home"
|
||||
// maxSessionDuration is the max federation session duration, which is 12
|
||||
// hours. The federation endpoint will error out if we request more.
|
||||
//
|
||||
|
||||
@@ -29,6 +29,7 @@ import (
|
||||
"github.com/aws/aws-sdk-go/service/sts"
|
||||
"github.com/jonboulle/clockwork"
|
||||
|
||||
"github.com/gravitational/teleport/api/constants"
|
||||
"github.com/gravitational/teleport/lib/tlsca"
|
||||
"github.com/gravitational/trace"
|
||||
"github.com/stretchr/testify/require"
|
||||
@@ -287,3 +288,33 @@ func TestCloudGetAWSSigninToken(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCloudGetFederationURL(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
inputTargetURL string
|
||||
expectedFederationURL string
|
||||
}{
|
||||
{
|
||||
name: "AWS GovCloud (US)",
|
||||
inputTargetURL: constants.AWSUSGovConsoleURL,
|
||||
expectedFederationURL: "https://signin.amazonaws-us-gov.com/federation",
|
||||
},
|
||||
{
|
||||
name: "AWS China",
|
||||
inputTargetURL: constants.AWSCNConsoleURL,
|
||||
expectedFederationURL: "https://signin.amazonaws.cn/federation",
|
||||
},
|
||||
{
|
||||
name: "AWS Standard",
|
||||
inputTargetURL: constants.AWSConsoleURL,
|
||||
expectedFederationURL: "https://signin.aws.amazon.com/federation",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
require.Equal(t, test.expectedFederationURL, getFederationURL(test.inputTargetURL))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user