Skip to content
This repository was archived by the owner on Jan 12, 2021. It is now read-only.

Fix feature detection between MySQL and MariaDB #110

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
21 changes: 0 additions & 21 deletions mysql/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"time"

"github.com/go-sql-driver/mysql"
"github.com/hashicorp/go-version"

"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
Expand Down Expand Up @@ -172,26 +171,6 @@ func quoteIdentifier(in string) string {
return fmt.Sprintf("`%s`", identQuoteReplacer.Replace(in))
}

func serverVersion(db *sql.DB) (*version.Version, error) {
var versionString string
err := db.QueryRow("SELECT @@GLOBAL.innodb_version").Scan(&versionString)
if err != nil {
return nil, err
}

return version.NewVersion(versionString)
}

func serverVersionString(db *sql.DB) (string, error) {
var versionString string
err := db.QueryRow("SELECT @@GLOBAL.version").Scan(&versionString)
if err != nil {
return "", err
}

return versionString, nil
}

func connectToMySQL(conf *MySQLConfiguration) (*sql.DB, error) {

dsn := conf.Config.FormatDSN()
Expand Down
10 changes: 1 addition & 9 deletions mysql/resource_database.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"strings"

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

Expand Down Expand Up @@ -119,20 +118,13 @@ func ReadDatabase(d *schema.ResourceData, meta interface{}) error {
stmtSQL := "SHOW COLLATION WHERE `Charset` = ? AND `Default` = 'Yes'"
var empty interface{}

requiredVersion, _ := version.NewVersion("8.0.0")
currentVersion, err := serverVersion(db)
if err != nil {
return err
}

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

// MySQL 8 returns more data in a row.
var res error
if !strings.Contains(serverVersionString, "MariaDB") && currentVersion.GreaterThan(requiredVersion) {
if currentVersion.extraColumnInShowCollation() {
res = db.QueryRow(stmtSQL, defaultCharset).Scan(&defaultCollation, &empty, &empty, &empty, &empty, &empty, &empty)
} else {
res = db.QueryRow(stmtSQL, defaultCharset).Scan(&defaultCollation, &empty, &empty, &empty, &empty, &empty)
Expand Down
22 changes: 6 additions & 16 deletions mysql/resource_grant.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
package mysql

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

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

Expand Down Expand Up @@ -127,27 +125,17 @@ func userOrRole(user string, host string, role string, hasRoles bool) (string, b
}
}

func supportsRoles(db *sql.DB) (bool, error) {
currentVersion, err := serverVersion(db)
if err != nil {
return false, err
}

requiredVersion, _ := version.NewVersion("8.0.0")
hasRoles := currentVersion.GreaterThan(requiredVersion)
return hasRoles, nil
}

func CreateGrant(d *schema.ResourceData, meta interface{}) error {
db, err := connectToMySQL(meta.(*MySQLConfiguration))
if err != nil {
return err
}

hasRoles, err := supportsRoles(db)
serverVersion, err := serverVersion(db)
if err != nil {
return err
}
hasRoles := serverVersion.supportsRoles()

var (
privilegesOrRoles string
Expand Down Expand Up @@ -223,10 +211,11 @@ func ReadGrant(d *schema.ResourceData, meta interface{}) error {
return err
}

hasRoles, err := supportsRoles(db)
serverVersion, err := serverVersion(db)
if err != nil {
return err
}
hasRoles := serverVersion.supportsRoles()

userOrRole, _, err := userOrRole(
d.Get("user").(string),
Expand Down Expand Up @@ -260,10 +249,11 @@ func DeleteGrant(d *schema.ResourceData, meta interface{}) error {

table := formatTableName(d.Get("table").(string))

hasRoles, err := supportsRoles(db)
serverVersion, err := serverVersion(db)
if err != nil {
return err
}
hasRoles := serverVersion.supportsRoles()

userOrRole, isRole, err := userOrRole(
d.Get("user").(string),
Expand Down
17 changes: 8 additions & 9 deletions mysql/resource_grant_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"time"

"github.com/go-sql-driver/mysql"
"github.com/hashicorp/go-version"
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/terraform"
)
Expand Down Expand Up @@ -58,14 +57,14 @@ func TestAccGrant_role(t *testing.T) {
return
}

requiredVersion, _ := version.NewVersion("8.0.0")
currentVersion, err := serverVersion(db)
serverVersion, err := serverVersion(db)
if err != nil {
return
}
hasRoles := serverVersion.supportsRoles()

if currentVersion.LessThan(requiredVersion) {
t.Skip("Roles require MySQL 8+")
if !hasRoles {
t.Skip("Roles are not supported by this version")
}
},
Providers: testAccProviders,
Expand Down Expand Up @@ -93,14 +92,14 @@ func TestAccGrant_roleToUser(t *testing.T) {
return
}

requiredVersion, _ := version.NewVersion("8.0.0")
currentVersion, err := serverVersion(db)
serverVersion, err := serverVersion(db)
if err != nil {
return
}
hasRoles := serverVersion.supportsRoles()

if currentVersion.LessThan(requiredVersion) {
t.Skip("Roles require MySQL 8+")
if !hasRoles {
t.Skip("Roles are not supported by this version")
}
},
Providers: testAccProviders,
Expand Down
9 changes: 4 additions & 5 deletions mysql/resource_role_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"fmt"
"testing"

"github.com/hashicorp/go-version"
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/terraform"
)
Expand All @@ -22,14 +21,14 @@ func TestAccRole_basic(t *testing.T) {
return
}

requiredVersion, _ := version.NewVersion("8.0.0")
currentVersion, err := serverVersion(db)
serverVersion, err := serverVersion(db)
if err != nil {
return
}
hasRoles := serverVersion.supportsRoles()

if currentVersion.LessThan(requiredVersion) {
t.Skip("Roles require MySQL 8+")
if !hasRoles {
t.Skip("Roles are not supported by this version")
}
},
Providers: testAccProviders,
Expand Down
15 changes: 5 additions & 10 deletions mysql/resource_user.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (

"errors"

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

Expand Down Expand Up @@ -105,13 +104,12 @@ func CreateUser(d *schema.ResourceData, meta interface{}) error {
stmtSQL = stmtSQL + fmt.Sprintf(" IDENTIFIED BY '%s'", password)
}

requiredVersion, _ := version.NewVersion("5.7.0")
currentVersion, err := serverVersion(db)
if err != nil {
return err
}

if currentVersion.GreaterThan(requiredVersion) && d.Get("tls_option").(string) != "" {
if currentVersion.supportsTlsOption() && d.Get("tls_option").(string) != "" {
stmtSQL += fmt.Sprintf(" REQUIRE %s", d.Get("tls_option").(string))
}

Expand Down Expand Up @@ -155,20 +153,18 @@ func UpdateUser(d *schema.ResourceData, meta interface{}) error {
if newpw != nil {
var stmtSQL string

/* ALTER USER syntax introduced in MySQL 5.7.6 deprecates SET PASSWORD (GH-8230) */
serverVersion, err := serverVersion(db)
if err != nil {
return fmt.Errorf("Could not determine server version: %s", err)
}

ver, _ := version.NewVersion("5.7.6")
if serverVersion.LessThan(ver) {
stmtSQL = fmt.Sprintf("SET PASSWORD FOR '%s'@'%s' = PASSWORD('%s')",
if serverVersion.deprecatedSetPassword() {
stmtSQL = fmt.Sprintf("ALTER USER '%s'@'%s' IDENTIFIED BY '%s'",
d.Get("user").(string),
d.Get("host").(string),
newpw.(string))
} else {
stmtSQL = fmt.Sprintf("ALTER USER '%s'@'%s' IDENTIFIED BY '%s'",
stmtSQL = fmt.Sprintf("SET PASSWORD FOR '%s'@'%s' = PASSWORD('%s')",
d.Get("user").(string),
d.Get("host").(string),
newpw.(string))
Expand All @@ -181,13 +177,12 @@ func UpdateUser(d *schema.ResourceData, meta interface{}) error {
}
}

requiredVersion, _ := version.NewVersion("5.7.0")
currentVersion, err := serverVersion(db)
if err != nil {
return err
}

if d.HasChange("tls_option") && currentVersion.GreaterThan(requiredVersion) {
if currentVersion.supportsTlsOption() && d.HasChange("tls_option") {
var stmtSQL string

stmtSQL = fmt.Sprintf("ALTER USER '%s'@'%s' REQUIRE %s",
Expand Down
4 changes: 1 addition & 3 deletions mysql/resource_user_password.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"fmt"

"github.com/gofrs/uuid"
"github.com/hashicorp/go-version"
"github.com/hashicorp/terraform-plugin-sdk/helper/encryption"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
Expand Down Expand Up @@ -67,14 +66,13 @@ func SetUserPassword(d *schema.ResourceData, meta interface{}) error {
d.Set("key_fingerprint", fingerprint)
d.Set("encrypted_password", encrypted)

requiredVersion, _ := version.NewVersion("8.0.0")
currentVersion, err := serverVersion(db)
if err != nil {
return err
}

passSQL := fmt.Sprintf("'%s'", password)
if currentVersion.LessThan(requiredVersion) {
if currentVersion.requiresExplicitPassword() {
passSQL = fmt.Sprintf("PASSWORD(%s)", passSQL)
}

Expand Down
17 changes: 16 additions & 1 deletion mysql/resource_user_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,22 @@ func TestAccUser_basic(t *testing.T) {

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

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

if serverVersion.vendor == MariaDB {
t.Skip("MariaDB does not support the mysql_no_login plugin")
}
},
Providers: testAccProviders,
CheckDestroy: testAccUserCheckDestroy,
Steps: []resource.TestStep{
Expand Down
Loading