From 860019048d51ab0d676dcaa158727f938e6d9c0c Mon Sep 17 00:00:00 2001 From: Evan Brown Date: Tue, 31 Jan 2017 22:21:11 -0800 Subject: [PATCH] providers/google: No default root user for SQL Cloud SQL Gen 2 instances come with a default 'root'@'%' user on creation. This change automatically deletes that user after creation. A Terraform user must use the google_sql_user to create a user with appropriate host and password. --- .../google/resource_sql_database_instance.go | 25 ++++++++- .../resource_sql_database_instance_test.go | 54 +++++++++++++++++++ .../r/sql_database_instance.html.markdown | 6 +++ 3 files changed, 84 insertions(+), 1 deletion(-) diff --git a/builtin/providers/google/resource_sql_database_instance.go b/builtin/providers/google/resource_sql_database_instance.go index f07dc68fe..8a7b25b4c 100644 --- a/builtin/providers/google/resource_sql_database_instance.go +++ b/builtin/providers/google/resource_sql_database_instance.go @@ -502,7 +502,30 @@ func resourceSqlDatabaseInstanceCreate(d *schema.ResourceData, meta interface{}) return err } - return resourceSqlDatabaseInstanceRead(d, meta) + err = resourceSqlDatabaseInstanceRead(d, meta) + if err != nil { + return err + } + + // If a root user exists with a wildcard ('%') hostname, delete it. + users, err := config.clientSqlAdmin.Users.List(project, instance.Name).Do() + if err != nil { + return fmt.Errorf("Error, attempting to list users associated with instance %s: %s", instance.Name, err) + } + for _, u := range users.Items { + if u.Name == "root" && u.Host == "%" { + op, err = config.clientSqlAdmin.Users.Delete(project, instance.Name, u.Host, u.Name).Do() + if err != nil { + return fmt.Errorf("Error, failed to delete default 'root'@'*' user, but the database was created successfully: %s", err) + } + err = sqladminOperationWait(config, op, "Delete default root User") + if err != nil { + return err + } + } + } + + return nil } func resourceSqlDatabaseInstanceRead(d *schema.ResourceData, meta interface{}) error { diff --git a/builtin/providers/google/resource_sql_database_instance_test.go b/builtin/providers/google/resource_sql_database_instance_test.go index 48073796c..e36cfcd28 100644 --- a/builtin/providers/google/resource_sql_database_instance_test.go +++ b/builtin/providers/google/resource_sql_database_instance_test.go @@ -64,6 +64,30 @@ func TestAccGoogleSqlDatabaseInstance_basic2(t *testing.T) { }) } +func TestAccGoogleSqlDatabaseInstance_basic3(t *testing.T) { + var instance sqladmin.DatabaseInstance + databaseID := acctest.RandInt() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccGoogleSqlDatabaseInstanceDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: fmt.Sprintf( + testGoogleSqlDatabaseInstance_basic3, databaseID), + Check: resource.ComposeTestCheckFunc( + testAccCheckGoogleSqlDatabaseInstanceExists( + "google_sql_database_instance.instance", &instance), + testAccCheckGoogleSqlDatabaseInstanceEquals( + "google_sql_database_instance.instance", &instance), + testAccCheckGoogleSqlDatabaseRootUserDoesNotExist( + &instance), + ), + }, + }, + }) +} func TestAccGoogleSqlDatabaseInstance_settings_basic(t *testing.T) { var instance sqladmin.DatabaseInstance databaseID := acctest.RandInt() @@ -406,6 +430,27 @@ func testAccGoogleSqlDatabaseInstanceDestroy(s *terraform.State) error { return nil } +func testAccCheckGoogleSqlDatabaseRootUserDoesNotExist( + instance *sqladmin.DatabaseInstance) resource.TestCheckFunc { + return func(s *terraform.State) error { + config := testAccProvider.Meta().(*Config) + + users, err := config.clientSqlAdmin.Users.List(config.Project, instance.Name).Do() + + if err != nil { + return fmt.Errorf("Could not list database users for %q: %s", instance.Name, err) + } + + for _, u := range users.Items { + if u.Name == "root" && u.Host == "%" { + return fmt.Errorf("%v@%v user still exists", u.Name, u.Host) + } + } + + return nil + } +} + var testGoogleSqlDatabaseInstance_basic = ` resource "google_sql_database_instance" "instance" { name = "tf-lw-%d" @@ -426,6 +471,15 @@ resource "google_sql_database_instance" "instance" { } } ` +var testGoogleSqlDatabaseInstance_basic3 = ` +resource "google_sql_database_instance" "instance" { + name = "tf-lw-%d" + region = "us-central" + settings { + tier = "db-f1-micro" + } +} +` var testGoogleSqlDatabaseInstance_settings = ` resource "google_sql_database_instance" "instance" { diff --git a/website/source/docs/providers/google/r/sql_database_instance.html.markdown b/website/source/docs/providers/google/r/sql_database_instance.html.markdown index 817ed6c70..1f1f73cd9 100644 --- a/website/source/docs/providers/google/r/sql_database_instance.html.markdown +++ b/website/source/docs/providers/google/r/sql_database_instance.html.markdown @@ -10,6 +10,12 @@ description: |- Creates a new Google SQL Database 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/instances). +~> **NOTE on `google_sql_database_instance`:** - Second-generation instances include a +default 'root'@'%' user with no password. This user will be deleted by Terraform on +instance creation. You should use a `google_sql_user` to define a customer user with +a restricted host and strong password. + + ## Example Usage Example creating a SQL Database.