-
Notifications
You must be signed in to change notification settings - Fork 9.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #4669 from lwander/f-gcp-sql-user
provider/google: SQL user resource, documentation & tests
- Loading branch information
Showing
5 changed files
with
377 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,183 @@ | ||
package google | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
|
||
"github.com/hashicorp/terraform/helper/schema" | ||
|
||
"google.golang.org/api/googleapi" | ||
"google.golang.org/api/sqladmin/v1beta4" | ||
) | ||
|
||
func resourceSqlUser() *schema.Resource { | ||
return &schema.Resource{ | ||
Create: resourceSqlUserCreate, | ||
Read: resourceSqlUserRead, | ||
Update: resourceSqlUserUpdate, | ||
Delete: resourceSqlUserDelete, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"name": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
}, | ||
|
||
"password": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Required: true, | ||
}, | ||
|
||
"host": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
}, | ||
|
||
"instance": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func resourceSqlUserCreate(d *schema.ResourceData, meta interface{}) error { | ||
config := meta.(*Config) | ||
|
||
name := d.Get("name").(string) | ||
instance := d.Get("instance").(string) | ||
password := d.Get("password").(string) | ||
host := d.Get("host").(string) | ||
project := config.Project | ||
|
||
user := &sqladmin.User{ | ||
Name: name, | ||
Instance: instance, | ||
Password: password, | ||
Host: host, | ||
} | ||
|
||
op, err := config.clientSqlAdmin.Users.Insert(project, instance, | ||
user).Do() | ||
|
||
if err != nil { | ||
return fmt.Errorf("Error, failed to insert "+ | ||
"user %s into instance %s: %s", name, instance, err) | ||
} | ||
|
||
err = sqladminOperationWait(config, op, "Insert User") | ||
|
||
if err != nil { | ||
return fmt.Errorf("Error, failure waiting for insertion of %s "+ | ||
"into %s: %s", name, instance, err) | ||
} | ||
|
||
return resourceSqlUserRead(d, meta) | ||
} | ||
|
||
func resourceSqlUserRead(d *schema.ResourceData, meta interface{}) error { | ||
config := meta.(*Config) | ||
|
||
name := d.Get("name").(string) | ||
instance := d.Get("instance").(string) | ||
project := config.Project | ||
|
||
users, err := config.clientSqlAdmin.Users.List(project, instance).Do() | ||
|
||
if err != nil { | ||
if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 { | ||
log.Printf("[WARN] Removing SQL User %q because it's gone", d.Get("name").(string)) | ||
d.SetId("") | ||
|
||
return nil | ||
} | ||
|
||
return fmt.Errorf("Error, failed to get user %s in instance %s: %s", name, instance, err) | ||
} | ||
|
||
found := false | ||
for _, user := range users.Items { | ||
if user.Name == name { | ||
found = true | ||
break | ||
} | ||
} | ||
|
||
if !found { | ||
log.Printf("[WARN] Removing SQL User %q because it's gone", d.Get("name").(string)) | ||
d.SetId("") | ||
|
||
return nil | ||
} | ||
|
||
d.SetId(name) | ||
|
||
return nil | ||
} | ||
|
||
func resourceSqlUserUpdate(d *schema.ResourceData, meta interface{}) error { | ||
config := meta.(*Config) | ||
|
||
if d.HasChange("password") { | ||
name := d.Get("name").(string) | ||
instance := d.Get("instance").(string) | ||
host := d.Get("host").(string) | ||
password := d.Get("password").(string) | ||
project := config.Project | ||
|
||
user := &sqladmin.User{ | ||
Name: name, | ||
Instance: instance, | ||
Password: password, | ||
Host: host, | ||
} | ||
|
||
op, err := config.clientSqlAdmin.Users.Update(project, instance, host, name, | ||
user).Do() | ||
|
||
if err != nil { | ||
return fmt.Errorf("Error, failed to update"+ | ||
"user %s into user %s: %s", name, instance, err) | ||
} | ||
|
||
err = sqladminOperationWait(config, op, "Insert User") | ||
|
||
if err != nil { | ||
return fmt.Errorf("Error, failure waiting for update of %s "+ | ||
"in %s: %s", name, instance, err) | ||
} | ||
|
||
return resourceSqlUserRead(d, meta) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func resourceSqlUserDelete(d *schema.ResourceData, meta interface{}) error { | ||
config := meta.(*Config) | ||
|
||
name := d.Get("name").(string) | ||
instance := d.Get("instance").(string) | ||
host := d.Get("host").(string) | ||
project := config.Project | ||
|
||
op, err := config.clientSqlAdmin.Users.Delete(project, instance, host, name).Do() | ||
|
||
if err != nil { | ||
return fmt.Errorf("Error, failed to delete"+ | ||
"user %s in instance %s: %s", name, | ||
instance, err) | ||
} | ||
|
||
err = sqladminOperationWait(config, op, "Delete User") | ||
|
||
if err != nil { | ||
return fmt.Errorf("Error, failure waiting for deletion of %s "+ | ||
"in %s: %s", name, instance, err) | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
package google | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/hashicorp/terraform/helper/acctest" | ||
"github.com/hashicorp/terraform/helper/resource" | ||
"github.com/hashicorp/terraform/terraform" | ||
) | ||
|
||
func TestAccGoogleSqlUser_basic(t *testing.T) { | ||
user := acctest.RandString(10) | ||
instance := acctest.RandString(10) | ||
|
||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
Providers: testAccProviders, | ||
CheckDestroy: testAccGoogleSqlUserDestroy, | ||
Steps: []resource.TestStep{ | ||
resource.TestStep{ | ||
Config: testGoogleSqlUser_basic(instance, user), | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckGoogleSqlUserExists("google_sql_user.user"), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func TestAccGoogleSqlUser_update(t *testing.T) { | ||
user := acctest.RandString(10) | ||
instance := acctest.RandString(10) | ||
|
||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
Providers: testAccProviders, | ||
CheckDestroy: testAccGoogleSqlUserDestroy, | ||
Steps: []resource.TestStep{ | ||
resource.TestStep{ | ||
Config: testGoogleSqlUser_basic(instance, user), | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckGoogleSqlUserExists("google_sql_user.user"), | ||
), | ||
}, | ||
|
||
resource.TestStep{ | ||
Config: testGoogleSqlUser_basic2(instance, user), | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckGoogleSqlUserExists("google_sql_user.user"), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func testAccCheckGoogleSqlUserExists(n string) resource.TestCheckFunc { | ||
return func(s *terraform.State) error { | ||
config := testAccProvider.Meta().(*Config) | ||
rs, ok := s.RootModule().Resources[n] | ||
if !ok { | ||
return fmt.Errorf("Resource not found: %s", n) | ||
} | ||
|
||
name := rs.Primary.Attributes["name"] | ||
instance := rs.Primary.Attributes["instance"] | ||
host := rs.Primary.Attributes["host"] | ||
users, err := config.clientSqlAdmin.Users.List(config.Project, | ||
instance).Do() | ||
|
||
for _, user := range users.Items { | ||
if user.Name == name && user.Host == host { | ||
return nil | ||
} | ||
} | ||
|
||
return fmt.Errorf("Not found: %s: %s", n, err) | ||
} | ||
} | ||
|
||
func testAccGoogleSqlUserDestroy(s *terraform.State) error { | ||
for _, rs := range s.RootModule().Resources { | ||
config := testAccProvider.Meta().(*Config) | ||
if rs.Type != "google_sql_database" { | ||
continue | ||
} | ||
|
||
name := rs.Primary.Attributes["name"] | ||
instance := rs.Primary.Attributes["instance"] | ||
host := rs.Primary.Attributes["host"] | ||
users, err := config.clientSqlAdmin.Users.List(config.Project, | ||
instance).Do() | ||
|
||
for _, user := range users.Items { | ||
if user.Name == name && user.Host == host { | ||
return fmt.Errorf("User still %s exists %s", name, err) | ||
} | ||
} | ||
|
||
return nil | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func testGoogleSqlUser_basic(instance, user string) string { | ||
return fmt.Sprintf(` | ||
resource "google_sql_database_instance" "instance" { | ||
name = "i%s" | ||
region = "us-central" | ||
settings { | ||
tier = "D0" | ||
} | ||
} | ||
resource "google_sql_user" "user" { | ||
name = "user%s" | ||
instance = "${google_sql_database_instance.instance.name}" | ||
host = "google.com" | ||
password = "hunter2" | ||
} | ||
`, instance, user) | ||
} | ||
|
||
func testGoogleSqlUser_basic2(instance, user string) string { | ||
return fmt.Sprintf(` | ||
resource "google_sql_database_instance" "instance" { | ||
name = "i%s" | ||
region = "us-central" | ||
settings { | ||
tier = "D0" | ||
} | ||
} | ||
resource "google_sql_user" "user" { | ||
name = "user%s" | ||
instance = "${google_sql_database_instance.instance.name}" | ||
host = "google.com" | ||
password = "oops" | ||
} | ||
`, instance, user) | ||
} |
47 changes: 47 additions & 0 deletions
47
website/source/docs/providers/google/r/sql_user.html.markdown
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
--- | ||
layout: "google" | ||
page_title: "Google: google_sql_user" | ||
sidebar_current: "docs-google-sql-user" | ||
description: |- | ||
Creates a new SQL user in Google Cloud SQL. | ||
--- | ||
|
||
# google\_sql\_user | ||
|
||
Creates a new Google SQL User on a Google SQL User Instance. For more information, see the [official documentation](https://cloud.google.com/sql/), or the [JSON API](https://cloud.google.com/sql/docs/admin-api/v1beta4/users). | ||
|
||
## Example Usage | ||
|
||
Example creating a SQL User. | ||
|
||
``` | ||
resource "google_sql_database_instance" "master" { | ||
name = "master-instance" | ||
settings { | ||
tier = "D0" | ||
} | ||
} | ||
resource "google_sql_user" "users" { | ||
name = "me" | ||
instance = "${google_sql_database_instance.master.name}" | ||
host = "me.com" | ||
} | ||
``` | ||
|
||
## Argument Reference | ||
|
||
The following arguments are supported: | ||
|
||
* `name` - (Required) The name of the user. | ||
Changing this forces a new resource to be created. | ||
|
||
* `host` - (Required) The host the user can connect from. Can be an IP address. | ||
Changing this forces a new resource to be created. | ||
|
||
* `password` - (Required) The users password. Can be updated. | ||
|
||
* `instance` - (Required) The name of the Cloud SQL instance. | ||
Changing this forces a new resource to be created. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters