From 911e02e34c53048e96e17f9e8cf9bfb159496c99 Mon Sep 17 00:00:00 2001 From: Dorst Date: Thu, 15 Dec 2022 13:19:19 -0300 Subject: [PATCH 1/5] feat: add binlog retention resource --- mysql/provider.go | 17 +++--- mysql/resource_binlog.go | 129 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 138 insertions(+), 8 deletions(-) create mode 100644 mysql/resource_binlog.go diff --git a/mysql/provider.go b/mysql/provider.go index 86e5f2e3..7aabf8fc 100644 --- a/mysql/provider.go +++ b/mysql/provider.go @@ -141,14 +141,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_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(), }, ConfigureContextFunc: providerConfigure, diff --git a/mysql/resource_binlog.go b/mysql/resource_binlog.go new file mode 100644 index 00000000..68dad59f --- /dev/null +++ b/mysql/resource_binlog.go @@ -0,0 +1,129 @@ +package mysql + +import ( + "context" + "fmt" + "log" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + + "github.com/go-sql-driver/mysql" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func resourceBinLog() *schema.Resource { + return &schema.Resource{ + CreateContext: CreateBinLog, + UpdateContext: UpdateBinLog, + ReadContext: ReadBinLog, + DeleteContext: DeleteBinLog, + Importer: &schema.ResourceImporter{ + StateContext: ImportDatabase, + }, + Schema: map[string]*schema.Schema{ + "retention_period": { + Type: schema.TypeString, + Optional: true, + Default: "NULL", + }, + }, + } +} + +func CreateBinLog(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + db, err := getDatabaseFromMeta(ctx, meta) + if err != nil { + return diag.FromErr(err) + } + + stmtSQL := binlogConfigSQL(d) + log.Println("Executing statement:", stmtSQL) + + _, err = db.ExecContext(ctx, stmtSQL) + if err != nil { + return diag.Errorf("failed running SQL to set binlog retention period: %v", err) + } + + d.SetId(d.Get("retention_period").(string)) + + return ReadBinLog(ctx, d, meta) +} + +func UpdateBinLog(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + db, err := getDatabaseFromMeta(ctx, meta) + if err != nil { + return diag.FromErr(err) + } + + stmtSQL := binlogConfigSQL(d) + log.Println("Executing statement:", stmtSQL) + + _, err = db.ExecContext(ctx, stmtSQL) + if err != nil { + return diag.Errorf("failed updating binlog retention period: %v", err) + } + + return ReadBinLog(ctx, d, meta) +} + +func ReadBinLog(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 binlog retention period: %s", err) + } + + results := make(map[string]string) + for rows.Next() { + var name, value, description string + + if err := rows.Scan(&name, &value, &description); err != nil { + return diag.Errorf("failed reading binlog retention period: %v", err) + } + results[name] = value + } + + d.Set("retention_period", results["binlog retention hours"]) + + return nil +} + +func DeleteBinLog(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_set_configuration('binlog retention hours', NULL)" + log.Println("Executing statement:", stmtSQL) + + _, err = db.ExecContext(ctx, stmtSQL) + if err != nil { + return diag.Errorf("failed unsetting binlog retention period: %v", err) + } + + d.SetId("") + return nil +} + +func binlogConfigSQL(d *schema.ResourceData) string { + retention_period := d.Get("retention_period").(string) + + return fmt.Sprintf( + "call mysql.rds_set_configuration('binlog retention hours', %s)", + retention_period, + ) +} From 1fb4571b63d77c5187353958be993eaa944f70c0 Mon Sep 17 00:00:00 2001 From: Dorst Date: Tue, 3 Jan 2023 13:22:55 -0300 Subject: [PATCH 2/5] chore: add release workflow --- .github/workflows/release.yml | 51 +++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..e83b1fb3 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,51 @@ +# This GitHub action can publish assets for release when a tag is created. +# Currently its setup to run on any tag that matches the pattern "v*" (ie. v0.1.0). +# +# This uses an action (hashicorp/ghaction-import-gpg) that assumes you set your +# private key in the `GPG_PRIVATE_KEY` secret and passphrase in the `PASSPHRASE` +# secret. If you would rather own your own GPG handling, please fork this action +# or use an alternative one for key handling. +# +# You will need to pass the `--batch` flag to `gpg` in your signing step +# in `goreleaser` to indicate this is being used in a non-interactive mode. +# +name: release +on: + push: + tags: + - 'v*' +permissions: + contents: write +jobs: + goreleaser: + runs-on: ubuntu-latest + steps: + - + name: Checkout + uses: actions/checkout@v3 + - + name: Unshallow + run: git fetch --prune --unshallow + - + name: Set up Go + uses: actions/setup-go@v3 + with: + go-version-file: 'go.mod' + cache: true + - + name: Import GPG key + uses: crazy-max/ghaction-import-gpg@v5 + id: import_gpg + with: + gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} + passphrase: ${{ secrets.PASSPHRASE }} + - + name: Run GoReleaser + uses: goreleaser/goreleaser-action@v4.1.0 + with: + version: latest + args: release --rm-dist + env: + GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }} + # GitHub sets this automatically + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 7f6d2b1e534331813f96ceb22233383eb4d59ae3 Mon Sep 17 00:00:00 2001 From: Dorst Date: Tue, 10 Jan 2023 12:42:51 -0300 Subject: [PATCH 3/5] fix: read binlog retention when null. Unique id --- mysql/resource_binlog.go | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/mysql/resource_binlog.go b/mysql/resource_binlog.go index 68dad59f..924b5c8d 100644 --- a/mysql/resource_binlog.go +++ b/mysql/resource_binlog.go @@ -2,8 +2,11 @@ package mysql import ( "context" + "database/sql" "fmt" "log" + "strconv" + "time" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" @@ -44,7 +47,9 @@ func CreateBinLog(ctx context.Context, d *schema.ResourceData, meta interface{}) return diag.Errorf("failed running SQL to set binlog retention period: %v", err) } - d.SetId(d.Get("retention_period").(string)) + id := strconv.FormatInt(time.Now().UTC().UnixNano(), 10) + + d.SetId(id) return ReadBinLog(ctx, d, meta) } @@ -86,15 +91,19 @@ func ReadBinLog(ctx context.Context, d *schema.ResourceData, meta interface{}) d return diag.Errorf("Error verifying binlog retention period: %s", err) } - results := make(map[string]string) + results := make(map[string]interface{}) for rows.Next() { - var name, value, description string + var name, description string + var value sql.NullString if err := rows.Scan(&name, &value, &description); err != nil { return diag.Errorf("failed reading binlog retention period: %v", err) } results[name] = value } + if results["binlog retention hours"] == "NULL" { + results["binlog retention hours"] = "0" + } d.Set("retention_period", results["binlog retention hours"]) @@ -121,9 +130,14 @@ func DeleteBinLog(ctx context.Context, d *schema.ResourceData, meta interface{}) func binlogConfigSQL(d *schema.ResourceData) string { retention_period := d.Get("retention_period").(string) - - return fmt.Sprintf( - "call mysql.rds_set_configuration('binlog retention hours', %s)", - retention_period, - ) + if retention_period == "0" { + return fmt.Sprintf( + "call mysql.rds_set_configuration('binlog retention hours', %s)", + "NULL") + } else { + return fmt.Sprintf( + "call mysql.rds_set_configuration('binlog retention hours', %s)", + retention_period, + ) + } } From 123f9324ce48ad7947a5743d6239023837b1bbd5 Mon Sep 17 00:00:00 2001 From: Dorst Date: Tue, 10 Jan 2023 13:33:57 -0300 Subject: [PATCH 4/5] fix: retention period set to number --- mysql/resource_binlog.go | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/mysql/resource_binlog.go b/mysql/resource_binlog.go index 924b5c8d..312a04f4 100644 --- a/mysql/resource_binlog.go +++ b/mysql/resource_binlog.go @@ -25,9 +25,10 @@ func resourceBinLog() *schema.Resource { }, Schema: map[string]*schema.Schema{ "retention_period": { - Type: schema.TypeString, - Optional: true, - Default: "NULL", + Type: schema.TypeInt, + Optional: true, + Default: 0, + Description: "Retention period in hours. 0 value disables binlog retention", }, }, } @@ -51,7 +52,7 @@ func CreateBinLog(ctx context.Context, d *schema.ResourceData, meta interface{}) d.SetId(id) - return ReadBinLog(ctx, d, meta) + return nil } func UpdateBinLog(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { @@ -68,7 +69,7 @@ func UpdateBinLog(ctx context.Context, d *schema.ResourceData, meta interface{}) return diag.Errorf("failed updating binlog retention period: %v", err) } - return ReadBinLog(ctx, d, meta) + return nil } func ReadBinLog(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { @@ -105,7 +106,7 @@ func ReadBinLog(ctx context.Context, d *schema.ResourceData, meta interface{}) d results["binlog retention hours"] = "0" } - d.Set("retention_period", results["binlog retention hours"]) + d.Set("retention_period", fmt.Sprintf("%d", results["binlog retention hours"])) return nil } @@ -129,14 +130,14 @@ func DeleteBinLog(ctx context.Context, d *schema.ResourceData, meta interface{}) } func binlogConfigSQL(d *schema.ResourceData) string { - retention_period := d.Get("retention_period").(string) - if retention_period == "0" { + retention_period := d.Get("retention_period") + if retention_period == 0 { return fmt.Sprintf( "call mysql.rds_set_configuration('binlog retention hours', %s)", "NULL") } else { return fmt.Sprintf( - "call mysql.rds_set_configuration('binlog retention hours', %s)", + "call mysql.rds_set_configuration('binlog retention hours', %d)", retention_period, ) } From f9d0980f9cf4be6c061fee82cd826b425d0a466b Mon Sep 17 00:00:00 2001 From: Dorst Date: Tue, 17 Jan 2023 16:44:23 -0300 Subject: [PATCH 5/5] chore: better styling --- mysql/resource_binlog.go | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/mysql/resource_binlog.go b/mysql/resource_binlog.go index 312a04f4..dd629358 100644 --- a/mysql/resource_binlog.go +++ b/mysql/resource_binlog.go @@ -130,15 +130,11 @@ func DeleteBinLog(ctx context.Context, d *schema.ResourceData, meta interface{}) } func binlogConfigSQL(d *schema.ResourceData) string { - retention_period := d.Get("retention_period") - if retention_period == 0 { - return fmt.Sprintf( - "call mysql.rds_set_configuration('binlog retention hours', %s)", - "NULL") - } else { - return fmt.Sprintf( - "call mysql.rds_set_configuration('binlog retention hours', %d)", - retention_period, - ) + retention_period := strconv.Itoa(d.Get("retention_period").(int)) + if retention_period == "0" { + retention_period = "NULL" } + return fmt.Sprintf( + "call mysql.rds_set_configuration('binlog retention hours', %s)", + retention_period) }