diff --git a/lib/services/database.go b/lib/services/database.go index a25d2ed609770..eed6b7bea19a6 100644 --- a/lib/services/database.go +++ b/lib/services/database.go @@ -213,6 +213,12 @@ func NewDatabasesFromRDSClusterCustomEndpoints(cluster *rds.DBCluster) (types.Da // NewDatabaseFromRedshiftCluster creates a database resource from a Redshift cluster. func NewDatabaseFromRedshiftCluster(cluster *redshift.Cluster) (types.Database, error) { + // Endpoint can be nil while the cluster is being created. Return an error + // until the Endpoint is available. + if cluster.Endpoint == nil { + return nil, trace.BadParameter("missing endpoint in Redshift cluster %v", aws.StringValue(cluster.ClusterIdentifier)) + } + metadata, err := MetadataFromRedshiftCluster(cluster) if err != nil { return nil, trace.Wrap(err) diff --git a/lib/services/database_test.go b/lib/services/database_test.go index f0efc3228f4dc..c16862d506f3a 100644 --- a/lib/services/database_test.go +++ b/lib/services/database_test.go @@ -27,6 +27,7 @@ import ( "github.com/gravitational/teleport/lib/defaults" "github.com/gravitational/teleport/lib/fixtures" "github.com/gravitational/teleport/lib/utils" + "github.com/gravitational/trace" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/rds" @@ -384,46 +385,58 @@ func TestRDSTagsToLabels(t *testing.T) { // TestDatabaseFromRedshiftCluster tests converting an Redshift cluster to a database resource. func TestDatabaseFromRedshiftCluster(t *testing.T) { - cluster := &redshift.Cluster{ - ClusterIdentifier: aws.String("mycluster"), - ClusterNamespaceArn: aws.String("arn:aws:redshift:us-east-1:1234567890:namespace:u-u-i-d"), - Endpoint: &redshift.Endpoint{ - Address: aws.String("localhost"), - Port: aws.Int64(5439), - }, - Tags: []*redshift.Tag{ - { - Key: aws.String("key"), - Value: aws.String("val"), + t.Run("success", func(t *testing.T) { + cluster := &redshift.Cluster{ + ClusterIdentifier: aws.String("mycluster"), + ClusterNamespaceArn: aws.String("arn:aws:redshift:us-east-1:1234567890:namespace:u-u-i-d"), + Endpoint: &redshift.Endpoint{ + Address: aws.String("localhost"), + Port: aws.Int64(5439), }, - { - Key: aws.String("elasticbeanstalk:environment-id"), - Value: aws.String("id"), + Tags: []*redshift.Tag{ + { + Key: aws.String("key"), + Value: aws.String("val"), + }, + { + Key: aws.String("elasticbeanstalk:environment-id"), + Value: aws.String("id"), + }, }, - }, - } - expected, err := types.NewDatabaseV3(types.Metadata{ - Name: "mycluster", - Description: "Redshift cluster in us-east-1", - Labels: map[string]string{ - types.OriginLabel: types.OriginCloud, - labelAccountID: "1234567890", - labelRegion: "us-east-1", - "key": "val", - }, - }, types.DatabaseSpecV3{ - Protocol: defaults.ProtocolPostgres, - URI: "localhost:5439", - AWS: types.AWS{ - AccountID: "1234567890", - Region: "us-east-1", - Redshift: types.Redshift{ - ClusterID: "mycluster", + } + expected, err := types.NewDatabaseV3(types.Metadata{ + Name: "mycluster", + Description: "Redshift cluster in us-east-1", + Labels: map[string]string{ + types.OriginLabel: types.OriginCloud, + labelAccountID: "1234567890", + labelRegion: "us-east-1", + "key": "val", }, - }, + }, types.DatabaseSpecV3{ + Protocol: defaults.ProtocolPostgres, + URI: "localhost:5439", + AWS: types.AWS{ + AccountID: "1234567890", + Region: "us-east-1", + Redshift: types.Redshift{ + ClusterID: "mycluster", + }, + }, + }) + + require.NoError(t, err) + + actual, err := NewDatabaseFromRedshiftCluster(cluster) + require.NoError(t, err) + require.Equal(t, expected, actual) + }) + + t.Run("missing endpoint", func(t *testing.T) { + _, err := NewDatabaseFromRedshiftCluster(&redshift.Cluster{ + ClusterIdentifier: aws.String("still-creating"), + }) + require.Error(t, err) + require.True(t, trace.IsBadParameter(err), "Expected trace.BadParameter, got %v", err) }) - require.NoError(t, err) - actual, err := NewDatabaseFromRedshiftCluster(cluster) - require.NoError(t, err) - require.Equal(t, expected, actual) }