Skip to content

Commit

Permalink
Merge pull request petoju#14 from borissavelev/mysql-global-variable
Browse files Browse the repository at this point in the history
New resource: mysql_global_variable
  • Loading branch information
petoju authored Jun 27, 2022
2 parents 62015ce + 04fdf87 commit 4e47831
Show file tree
Hide file tree
Showing 10 changed files with 296 additions and 16 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,14 @@ website/node_modules
*~
.*.swp
.idea
/.vscode
*.iml
*.test
*.iml

# goreleaser
/dist

website/vendor

# Test exclusions
Expand Down
23 changes: 17 additions & 6 deletions GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ GOFMT_FILES?=$$(find . -name '*.go' |grep -v vendor)
WEBSITE_REPO=github.com/hashicorp/terraform-website
PKG_NAME=mysql
TERRAFORM_VERSION=0.14.7
TERRAFORM_OS=$(shell uname -s | tr A-Z a-z)
TEST_USER=root
TEST_PASSWORD=my-secret-pw

Expand All @@ -17,21 +18,22 @@ test: fmtcheck
xargs -t -n4 go test $(TESTARGS) -timeout=60s -parallel=4

bin/terraform:
mkdir "$(CURDIR)/bin"
curl https://releases.hashicorp.com/terraform/$(TERRAFORM_VERSION)/terraform_$(TERRAFORM_VERSION)_linux_amd64.zip > $(CURDIR)/bin/terraform.zip
mkdir -p "$(CURDIR)/bin"
curl -sfL https://releases.hashicorp.com/terraform/$(TERRAFORM_VERSION)/terraform_$(TERRAFORM_VERSION)_$(TERRAFORM_OS)_amd64.zip > $(CURDIR)/bin/terraform.zip
(cd $(CURDIR)/bin/ ; unzip terraform.zip)

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
acceptance: testversion5.6 testversion5.7 testversion8.0 testpercona5.7 testpercona8.0 testtidb6.1.0

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

testversion:
-docker run --rm --name test-mysql$(MYSQL_VERSION) -e MYSQL_ROOT_PASSWORD="$(TEST_PASSWORD)" -d -p $(MYSQL_PORT):3306 mysql:$(MYSQL_VERSION)
@while ! mysql -h 127.0.0.1 -P $(MYSQL_PORT) -u "$(TEST_USER)" -p"$(TEST_PASSWORD)" -e 'SELECT 1'; do echo 'Waiting for MySQL...'; sleep 1; done
@echo 'Waiting for MySQL...'
@while ! mysql -h 127.0.0.1 -P $(MYSQL_PORT) -u "$(TEST_USER)" -p"$(TEST_PASSWORD)" -e 'SELECT 1' >/dev/null 2>&1; do printf '.'; sleep 1; done ; echo ; echo "Connected!"
-mysql -h 127.0.0.1 -P $(MYSQL_PORT) -u "$(TEST_USER)" -p"$(TEST_PASSWORD)" -e "INSTALL PLUGIN mysql_no_login SONAME 'mysql_no_login.so';"
MYSQL_USERNAME="$(TEST_USER)" MYSQL_PASSWORD="$(TEST_PASSWORD)" MYSQL_ENDPOINT=127.0.0.1:$(MYSQL_PORT) $(MAKE) testacc
docker rm -f test-mysql$(MYSQL_VERSION)
Expand All @@ -41,11 +43,21 @@ testpercona%:

testpercona:
-docker run --rm --name test-percona$(MYSQL_VERSION) -e MYSQL_ROOT_PASSWORD="$(TEST_PASSWORD)" -d -p $(MYSQL_PORT):3306 percona:$(MYSQL_VERSION)
@while ! mysql -h 127.0.0.1 -P $(MYSQL_PORT) -u "$(TEST_USER)" -p"$(TEST_PASSWORD)" -e 'SELECT 1'; do echo 'Waiting for Percona...'; sleep 1; done
@echo 'Waiting for Percona...'
@while ! mysql -h 127.0.0.1 -P $(MYSQL_PORT) -u "$(TEST_USER)" -p"$(TEST_PASSWORD)" -e 'SELECT 1' >/dev/null 2>&1; do printf '.'; sleep 1; done ; echo ; echo "Connected!"
-mysql -h 127.0.0.1 -P $(MYSQL_PORT) -u "$(TEST_USER)" -p"$(TEST_PASSWORD)" -e "INSTALL PLUGIN mysql_no_login SONAME 'mysql_no_login.so';"
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)

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

testtidb:
-docker run --rm --name test-tidb$(MYSQL_VERSION) -d -p $(MYSQL_PORT):4000 pingcap/tidb:v$(MYSQL_VERSION)
@echo 'Waiting for TiDB...'
@while ! mysql -h 127.0.0.1 -P $(MYSQL_PORT) -u "$(TEST_USER)" -e 'SELECT 1' >/dev/null 2>&1; do printf '.'; sleep 1; done ; echo ; echo "Connected!"
MYSQL_USERNAME="$(TEST_USER)" MYSQL_PASSWORD="" MYSQL_ENDPOINT=127.0.0.1:$(MYSQL_PORT) $(MAKE) testacc
docker rm -f test-tidb$(MYSQL_VERSION)

vet:
@echo "go vet ."
Expand Down Expand Up @@ -88,4 +100,3 @@ endif
@$(MAKE) -C $(GOPATH)/src/$(WEBSITE_REPO) website-provider PROVIDER_PATH=$(shell pwd) PROVIDER_NAME=$(PKG_NAME)

.PHONY: build test testacc vet fmt fmtcheck errcheck vendor-status test-compile website website-test

13 changes: 7 additions & 6 deletions mysql/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,12 +131,13 @@ func Provider() *schema.Provider {
},

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

ConfigureFunc: providerConfigure,
Expand Down
18 changes: 18 additions & 0 deletions mysql/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package mysql
import (
"context"
"os"
"strings"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
Expand Down Expand Up @@ -65,3 +66,20 @@ func testAccPreCheck(t *testing.T) {
t.Fatal(err)
}
}

func testAccPreCheckSkipTiDB(t *testing.T) {
testAccPreCheck(t)
db, err := connectToMySQL(testAccProvider.Meta().(*MySQLConfiguration))
if err != nil {
return
}

currentVersionString, err := serverVersionString(db)
if err != nil {
return
}

if strings.Contains(currentVersionString, "TiDB") {
t.Skip("Skip on TiDB")
}
}
4 changes: 2 additions & 2 deletions mysql/resource_database_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
func TestAccDatabase(t *testing.T) {
dbName := "terraform_acceptance_test"
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
PreCheck: func() { testAccPreCheckSkipTiDB(t) },
Providers: testAccProviders,
CheckDestroy: testAccDatabaseCheckDestroy(dbName),
Steps: []resource.TestStep{
Expand All @@ -39,7 +39,7 @@ func TestAccDatabase_collationChange(t *testing.T) {
resourceName := "mysql_database.test"

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
PreCheck: func() { testAccPreCheckSkipTiDB(t) },
Providers: testAccProviders,
CheckDestroy: testAccDatabaseCheckDestroy(dbName),
Steps: []resource.TestStep{
Expand Down
106 changes: 106 additions & 0 deletions mysql/resource_global_variable.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package mysql

import (
"database/sql"
"fmt"
"log"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func resourceGlobalVariable() *schema.Resource {
return &schema.Resource{
Create: CreateGlobalVariable,
Read: ReadGlobalVariable,
Update: UpdateGlobalVariable,
Delete: DeleteGlobalVariable,
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"value": {
Type: schema.TypeString,
Required: true,
},
},
}
}

func CreateGlobalVariable(d *schema.ResourceData, meta interface{}) error {
db := meta.(*MySQLConfiguration).Db

name := d.Get("name").(string)
value := d.Get("value").(string)

sql := fmt.Sprintf("SET GLOBAL %s = %s", quoteIdentifier(name), value)
log.Printf("[DEBUG] SQL: %s", sql)

_, err := db.Exec(sql)
if err != nil {
return fmt.Errorf("error setting value: %s", err)
}

d.SetId(name)

return nil
}

func ReadGlobalVariable(d *schema.ResourceData, meta interface{}) error {
db := meta.(*MySQLConfiguration).Db

stmt, err := db.Prepare("SHOW GLOBAL VARIABLES WHERE VARIABLE_NAME = ?")
if err != nil {
return fmt.Errorf("error during prepare statement for global variable: %s", err)
}

var name, value string
err = stmt.QueryRow(d.Id()).Scan(&name, &value)

if err != nil && err != sql.ErrNoRows {
d.SetId("")
return fmt.Errorf("error during show global variables: %s", err)
}

d.Set("name", name)
d.Set("value", value)

return nil
}

func UpdateGlobalVariable(d *schema.ResourceData, meta interface{}) error {
db := meta.(*MySQLConfiguration).Db

name := d.Get("name").(string)
value := d.Get("value").(string)

sql := fmt.Sprintf("SET GLOBAL %s = %s", quoteIdentifier(name), value)
log.Printf("[DEBUG] SQL: %s", sql)

_, err := db.Exec(sql)
if err != nil {
return fmt.Errorf("error update value: %s", err)
}
return ReadGlobalVariable(d, meta)
}

func DeleteGlobalVariable(d *schema.ResourceData, meta interface{}) error {
db := meta.(*MySQLConfiguration).Db
name := d.Get("name").(string)

sql := fmt.Sprintf("SET GLOBAL %s = DEFAULT", quoteIdentifier(name))
log.Printf("[DEBUG] SQL: %s", sql)

_, err := db.Exec(sql)
if err != nil {
log.Printf("[WARN] Variable_name (%s) not found; removing from state", d.Id())
d.SetId("")
return nil
}

return nil
}
93 changes: 93 additions & 0 deletions mysql/resource_global_variable_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package mysql

import (
"database/sql"
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
)

func TestAccGlobalVar_basic(t *testing.T) {
varName := "max_connections"
resourceName := "mysql_global_variable.test"

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccGlobalVarCheckDestroy(varName),
Steps: []resource.TestStep{
{
Config: testAccGlobalVarConfig_basic(varName),
Check: resource.ComposeTestCheckFunc(
testAccGlobalVarExists(varName),
resource.TestCheckResourceAttr(resourceName, "name", varName),
),
},
},
})
}

func testAccGlobalVarExists(varName string) resource.TestCheckFunc {
return func(s *terraform.State) error {
db, err := connectToMySQL(testAccProvider.Meta().(*MySQLConfiguration))
if err != nil {
return err
}

count, err := testAccGetGlobalVar(varName, db)

if err != nil {
return err
}

if count == 1 {
return nil
}

return fmt.Errorf("variable '%s' not found", varName)
}
}

func testAccGetGlobalVar(varName string, db *sql.DB) (int, error) {
stmt, err := db.Prepare("SHOW GLOBAL VARIABLES WHERE VARIABLE_NAME = ?")
if err != nil {
return 0, err
}

var name string
var value int
err = stmt.QueryRow(varName).Scan(&name, &value)

if err != nil && err != sql.ErrNoRows {
return 0, err
}

return value, nil
}

func testAccGlobalVarCheckDestroy(varName string) resource.TestCheckFunc {
return func(s *terraform.State) error {
db, err := connectToMySQL(testAccProvider.Meta().(*MySQLConfiguration))
if err != nil {
return err
}

count, err := testAccGetGlobalVar(varName, db)
if count == 1 {
return fmt.Errorf("Global variable '%s' still has non default value", varName)
}

return nil
}
}

func testAccGlobalVarConfig_basic(varName string) string {
return fmt.Sprintf(`
resource "mysql_global_variable" "test" {
name = "%s"
value = 1
}
`, varName)
}
2 changes: 1 addition & 1 deletion mysql/resource_grant_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ func TestAccDifferentHosts(t *testing.T) {
func TestAccGrantComplex(t *testing.T) {
dbName := fmt.Sprintf("tf-test-%d", rand.Intn(100))
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
PreCheck: func() { testAccPreCheckSkipTiDB(t) },
Providers: testAccProviders,
CheckDestroy: testAccGrantCheckDestroy,
Steps: []resource.TestStep{
Expand Down
2 changes: 1 addition & 1 deletion mysql/resource_user_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func TestAccUser_basic(t *testing.T) {

func TestAccUser_auth(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
PreCheck: func() { testAccPreCheckSkipTiDB(t) },
Providers: testAccProviders,
CheckDestroy: testAccUserCheckDestroy,
Steps: []resource.TestStep{
Expand Down
Loading

0 comments on commit 4e47831

Please sign in to comment.