Skip to content

Commit 61ea343

Browse files
authored
[databases]: add support for MongoDB advanced configuration (#1582)
* [databases]: add support for MongoDB advanced configuration * use mongodb as a slug
1 parent aa0ecb5 commit 61ea343

File tree

7 files changed

+291
-10
lines changed

7 files changed

+291
-10
lines changed

commands/databases.go

+28-8
Original file line numberDiff line numberDiff line change
@@ -2439,6 +2439,7 @@ func databaseConfiguration() *Command {
24392439
displayerType(&displayers.MySQLConfiguration{}),
24402440
displayerType(&displayers.PostgreSQLConfiguration{}),
24412441
displayerType(&displayers.RedisConfiguration{}),
2442+
displayerType(&displayers.MongoDBConfiguration{}),
24422443
)
24432444
AddStringFlag(
24442445
getDatabaseCfgCommand,
@@ -2493,12 +2494,13 @@ func RunDatabaseConfigurationGet(c *CmdConfig) error {
24932494
}
24942495

24952496
allowedEngines := map[string]any{
2496-
"mysql": nil,
2497-
"pg": nil,
2498-
"redis": nil,
2497+
"mysql": nil,
2498+
"pg": nil,
2499+
"redis": nil,
2500+
"mongodb": nil,
24992501
}
25002502
if _, ok := allowedEngines[engine]; !ok {
2501-
return fmt.Errorf("(%s) command: engine must be one of: 'pg', 'mysql', 'redis'", c.NS)
2503+
return fmt.Errorf("(%s) command: engine must be one of: 'pg', 'mysql', 'redis', 'mongodb'", c.NS)
25022504
}
25032505

25042506
dbId := args[0]
@@ -2532,7 +2534,18 @@ func RunDatabaseConfigurationGet(c *CmdConfig) error {
25322534
RedisConfig: *config,
25332535
}
25342536
return c.Display(&displayer)
2537+
} else if engine == "mongodb" {
2538+
config, err := c.Databases().GetMongoDBConfiguration(dbId)
2539+
if err != nil {
2540+
return err
2541+
}
2542+
2543+
displayer := displayers.MongoDBConfiguration{
2544+
MongoDBConfig: *config,
2545+
}
2546+
return c.Display(&displayer)
25352547
}
2548+
25362549
return nil
25372550
}
25382551

@@ -2551,12 +2564,13 @@ func RunDatabaseConfigurationUpdate(c *CmdConfig) error {
25512564
}
25522565

25532566
allowedEngines := map[string]any{
2554-
"mysql": nil,
2555-
"pg": nil,
2556-
"redis": nil,
2567+
"mysql": nil,
2568+
"pg": nil,
2569+
"redis": nil,
2570+
"mongodb": nil,
25572571
}
25582572
if _, ok := allowedEngines[engine]; !ok {
2559-
return fmt.Errorf("(%s) command: engine must be one of: 'pg', 'mysql', 'redis'", c.NS)
2573+
return fmt.Errorf("(%s) command: engine must be one of: 'pg', 'mysql', 'redis', 'mongodb'", c.NS)
25602574
}
25612575

25622576
configJson, err := c.Doit.GetString(c.NS, doctl.ArgDatabaseConfigJson)
@@ -2580,7 +2594,13 @@ func RunDatabaseConfigurationUpdate(c *CmdConfig) error {
25802594
if err != nil {
25812595
return err
25822596
}
2597+
} else if engine == "mongodb" {
2598+
err := c.Databases().UpdateMongoDBConfiguration(dbId, configJson)
2599+
if err != nil {
2600+
return err
2601+
}
25832602
}
2603+
25842604
return nil
25852605
}
25862606

commands/databases_test.go

+78
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,10 @@ var (
211211
RedisConfig: &godo.RedisConfig{},
212212
}
213213

214+
testMongoDBConfiguration = do.MongoDBConfig{
215+
MongoDBConfig: &godo.MongoDBConfig{},
216+
}
217+
214218
topicReplicationFactor = uint32(3)
215219
testKafkaTopic = do.DatabaseTopic{
216220
DatabaseTopic: &godo.DatabaseTopic{
@@ -1652,6 +1656,16 @@ func TestDatabaseConfigurationGet(t *testing.T) {
16521656
assert.NoError(t, err)
16531657
})
16541658

1659+
withTestClient(t, func(config *CmdConfig, tm *tcMocks) {
1660+
tm.databases.EXPECT().GetMongoDBConfiguration(testDBCluster.ID).Return(&testMongoDBConfiguration, nil)
1661+
config.Args = append(config.Args, testDBCluster.ID)
1662+
config.Doit.Set(config.NS, doctl.ArgDatabaseEngine, "mongodb")
1663+
1664+
err := RunDatabaseConfigurationGet(config)
1665+
1666+
assert.NoError(t, err)
1667+
})
1668+
16551669
withTestClient(t, func(config *CmdConfig, tm *tcMocks) {
16561670
err := RunDatabaseConfigurationGet(config)
16571671

@@ -1674,3 +1688,67 @@ func TestDatabaseConfigurationGet(t *testing.T) {
16741688
assert.Error(t, err)
16751689
})
16761690
}
1691+
1692+
func TestDatabaseConfigurationUpdate(t *testing.T) {
1693+
withTestClient(t, func(config *CmdConfig, tm *tcMocks) {
1694+
tm.databases.EXPECT().UpdateMySQLConfiguration(testDBCluster.ID, "").Return(nil)
1695+
config.Args = append(config.Args, testDBCluster.ID)
1696+
config.Doit.Set(config.NS, doctl.ArgDatabaseEngine, "mysql")
1697+
1698+
err := RunDatabaseConfigurationUpdate(config)
1699+
1700+
assert.NoError(t, err)
1701+
})
1702+
1703+
withTestClient(t, func(config *CmdConfig, tm *tcMocks) {
1704+
tm.databases.EXPECT().UpdatePostgreSQLConfiguration(testDBCluster.ID, "").Return(nil)
1705+
config.Args = append(config.Args, testDBCluster.ID)
1706+
config.Doit.Set(config.NS, doctl.ArgDatabaseEngine, "pg")
1707+
1708+
err := RunDatabaseConfigurationUpdate(config)
1709+
1710+
assert.NoError(t, err)
1711+
})
1712+
1713+
withTestClient(t, func(config *CmdConfig, tm *tcMocks) {
1714+
tm.databases.EXPECT().UpdateRedisConfiguration(testDBCluster.ID, "").Return(nil)
1715+
config.Args = append(config.Args, testDBCluster.ID)
1716+
config.Doit.Set(config.NS, doctl.ArgDatabaseEngine, "redis")
1717+
1718+
err := RunDatabaseConfigurationUpdate(config)
1719+
1720+
assert.NoError(t, err)
1721+
})
1722+
1723+
withTestClient(t, func(config *CmdConfig, tm *tcMocks) {
1724+
tm.databases.EXPECT().UpdateMongoDBConfiguration(testDBCluster.ID, "").Return(nil)
1725+
config.Args = append(config.Args, testDBCluster.ID)
1726+
config.Doit.Set(config.NS, doctl.ArgDatabaseEngine, "mongodb")
1727+
1728+
err := RunDatabaseConfigurationUpdate(config)
1729+
1730+
assert.NoError(t, err)
1731+
})
1732+
1733+
withTestClient(t, func(config *CmdConfig, tm *tcMocks) {
1734+
err := RunDatabaseConfigurationUpdate(config)
1735+
1736+
assert.Equal(t, err, doctl.NewMissingArgsErr(config.NS))
1737+
})
1738+
1739+
withTestClient(t, func(config *CmdConfig, tm *tcMocks) {
1740+
config.Args = append(config.Args, testDBCluster.ID, "extra arg")
1741+
1742+
err := RunDatabaseConfigurationUpdate(config)
1743+
1744+
assert.Equal(t, err, doctl.NewTooManyArgsErr(config.NS))
1745+
})
1746+
1747+
withTestClient(t, func(config *CmdConfig, tm *tcMocks) {
1748+
config.Args = append(config.Args, testDBCluster.ID)
1749+
1750+
err := RunDatabaseConfigurationUpdate(config)
1751+
1752+
assert.Error(t, err)
1753+
})
1754+
}

commands/displayers/database.go

+61
Original file line numberDiff line numberDiff line change
@@ -1678,6 +1678,67 @@ func (dc *RedisConfiguration) KV() []map[string]any {
16781678
return o
16791679
}
16801680

1681+
type MongoDBConfiguration struct {
1682+
MongoDBConfig do.MongoDBConfig
1683+
}
1684+
1685+
var _ Displayable = &MongoDBConfiguration{}
1686+
1687+
func (dc *MongoDBConfiguration) JSON(out io.Writer) error {
1688+
return writeJSON(dc.MongoDBConfig, out)
1689+
}
1690+
1691+
func (dc *MongoDBConfiguration) Cols() []string {
1692+
return []string{
1693+
"key",
1694+
"value",
1695+
}
1696+
}
1697+
1698+
func (dc *MongoDBConfiguration) ColMap() map[string]string {
1699+
return map[string]string{
1700+
"key": "key",
1701+
"value": "value",
1702+
}
1703+
}
1704+
1705+
func (dc *MongoDBConfiguration) KV() []map[string]any {
1706+
c := dc.MongoDBConfig
1707+
o := []map[string]any{}
1708+
if c.DefaultReadConcern != nil {
1709+
o = append(o, map[string]any{
1710+
"key": "DefaultReadConcern",
1711+
"value": *c.DefaultReadConcern,
1712+
})
1713+
}
1714+
if c.DefaultWriteConcern != nil {
1715+
o = append(o, map[string]any{
1716+
"key": "DefaultWriteConcern",
1717+
"value": *c.DefaultWriteConcern,
1718+
})
1719+
}
1720+
if c.SlowOpThresholdMs != nil {
1721+
o = append(o, map[string]any{
1722+
"key": "SlowOpThresholdMs",
1723+
"value": *c.SlowOpThresholdMs,
1724+
})
1725+
}
1726+
if c.TransactionLifetimeLimitSeconds != nil {
1727+
o = append(o, map[string]any{
1728+
"key": "TransactionLifetimeLimitSeconds",
1729+
"value": *c.TransactionLifetimeLimitSeconds,
1730+
})
1731+
}
1732+
if c.Verbosity != nil {
1733+
o = append(o, map[string]any{
1734+
"key": "Verbosity",
1735+
"value": *c.Verbosity,
1736+
})
1737+
}
1738+
1739+
return o
1740+
}
1741+
16811742
type DatabaseEvents struct {
16821743
DatabaseEvents do.DatabaseEvents
16831744
}

do/databases.go

+33
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,11 @@ type RedisConfig struct {
120120
*godo.RedisConfig
121121
}
122122

123+
// MongoDBConfig is a wrapper for godo.MongoDBConfig
124+
type MongoDBConfig struct {
125+
*godo.MongoDBConfig
126+
}
127+
123128
// DatabaseTopics is a slice of DatabaseTopic
124129
type DatabaseTopics []DatabaseTopic
125130

@@ -200,10 +205,12 @@ type DatabasesService interface {
200205
GetMySQLConfiguration(databaseID string) (*MySQLConfig, error)
201206
GetPostgreSQLConfiguration(databaseID string) (*PostgreSQLConfig, error)
202207
GetRedisConfiguration(databaseID string) (*RedisConfig, error)
208+
GetMongoDBConfiguration(databaseID string) (*MongoDBConfig, error)
203209

204210
UpdateMySQLConfiguration(databaseID string, confString string) error
205211
UpdatePostgreSQLConfiguration(databaseID string, confString string) error
206212
UpdateRedisConfiguration(databaseID string, confString string) error
213+
UpdateMongoDBConfiguration(databaseID string, confString string) error
207214

208215
ListTopics(string) (DatabaseTopics, error)
209216
GetTopic(string, string) (*DatabaseTopic, error)
@@ -695,6 +702,17 @@ func (ds *databasesService) GetRedisConfiguration(databaseID string) (*RedisConf
695702
}, nil
696703
}
697704

705+
func (ds *databasesService) GetMongoDBConfiguration(databaseID string) (*MongoDBConfig, error) {
706+
cfg, _, err := ds.client.Databases.GetMongoDBConfig(context.TODO(), databaseID)
707+
if err != nil {
708+
return nil, err
709+
}
710+
711+
return &MongoDBConfig{
712+
MongoDBConfig: cfg,
713+
}, nil
714+
}
715+
698716
func (ds *databasesService) UpdateMySQLConfiguration(databaseID string, confString string) error {
699717
var conf godo.MySQLConfig
700718
err := json.Unmarshal([]byte(confString), &conf)
@@ -740,6 +758,21 @@ func (ds *databasesService) UpdateRedisConfiguration(databaseID string, confStri
740758
return nil
741759
}
742760

761+
func (ds *databasesService) UpdateMongoDBConfiguration(databaseID string, confString string) error {
762+
var conf godo.MongoDBConfig
763+
err := json.Unmarshal([]byte(confString), &conf)
764+
if err != nil {
765+
return err
766+
}
767+
768+
_, err = ds.client.Databases.UpdateMongoDBConfig(context.TODO(), databaseID, &conf)
769+
if err != nil {
770+
return err
771+
}
772+
773+
return nil
774+
}
775+
743776
func (ds *databasesService) ListTopics(databaseID string) (DatabaseTopics, error) {
744777
f := func(opt *godo.ListOptions) ([]any, *godo.Response, error) {
745778
list, resp, err := ds.client.Databases.ListTopics(context.TODO(), databaseID, opt)

do/mocks/DatabasesService.go

+29
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

integration/database_config_get_test.go

+23-2
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,18 @@ var _ = suite("database/config/get", func(t *testing.T, when spec.G, it spec.S)
6060
}
6161

6262
w.Write([]byte(databaseConfigRedisGetResponse))
63+
case "/v2/databases/mongodb-database-id/config":
64+
auth := req.Header.Get("Authorization")
65+
if auth != "Bearer some-magic-token" {
66+
w.WriteHeader(http.StatusTeapot)
67+
}
68+
69+
if req.Method != http.MethodGet {
70+
w.WriteHeader(http.StatusMethodNotAllowed)
71+
return
72+
}
73+
74+
w.Write([]byte(databaseConfigMongoDBGetResponse))
6375
default:
6476
dump, err := httputil.DumpRequest(req, true)
6577
if err != nil {
@@ -256,6 +268,15 @@ RedisACLChannelsDefault allchannels
256268
"redis_persistence": "rdb",
257269
"redis_acl_channels_default": "allchannels"
258270
}
259-
}
260-
`
271+
}`
272+
273+
databaseConfigMongoDBGetResponse = `{
274+
"config": {
275+
"default_read_concern": "local",
276+
"default_write_concern": "majority",
277+
"slow_op_threshold_ms": 100,
278+
"transaction_lifetime_limit_seconds": 60,
279+
"verbosity": 1
280+
}
281+
}`
261282
)

0 commit comments

Comments
 (0)