Skip to content

Commit

Permalink
feat: resource mysql_rds_config (petoju#3)
Browse files Browse the repository at this point in the history
* feat: replace binlog resource for RDS config resource

* chore: add mysq_rds_config read, update and import acctest
  • Loading branch information
cemdorst authored Feb 1, 2023
1 parent adbfa67 commit 227309b
Show file tree
Hide file tree
Showing 10 changed files with 466 additions and 182 deletions.
11 changes: 10 additions & 1 deletion GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ TERRAFORM_OS=$(shell uname -s | tr A-Z a-z)
TEST_USER=root
TEST_PASSWORD=my-secret-pw


default: build

build: fmtcheck
Expand All @@ -25,7 +26,7 @@ bin/terraform:
testacc: fmtcheck bin/terraform
PATH="$(CURDIR)/bin:${PATH}" TF_ACC=1 go test $(TEST) -v $(TESTARGS) -timeout=60s

acceptance: testversion5.6 testversion5.7 testversion8.0 testpercona5.7 testpercona8.0 testmariadb10.3 testmariadb10.8 testmariadb10.10 testtidb6.1.0
acceptance: testversion5.6 testversion5.7 testversion8.0 testpercona5.7 testpercona8.0 testmariadb10.3 testmariadb10.8 testmariadb10.10 testtidb6.1.0 testrdsdb5.7 testrdsdb8.0

testversion%:
$(MAKE) MYSQL_VERSION=$* MYSQL_PORT=33$(shell echo "$*" | tr -d '.') testversion
Expand All @@ -49,6 +50,14 @@ testpercona:
MYSQL_USERNAME="$(TEST_USER)" MYSQL_PASSWORD="$(TEST_PASSWORD)" MYSQL_ENDPOINT=127.0.0.1:$(MYSQL_PORT) $(MAKE) testacc
docker rm -f test-percona$(MYSQL_VERSION)

testrdsdb%:
$(MAKE) MYSQL_VERSION=$* MYSQL_USERNAME=${MYSQL_USERNAME} MYSQL_HOST=$(shell echo ${MYSQL_ENDPOINT} | cut -d: -f1) MYSQL_PASSWORD=${MYSQL_PASSWORD} MYSQL_PORT=$(shell echo ${MYSQL_ENDPOINT} | cut -d: -f2) testrdsdb

testrdsdb:
@echo 'Waiting for AMAZON RDS...'
@while ! mysql -h "$(MYSQL_HOST)" -P "$(MYSQL_PORT)" -u "$(MYSQL_USERNAME)" -p"$(MYSQL_PASSWORD)" -e 'SELECT 1' >/dev/null 2>&1; do printf '.'; sleep 1; done ; echo ; echo "Connected!"
$(MAKE) testacc

testtidb%:
$(MAKE) MYSQL_VERSION=$* MYSQL_PORT=34$(shell echo "$*" | tr -d '.') testtidb

Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ require (
cloud.google.com/go/compute v1.15.1 // indirect
cloud.google.com/go/compute/metadata v0.2.3 // indirect
github.com/agext/levenshtein v1.2.3 // indirect
github.com/apparentlymart/go-cidr v1.1.0 // indirect
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fatih/color v1.13.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,8 @@ github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7l
github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/apparentlymart/go-cidr v1.1.0 h1:2mAhrMoF+nhXqxTzSZMUzDHkLjmIHC+Zzn4tdgBZjnU=
github.com/apparentlymart/go-cidr v1.1.0/go.mod h1:EBcsNrHc3zQeuaeCeCtQruQm+n9/YjEn/vI25Lg7Gwc=
github.com/apparentlymart/go-dump v0.0.0-20190214190832-042adf3cf4a0 h1:MzVXffFUye+ZcSR6opIgz9Co7WcDx6ZcY+RjfFHoA0I=
github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk=
github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec=
Expand Down
18 changes: 9 additions & 9 deletions mysql/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,15 +142,15 @@ func Provider() *schema.Provider {
},

ResourcesMap: map[string]*schema.Resource{
"mysql_database": resourceDatabase(),
"mysql_global_variable": resourceGlobalVariable(),
"mysql_grant": resourceGrant(),
"mysql_role": resourceRole(),
"mysql_sql": resourceSql(),
"mysql_user_password": resourceUserPassword(),
"mysql_user": resourceUser(),
"mysql_ti_config": resourceTiConfigVariable(),
"mysql_binlog_retention": resourceBinLog(),
"mysql_database": resourceDatabase(),
"mysql_global_variable": resourceGlobalVariable(),
"mysql_grant": resourceGrant(),
"mysql_role": resourceRole(),
"mysql_sql": resourceSql(),
"mysql_user_password": resourceUserPassword(),
"mysql_user": resourceUser(),
"mysql_ti_config": resourceTiConfigVariable(),
"mysql_rds_config": resourceRDSConfig(),
},

ConfigureContextFunc: providerConfigure,
Expand Down
140 changes: 0 additions & 140 deletions mysql/resource_binlog.go

This file was deleted.

182 changes: 182 additions & 0 deletions mysql/resource_rds_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
package mysql

import (
"context"
"database/sql"
"fmt"
"log"
"strconv"
"time"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"

"github.com/go-sql-driver/mysql"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func resourceRDSConfig() *schema.Resource {
return &schema.Resource{
CreateContext: CreateRDSConfig,
UpdateContext: UpdateRDSConfig,
ReadContext: ReadRDSConfig,
DeleteContext: DeleteRDSConfig,
Importer: &schema.ResourceImporter{
StateContext: ImportRDSConfig,
},
Schema: map[string]*schema.Schema{
"binlog_retention_period": {
Type: schema.TypeInt,
Optional: true,
Default: 0,
Description: "Sets the number of hours to retain binary log files",
},
"replication_target_delay": {
Type: schema.TypeInt,
Optional: true,
Default: 0,
Description: "Sets the number of seconds to delay replication from source database instance to the read replica",
},
},
}
}

func CreateRDSConfig(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
db, err := getDatabaseFromMeta(ctx, meta)
if err != nil {
return diag.FromErr(err)
}

for _, stmtSQL := range RDSConfigSQL(d) {
log.Println("Executing statement:", stmtSQL)

_, err = db.ExecContext(ctx, stmtSQL)
if err != nil {
return diag.Errorf("failed running SQL to set RDS Config: %v", err)
}
}

id := strconv.FormatInt(time.Now().UTC().UnixNano(), 10)

d.SetId(id)

return nil
}

func UpdateRDSConfig(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
db, err := getDatabaseFromMeta(ctx, meta)
if err != nil {
return diag.FromErr(err)
}

for _, stmtSQL := range RDSConfigSQL(d) {
log.Println("Executing statement:", stmtSQL)

_, err = db.ExecContext(ctx, stmtSQL)
if err != nil {
return diag.Errorf("failed updating RDS config: %v", err)
}
}

return nil
}

func ReadRDSConfig(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
db, err := getDatabaseFromMeta(ctx, meta)
if err != nil {
return diag.FromErr(err)
}

stmtSQL := "call mysql.rds_show_configuration"

log.Println("Executing query:", stmtSQL)
rows, err := db.QueryContext(ctx, stmtSQL)
if err != nil {
if mysqlErr, ok := err.(*mysql.MySQLError); ok {
if mysqlErr.Number == unknownDatabaseErrCode {
d.SetId("")
return nil
}
}
return diag.Errorf("Error verifying RDS config: %s", err)
}

results := make(map[string]string)
for rows.Next() {
var name, description string
var value sql.NullString

if err := rows.Scan(&name, &value, &description); err != nil {
return diag.Errorf("failed reading RDS config: %v", err)
}

if value.Valid {
results[name] = value.String
} else {
results[name] = "0"
}
}

binlog_retention_period, err := strconv.Atoi(results["binlog retention hours"])
if err != nil {
return diag.Errorf("failed reading RDS config: %v", err)
}
replication_target_delay, err := strconv.Atoi(results["target delay"])
if err != nil {
return diag.Errorf("failed reading RDS config: %v", err)
}

d.Set("replication_target_delay", replication_target_delay)
d.Set("binlog_retention_period", binlog_retention_period)

return nil
}

func DeleteRDSConfig(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
db, err := getDatabaseFromMeta(ctx, meta)
if err != nil {
return diag.FromErr(err)
}

stmtsSQL := []string{"call mysql.rds_set_configuration('binlog retention hours', NULL)", "call mysql.rds_set_configuration('target delay', 0)"}
for _, stmtSQL := range stmtsSQL {
log.Println("Executing statement:", stmtSQL)

_, err = db.ExecContext(ctx, stmtSQL)
if err != nil {
return diag.Errorf("failed unsetting RDS config: %v", err)
}
}

d.SetId("")
return nil
}

func RDSConfigSQL(d *schema.ResourceData) []string {
result := []string{}
if d.Get("binlog_retention_period") != nil {
retention_period := strconv.Itoa(d.Get("binlog_retention_period").(int))
if retention_period == "0" {
retention_period = "NULL"
}
result = append(result, (fmt.Sprintf("call mysql.rds_set_configuration('binlog retention hours', %s)", retention_period)))
}

if d.Get("replication_target_delay") != nil {
target_delay := strconv.Itoa(d.Get("replication_target_delay").(int))
result = append(result, (fmt.Sprintf("call mysql.rds_set_configuration('target delay', %s)", target_delay)))
}

return result
}

func ImportRDSConfig(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
id := strconv.FormatInt(time.Now().UTC().UnixNano(), 10)
d.SetId(id)

err := ReadRDSConfig(ctx, d, meta)
if err != nil {
return nil, fmt.Errorf("error while importing: %v", err)
}

return []*schema.ResourceData{d}, nil
}
Loading

0 comments on commit 227309b

Please sign in to comment.