mirror of
https://github.com/bpg/terraform-provider-proxmox.git
synced 2025-08-22 19:38:35 +00:00
fix(user): expiration_date
attribute handling (#1066)
Signed-off-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com>
This commit is contained in:
parent
953a23d2a7
commit
3c5276093a
@ -23,6 +23,9 @@ issues:
|
|||||||
- path: _types\.go
|
- path: _types\.go
|
||||||
linters:
|
linters:
|
||||||
- lll
|
- lll
|
||||||
|
- path: fwprovider/tests/.*\.go
|
||||||
|
linters:
|
||||||
|
- paralleltest
|
||||||
linters-settings:
|
linters-settings:
|
||||||
exhaustive:
|
exhaustive:
|
||||||
default-signifies-exhaustive: true
|
default-signifies-exhaustive: true
|
||||||
|
@ -5,14 +5,15 @@ resource "proxmox_virtual_environment_user" "example" {
|
|||||||
role_id = "PVEVMAdmin"
|
role_id = "PVEVMAdmin"
|
||||||
}
|
}
|
||||||
|
|
||||||
comment = "Managed by Terraform"
|
comment = "Managed by Terraform"
|
||||||
password = "Test1234!"
|
password = "Test1234!"
|
||||||
user_id = "terraform-provider-proxmox-example@pve"
|
user_id = "terraform-provider-proxmox-example@pve"
|
||||||
|
expiration_date = "2035-12-31T23:59:59Z"
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "proxmox_virtual_environment_user" "example2" {
|
resource "proxmox_virtual_environment_user" "example2" {
|
||||||
comment = "Managed by Terraform"
|
comment = "Managed by Terraform"
|
||||||
user_id = "terraform-provider-proxmox-example2@pve"
|
user_id = "terraform-provider-proxmox-example2@pve"
|
||||||
}
|
}
|
||||||
|
|
||||||
output "resource_proxmox_virtual_environment_user_example_acl" {
|
output "resource_proxmox_virtual_environment_user_example_acl" {
|
||||||
|
@ -21,7 +21,6 @@ const (
|
|||||||
accTestContainerCloneName = "proxmox_virtual_environment_container.test_container_clone"
|
accTestContainerCloneName = "proxmox_virtual_environment_container.test_container_clone"
|
||||||
)
|
)
|
||||||
|
|
||||||
//nolint:paralleltest
|
|
||||||
func TestAccResourceContainer(t *testing.T) {
|
func TestAccResourceContainer(t *testing.T) {
|
||||||
accProviders := testAccMuxProviders(context.Background(), t)
|
accProviders := testAccMuxProviders(context.Background(), t)
|
||||||
|
|
||||||
|
@ -23,7 +23,6 @@ const (
|
|||||||
fakeFileQCOW2 = "https://cdn.githubraw.com/rafsaf/036eece601975a3ad632a77fc2809046/raw/10500012fca9b4425b50de67a7258a12cba0c076/fake_file.qcow2"
|
fakeFileQCOW2 = "https://cdn.githubraw.com/rafsaf/036eece601975a3ad632a77fc2809046/raw/10500012fca9b4425b50de67a7258a12cba0c076/fake_file.qcow2"
|
||||||
)
|
)
|
||||||
|
|
||||||
//nolint:paralleltest
|
|
||||||
func TestAccResourceDownloadFile(t *testing.T) {
|
func TestAccResourceDownloadFile(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
|
@ -20,7 +20,6 @@ const (
|
|||||||
accTestLinuxBridgeName = "proxmox_virtual_environment_network_linux_bridge.test"
|
accTestLinuxBridgeName = "proxmox_virtual_environment_network_linux_bridge.test"
|
||||||
)
|
)
|
||||||
|
|
||||||
//nolint:paralleltest
|
|
||||||
func TestAccResourceLinuxBridge(t *testing.T) {
|
func TestAccResourceLinuxBridge(t *testing.T) {
|
||||||
accProviders := testAccMuxProviders(context.Background(), t)
|
accProviders := testAccMuxProviders(context.Background(), t)
|
||||||
|
|
||||||
|
@ -20,7 +20,6 @@ const (
|
|||||||
accTestLinuxVLANName = "proxmox_virtual_environment_network_linux_vlan.test"
|
accTestLinuxVLANName = "proxmox_virtual_environment_network_linux_vlan.test"
|
||||||
)
|
)
|
||||||
|
|
||||||
//nolint:paralleltest
|
|
||||||
func TestAccResourceLinuxVLAN(t *testing.T) {
|
func TestAccResourceLinuxVLAN(t *testing.T) {
|
||||||
accProviders := testAccMuxProviders(context.Background(), t)
|
accProviders := testAccMuxProviders(context.Background(), t)
|
||||||
|
|
||||||
|
76
fwprovider/tests/resource_user_test.go
Normal file
76
fwprovider/tests/resource_user_test.go
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package tests
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAccResourceUser(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
steps []resource.TestStep
|
||||||
|
}{
|
||||||
|
{"create and update user", []resource.TestStep{{
|
||||||
|
Config: `
|
||||||
|
resource "proxmox_virtual_environment_user" "user1" {
|
||||||
|
comment = "Managed by Terraform"
|
||||||
|
email = "user1@pve"
|
||||||
|
enabled = true
|
||||||
|
expiration_date = "2034-01-01T22:00:00Z"
|
||||||
|
first_name = "First"
|
||||||
|
last_name = "Last"
|
||||||
|
//password = "password"
|
||||||
|
user_id = "user1@pve"
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testResourceAttributes("proxmox_virtual_environment_user.user1", map[string]string{
|
||||||
|
"comment": "Managed by Terraform",
|
||||||
|
"email": "user1@pve",
|
||||||
|
"enabled": "true",
|
||||||
|
"expiration_date": "2034-01-01T22:00:00Z",
|
||||||
|
"first_name": "First",
|
||||||
|
"last_name": "Last",
|
||||||
|
"user_id": "user1@pve",
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
}, {
|
||||||
|
Config: `
|
||||||
|
resource "proxmox_virtual_environment_user" "user1" {
|
||||||
|
enabled = false
|
||||||
|
expiration_date = "2035-01-01T22:00:00Z"
|
||||||
|
user_id = "user1@pve"
|
||||||
|
first_name = "First One"
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testResourceAttributes("proxmox_virtual_environment_user.user1", map[string]string{
|
||||||
|
"enabled": "false",
|
||||||
|
"expiration_date": "2035-01-01T22:00:00Z",
|
||||||
|
"first_name": "First One",
|
||||||
|
"user_id": "user1@pve",
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
}}},
|
||||||
|
}
|
||||||
|
|
||||||
|
accProviders := testAccMuxProviders(context.Background(), t)
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
tt := tt
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
ProtoV6ProviderFactories: accProviders,
|
||||||
|
Steps: tt.steps,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -77,7 +77,6 @@ func TestAccResourceVM(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:paralleltest
|
|
||||||
func TestAccResourceVMNetwork(t *testing.T) {
|
func TestAccResourceVMNetwork(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
|
@ -12,10 +12,8 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"sort"
|
"sort"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox/api"
|
"github.com/bpg/terraform-provider-proxmox/proxmox/api"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox/types"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *Client) usersPath() string {
|
func (c *Client) usersPath() string {
|
||||||
@ -74,11 +72,6 @@ func (c *Client) GetUser(ctx context.Context, id string) (*UserGetResponseData,
|
|||||||
return nil, api.ErrNoDataObjectInResponse
|
return nil, api.ErrNoDataObjectInResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
if resBody.Data.ExpirationDate != nil {
|
|
||||||
expirationDate := types.CustomTimestamp(time.Time(*resBody.Data.ExpirationDate).UTC())
|
|
||||||
resBody.Data.ExpirationDate = &expirationDate
|
|
||||||
}
|
|
||||||
|
|
||||||
if resBody.Data.Groups != nil {
|
if resBody.Data.Groups != nil {
|
||||||
sort.Strings(*resBody.Data.Groups)
|
sort.Strings(*resBody.Data.Groups)
|
||||||
}
|
}
|
||||||
@ -104,11 +97,6 @@ func (c *Client) ListUsers(ctx context.Context) ([]*UserListResponseData, error)
|
|||||||
})
|
})
|
||||||
|
|
||||||
for i := range resBody.Data {
|
for i := range resBody.Data {
|
||||||
if resBody.Data[i].ExpirationDate != nil {
|
|
||||||
expirationDate := types.CustomTimestamp(time.Time(*resBody.Data[i].ExpirationDate).UTC())
|
|
||||||
resBody.Data[i].ExpirationDate = &expirationDate
|
|
||||||
}
|
|
||||||
|
|
||||||
if resBody.Data[i].Groups != nil {
|
if resBody.Data[i].Groups != nil {
|
||||||
sort.Strings(*resBody.Data[i].Groups)
|
sort.Strings(*resBody.Data[i].Groups)
|
||||||
}
|
}
|
||||||
|
@ -18,16 +18,16 @@ type UserChangePasswordRequestBody struct {
|
|||||||
|
|
||||||
// UserCreateRequestBody contains the data for a user create request.
|
// UserCreateRequestBody contains the data for a user create request.
|
||||||
type UserCreateRequestBody struct {
|
type UserCreateRequestBody struct {
|
||||||
Comment *string `json:"comment,omitempty" url:"comment,omitempty"`
|
Comment *string `json:"comment,omitempty" url:"comment,omitempty"`
|
||||||
Email *string `json:"email,omitempty" url:"email,omitempty"`
|
Email *string `json:"email,omitempty" url:"email,omitempty"`
|
||||||
Enabled *types.CustomBool `json:"enable,omitempty" url:"enable,omitempty,int"`
|
Enabled *types.CustomBool `json:"enable,omitempty" url:"enable,omitempty,int"`
|
||||||
ExpirationDate *types.CustomTimestamp `json:"expire,omitempty" url:"expire,omitempty,unix"`
|
ExpirationDate *int64 `json:"expire,omitempty" url:"expire,omitempty"`
|
||||||
FirstName *string `json:"firstname,omitempty" url:"firstname,omitempty"`
|
FirstName *string `json:"firstname,omitempty" url:"firstname,omitempty"`
|
||||||
Groups []string `json:"groups,omitempty" url:"groups,omitempty,comma"`
|
Groups []string `json:"groups,omitempty" url:"groups,omitempty,comma"`
|
||||||
ID string `json:"userid" url:"userid"`
|
ID string `json:"userid" url:"userid"`
|
||||||
Keys *string `json:"keys,omitempty" url:"keys,omitempty"`
|
Keys *string `json:"keys,omitempty" url:"keys,omitempty"`
|
||||||
LastName *string `json:"lastname,omitempty" url:"lastname,omitempty"`
|
LastName *string `json:"lastname,omitempty" url:"lastname,omitempty"`
|
||||||
Password string `json:"password" url:"password,omitempty"`
|
Password string `json:"password" url:"password,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// UserGetResponseBody contains the body from a user get response.
|
// UserGetResponseBody contains the body from a user get response.
|
||||||
@ -37,14 +37,14 @@ type UserGetResponseBody struct {
|
|||||||
|
|
||||||
// UserGetResponseData contains the data from an user get response.
|
// UserGetResponseData contains the data from an user get response.
|
||||||
type UserGetResponseData struct {
|
type UserGetResponseData struct {
|
||||||
Comment *string `json:"comment,omitempty"`
|
Comment *string `json:"comment,omitempty"`
|
||||||
Email *string `json:"email,omitempty"`
|
Email *string `json:"email,omitempty"`
|
||||||
Enabled *types.CustomBool `json:"enable,omitempty"`
|
Enabled *types.CustomBool `json:"enable,omitempty"`
|
||||||
ExpirationDate *types.CustomTimestamp `json:"expire,omitempty"`
|
ExpirationDate *int64 `json:"expire,omitempty"`
|
||||||
FirstName *string `json:"firstname,omitempty"`
|
FirstName *string `json:"firstname,omitempty"`
|
||||||
Groups *[]string `json:"groups,omitempty"`
|
Groups *[]string `json:"groups,omitempty"`
|
||||||
Keys *string `json:"keys,omitempty"`
|
Keys *string `json:"keys,omitempty"`
|
||||||
LastName *string `json:"lastname,omitempty"`
|
LastName *string `json:"lastname,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// UserListResponseBody contains the body from a user list response.
|
// UserListResponseBody contains the body from a user list response.
|
||||||
@ -54,26 +54,26 @@ type UserListResponseBody struct {
|
|||||||
|
|
||||||
// UserListResponseData contains the data from an user list response.
|
// UserListResponseData contains the data from an user list response.
|
||||||
type UserListResponseData struct {
|
type UserListResponseData struct {
|
||||||
Comment *string `json:"comment,omitempty"`
|
Comment *string `json:"comment,omitempty"`
|
||||||
Email *string `json:"email,omitempty"`
|
Email *string `json:"email,omitempty"`
|
||||||
Enabled *types.CustomBool `json:"enable,omitempty"`
|
Enabled *types.CustomBool `json:"enable,omitempty"`
|
||||||
ExpirationDate *types.CustomTimestamp `json:"expire,omitempty"`
|
ExpirationDate *int64 `json:"expire,omitempty"`
|
||||||
FirstName *string `json:"firstname,omitempty"`
|
FirstName *string `json:"firstname,omitempty"`
|
||||||
Groups *[]string `json:"groups,omitempty"`
|
Groups *[]string `json:"groups,omitempty"`
|
||||||
ID string `json:"userid"`
|
ID string `json:"userid"`
|
||||||
Keys *string `json:"keys,omitempty"`
|
Keys *string `json:"keys,omitempty"`
|
||||||
LastName *string `json:"lastname,omitempty"`
|
LastName *string `json:"lastname,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// UserUpdateRequestBody contains the data for an user update request.
|
// UserUpdateRequestBody contains the data for an user update request.
|
||||||
type UserUpdateRequestBody struct {
|
type UserUpdateRequestBody struct {
|
||||||
Append *types.CustomBool `json:"append,omitempty" url:"append,omitempty"`
|
Append *types.CustomBool `json:"append,omitempty" url:"append,omitempty"`
|
||||||
Comment *string `json:"comment,omitempty" url:"comment,omitempty"`
|
Comment *string `json:"comment,omitempty" url:"comment,omitempty"`
|
||||||
Email *string `json:"email,omitempty" url:"email,omitempty"`
|
Email *string `json:"email,omitempty" url:"email,omitempty"`
|
||||||
Enabled *types.CustomBool `json:"enable,omitempty" url:"enable,omitempty,int"`
|
Enabled *types.CustomBool `json:"enable,omitempty" url:"enable,omitempty,int"`
|
||||||
ExpirationDate *types.CustomTimestamp `json:"expire,omitempty" url:"expire,omitempty,unix"`
|
ExpirationDate *int64 `json:"expire,omitempty" url:"expire,omitempty,int"`
|
||||||
FirstName *string `json:"firstname,omitempty" url:"firstname,omitempty"`
|
FirstName *string `json:"firstname,omitempty" url:"firstname,omitempty"`
|
||||||
Groups []string `json:"groups,omitempty" url:"groups,omitempty,comma"`
|
Groups []string `json:"groups,omitempty" url:"groups,omitempty,comma"`
|
||||||
Keys *string `json:"keys,omitempty" url:"keys,omitempty"`
|
Keys *string `json:"keys,omitempty" url:"keys,omitempty"`
|
||||||
LastName *string `json:"lastname,omitempty" url:"lastname,omitempty"`
|
LastName *string `json:"lastname,omitempty" url:"lastname,omitempty"`
|
||||||
}
|
}
|
||||||
|
@ -178,7 +178,7 @@ func userRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.D
|
|||||||
diags = append(diags, diag.FromErr(err)...)
|
diags = append(diags, diag.FromErr(err)...)
|
||||||
|
|
||||||
if v.ExpirationDate != nil {
|
if v.ExpirationDate != nil {
|
||||||
t := time.Time(*v.ExpirationDate)
|
t := time.Unix(*v.ExpirationDate, 0)
|
||||||
if t.Unix() > 0 {
|
if t.Unix() > 0 {
|
||||||
err = d.Set(
|
err = d.Set(
|
||||||
mkDataSourceVirtualEnvironmentUserExpirationDate,
|
mkDataSourceVirtualEnvironmentUserExpirationDate,
|
||||||
|
@ -138,7 +138,7 @@ func usersRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.
|
|||||||
}
|
}
|
||||||
|
|
||||||
if v.ExpirationDate != nil {
|
if v.ExpirationDate != nil {
|
||||||
t := time.Time(*v.ExpirationDate)
|
t := time.Unix(*v.ExpirationDate, 0)
|
||||||
|
|
||||||
if t.Unix() > 0 {
|
if t.Unix() > 0 {
|
||||||
expirationDates[i] = t.UTC().Format(time.RFC3339)
|
expirationDates[i] = t.UTC().Format(time.RFC3339)
|
||||||
|
@ -132,6 +132,7 @@ func User() *schema.Resource {
|
|||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Description: "The user's password",
|
Description: "The user's password",
|
||||||
Optional: true,
|
Optional: true,
|
||||||
|
Sensitive: true,
|
||||||
},
|
},
|
||||||
mkResourceVirtualEnvironmentUserUserID: {
|
mkResourceVirtualEnvironmentUserUserID: {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
@ -168,7 +169,7 @@ func userCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag
|
|||||||
return diag.FromErr(err)
|
return diag.FromErr(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
expirationDateCustom := types.CustomTimestamp(expirationDate)
|
expirationDateCustom := expirationDate.Unix()
|
||||||
firstName := d.Get(mkResourceVirtualEnvironmentUserFirstName).(string)
|
firstName := d.Get(mkResourceVirtualEnvironmentUserFirstName).(string)
|
||||||
groups := d.Get(mkResourceVirtualEnvironmentUserGroups).(*schema.Set).List()
|
groups := d.Get(mkResourceVirtualEnvironmentUserGroups).(*schema.Set).List()
|
||||||
groupsCustom := make([]string, len(groups))
|
groupsCustom := make([]string, len(groups))
|
||||||
@ -303,7 +304,7 @@ func userRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.D
|
|||||||
if user.ExpirationDate != nil {
|
if user.ExpirationDate != nil {
|
||||||
err = d.Set(
|
err = d.Set(
|
||||||
mkResourceVirtualEnvironmentUserExpirationDate,
|
mkResourceVirtualEnvironmentUserExpirationDate,
|
||||||
time.Time(*user.ExpirationDate).Format(time.RFC3339),
|
time.Unix(*user.ExpirationDate, 0).UTC().Format(time.RFC3339),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
err = d.Set(mkResourceVirtualEnvironmentUserExpirationDate, time.Unix(0, 0).UTC().Format(time.RFC3339))
|
err = d.Set(mkResourceVirtualEnvironmentUserExpirationDate, time.Unix(0, 0).UTC().Format(time.RFC3339))
|
||||||
@ -363,7 +364,7 @@ func userUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag
|
|||||||
return diag.FromErr(err)
|
return diag.FromErr(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
expirationDateCustom := types.CustomTimestamp(expirationDate)
|
expirationDateCustom := expirationDate.Unix()
|
||||||
firstName := d.Get(mkResourceVirtualEnvironmentUserFirstName).(string)
|
firstName := d.Get(mkResourceVirtualEnvironmentUserFirstName).(string)
|
||||||
groups := d.Get(mkResourceVirtualEnvironmentUserGroups).(*schema.Set).List()
|
groups := d.Get(mkResourceVirtualEnvironmentUserGroups).(*schema.Set).List()
|
||||||
groupsCustom := make([]string, len(groups))
|
groupsCustom := make([]string, len(groups))
|
||||||
|
Loading…
Reference in New Issue
Block a user