github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/builtin/providers/mysql/provider.go (about) 1 package mysql 2 3 import ( 4 "fmt" 5 "strings" 6 7 "github.com/hashicorp/go-version" 8 mysqlc "github.com/ziutek/mymysql/mysql" 9 mysqlts "github.com/ziutek/mymysql/thrsafe" 10 11 "github.com/hashicorp/terraform/helper/schema" 12 "github.com/hashicorp/terraform/terraform" 13 ) 14 15 type providerConfiguration struct { 16 Conn mysqlc.Conn 17 ServerVersion *version.Version 18 } 19 20 func Provider() terraform.ResourceProvider { 21 return &schema.Provider{ 22 Schema: map[string]*schema.Schema{ 23 "endpoint": &schema.Schema{ 24 Type: schema.TypeString, 25 Required: true, 26 DefaultFunc: schema.EnvDefaultFunc("MYSQL_ENDPOINT", nil), 27 ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) { 28 value := v.(string) 29 if value == "" { 30 errors = append(errors, fmt.Errorf("Endpoint must not be an empty string")) 31 } 32 33 return 34 }, 35 }, 36 37 "username": &schema.Schema{ 38 Type: schema.TypeString, 39 Required: true, 40 DefaultFunc: schema.EnvDefaultFunc("MYSQL_USERNAME", nil), 41 ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) { 42 value := v.(string) 43 if value == "" { 44 errors = append(errors, fmt.Errorf("Username must not be an empty string")) 45 } 46 47 return 48 }, 49 }, 50 51 "password": &schema.Schema{ 52 Type: schema.TypeString, 53 Optional: true, 54 DefaultFunc: schema.EnvDefaultFunc("MYSQL_PASSWORD", nil), 55 }, 56 }, 57 58 ResourcesMap: map[string]*schema.Resource{ 59 "mysql_database": resourceDatabase(), 60 "mysql_user": resourceUser(), 61 "mysql_grant": resourceGrant(), 62 }, 63 64 ConfigureFunc: providerConfigure, 65 } 66 } 67 68 func providerConfigure(d *schema.ResourceData) (interface{}, error) { 69 70 var username = d.Get("username").(string) 71 var password = d.Get("password").(string) 72 var endpoint = d.Get("endpoint").(string) 73 74 proto := "tcp" 75 if len(endpoint) > 0 && endpoint[0] == '/' { 76 proto = "unix" 77 } 78 79 // mysqlts is the thread-safe implementation of mymysql, so we can 80 // safely re-use the same connection between multiple parallel 81 // operations. 82 conn := mysqlts.New(proto, "", endpoint, username, password) 83 84 err := conn.Connect() 85 if err != nil { 86 return nil, err 87 } 88 89 ver, err := serverVersion(conn) 90 if err != nil { 91 return nil, err 92 } 93 94 return &providerConfiguration{ 95 Conn: conn, 96 ServerVersion: ver, 97 }, nil 98 } 99 100 var identQuoteReplacer = strings.NewReplacer("`", "``") 101 102 func quoteIdentifier(in string) string { 103 return fmt.Sprintf("`%s`", identQuoteReplacer.Replace(in)) 104 } 105 106 func serverVersion(conn mysqlc.Conn) (*version.Version, error) { 107 rows, _, err := conn.Query("SELECT VERSION()") 108 if err != nil { 109 return nil, err 110 } 111 if len(rows) == 0 { 112 return nil, fmt.Errorf("SELECT VERSION() returned an empty set") 113 } 114 115 return version.NewVersion(rows[0].Str(0)) 116 }