diff --git a/docs/data-sources/user.md b/docs/data-sources/user.md index dc2cce2c..e08409e6 100644 --- a/docs/data-sources/user.md +++ b/docs/data-sources/user.md @@ -26,5 +26,6 @@ data "rancher2_user" "foo" { * `name` - (Computed) The user common name (string) * `annotations` - (Computed) Annotations of the resource (map) * `enabled` - (Computed) The user is enabled (bool) +* `must_change_password` - (Computed) The user must change password at first login (bool) * `principal_ids` - (Computed) The user principal IDs (list) * `labels` - (Computed) Labels of the resource (map) diff --git a/docs/resources/user.md b/docs/resources/user.md index ee1508b9..777f8cd5 100644 --- a/docs/resources/user.md +++ b/docs/resources/user.md @@ -17,6 +17,7 @@ resource "rancher2_user" "foo" { username = "foo" password = "changeme" enabled = true + must_change_password = true } # Create a new rancher2 global_role_binding for User resource "rancher2_global_role_binding" "foo" { @@ -33,6 +34,7 @@ The following arguments are supported: * `username` - (Required/ForceNew) The user username (string) * `password` - (Required/ForceNew) The user password (string) * `name` - (Optional) The user full name (string) +* `must_change_password` - (Optional)The user must change password at first login (bool) * `annotations` - (Optional/Computed) Annotations for global role binding (map) * `labels` - (Optional/Computed) Labels for global role binding (map) diff --git a/rancher2/data_source_rancher2_user.go b/rancher2/data_source_rancher2_user.go index 1ff0a3c8..fcc9ebd5 100644 --- a/rancher2/data_source_rancher2_user.go +++ b/rancher2/data_source_rancher2_user.go @@ -26,6 +26,10 @@ func dataSourceRancher2User() *schema.Resource { Type: schema.TypeBool, Computed: true, }, + "must_change_password": { + Type: schema.TypeBool, + Computed: true, + }, "is_external": { Type: schema.TypeBool, Optional: true, diff --git a/rancher2/resource_rancher2_user.go b/rancher2/resource_rancher2_user.go index 3cdacdcd..6cb5347b 100644 --- a/rancher2/resource_rancher2_user.go +++ b/rancher2/resource_rancher2_user.go @@ -108,10 +108,11 @@ func resourceRancher2UserUpdate(d *schema.ResourceData, meta interface{}) error } update := map[string]interface{}{ - "name": d.Get("name").(string), - "enabled": d.Get("enabled").(bool), - "annotations": toMapString(d.Get("annotations").(map[string]interface{})), - "labels": toMapString(d.Get("labels").(map[string]interface{})), + "name": d.Get("name").(string), + "enabled": d.Get("enabled").(bool), + "must_change_password": d.Get("must_change_password").(bool), + "annotations": toMapString(d.Get("annotations").(map[string]interface{})), + "labels": toMapString(d.Get("labels").(map[string]interface{})), } newUser, err := client.User.Update(user, update) diff --git a/rancher2/resource_rancher2_user_test.go b/rancher2/resource_rancher2_user_test.go index a223fb8f..09f5a2e7 100644 --- a/rancher2/resource_rancher2_user_test.go +++ b/rancher2/resource_rancher2_user_test.go @@ -15,8 +15,9 @@ const ( ) var ( - testAccRancher2User string - testAccRancher2UserUpdate string + testAccRancher2User string + testAccRancher2UserUpdate string + testAccRancher2UserUpdatePasswordReset string ) func init() { @@ -26,6 +27,7 @@ resource "` + testAccRancher2UserType + `" "foo" { username = "foo" password = "TestACC123456" enabled = true + must_change_password = true } ` testAccRancher2UserUpdate = ` @@ -34,8 +36,19 @@ resource "` + testAccRancher2UserType + `" "foo" { username = "foo" password = "TestACC1234567" enabled = false + must_change_password = true } ` + + testAccRancher2UserUpdatePasswordReset = ` + resource "` + testAccRancher2UserType + `" "foo" { + name = "Terraform user acceptance test - Updated" + username = "foo" + password = "TestACC1234567" + enabled = true + must_change_password = false + } + ` } func TestAccRancher2User_basic(t *testing.T) { @@ -52,6 +65,7 @@ func TestAccRancher2User_basic(t *testing.T) { resource.TestCheckResourceAttr(testAccRancher2UserType+".foo", "name", "Terraform user acceptance test"), resource.TestCheckResourceAttr(testAccRancher2UserType+".foo", "password", "TestACC123456"), resource.TestCheckResourceAttr(testAccRancher2UserType+".foo", "enabled", "true"), + resource.TestCheckResourceAttr(testAccRancher2UserType+".foo", "must_change_password", "true"), ), }, { @@ -61,6 +75,48 @@ func TestAccRancher2User_basic(t *testing.T) { resource.TestCheckResourceAttr(testAccRancher2UserType+".foo", "name", "Terraform user acceptance test - Updated"), resource.TestCheckResourceAttr(testAccRancher2UserType+".foo", "password", "TestACC1234567"), resource.TestCheckResourceAttr(testAccRancher2UserType+".foo", "enabled", "false"), + resource.TestCheckResourceAttr(testAccRancher2UserType+".foo", "must_change_password", "true"), + ), + }, + { + Config: testAccRancher2User, + Check: resource.ComposeTestCheckFunc( + testAccCheckRancher2UserExists(testAccRancher2UserType+".foo", user), + resource.TestCheckResourceAttr(testAccRancher2UserType+".foo", "name", "Terraform user acceptance test"), + resource.TestCheckResourceAttr(testAccRancher2UserType+".foo", "password", "TestACC123456"), + resource.TestCheckResourceAttr(testAccRancher2UserType+".foo", "enabled", "true"), + resource.TestCheckResourceAttr(testAccRancher2UserType+".foo", "must_change_password", "true"), + ), + }, + }, + }) +} + +func TestAccRancher2User_passwordReset(t *testing.T) { + var user *managementClient.User + + resource.Test(t, resource.TestCase{ + Providers: testAccProviders, + CheckDestroy: testAccCheckRancher2UserDestroy, + Steps: []resource.TestStep{ + { + Config: testAccRancher2User, + Check: resource.ComposeTestCheckFunc( + testAccCheckRancher2UserExists(testAccRancher2UserType+".foo", user), + resource.TestCheckResourceAttr(testAccRancher2UserType+".foo", "name", "Terraform user acceptance test"), + resource.TestCheckResourceAttr(testAccRancher2UserType+".foo", "password", "TestACC123456"), + resource.TestCheckResourceAttr(testAccRancher2UserType+".foo", "enabled", "true"), + resource.TestCheckResourceAttr(testAccRancher2UserType+".foo", "must_change_password", "true"), + ), + }, + { + Config: testAccRancher2UserUpdatePasswordReset, + Check: resource.ComposeTestCheckFunc( + testAccCheckRancher2UserExists(testAccRancher2UserType+".foo", user), + resource.TestCheckResourceAttr(testAccRancher2UserType+".foo", "name", "Terraform user acceptance test - Updated (password reset)"), + resource.TestCheckResourceAttr(testAccRancher2UserType+".foo", "password", "TestACC1234567"), + resource.TestCheckResourceAttr(testAccRancher2UserType+".foo", "enabled", "true"), + resource.TestCheckResourceAttr(testAccRancher2UserType+".foo", "must_change_password", "false"), ), }, { @@ -70,6 +126,7 @@ func TestAccRancher2User_basic(t *testing.T) { resource.TestCheckResourceAttr(testAccRancher2UserType+".foo", "name", "Terraform user acceptance test"), resource.TestCheckResourceAttr(testAccRancher2UserType+".foo", "password", "TestACC123456"), resource.TestCheckResourceAttr(testAccRancher2UserType+".foo", "enabled", "true"), + resource.TestCheckResourceAttr(testAccRancher2UserType+".foo", "must_change_password", "true"), ), }, }, diff --git a/rancher2/schema_user.go b/rancher2/schema_user.go index 2ed2d9d6..944b9ebf 100644 --- a/rancher2/schema_user.go +++ b/rancher2/schema_user.go @@ -23,6 +23,11 @@ func userFields() map[string]*schema.Schema { Optional: true, Default: true, }, + "must_change_password": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, "name": { Type: schema.TypeString, Optional: true, diff --git a/rancher2/structure_user.go b/rancher2/structure_user.go index 645c7fc8..7791521d 100644 --- a/rancher2/structure_user.go +++ b/rancher2/structure_user.go @@ -15,6 +15,7 @@ func flattenUser(d *schema.ResourceData, in *managementClient.User) error { d.SetId(in.ID) d.Set("username", in.Username) d.Set("enabled", in.Enabled) + d.Set("must_change_password", in.MustChangePassword) if len(in.Name) > 0 { d.Set("name", in.Name) @@ -55,6 +56,7 @@ func expandUser(in *schema.ResourceData) *managementClient.User { obj.Username = in.Get("username").(string) enabled := in.Get("enabled").(bool) obj.Enabled = &enabled + obj.MustChangePassword = in.Get("must_change_password").(bool) if v, ok := in.Get("name").(string); ok && len(v) > 0 { obj.Name = v diff --git a/rancher2/structure_user_test.go b/rancher2/structure_user_test.go index 11e71a2a..78e49fac 100644 --- a/rancher2/structure_user_test.go +++ b/rancher2/structure_user_test.go @@ -15,14 +15,16 @@ var ( func init() { testUserConf = &managementClient.User{ - Name: "name", - Username: "username", - Enabled: newTrue(), + Name: "name", + Username: "username", + Enabled: newTrue(), + MustChangePassword: *newTrue(), } testUserInterface = map[string]interface{}{ - "name": "name", - "username": "username", - "enabled": true, + "name": "name", + "username": "username", + "enabled": true, + "must_change_password": true, } }