diff --git a/.changelog/6165.txt b/.changelog/6165.txt new file mode 100644 index 00000000000..b3d2e215ac3 --- /dev/null +++ b/.changelog/6165.txt @@ -0,0 +1,3 @@ +```release-note:breaking-change +sql: updated `google_sql_user.sql_server_user_details` to be read only. Any configuration attempting to set this field is invalid and will cause the provider to crash during plan time. +``` diff --git a/google/resource_cgc_snippet_generated_test.go b/google/resource_cgc_snippet_generated_test.go index c8dc9955755..b3be19cac70 100644 --- a/google/resource_cgc_snippet_generated_test.go +++ b/google/resource_cgc_snippet_generated_test.go @@ -396,6 +396,10 @@ func TestAccCGCSnippet_sqlDatabaseInstanceSqlserverExample(t *testing.T) { vcrTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, + ExternalProviders: map[string]resource.ExternalProvider{ + "random": {}, + "time": {}, + }, Steps: []resource.TestStep{ { Config: testAccCGCSnippet_sqlDatabaseInstanceSqlserverExample(context), diff --git a/google/resource_sql_user.go b/google/resource_sql_user.go index bad11970336..73b0379400b 100644 --- a/google/resource_sql_user.go +++ b/google/resource_sql_user.go @@ -85,19 +85,17 @@ func resourceSqlUser() *schema.Resource { }, "sql_server_user_details": { Type: schema.TypeList, - Optional: true, - MaxItems: 1, + Computed: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "disabled": { Type: schema.TypeBool, - Optional: true, - Default: false, + Computed: true, Description: `If the user has been disabled.`, }, "server_roles": { Type: schema.TypeList, - Optional: true, + Computed: true, Description: `The server roles for this user in the database.`, Elem: &schema.Schema{Type: schema.TypeString}, }, @@ -174,20 +172,14 @@ func resourceSqlUser() *schema.Resource { } } -func expandSqlServerUserDetails(cfg interface{}) (*sqladmin.SqlServerUserDetails, error) { - raw := cfg.([]interface{})[0].(map[string]interface{}) - - ssud := &sqladmin.SqlServerUserDetails{} - - if v, ok := raw["disabled"]; ok { - ssud.Disabled = v.(bool) - } - if v, ok := raw["server_roles"]; ok { - ssud.ServerRoles = expandStringArray(v) +func flattenSqlServerUserDetails(v *sqladmin.SqlServerUserDetails) []interface{} { + if v == nil { + return []interface{}{} } - - return ssud, nil - + transformed := make(map[string]interface{}) + transformed["disabled"] = v.Disabled + transformed["server_roles"] = v.ServerRoles + return []interface{}{transformed} } func expandPasswordPolicy(cfg interface{}) *sqladmin.UserPasswordValidationPolicy { @@ -240,14 +232,6 @@ func resourceSqlUserCreate(d *schema.ResourceData, meta interface{}) error { Type: typ, } - if v, ok := d.GetOk("sql_server_user_details"); ok { - ssud, err := expandSqlServerUserDetails(v) - if err != nil { - return err - } - user.SqlserverUserDetails = ssud - } - if v, ok := d.GetOk("password_policy"); ok { pp := expandPasswordPolicy(v) user.PasswordPolicy = pp @@ -351,15 +335,9 @@ func resourceSqlUserRead(d *schema.ResourceData, meta interface{}) error { if err := d.Set("project", project); err != nil { return fmt.Errorf("Error setting project: %s", err) } - if user.SqlserverUserDetails != nil { - if err := d.Set("disabled", user.SqlserverUserDetails.Disabled); err != nil { - return fmt.Errorf("Error setting disabled: %s", err) - } - if err := d.Set("server_roles", user.SqlserverUserDetails.ServerRoles); err != nil { - return fmt.Errorf("Error setting server_roles: %s", err) - } + if err := d.Set("sql_server_user_details", flattenSqlServerUserDetails(user.SqlserverUserDetails)); err != nil { + return fmt.Errorf("Error setting sql server user details: %s", err) } - if user.PasswordPolicy != nil { passwordPolicy := flattenPasswordPolicy(user.PasswordPolicy) if len(passwordPolicy.([]map[string]interface{})[0]) != 0 { @@ -368,6 +346,7 @@ func resourceSqlUserRead(d *schema.ResourceData, meta interface{}) error { } } } + d.SetId(fmt.Sprintf("%s/%s/%s", user.Name, user.Host, user.Instance)) return nil } @@ -435,15 +414,6 @@ func resourceSqlUserUpdate(d *schema.ResourceData, meta interface{}) error { Password: password, } - if v, ok := d.GetOk("sql_server_user_details"); ok { - ssud, err := expandSqlServerUserDetails(v) - if err != nil { - return err - } - user.SqlserverUserDetails = ssud - } - user.PasswordPolicy = expandPasswordPolicy(d.Get("password_policy")) - mutexKV.Lock(instanceMutexKey(project, instance)) defer mutexKV.Unlock(instanceMutexKey(project, instance)) var op *sqladmin.Operation diff --git a/google/resource_sql_user_test.go b/google/resource_sql_user_test.go index e55e6b87126..89b38652450 100644 --- a/google/resource_sql_user_test.go +++ b/google/resource_sql_user_test.go @@ -20,7 +20,7 @@ func TestAccSqlUser_mysql(t *testing.T) { CheckDestroy: testAccSqlUserDestroyProducer(t), Steps: []resource.TestStep{ { - Config: testGoogleSqlUser_mysql(instance, "password", false), + Config: testGoogleSqlUser_mysql(instance, "password"), Check: resource.ComposeTestCheckFunc( testAccCheckGoogleSqlUserExists(t, "google_sql_user.user1"), testAccCheckGoogleSqlUserExists(t, "google_sql_user.user2"), @@ -28,7 +28,7 @@ func TestAccSqlUser_mysql(t *testing.T) { }, { // Update password - Config: testGoogleSqlUser_mysql(instance, "new_password", false), + Config: testGoogleSqlUser_mysql(instance, "new_password"), Check: resource.ComposeTestCheckFunc( testAccCheckGoogleSqlUserExists(t, "google_sql_user.user1"), testAccCheckGoogleSqlUserExists(t, "google_sql_user.user2"), @@ -45,40 +45,6 @@ func TestAccSqlUser_mysql(t *testing.T) { }) } -func TestAccSqlUser_mysqlDisabled(t *testing.T) { - t.Parallel() - - instance := fmt.Sprintf("i-%d", randInt(t)) - vcrTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccSqlUserDestroyProducer(t), - Steps: []resource.TestStep{ - { - Config: testGoogleSqlUser_mysql(instance, "password", true), - }, - { - ResourceName: "google_sql_user.user1", - ImportStateId: fmt.Sprintf("%s/%s/gmail.com/admin", getTestProjectFromEnv(), instance), - ImportState: true, - ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"password"}, - }, - { - // Update password - Config: testGoogleSqlUser_mysql(instance, "password", false), - }, - { - ResourceName: "google_sql_user.user1", - ImportStateId: fmt.Sprintf("%s/%s/gmail.com/admin", getTestProjectFromEnv(), instance), - ImportState: true, - ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"password"}, - }, - }, - }) -} - func TestAccSqlUser_iamUser(t *testing.T) { // Multiple fine-grained resources skipIfVcr(t) @@ -291,7 +257,7 @@ func TestAccSqlUser_mysqlPasswordPolicy(t *testing.T) { CheckDestroy: testAccSqlUserDestroyProducer(t), Steps: []resource.TestStep{ { - Config: testGoogleSqlUser_mysqlPasswordPolicy(instance, "password", false), + Config: testGoogleSqlUser_mysqlPasswordPolicy(instance, "password"), Check: resource.ComposeTestCheckFunc( testAccCheckGoogleSqlUserExists(t, "google_sql_user.user1"), testAccCheckGoogleSqlUserExists(t, "google_sql_user.user2"), @@ -299,7 +265,7 @@ func TestAccSqlUser_mysqlPasswordPolicy(t *testing.T) { }, { // Update password - Config: testGoogleSqlUser_mysqlPasswordPolicy(instance, "new_password", false), + Config: testGoogleSqlUser_mysqlPasswordPolicy(instance, "new_password"), Check: resource.ComposeTestCheckFunc( testAccCheckGoogleSqlUserExists(t, "google_sql_user.user1"), testAccCheckGoogleSqlUserExists(t, "google_sql_user.user2"), @@ -316,7 +282,7 @@ func TestAccSqlUser_mysqlPasswordPolicy(t *testing.T) { }) } -func testGoogleSqlUser_mysql(instance, password string, disabled bool) string { +func testGoogleSqlUser_mysql(instance, password string) string { return fmt.Sprintf(` resource "google_sql_database_instance" "instance" { name = "%s" @@ -333,10 +299,6 @@ resource "google_sql_user" "user1" { instance = google_sql_database_instance.instance.name host = "google.com" password = "%s" - sql_server_user_details { - disabled = "%t" - server_roles = [ "admin" ] - } } resource "google_sql_user" "user2" { @@ -344,12 +306,11 @@ resource "google_sql_user" "user2" { instance = google_sql_database_instance.instance.name host = "gmail.com" password = "hunter2" - depends_on = [google_sql_user.user1] } -`, instance, password, disabled) +`, instance, password) } -func testGoogleSqlUser_mysqlPasswordPolicy(instance, password string, disabled bool) string { +func testGoogleSqlUser_mysqlPasswordPolicy(instance, password string) string { return fmt.Sprintf(` resource "google_sql_database_instance" "instance" { name = "%s" @@ -366,10 +327,7 @@ resource "google_sql_user" "user1" { instance = google_sql_database_instance.instance.name host = "google.com" password = "%s" - sql_server_user_details { - disabled = "%t" - server_roles = [ "admin" ] - } + password_policy { allowed_failed_attempts = 6 password_expiration_duration = "2592000s" @@ -388,7 +346,7 @@ resource "google_sql_user" "user2" { enable_failed_attempts_check = true } } -`, instance, password, disabled) +`, instance, password) } func testGoogleSqlUser_postgres(instance, password string) string {