Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Databases: Set Kafka Connection Attributes (port, uri, private_uri) #1131

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
30 changes: 27 additions & 3 deletions digitalocean/database/resource_database_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ const (
mongoDBEngineSlug = "mongodb"
mysqlDBEngineSlug = "mysql"
redisDBEngineSlug = "redis"
kafkaDBEngineSlug = "kafka"

kafkaPublicSSLPort = 25073
kafkaPrivateSSLPort = 25080
)

func ResourceDigitalOceanDatabaseCluster() *schema.Resource {
Expand Down Expand Up @@ -307,7 +311,7 @@ func resourceDigitalOceanDatabaseClusterCreate(ctx context.Context, d *schema.Re

// MongoDB clusters only return the password in response to the initial POST.
// We need to set it here before any subsequent GETs.
if database.EngineSlug == mongoDBEngineSlug {
if database.EngineSlug == mongoDBEngineSlug || database.EngineSlug == kafkaDBEngineSlug {
err = setDatabaseConnectionInfo(database, d)
if err != nil {
return diag.Errorf("Error setting connection info for database cluster: %s", err)
Expand Down Expand Up @@ -609,8 +613,12 @@ func flattenMaintWindowOpts(opts godo.DatabaseMaintenanceWindow) []map[string]in
func setDatabaseConnectionInfo(database *godo.Database, d *schema.ResourceData) error {
if database.Connection != nil {
d.Set("host", database.Connection.Host)
d.Set("port", database.Connection.Port)
d.Set("uri", database.Connection.URI)
if database.EngineSlug == kafkaDBEngineSlug {
// default for kafka will be Public SASL port, consistent with UI
d.Set("port", kafkaPublicSSLPort)
Comment on lines +617 to +618
Copy link
Member

Choose a reason for hiding this comment

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

Are the ports guaranteed to be stable? Maybe we should grab it from the response? Something like:

const kafkaSASL = "sasl"
if database.Connection.ApplicationPorts != nil {
	if saslPort, ok := database.Connection.ApplicationPorts[kafkaSASL]; ok {
		d.Set("port", saslPort)
	}
}

} else {
d.Set("port", database.Connection.Port)
}
d.Set("database", database.Connection.Database)
d.Set("user", database.Connection.User)
if database.EngineSlug == mongoDBEngineSlug {
Expand All @@ -622,6 +630,9 @@ func setDatabaseConnectionInfo(database *godo.Database, d *schema.ResourceData)
return err
}
d.Set("uri", uri)
} else if database.EngineSlug == kafkaDBEngineSlug {
uri := buildKafkaConnectionURI(database.Connection, kafkaPublicSSLPort)
d.Set("uri", uri)
} else {
d.Set("password", database.Connection.Password)
d.Set("uri", database.Connection.URI)
Expand All @@ -636,6 +647,9 @@ func setDatabaseConnectionInfo(database *godo.Database, d *schema.ResourceData)
return err
}
d.Set("private_uri", uri)
} else if database.EngineSlug == kafkaDBEngineSlug {
uri := buildKafkaConnectionURI(database.PrivateConnection, kafkaPrivateSSLPort)
d.Set("private_uri", uri)
} else {
d.Set("private_uri", database.PrivateConnection.URI)
}
Expand All @@ -661,6 +675,16 @@ func buildMongoDBConnectionURI(conn *godo.DatabaseConnection, d *schema.Resource
return uri.String(), nil
}

// DO API returns null values for uri and private uri for Kafka clusters.
// buildKafkaConnectionURI sets the uri and private uri using connection's host.
func buildKafkaConnectionURI(conn *godo.DatabaseConnection, port int) string {
host := conn.Host

uri := fmt.Sprintf("%s:%d", host, port)
Copy link
Member

Choose a reason for hiding this comment

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

Lets make sure that this is consistent with what the DBaaS team will eventually return from the API. Should there be a scheme? The other engines all seem to use the format scheme://user:pass@host:port

Copy link
Member Author

Choose a reason for hiding this comment

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

Lets make sure that this is consistent with what the DBaaS team will eventually return from the API. Should there be a scheme? The other engines all seem to use the format scheme://user:pass@host:port

Converting this PR to a draft as dbaas said they might actually get to it this week or next!

Copy link
Member

Choose a reason for hiding this comment

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

Sounds good!


return uri
}

func expandBackupRestore(config []interface{}) *godo.DatabaseBackupRestore {
backupRestoreConfig := config[0].(map[string]interface{})

Expand Down
32 changes: 32 additions & 0 deletions digitalocean/database/resource_database_cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,38 @@ func TestAccDigitalOceanDatabaseCluster_Basic(t *testing.T) {
})
}

func TestAccDigitalOceanDatabaseCluster_KafkaConnectionDetails(t *testing.T) {
var database godo.Database
databaseName := acceptance.RandomTestName()

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acceptance.TestAccPreCheck(t) },
ProviderFactories: acceptance.TestAccProviderFactories,
CheckDestroy: testAccCheckDigitalOceanDatabaseClusterDestroy,
Steps: []resource.TestStep{
{
Config: fmt.Sprintf(testAccCheckDigitalOceanDatabaseClusterKafka, databaseName, "3.5"),
Check: resource.ComposeTestCheckFunc(
testAccCheckDigitalOceanDatabaseClusterExists("digitalocean_database_cluster.foobar", &database),
testAccCheckDigitalOceanDatabaseClusterAttributes(&database, databaseName),
resource.TestCheckResourceAttr(
"digitalocean_database_cluster.foobar", "name", databaseName),
resource.TestCheckResourceAttr(
"digitalocean_database_cluster.foobar", "engine", "kafka"),
resource.TestCheckResourceAttr(
"digitalocean_database_cluster.foobar", "port", "25073"),
resource.TestCheckResourceAttrSet(
"digitalocean_database_cluster.foobar", "uri"),
resource.TestCheckResourceAttrSet(
"digitalocean_database_cluster.foobar", "private_uri"),
resource.TestCheckResourceAttrSet(
"digitalocean_database_cluster.foobar", "host"),
),
},
},
})
}

func TestAccDigitalOceanDatabaseCluster_WithUpdate(t *testing.T) {
var database godo.Database
databaseName := acceptance.RandomTestName()
Expand Down
2 changes: 2 additions & 0 deletions docs/data-sources/database_cluster.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ The following attributes are exported:
* `host` - Database cluster's hostname.
* `private_host` - Same as `host`, but only accessible from resources within the account and in the same region.
* `port` - Network port that the database cluster is listening on.
> Note: For kafka clusters, this is set to be the default public SASL port of 25073.
* `uri` - The full URI for connecting to the database cluster.
> Note: Documentation for connecting to clusters can be found here: [Kafka](https://docs.digitalocean.com/products/databases/kafka/how-to/connect/#connect-via-sasl), [PostgreSQL](https://docs.digitalocean.com/products/databases/postgresql/how-to/connect/), [MySQL](https://docs.digitalocean.com/products/databases/mysql/how-to/connect/), [Redis](https://docs.digitalocean.com/products/databases/redis/how-to/connect/), and [MongoDB](https://docs.digitalocean.com/products/databases/mongodb/how-to/connect/).
* `private_uri` - Same as `uri`, but only accessible from resources within the account and in the same region.
* `database` - Name of the cluster's default database.
* `user` - Username for the cluster's default user.
Expand Down
2 changes: 2 additions & 0 deletions docs/resources/database_cluster.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,9 @@ In addition to the above arguments, the following attributes are exported:
* `host` - Database cluster's hostname.
* `private_host` - Same as `host`, but only accessible from resources within the account and in the same region.
* `port` - Network port that the database cluster is listening on.
> Note: For kafka clusters, this is set to be the default public SASL port of 25073.
* `uri` - The full URI for connecting to the database cluster.
> Note: Documentation for connecting to clusters can be found here: [Kafka](https://docs.digitalocean.com/products/databases/kafka/how-to/connect/#connect-via-sasl), [PostgreSQL](https://docs.digitalocean.com/products/databases/postgresql/how-to/connect/), [MySQL](https://docs.digitalocean.com/products/databases/mysql/how-to/connect/), [Redis](https://docs.digitalocean.com/products/databases/redis/how-to/connect/), and [MongoDB](https://docs.digitalocean.com/products/databases/mongodb/how-to/connect/).
* `private_uri` - Same as `uri`, but only accessible from resources within the account and in the same region.
* `database` - Name of the cluster's default database.
* `user` - Username for the cluster's default user.
Expand Down
Loading