diff --git a/docs/data-sources/local_user.md b/docs/data-sources/local_user.md
index ec7b9a1..bfdc072 100644
--- a/docs/data-sources/local_user.md
+++ b/docs/data-sources/local_user.md
@@ -35,7 +35,7 @@ data "windows_local_user" "admin" {
- `enabled` (Boolean) Get the status of the local user.
- `full_name` (String) The full name of the local user.
- `id` (String) The ID of the retrieved local user. This is the same as the SID.
-- `last_login` (String) The last login time of the local user.
+- `last_logon` (String) The last logon time of the local user.
- `password_changeable_date` (String) The password changeable date of the local user.
- `password_expires` (String) The time when the password of the local user expires.
- `password_last_set` (String) The last time when the password was set for the local user.
diff --git a/docs/data-sources/local_users.md b/docs/data-sources/local_users.md
new file mode 100644
index 0000000..412d2e3
--- /dev/null
+++ b/docs/data-sources/local_users.md
@@ -0,0 +1,42 @@
+---
+page_title: "windows_local_users Data Source - terraform-provider-windows"
+subcategory: "Local"
+description: |-
+ Retrieve a list of all local users
+---
+# windows_local_users (Data Source)
+
+
+Retrieve a list of all local users.
+
+
+## Schema
+
+### Read-Only
+
+- `users` (Attributes List) (see [below for nested schema](#nestedatt--users))
+
+
+### Nested Schema for `users`
+
+Required:
+
+- `name` (String) Define the name of the local user.
+
+Optional:
+
+- `sid` (String) The security ID of the local user.
+
+Read-Only:
+
+- `account_expires` (String) Retrieve the time where the local user account expires.
+- `description` (String) The description of the local user.
+- `enabled` (Boolean) Get the status of the local user.
+- `full_name` (String) The full name of the local user.
+- `id` (String) The ID of the retrieved local user. This is the same as the SID.
+- `last_logon` (String) The last logon time of the local user.
+- `password_changeable_date` (String) The password changeable date of the local user.
+- `password_expires` (String) The time when the password of the local user expires.
+- `password_last_set` (String) The last time when the password was set for the local user.
+- `password_required` (Boolean) If true a password is required login with the local user.
+- `user_may_change_password` (Boolean) If true the local user can change it's password.
diff --git a/docs/resources/local_user.md b/docs/resources/local_user.md
index ab23dac..93e94bf 100644
--- a/docs/resources/local_user.md
+++ b/docs/resources/local_user.md
@@ -26,7 +26,7 @@ resource "windows_local_user" "this" {
### Optional
-- `account_expires` (String) Define when the local user account expires (UTC). If not specified, the user account never expires.
The string time format is the following: `yyyy-MM-dd hh:mm:ss` (see [go time package](https://pkg.go.dev/time#pkg-constants) `DateTime`).
+- `account_expires` (String) Define when the local user account expires. If not specified, the user account never expires.
The string time format is the following: `2023-07-25T20:43:16Z` (see [Terraform timetypes](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework-timetypes@v0.3.0/timetypes#RFC3339)).
- `description` (String) Define a description for the local user. The maximum length is 48 characters.
- `enabled` (Boolean) (Default: `true`)
Define whether the local user is enabled.
- `full_name` (String) Define the full name of the local user. The full name differs from the user name of the user account.
@@ -37,7 +37,7 @@ resource "windows_local_user" "this" {
### Read-Only
- `id` (String) The ID of the retrieved local security group. This is the same as the SID.
-- `last_login` (String) The last login time of the local user.
+- `last_logon` (String) The last logon time of the local user.
- `password_changeable_date` (String) The password changeable date of the local user.
- `password_expires` (String) The time when the password of the local user expires.
- `password_last_set` (String) The last time when the password was set for the local user.
diff --git a/go.mod b/go.mod
index 6e201e1..643e152 100644
--- a/go.mod
+++ b/go.mod
@@ -8,6 +8,7 @@ require (
github.com/d-strobel/gowindows v0.0.0-20240105224217-566c4d2dcc50
github.com/hashicorp/terraform-plugin-docs v0.17.0
github.com/hashicorp/terraform-plugin-framework v1.5.0
+ github.com/hashicorp/terraform-plugin-framework-timetypes v0.3.0
github.com/hashicorp/terraform-plugin-framework-validators v0.12.0
github.com/hashicorp/terraform-plugin-go v0.20.0
)
diff --git a/go.sum b/go.sum
index 667e900..d3762bd 100644
--- a/go.sum
+++ b/go.sum
@@ -106,6 +106,8 @@ github.com/hashicorp/terraform-plugin-docs v0.17.0 h1:H1Yc+bgB//Geau5g7YKkhG5v9t
github.com/hashicorp/terraform-plugin-docs v0.17.0/go.mod h1:cKC8GSLE+0a0bi7LtlpXgrqnlRDCGoGDn15PTEA+Ang=
github.com/hashicorp/terraform-plugin-framework v1.5.0 h1:8kcvqJs/x6QyOFSdeAyEgsenVOUeC/IyKpi2ul4fjTg=
github.com/hashicorp/terraform-plugin-framework v1.5.0/go.mod h1:6waavirukIlFpVpthbGd2PUNYaFedB0RwW3MDzJ/rtc=
+github.com/hashicorp/terraform-plugin-framework-timetypes v0.3.0 h1:egR4InfakWkgepZNUATWGwkrPhaAYOTEybPfEol+G/I=
+github.com/hashicorp/terraform-plugin-framework-timetypes v0.3.0/go.mod h1:9vjvl36aY1p6KltaA5QCvGC5hdE/9t4YuhGftw6WOgE=
github.com/hashicorp/terraform-plugin-framework-validators v0.12.0 h1:HOjBuMbOEzl7snOdOoUfE2Jgeto6JOjLVQ39Ls2nksc=
github.com/hashicorp/terraform-plugin-framework-validators v0.12.0/go.mod h1:jfHGE/gzjxYz6XoUwi/aYiiKrJDeutQNUtGQXkaHklg=
github.com/hashicorp/terraform-plugin-go v0.20.0 h1:oqvoUlL+2EUbKNsJbIt3zqqZ7wi6lzn4ufkn/UA51xQ=
diff --git a/internal/generate/datasource_local_user/local_user_data_source_gen.go b/internal/generate/datasource_local_user/local_user_data_source_gen.go
index c388175..a8d9028 100644
--- a/internal/generate/datasource_local_user/local_user_data_source_gen.go
+++ b/internal/generate/datasource_local_user/local_user_data_source_gen.go
@@ -4,6 +4,7 @@ package datasource_local_user
import (
"context"
+ "github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
@@ -13,6 +14,7 @@ func LocalUserDataSourceSchema(ctx context.Context) schema.Schema {
return schema.Schema{
Attributes: map[string]schema.Attribute{
"account_expires": schema.StringAttribute{
+ CustomType: timetypes.RFC3339Type{},
Computed: true,
Description: "Retrieve the time where the local user account expires.",
MarkdownDescription: "Retrieve the time where the local user account expires.",
@@ -37,10 +39,11 @@ func LocalUserDataSourceSchema(ctx context.Context) schema.Schema {
Description: "The ID of the retrieved local user. This is the same as the SID.",
MarkdownDescription: "The ID of the retrieved local user. This is the same as the SID.",
},
- "last_login": schema.StringAttribute{
+ "last_logon": schema.StringAttribute{
+ CustomType: timetypes.RFC3339Type{},
Computed: true,
- Description: "The last login time of the local user.",
- MarkdownDescription: "The last login time of the local user.",
+ Description: "The last logon time of the local user.",
+ MarkdownDescription: "The last logon time of the local user.",
},
"name": schema.StringAttribute{
Required: true,
@@ -48,16 +51,19 @@ func LocalUserDataSourceSchema(ctx context.Context) schema.Schema {
MarkdownDescription: "Define the name of the local user.",
},
"password_changeable_date": schema.StringAttribute{
+ CustomType: timetypes.RFC3339Type{},
Computed: true,
Description: "The password changeable date of the local user.",
MarkdownDescription: "The password changeable date of the local user.",
},
"password_expires": schema.StringAttribute{
+ CustomType: timetypes.RFC3339Type{},
Computed: true,
Description: "The time when the password of the local user expires.",
MarkdownDescription: "The time when the password of the local user expires.",
},
"password_last_set": schema.StringAttribute{
+ CustomType: timetypes.RFC3339Type{},
Computed: true,
Description: "The last time when the password was set for the local user.",
MarkdownDescription: "The last time when the password was set for the local user.",
@@ -82,17 +88,17 @@ func LocalUserDataSourceSchema(ctx context.Context) schema.Schema {
}
type LocalUserModel struct {
- AccountExpires types.String `tfsdk:"account_expires"`
- Description types.String `tfsdk:"description"`
- Enabled types.Bool `tfsdk:"enabled"`
- FullName types.String `tfsdk:"full_name"`
- Id types.String `tfsdk:"id"`
- LastLogin types.String `tfsdk:"last_login"`
- Name types.String `tfsdk:"name"`
- PasswordChangeableDate types.String `tfsdk:"password_changeable_date"`
- PasswordExpires types.String `tfsdk:"password_expires"`
- PasswordLastSet types.String `tfsdk:"password_last_set"`
- PasswordRequired types.Bool `tfsdk:"password_required"`
- Sid types.String `tfsdk:"sid"`
- UserMayChangePassword types.Bool `tfsdk:"user_may_change_password"`
+ AccountExpires timetypes.RFC3339 `tfsdk:"account_expires"`
+ Description types.String `tfsdk:"description"`
+ Enabled types.Bool `tfsdk:"enabled"`
+ FullName types.String `tfsdk:"full_name"`
+ Id types.String `tfsdk:"id"`
+ LastLogon timetypes.RFC3339 `tfsdk:"last_logon"`
+ Name types.String `tfsdk:"name"`
+ PasswordChangeableDate timetypes.RFC3339 `tfsdk:"password_changeable_date"`
+ PasswordExpires timetypes.RFC3339 `tfsdk:"password_expires"`
+ PasswordLastSet timetypes.RFC3339 `tfsdk:"password_last_set"`
+ PasswordRequired types.Bool `tfsdk:"password_required"`
+ Sid types.String `tfsdk:"sid"`
+ UserMayChangePassword types.Bool `tfsdk:"user_may_change_password"`
}
diff --git a/internal/generate/datasource_local_users/local_users_data_source_gen.go b/internal/generate/datasource_local_users/local_users_data_source_gen.go
new file mode 100644
index 0000000..639020a
--- /dev/null
+++ b/internal/generate/datasource_local_users/local_users_data_source_gen.go
@@ -0,0 +1,1084 @@
+// Code generated by terraform-plugin-framework-generator DO NOT EDIT.
+
+package datasource_local_users
+
+import (
+ "context"
+ "fmt"
+ "github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes"
+ "github.com/hashicorp/terraform-plugin-framework/attr"
+ "github.com/hashicorp/terraform-plugin-framework/diag"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+ "github.com/hashicorp/terraform-plugin-framework/types/basetypes"
+ "github.com/hashicorp/terraform-plugin-go/tftypes"
+ "strings"
+
+ "github.com/hashicorp/terraform-plugin-framework/datasource/schema"
+)
+
+func LocalUsersDataSourceSchema(ctx context.Context) schema.Schema {
+ return schema.Schema{
+ Attributes: map[string]schema.Attribute{
+ "users": schema.ListNestedAttribute{
+ NestedObject: schema.NestedAttributeObject{
+ Attributes: map[string]schema.Attribute{
+ "account_expires": schema.StringAttribute{
+ CustomType: timetypes.RFC3339Type{},
+ Computed: true,
+ Description: "Retrieve the time where the local user account expires.",
+ MarkdownDescription: "Retrieve the time where the local user account expires.",
+ },
+ "description": schema.StringAttribute{
+ Computed: true,
+ Description: "The description of the local user.",
+ MarkdownDescription: "The description of the local user.",
+ },
+ "enabled": schema.BoolAttribute{
+ Computed: true,
+ Description: "Get the status of the local user.",
+ MarkdownDescription: "Get the status of the local user.",
+ },
+ "full_name": schema.StringAttribute{
+ Computed: true,
+ Description: "The full name of the local user.",
+ MarkdownDescription: "The full name of the local user.",
+ },
+ "id": schema.StringAttribute{
+ Computed: true,
+ Description: "The ID of the retrieved local user. This is the same as the SID.",
+ MarkdownDescription: "The ID of the retrieved local user. This is the same as the SID.",
+ },
+ "last_logon": schema.StringAttribute{
+ CustomType: timetypes.RFC3339Type{},
+ Computed: true,
+ Description: "The last logon time of the local user.",
+ MarkdownDescription: "The last logon time of the local user.",
+ },
+ "name": schema.StringAttribute{
+ Required: true,
+ Description: "Define the name of the local user.",
+ MarkdownDescription: "Define the name of the local user.",
+ },
+ "password_changeable_date": schema.StringAttribute{
+ CustomType: timetypes.RFC3339Type{},
+ Computed: true,
+ Description: "The password changeable date of the local user.",
+ MarkdownDescription: "The password changeable date of the local user.",
+ },
+ "password_expires": schema.StringAttribute{
+ CustomType: timetypes.RFC3339Type{},
+ Computed: true,
+ Description: "The time when the password of the local user expires.",
+ MarkdownDescription: "The time when the password of the local user expires.",
+ },
+ "password_last_set": schema.StringAttribute{
+ CustomType: timetypes.RFC3339Type{},
+ Computed: true,
+ Description: "The last time when the password was set for the local user.",
+ MarkdownDescription: "The last time when the password was set for the local user.",
+ },
+ "password_required": schema.BoolAttribute{
+ Computed: true,
+ Description: "If true a password is required login with the local user.",
+ MarkdownDescription: "If true a password is required login with the local user.",
+ },
+ "sid": schema.StringAttribute{
+ Optional: true,
+ Description: "The security ID of the local user.",
+ MarkdownDescription: "The security ID of the local user.",
+ },
+ "user_may_change_password": schema.BoolAttribute{
+ Computed: true,
+ Description: "If true the local user can change it's password.",
+ MarkdownDescription: "If true the local user can change it's password.",
+ },
+ },
+ CustomType: UsersType{
+ ObjectType: types.ObjectType{
+ AttrTypes: UsersValue{}.AttributeTypes(ctx),
+ },
+ },
+ },
+ Computed: true,
+ },
+ },
+ }
+}
+
+type LocalUsersModel struct {
+ Users types.List `tfsdk:"users"`
+}
+
+var _ basetypes.ObjectTypable = UsersType{}
+
+type UsersType struct {
+ basetypes.ObjectType
+}
+
+func (t UsersType) Equal(o attr.Type) bool {
+ other, ok := o.(UsersType)
+
+ if !ok {
+ return false
+ }
+
+ return t.ObjectType.Equal(other.ObjectType)
+}
+
+func (t UsersType) String() string {
+ return "UsersType"
+}
+
+func (t UsersType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) {
+ var diags diag.Diagnostics
+
+ attributes := in.Attributes()
+
+ accountExpiresAttribute, ok := attributes["account_expires"]
+
+ if !ok {
+ diags.AddError(
+ "Attribute Missing",
+ `account_expires is missing from object`)
+
+ return nil, diags
+ }
+
+ accountExpiresVal, ok := accountExpiresAttribute.(basetypes.StringValue)
+
+ if !ok {
+ diags.AddError(
+ "Attribute Wrong Type",
+ fmt.Sprintf(`account_expires expected to be basetypes.StringValue, was: %T`, accountExpiresAttribute))
+ }
+
+ descriptionAttribute, ok := attributes["description"]
+
+ if !ok {
+ diags.AddError(
+ "Attribute Missing",
+ `description is missing from object`)
+
+ return nil, diags
+ }
+
+ descriptionVal, ok := descriptionAttribute.(basetypes.StringValue)
+
+ if !ok {
+ diags.AddError(
+ "Attribute Wrong Type",
+ fmt.Sprintf(`description expected to be basetypes.StringValue, was: %T`, descriptionAttribute))
+ }
+
+ enabledAttribute, ok := attributes["enabled"]
+
+ if !ok {
+ diags.AddError(
+ "Attribute Missing",
+ `enabled is missing from object`)
+
+ return nil, diags
+ }
+
+ enabledVal, ok := enabledAttribute.(basetypes.BoolValue)
+
+ if !ok {
+ diags.AddError(
+ "Attribute Wrong Type",
+ fmt.Sprintf(`enabled expected to be basetypes.BoolValue, was: %T`, enabledAttribute))
+ }
+
+ fullNameAttribute, ok := attributes["full_name"]
+
+ if !ok {
+ diags.AddError(
+ "Attribute Missing",
+ `full_name is missing from object`)
+
+ return nil, diags
+ }
+
+ fullNameVal, ok := fullNameAttribute.(basetypes.StringValue)
+
+ if !ok {
+ diags.AddError(
+ "Attribute Wrong Type",
+ fmt.Sprintf(`full_name expected to be basetypes.StringValue, was: %T`, fullNameAttribute))
+ }
+
+ idAttribute, ok := attributes["id"]
+
+ if !ok {
+ diags.AddError(
+ "Attribute Missing",
+ `id is missing from object`)
+
+ return nil, diags
+ }
+
+ idVal, ok := idAttribute.(basetypes.StringValue)
+
+ if !ok {
+ diags.AddError(
+ "Attribute Wrong Type",
+ fmt.Sprintf(`id expected to be basetypes.StringValue, was: %T`, idAttribute))
+ }
+
+ lastLogonAttribute, ok := attributes["last_logon"]
+
+ if !ok {
+ diags.AddError(
+ "Attribute Missing",
+ `last_logon is missing from object`)
+
+ return nil, diags
+ }
+
+ lastLogonVal, ok := lastLogonAttribute.(basetypes.StringValue)
+
+ if !ok {
+ diags.AddError(
+ "Attribute Wrong Type",
+ fmt.Sprintf(`last_logon expected to be basetypes.StringValue, was: %T`, lastLogonAttribute))
+ }
+
+ nameAttribute, ok := attributes["name"]
+
+ if !ok {
+ diags.AddError(
+ "Attribute Missing",
+ `name is missing from object`)
+
+ return nil, diags
+ }
+
+ nameVal, ok := nameAttribute.(basetypes.StringValue)
+
+ if !ok {
+ diags.AddError(
+ "Attribute Wrong Type",
+ fmt.Sprintf(`name expected to be basetypes.StringValue, was: %T`, nameAttribute))
+ }
+
+ passwordChangeableDateAttribute, ok := attributes["password_changeable_date"]
+
+ if !ok {
+ diags.AddError(
+ "Attribute Missing",
+ `password_changeable_date is missing from object`)
+
+ return nil, diags
+ }
+
+ passwordChangeableDateVal, ok := passwordChangeableDateAttribute.(basetypes.StringValue)
+
+ if !ok {
+ diags.AddError(
+ "Attribute Wrong Type",
+ fmt.Sprintf(`password_changeable_date expected to be basetypes.StringValue, was: %T`, passwordChangeableDateAttribute))
+ }
+
+ passwordExpiresAttribute, ok := attributes["password_expires"]
+
+ if !ok {
+ diags.AddError(
+ "Attribute Missing",
+ `password_expires is missing from object`)
+
+ return nil, diags
+ }
+
+ passwordExpiresVal, ok := passwordExpiresAttribute.(basetypes.StringValue)
+
+ if !ok {
+ diags.AddError(
+ "Attribute Wrong Type",
+ fmt.Sprintf(`password_expires expected to be basetypes.StringValue, was: %T`, passwordExpiresAttribute))
+ }
+
+ passwordLastSetAttribute, ok := attributes["password_last_set"]
+
+ if !ok {
+ diags.AddError(
+ "Attribute Missing",
+ `password_last_set is missing from object`)
+
+ return nil, diags
+ }
+
+ passwordLastSetVal, ok := passwordLastSetAttribute.(basetypes.StringValue)
+
+ if !ok {
+ diags.AddError(
+ "Attribute Wrong Type",
+ fmt.Sprintf(`password_last_set expected to be basetypes.StringValue, was: %T`, passwordLastSetAttribute))
+ }
+
+ passwordRequiredAttribute, ok := attributes["password_required"]
+
+ if !ok {
+ diags.AddError(
+ "Attribute Missing",
+ `password_required is missing from object`)
+
+ return nil, diags
+ }
+
+ passwordRequiredVal, ok := passwordRequiredAttribute.(basetypes.BoolValue)
+
+ if !ok {
+ diags.AddError(
+ "Attribute Wrong Type",
+ fmt.Sprintf(`password_required expected to be basetypes.BoolValue, was: %T`, passwordRequiredAttribute))
+ }
+
+ sidAttribute, ok := attributes["sid"]
+
+ if !ok {
+ diags.AddError(
+ "Attribute Missing",
+ `sid is missing from object`)
+
+ return nil, diags
+ }
+
+ sidVal, ok := sidAttribute.(basetypes.StringValue)
+
+ if !ok {
+ diags.AddError(
+ "Attribute Wrong Type",
+ fmt.Sprintf(`sid expected to be basetypes.StringValue, was: %T`, sidAttribute))
+ }
+
+ userMayChangePasswordAttribute, ok := attributes["user_may_change_password"]
+
+ if !ok {
+ diags.AddError(
+ "Attribute Missing",
+ `user_may_change_password is missing from object`)
+
+ return nil, diags
+ }
+
+ userMayChangePasswordVal, ok := userMayChangePasswordAttribute.(basetypes.BoolValue)
+
+ if !ok {
+ diags.AddError(
+ "Attribute Wrong Type",
+ fmt.Sprintf(`user_may_change_password expected to be basetypes.BoolValue, was: %T`, userMayChangePasswordAttribute))
+ }
+
+ if diags.HasError() {
+ return nil, diags
+ }
+
+ return UsersValue{
+ AccountExpires: accountExpiresVal,
+ Description: descriptionVal,
+ Enabled: enabledVal,
+ FullName: fullNameVal,
+ Id: idVal,
+ LastLogon: lastLogonVal,
+ Name: nameVal,
+ PasswordChangeableDate: passwordChangeableDateVal,
+ PasswordExpires: passwordExpiresVal,
+ PasswordLastSet: passwordLastSetVal,
+ PasswordRequired: passwordRequiredVal,
+ Sid: sidVal,
+ UserMayChangePassword: userMayChangePasswordVal,
+ state: attr.ValueStateKnown,
+ }, diags
+}
+
+func NewUsersValueNull() UsersValue {
+ return UsersValue{
+ state: attr.ValueStateNull,
+ }
+}
+
+func NewUsersValueUnknown() UsersValue {
+ return UsersValue{
+ state: attr.ValueStateUnknown,
+ }
+}
+
+func NewUsersValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (UsersValue, diag.Diagnostics) {
+ var diags diag.Diagnostics
+
+ // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521
+ ctx := context.Background()
+
+ for name, attributeType := range attributeTypes {
+ attribute, ok := attributes[name]
+
+ if !ok {
+ diags.AddError(
+ "Missing UsersValue Attribute Value",
+ "While creating a UsersValue value, a missing attribute value was detected. "+
+ "A UsersValue must contain values for all attributes, even if null or unknown. "+
+ "This is always an issue with the provider and should be reported to the provider developers.\n\n"+
+ fmt.Sprintf("UsersValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()),
+ )
+
+ continue
+ }
+
+ if !attributeType.Equal(attribute.Type(ctx)) {
+ diags.AddError(
+ "Invalid UsersValue Attribute Type",
+ "While creating a UsersValue value, an invalid attribute value was detected. "+
+ "A UsersValue must use a matching attribute type for the value. "+
+ "This is always an issue with the provider and should be reported to the provider developers.\n\n"+
+ fmt.Sprintf("UsersValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+
+ fmt.Sprintf("UsersValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)),
+ )
+ }
+ }
+
+ for name := range attributes {
+ _, ok := attributeTypes[name]
+
+ if !ok {
+ diags.AddError(
+ "Extra UsersValue Attribute Value",
+ "While creating a UsersValue value, an extra attribute value was detected. "+
+ "A UsersValue must not contain values beyond the expected attribute types. "+
+ "This is always an issue with the provider and should be reported to the provider developers.\n\n"+
+ fmt.Sprintf("Extra UsersValue Attribute Name: %s", name),
+ )
+ }
+ }
+
+ if diags.HasError() {
+ return NewUsersValueUnknown(), diags
+ }
+
+ accountExpiresAttribute, ok := attributes["account_expires"]
+
+ if !ok {
+ diags.AddError(
+ "Attribute Missing",
+ `account_expires is missing from object`)
+
+ return NewUsersValueUnknown(), diags
+ }
+
+ accountExpiresVal, ok := accountExpiresAttribute.(basetypes.StringValue)
+
+ if !ok {
+ diags.AddError(
+ "Attribute Wrong Type",
+ fmt.Sprintf(`account_expires expected to be basetypes.StringValue, was: %T`, accountExpiresAttribute))
+ }
+
+ descriptionAttribute, ok := attributes["description"]
+
+ if !ok {
+ diags.AddError(
+ "Attribute Missing",
+ `description is missing from object`)
+
+ return NewUsersValueUnknown(), diags
+ }
+
+ descriptionVal, ok := descriptionAttribute.(basetypes.StringValue)
+
+ if !ok {
+ diags.AddError(
+ "Attribute Wrong Type",
+ fmt.Sprintf(`description expected to be basetypes.StringValue, was: %T`, descriptionAttribute))
+ }
+
+ enabledAttribute, ok := attributes["enabled"]
+
+ if !ok {
+ diags.AddError(
+ "Attribute Missing",
+ `enabled is missing from object`)
+
+ return NewUsersValueUnknown(), diags
+ }
+
+ enabledVal, ok := enabledAttribute.(basetypes.BoolValue)
+
+ if !ok {
+ diags.AddError(
+ "Attribute Wrong Type",
+ fmt.Sprintf(`enabled expected to be basetypes.BoolValue, was: %T`, enabledAttribute))
+ }
+
+ fullNameAttribute, ok := attributes["full_name"]
+
+ if !ok {
+ diags.AddError(
+ "Attribute Missing",
+ `full_name is missing from object`)
+
+ return NewUsersValueUnknown(), diags
+ }
+
+ fullNameVal, ok := fullNameAttribute.(basetypes.StringValue)
+
+ if !ok {
+ diags.AddError(
+ "Attribute Wrong Type",
+ fmt.Sprintf(`full_name expected to be basetypes.StringValue, was: %T`, fullNameAttribute))
+ }
+
+ idAttribute, ok := attributes["id"]
+
+ if !ok {
+ diags.AddError(
+ "Attribute Missing",
+ `id is missing from object`)
+
+ return NewUsersValueUnknown(), diags
+ }
+
+ idVal, ok := idAttribute.(basetypes.StringValue)
+
+ if !ok {
+ diags.AddError(
+ "Attribute Wrong Type",
+ fmt.Sprintf(`id expected to be basetypes.StringValue, was: %T`, idAttribute))
+ }
+
+ lastLogonAttribute, ok := attributes["last_logon"]
+
+ if !ok {
+ diags.AddError(
+ "Attribute Missing",
+ `last_logon is missing from object`)
+
+ return NewUsersValueUnknown(), diags
+ }
+
+ lastLogonVal, ok := lastLogonAttribute.(basetypes.StringValue)
+
+ if !ok {
+ diags.AddError(
+ "Attribute Wrong Type",
+ fmt.Sprintf(`last_logon expected to be basetypes.StringValue, was: %T`, lastLogonAttribute))
+ }
+
+ nameAttribute, ok := attributes["name"]
+
+ if !ok {
+ diags.AddError(
+ "Attribute Missing",
+ `name is missing from object`)
+
+ return NewUsersValueUnknown(), diags
+ }
+
+ nameVal, ok := nameAttribute.(basetypes.StringValue)
+
+ if !ok {
+ diags.AddError(
+ "Attribute Wrong Type",
+ fmt.Sprintf(`name expected to be basetypes.StringValue, was: %T`, nameAttribute))
+ }
+
+ passwordChangeableDateAttribute, ok := attributes["password_changeable_date"]
+
+ if !ok {
+ diags.AddError(
+ "Attribute Missing",
+ `password_changeable_date is missing from object`)
+
+ return NewUsersValueUnknown(), diags
+ }
+
+ passwordChangeableDateVal, ok := passwordChangeableDateAttribute.(basetypes.StringValue)
+
+ if !ok {
+ diags.AddError(
+ "Attribute Wrong Type",
+ fmt.Sprintf(`password_changeable_date expected to be basetypes.StringValue, was: %T`, passwordChangeableDateAttribute))
+ }
+
+ passwordExpiresAttribute, ok := attributes["password_expires"]
+
+ if !ok {
+ diags.AddError(
+ "Attribute Missing",
+ `password_expires is missing from object`)
+
+ return NewUsersValueUnknown(), diags
+ }
+
+ passwordExpiresVal, ok := passwordExpiresAttribute.(basetypes.StringValue)
+
+ if !ok {
+ diags.AddError(
+ "Attribute Wrong Type",
+ fmt.Sprintf(`password_expires expected to be basetypes.StringValue, was: %T`, passwordExpiresAttribute))
+ }
+
+ passwordLastSetAttribute, ok := attributes["password_last_set"]
+
+ if !ok {
+ diags.AddError(
+ "Attribute Missing",
+ `password_last_set is missing from object`)
+
+ return NewUsersValueUnknown(), diags
+ }
+
+ passwordLastSetVal, ok := passwordLastSetAttribute.(basetypes.StringValue)
+
+ if !ok {
+ diags.AddError(
+ "Attribute Wrong Type",
+ fmt.Sprintf(`password_last_set expected to be basetypes.StringValue, was: %T`, passwordLastSetAttribute))
+ }
+
+ passwordRequiredAttribute, ok := attributes["password_required"]
+
+ if !ok {
+ diags.AddError(
+ "Attribute Missing",
+ `password_required is missing from object`)
+
+ return NewUsersValueUnknown(), diags
+ }
+
+ passwordRequiredVal, ok := passwordRequiredAttribute.(basetypes.BoolValue)
+
+ if !ok {
+ diags.AddError(
+ "Attribute Wrong Type",
+ fmt.Sprintf(`password_required expected to be basetypes.BoolValue, was: %T`, passwordRequiredAttribute))
+ }
+
+ sidAttribute, ok := attributes["sid"]
+
+ if !ok {
+ diags.AddError(
+ "Attribute Missing",
+ `sid is missing from object`)
+
+ return NewUsersValueUnknown(), diags
+ }
+
+ sidVal, ok := sidAttribute.(basetypes.StringValue)
+
+ if !ok {
+ diags.AddError(
+ "Attribute Wrong Type",
+ fmt.Sprintf(`sid expected to be basetypes.StringValue, was: %T`, sidAttribute))
+ }
+
+ userMayChangePasswordAttribute, ok := attributes["user_may_change_password"]
+
+ if !ok {
+ diags.AddError(
+ "Attribute Missing",
+ `user_may_change_password is missing from object`)
+
+ return NewUsersValueUnknown(), diags
+ }
+
+ userMayChangePasswordVal, ok := userMayChangePasswordAttribute.(basetypes.BoolValue)
+
+ if !ok {
+ diags.AddError(
+ "Attribute Wrong Type",
+ fmt.Sprintf(`user_may_change_password expected to be basetypes.BoolValue, was: %T`, userMayChangePasswordAttribute))
+ }
+
+ if diags.HasError() {
+ return NewUsersValueUnknown(), diags
+ }
+
+ return UsersValue{
+ AccountExpires: accountExpiresVal,
+ Description: descriptionVal,
+ Enabled: enabledVal,
+ FullName: fullNameVal,
+ Id: idVal,
+ LastLogon: lastLogonVal,
+ Name: nameVal,
+ PasswordChangeableDate: passwordChangeableDateVal,
+ PasswordExpires: passwordExpiresVal,
+ PasswordLastSet: passwordLastSetVal,
+ PasswordRequired: passwordRequiredVal,
+ Sid: sidVal,
+ UserMayChangePassword: userMayChangePasswordVal,
+ state: attr.ValueStateKnown,
+ }, diags
+}
+
+func NewUsersValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) UsersValue {
+ object, diags := NewUsersValue(attributeTypes, attributes)
+
+ if diags.HasError() {
+ // This could potentially be added to the diag package.
+ diagsStrings := make([]string, 0, len(diags))
+
+ for _, diagnostic := range diags {
+ diagsStrings = append(diagsStrings, fmt.Sprintf(
+ "%s | %s | %s",
+ diagnostic.Severity(),
+ diagnostic.Summary(),
+ diagnostic.Detail()))
+ }
+
+ panic("NewUsersValueMust received error(s): " + strings.Join(diagsStrings, "\n"))
+ }
+
+ return object
+}
+
+func (t UsersType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) {
+ if in.Type() == nil {
+ return NewUsersValueNull(), nil
+ }
+
+ if !in.Type().Equal(t.TerraformType(ctx)) {
+ return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type())
+ }
+
+ if !in.IsKnown() {
+ return NewUsersValueUnknown(), nil
+ }
+
+ if in.IsNull() {
+ return NewUsersValueNull(), nil
+ }
+
+ attributes := map[string]attr.Value{}
+
+ val := map[string]tftypes.Value{}
+
+ err := in.As(&val)
+
+ if err != nil {
+ return nil, err
+ }
+
+ for k, v := range val {
+ a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v)
+
+ if err != nil {
+ return nil, err
+ }
+
+ attributes[k] = a
+ }
+
+ return NewUsersValueMust(UsersValue{}.AttributeTypes(ctx), attributes), nil
+}
+
+func (t UsersType) ValueType(ctx context.Context) attr.Value {
+ return UsersValue{}
+}
+
+var _ basetypes.ObjectValuable = UsersValue{}
+
+type UsersValue struct {
+ AccountExpires basetypes.StringValue `tfsdk:"account_expires"`
+ Description basetypes.StringValue `tfsdk:"description"`
+ Enabled basetypes.BoolValue `tfsdk:"enabled"`
+ FullName basetypes.StringValue `tfsdk:"full_name"`
+ Id basetypes.StringValue `tfsdk:"id"`
+ LastLogon basetypes.StringValue `tfsdk:"last_logon"`
+ Name basetypes.StringValue `tfsdk:"name"`
+ PasswordChangeableDate basetypes.StringValue `tfsdk:"password_changeable_date"`
+ PasswordExpires basetypes.StringValue `tfsdk:"password_expires"`
+ PasswordLastSet basetypes.StringValue `tfsdk:"password_last_set"`
+ PasswordRequired basetypes.BoolValue `tfsdk:"password_required"`
+ Sid basetypes.StringValue `tfsdk:"sid"`
+ UserMayChangePassword basetypes.BoolValue `tfsdk:"user_may_change_password"`
+ state attr.ValueState
+}
+
+func (v UsersValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) {
+ attrTypes := make(map[string]tftypes.Type, 13)
+
+ var val tftypes.Value
+ var err error
+
+ attrTypes["account_expires"] = basetypes.StringType{}.TerraformType(ctx)
+ attrTypes["description"] = basetypes.StringType{}.TerraformType(ctx)
+ attrTypes["enabled"] = basetypes.BoolType{}.TerraformType(ctx)
+ attrTypes["full_name"] = basetypes.StringType{}.TerraformType(ctx)
+ attrTypes["id"] = basetypes.StringType{}.TerraformType(ctx)
+ attrTypes["last_logon"] = basetypes.StringType{}.TerraformType(ctx)
+ attrTypes["name"] = basetypes.StringType{}.TerraformType(ctx)
+ attrTypes["password_changeable_date"] = basetypes.StringType{}.TerraformType(ctx)
+ attrTypes["password_expires"] = basetypes.StringType{}.TerraformType(ctx)
+ attrTypes["password_last_set"] = basetypes.StringType{}.TerraformType(ctx)
+ attrTypes["password_required"] = basetypes.BoolType{}.TerraformType(ctx)
+ attrTypes["sid"] = basetypes.StringType{}.TerraformType(ctx)
+ attrTypes["user_may_change_password"] = basetypes.BoolType{}.TerraformType(ctx)
+
+ objectType := tftypes.Object{AttributeTypes: attrTypes}
+
+ switch v.state {
+ case attr.ValueStateKnown:
+ vals := make(map[string]tftypes.Value, 13)
+
+ val, err = v.AccountExpires.ToTerraformValue(ctx)
+
+ if err != nil {
+ return tftypes.NewValue(objectType, tftypes.UnknownValue), err
+ }
+
+ vals["account_expires"] = val
+
+ val, err = v.Description.ToTerraformValue(ctx)
+
+ if err != nil {
+ return tftypes.NewValue(objectType, tftypes.UnknownValue), err
+ }
+
+ vals["description"] = val
+
+ val, err = v.Enabled.ToTerraformValue(ctx)
+
+ if err != nil {
+ return tftypes.NewValue(objectType, tftypes.UnknownValue), err
+ }
+
+ vals["enabled"] = val
+
+ val, err = v.FullName.ToTerraformValue(ctx)
+
+ if err != nil {
+ return tftypes.NewValue(objectType, tftypes.UnknownValue), err
+ }
+
+ vals["full_name"] = val
+
+ val, err = v.Id.ToTerraformValue(ctx)
+
+ if err != nil {
+ return tftypes.NewValue(objectType, tftypes.UnknownValue), err
+ }
+
+ vals["id"] = val
+
+ val, err = v.LastLogon.ToTerraformValue(ctx)
+
+ if err != nil {
+ return tftypes.NewValue(objectType, tftypes.UnknownValue), err
+ }
+
+ vals["last_logon"] = val
+
+ val, err = v.Name.ToTerraformValue(ctx)
+
+ if err != nil {
+ return tftypes.NewValue(objectType, tftypes.UnknownValue), err
+ }
+
+ vals["name"] = val
+
+ val, err = v.PasswordChangeableDate.ToTerraformValue(ctx)
+
+ if err != nil {
+ return tftypes.NewValue(objectType, tftypes.UnknownValue), err
+ }
+
+ vals["password_changeable_date"] = val
+
+ val, err = v.PasswordExpires.ToTerraformValue(ctx)
+
+ if err != nil {
+ return tftypes.NewValue(objectType, tftypes.UnknownValue), err
+ }
+
+ vals["password_expires"] = val
+
+ val, err = v.PasswordLastSet.ToTerraformValue(ctx)
+
+ if err != nil {
+ return tftypes.NewValue(objectType, tftypes.UnknownValue), err
+ }
+
+ vals["password_last_set"] = val
+
+ val, err = v.PasswordRequired.ToTerraformValue(ctx)
+
+ if err != nil {
+ return tftypes.NewValue(objectType, tftypes.UnknownValue), err
+ }
+
+ vals["password_required"] = val
+
+ val, err = v.Sid.ToTerraformValue(ctx)
+
+ if err != nil {
+ return tftypes.NewValue(objectType, tftypes.UnknownValue), err
+ }
+
+ vals["sid"] = val
+
+ val, err = v.UserMayChangePassword.ToTerraformValue(ctx)
+
+ if err != nil {
+ return tftypes.NewValue(objectType, tftypes.UnknownValue), err
+ }
+
+ vals["user_may_change_password"] = val
+
+ if err := tftypes.ValidateValue(objectType, vals); err != nil {
+ return tftypes.NewValue(objectType, tftypes.UnknownValue), err
+ }
+
+ return tftypes.NewValue(objectType, vals), nil
+ case attr.ValueStateNull:
+ return tftypes.NewValue(objectType, nil), nil
+ case attr.ValueStateUnknown:
+ return tftypes.NewValue(objectType, tftypes.UnknownValue), nil
+ default:
+ panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state))
+ }
+}
+
+func (v UsersValue) IsNull() bool {
+ return v.state == attr.ValueStateNull
+}
+
+func (v UsersValue) IsUnknown() bool {
+ return v.state == attr.ValueStateUnknown
+}
+
+func (v UsersValue) String() string {
+ return "UsersValue"
+}
+
+func (v UsersValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) {
+ var diags diag.Diagnostics
+
+ objVal, diags := types.ObjectValue(
+ map[string]attr.Type{
+ "account_expires": basetypes.StringType{},
+ "description": basetypes.StringType{},
+ "enabled": basetypes.BoolType{},
+ "full_name": basetypes.StringType{},
+ "id": basetypes.StringType{},
+ "last_logon": basetypes.StringType{},
+ "name": basetypes.StringType{},
+ "password_changeable_date": basetypes.StringType{},
+ "password_expires": basetypes.StringType{},
+ "password_last_set": basetypes.StringType{},
+ "password_required": basetypes.BoolType{},
+ "sid": basetypes.StringType{},
+ "user_may_change_password": basetypes.BoolType{},
+ },
+ map[string]attr.Value{
+ "account_expires": v.AccountExpires,
+ "description": v.Description,
+ "enabled": v.Enabled,
+ "full_name": v.FullName,
+ "id": v.Id,
+ "last_logon": v.LastLogon,
+ "name": v.Name,
+ "password_changeable_date": v.PasswordChangeableDate,
+ "password_expires": v.PasswordExpires,
+ "password_last_set": v.PasswordLastSet,
+ "password_required": v.PasswordRequired,
+ "sid": v.Sid,
+ "user_may_change_password": v.UserMayChangePassword,
+ })
+
+ return objVal, diags
+}
+
+func (v UsersValue) Equal(o attr.Value) bool {
+ other, ok := o.(UsersValue)
+
+ if !ok {
+ return false
+ }
+
+ if v.state != other.state {
+ return false
+ }
+
+ if v.state != attr.ValueStateKnown {
+ return true
+ }
+
+ if !v.AccountExpires.Equal(other.AccountExpires) {
+ return false
+ }
+
+ if !v.Description.Equal(other.Description) {
+ return false
+ }
+
+ if !v.Enabled.Equal(other.Enabled) {
+ return false
+ }
+
+ if !v.FullName.Equal(other.FullName) {
+ return false
+ }
+
+ if !v.Id.Equal(other.Id) {
+ return false
+ }
+
+ if !v.LastLogon.Equal(other.LastLogon) {
+ return false
+ }
+
+ if !v.Name.Equal(other.Name) {
+ return false
+ }
+
+ if !v.PasswordChangeableDate.Equal(other.PasswordChangeableDate) {
+ return false
+ }
+
+ if !v.PasswordExpires.Equal(other.PasswordExpires) {
+ return false
+ }
+
+ if !v.PasswordLastSet.Equal(other.PasswordLastSet) {
+ return false
+ }
+
+ if !v.PasswordRequired.Equal(other.PasswordRequired) {
+ return false
+ }
+
+ if !v.Sid.Equal(other.Sid) {
+ return false
+ }
+
+ if !v.UserMayChangePassword.Equal(other.UserMayChangePassword) {
+ return false
+ }
+
+ return true
+}
+
+func (v UsersValue) Type(ctx context.Context) attr.Type {
+ return UsersType{
+ basetypes.ObjectType{
+ AttrTypes: v.AttributeTypes(ctx),
+ },
+ }
+}
+
+func (v UsersValue) AttributeTypes(ctx context.Context) map[string]attr.Type {
+ return map[string]attr.Type{
+ "account_expires": basetypes.StringType{},
+ "description": basetypes.StringType{},
+ "enabled": basetypes.BoolType{},
+ "full_name": basetypes.StringType{},
+ "id": basetypes.StringType{},
+ "last_logon": basetypes.StringType{},
+ "name": basetypes.StringType{},
+ "password_changeable_date": basetypes.StringType{},
+ "password_expires": basetypes.StringType{},
+ "password_last_set": basetypes.StringType{},
+ "password_required": basetypes.BoolType{},
+ "sid": basetypes.StringType{},
+ "user_may_change_password": basetypes.BoolType{},
+ }
+}
diff --git a/internal/generate/resource_local_user/local_user_resource_gen.go b/internal/generate/resource_local_user/local_user_resource_gen.go
index 5e9dd00..ca511a4 100644
--- a/internal/generate/resource_local_user/local_user_resource_gen.go
+++ b/internal/generate/resource_local_user/local_user_resource_gen.go
@@ -4,12 +4,15 @@ package resource_local_user
import (
"context"
+ "github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes"
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
+ "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
"github.com/hashicorp/terraform-plugin-framework/types"
+ "regexp"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
)
@@ -18,25 +21,22 @@ func LocalUserResourceSchema(ctx context.Context) schema.Schema {
return schema.Schema{
Attributes: map[string]schema.Attribute{
"account_expires": schema.StringAttribute{
+ CustomType: timetypes.RFC3339Type{},
Optional: true,
Computed: true,
- Description: "Define when the local user account expires (UTC). If not specified, the user account never expires.
The string time format is the following: `yyyy-MM-dd hh:mm:ss` (see [go time package](https://pkg.go.dev/time#pkg-constants) `DateTime`).",
- MarkdownDescription: "Define when the local user account expires (UTC). If not specified, the user account never expires.
The string time format is the following: `yyyy-MM-dd hh:mm:ss` (see [go time package](https://pkg.go.dev/time#pkg-constants) `DateTime`).",
- PlanModifiers: []planmodifier.String{
- stringplanmodifier.UseStateForUnknown(),
- },
+ Description: "Define when the local user account expires. If not specified, the user account never expires.
The string time format is the following: `2023-07-25T20:43:16Z` (see [Terraform timetypes](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework-timetypes@v0.3.0/timetypes#RFC3339)).",
+ MarkdownDescription: "Define when the local user account expires. If not specified, the user account never expires.
The string time format is the following: `2023-07-25T20:43:16Z` (see [Terraform timetypes](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework-timetypes@v0.3.0/timetypes#RFC3339)).",
+ Default: stringdefault.StaticString("0001-01-01T00:00:00Z"),
},
"description": schema.StringAttribute{
Optional: true,
Computed: true,
Description: "Define a description for the local user. The maximum length is 48 characters.",
MarkdownDescription: "Define a description for the local user. The maximum length is 48 characters.",
- PlanModifiers: []planmodifier.String{
- stringplanmodifier.UseStateForUnknown(),
- },
Validators: []validator.String{
- stringvalidator.LengthBetween(1, 48),
+ stringvalidator.LengthAtMost(48),
},
+ Default: stringdefault.StaticString(""),
},
"enabled": schema.BoolAttribute{
Optional: true,
@@ -50,9 +50,7 @@ func LocalUserResourceSchema(ctx context.Context) schema.Schema {
Computed: true,
Description: "Define the full name of the local user. The full name differs from the user name of the user account.",
MarkdownDescription: "Define the full name of the local user. The full name differs from the user name of the user account.",
- PlanModifiers: []planmodifier.String{
- stringplanmodifier.UseStateForUnknown(),
- },
+ Default: stringdefault.StaticString(""),
},
"id": schema.StringAttribute{
Computed: true,
@@ -62,10 +60,11 @@ func LocalUserResourceSchema(ctx context.Context) schema.Schema {
stringplanmodifier.UseStateForUnknown(),
},
},
- "last_login": schema.StringAttribute{
+ "last_logon": schema.StringAttribute{
+ CustomType: timetypes.RFC3339Type{},
Computed: true,
- Description: "The last login time of the local user.",
- MarkdownDescription: "The last login time of the local user.",
+ Description: "The last logon time of the local user.",
+ MarkdownDescription: "The last logon time of the local user.",
},
"name": schema.StringAttribute{
Required: true,
@@ -76,6 +75,7 @@ func LocalUserResourceSchema(ctx context.Context) schema.Schema {
},
Validators: []validator.String{
stringvalidator.LengthBetween(1, 20),
+ stringvalidator.RegexMatches(regexp.MustCompile(`^[^"/\[\]:;|=,+*?<>\@]+$`), `cannot contain the following characters: "/\[]:;|=,+*?<>@ `),
},
},
"password": schema.StringAttribute{
@@ -88,16 +88,19 @@ func LocalUserResourceSchema(ctx context.Context) schema.Schema {
},
},
"password_changeable_date": schema.StringAttribute{
+ CustomType: timetypes.RFC3339Type{},
Computed: true,
Description: "The password changeable date of the local user.",
MarkdownDescription: "The password changeable date of the local user.",
},
"password_expires": schema.StringAttribute{
+ CustomType: timetypes.RFC3339Type{},
Computed: true,
Description: "The time when the password of the local user expires.",
MarkdownDescription: "The time when the password of the local user expires.",
},
"password_last_set": schema.StringAttribute{
+ CustomType: timetypes.RFC3339Type{},
Computed: true,
Description: "The last time when the password was set for the local user.",
MarkdownDescription: "The last time when the password was set for the local user.",
@@ -134,19 +137,19 @@ func LocalUserResourceSchema(ctx context.Context) schema.Schema {
}
type LocalUserModel struct {
- AccountExpires types.String `tfsdk:"account_expires"`
- Description types.String `tfsdk:"description"`
- Enabled types.Bool `tfsdk:"enabled"`
- FullName types.String `tfsdk:"full_name"`
- Id types.String `tfsdk:"id"`
- LastLogin types.String `tfsdk:"last_login"`
- Name types.String `tfsdk:"name"`
- Password types.String `tfsdk:"password"`
- PasswordChangeableDate types.String `tfsdk:"password_changeable_date"`
- PasswordExpires types.String `tfsdk:"password_expires"`
- PasswordLastSet types.String `tfsdk:"password_last_set"`
- PasswordNeverExpires types.Bool `tfsdk:"password_never_expires"`
- PasswordRequired types.Bool `tfsdk:"password_required"`
- Sid types.String `tfsdk:"sid"`
- UserMayChangePassword types.Bool `tfsdk:"user_may_change_password"`
+ AccountExpires timetypes.RFC3339 `tfsdk:"account_expires"`
+ Description types.String `tfsdk:"description"`
+ Enabled types.Bool `tfsdk:"enabled"`
+ FullName types.String `tfsdk:"full_name"`
+ Id types.String `tfsdk:"id"`
+ LastLogon timetypes.RFC3339 `tfsdk:"last_logon"`
+ Name types.String `tfsdk:"name"`
+ Password types.String `tfsdk:"password"`
+ PasswordChangeableDate timetypes.RFC3339 `tfsdk:"password_changeable_date"`
+ PasswordExpires timetypes.RFC3339 `tfsdk:"password_expires"`
+ PasswordLastSet timetypes.RFC3339 `tfsdk:"password_last_set"`
+ PasswordNeverExpires types.Bool `tfsdk:"password_never_expires"`
+ PasswordRequired types.Bool `tfsdk:"password_required"`
+ Sid types.String `tfsdk:"sid"`
+ UserMayChangePassword types.Bool `tfsdk:"user_may_change_password"`
}
diff --git a/internal/provider/local/local_user_data_source.go b/internal/provider/local/local_user_data_source.go
index 09a842f..5a00426 100644
--- a/internal/provider/local/local_user_data_source.go
+++ b/internal/provider/local/local_user_data_source.go
@@ -8,7 +8,9 @@ import (
"github.com/d-strobel/gowindows"
"github.com/d-strobel/gowindows/windows/local"
+ "github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes"
"github.com/hashicorp/terraform-plugin-framework/datasource"
+ "github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/types"
)
@@ -50,6 +52,7 @@ func (d *localUserDataSource) Configure(ctx context.Context, req datasource.Conf
func (d *localUserDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var data datasource_local_user.LocalUserModel
+ var diag diag.Diagnostics
// Read Terraform configuration data into the model
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
@@ -68,22 +71,33 @@ func (d *localUserDataSource) Read(ctx context.Context, req datasource.ReadReque
if err != nil {
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to read local user, got error: %s", err))
return
-
}
// Set data
- data.Id = types.StringValue(winResp.SID.Value)
- data.Sid = types.StringValue(winResp.SID.Value)
- data.Name = types.StringValue(winResp.Name)
+ data.AccountExpires, diag = timetypes.NewRFC3339Value(winResp.AccountExpires.Format(time.RFC3339))
+ resp.Diagnostics.Append(diag...)
+
data.Description = types.StringValue(winResp.Description)
data.Enabled = types.BoolValue(winResp.Enabled)
- data.PasswordRequired = types.BoolValue(winResp.PasswordRequired)
- data.AccountExpires = types.StringValue(winResp.AccountExpires.Format(time.DateTime))
data.FullName = types.StringValue(winResp.FullName)
- data.LastLogin = types.StringValue(winResp.LastLogon.Format(time.DateTime))
- data.PasswordChangeableDate = types.StringValue(winResp.PasswordChangeableDate.Format(time.DateTime))
- data.PasswordExpires = types.StringValue(winResp.PasswordExpires.Format(time.DateTime))
- data.PasswordLastSet = types.StringValue(winResp.PasswordLastSet.Format(time.DateTime))
+ data.Id = types.StringValue(winResp.SID.Value)
+
+ data.LastLogon, diag = timetypes.NewRFC3339Value(winResp.LastLogon.Format(time.RFC3339))
+ resp.Diagnostics.Append(diag...)
+
+ data.Name = types.StringValue(winResp.Name)
+
+ data.PasswordChangeableDate, diag = timetypes.NewRFC3339Value(winResp.PasswordChangeableDate.Format(time.RFC3339))
+ resp.Diagnostics.Append(diag...)
+
+ data.PasswordExpires, diag = timetypes.NewRFC3339Value(winResp.PasswordExpires.Format(time.RFC3339))
+ resp.Diagnostics.Append(diag...)
+
+ data.PasswordLastSet, diag = timetypes.NewRFC3339Value(winResp.PasswordLastSet.Format(time.RFC3339))
+ resp.Diagnostics.Append(diag...)
+
+ data.PasswordRequired = types.BoolValue(winResp.PasswordRequired)
+ data.Sid = types.StringValue(winResp.SID.Value)
data.UserMayChangePassword = types.BoolValue(winResp.UserMayChangePassword)
// Save data into Terraform state
diff --git a/internal/provider/local/local_user_resource.go b/internal/provider/local/local_user_resource.go
index a1fbaed..cd72a65 100644
--- a/internal/provider/local/local_user_resource.go
+++ b/internal/provider/local/local_user_resource.go
@@ -8,6 +8,8 @@ import (
"github.com/d-strobel/gowindows"
"github.com/d-strobel/gowindows/windows/local"
+ "github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes"
+ "github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/types"
@@ -55,22 +57,14 @@ func (r *localUserResource) Create(ctx context.Context, req resource.CreateReque
// Read Terraform plan data into the model
resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
+ // Read time values from the plan
+ accountExpiresPlanValue, diag := data.AccountExpires.ValueRFC3339Time()
+ resp.Diagnostics.Append(diag...)
+
if resp.Diagnostics.HasError() {
return
}
- // Convert time string to time
- accountExpires := time.Time{}
- if !data.AccountExpires.IsUnknown() {
- var err error
-
- accountExpires, err = time.Parse(time.DateTime, data.AccountExpires.ValueString())
- if err != nil {
- resp.Diagnostics.AddAttributeError(path.Root("account_expires"), "Config Error", fmt.Sprintf("Unable to parse time, got error: %s", err))
- return
- }
- }
-
// Create API call logic
params := local.UserCreateParams{
Name: data.Name.ValueString(),
@@ -80,7 +74,7 @@ func (r *localUserResource) Create(ctx context.Context, req resource.CreateReque
Password: data.Password.ValueString(),
PasswordNeverExpires: data.PasswordNeverExpires.ValueBool(),
UserMayChangePassword: data.UserMayChangePassword.ValueBool(),
- AccountExpires: accountExpires,
+ AccountExpires: accountExpiresPlanValue,
}
winResp, err := r.client.Local.UserCreate(ctx, params)
@@ -90,16 +84,28 @@ func (r *localUserResource) Create(ctx context.Context, req resource.CreateReque
}
// Set data
- data.AccountExpires = types.StringValue(winResp.AccountExpires.Format(time.DateTime))
+ data.AccountExpires, diag = timetypes.NewRFC3339Value(winResp.AccountExpires.Format(time.RFC3339))
+ resp.Diagnostics.Append(diag...)
+
data.Description = types.StringValue(winResp.Description)
data.Enabled = types.BoolValue(winResp.Enabled)
data.FullName = types.StringValue(winResp.FullName)
data.Id = types.StringValue(winResp.SID.Value)
- data.LastLogin = types.StringValue(winResp.LastLogon.Format(time.DateTime))
+
+ data.LastLogon, diag = timetypes.NewRFC3339Value(winResp.LastLogon.Format(time.RFC3339))
+ resp.Diagnostics.Append(diag...)
+
data.Name = types.StringValue(winResp.Name)
- data.PasswordChangeableDate = types.StringValue(winResp.PasswordChangeableDate.Format(time.DateTime))
- data.PasswordExpires = types.StringValue(winResp.PasswordChangeableDate.Format(time.DateTime))
- data.PasswordLastSet = types.StringValue(winResp.PasswordLastSet.Format(time.DateTime))
+
+ data.PasswordChangeableDate, diag = timetypes.NewRFC3339Value(winResp.PasswordChangeableDate.Format(time.RFC3339))
+ resp.Diagnostics.Append(diag...)
+
+ data.PasswordExpires, diag = timetypes.NewRFC3339Value(winResp.PasswordExpires.Format(time.RFC3339))
+ resp.Diagnostics.Append(diag...)
+
+ data.PasswordLastSet, diag = timetypes.NewRFC3339Value(winResp.PasswordLastSet.Format(time.RFC3339))
+ resp.Diagnostics.Append(diag...)
+
data.PasswordRequired = types.BoolValue(winResp.PasswordRequired)
data.Sid = types.StringValue(winResp.SID.Value)
data.UserMayChangePassword = types.BoolValue(winResp.UserMayChangePassword)
@@ -110,6 +116,7 @@ func (r *localUserResource) Create(ctx context.Context, req resource.CreateReque
func (r *localUserResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
var data resource_local_user.LocalUserModel
+ var diag diag.Diagnostics
// Read Terraform prior state data into the model
resp.Diagnostics.Append(req.State.Get(ctx, &data)...)
@@ -126,18 +133,30 @@ func (r *localUserResource) Read(ctx context.Context, req resource.ReadRequest,
}
// Set data
- data.Id = types.StringValue(winResp.SID.Value)
- data.Sid = types.StringValue(winResp.SID.Value)
- data.Name = types.StringValue(winResp.Name)
+ data.AccountExpires, diag = timetypes.NewRFC3339Value(winResp.AccountExpires.Format(time.RFC3339))
+ resp.Diagnostics.Append(diag...)
+
data.Description = types.StringValue(winResp.Description)
data.Enabled = types.BoolValue(winResp.Enabled)
- data.PasswordRequired = types.BoolValue(winResp.PasswordRequired)
- data.AccountExpires = types.StringValue(winResp.AccountExpires.Format(time.DateTime))
data.FullName = types.StringValue(winResp.FullName)
- data.LastLogin = types.StringValue(winResp.LastLogon.Format(time.DateTime))
- data.PasswordChangeableDate = types.StringValue(winResp.PasswordChangeableDate.Format(time.DateTime))
- data.PasswordExpires = types.StringValue(winResp.PasswordExpires.Format(time.DateTime))
- data.PasswordLastSet = types.StringValue(winResp.PasswordLastSet.Format(time.DateTime))
+ data.Id = types.StringValue(winResp.SID.Value)
+
+ data.LastLogon, diag = timetypes.NewRFC3339Value(winResp.LastLogon.Format(time.RFC3339))
+ resp.Diagnostics.Append(diag...)
+
+ data.Name = types.StringValue(winResp.Name)
+
+ data.PasswordChangeableDate, diag = timetypes.NewRFC3339Value(winResp.PasswordChangeableDate.Format(time.RFC3339))
+ resp.Diagnostics.Append(diag...)
+
+ data.PasswordExpires, diag = timetypes.NewRFC3339Value(winResp.PasswordExpires.Format(time.RFC3339))
+ resp.Diagnostics.Append(diag...)
+
+ data.PasswordLastSet, diag = timetypes.NewRFC3339Value(winResp.PasswordLastSet.Format(time.RFC3339))
+ resp.Diagnostics.Append(diag...)
+
+ data.PasswordRequired = types.BoolValue(winResp.PasswordRequired)
+ data.Sid = types.StringValue(winResp.SID.Value)
data.UserMayChangePassword = types.BoolValue(winResp.UserMayChangePassword)
// Save updated data into Terraform state
@@ -150,32 +169,24 @@ func (r *localUserResource) Update(ctx context.Context, req resource.UpdateReque
// Read Terraform plan data into the model
resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
+ // Read time values from the plan
+ accountExpiresValue, diag := data.AccountExpires.ValueRFC3339Time()
+ resp.Diagnostics.Append(diag...)
+
if resp.Diagnostics.HasError() {
return
}
- // Convert time string to time
- accountExpires := time.Time{}
- if !data.AccountExpires.IsUnknown() {
- var err error
-
- accountExpires, err = time.Parse(time.DateTime, data.AccountExpires.ValueString())
- if err != nil {
- resp.Diagnostics.AddAttributeError(path.Root("account_expires"), "Config Error", fmt.Sprintf("Unable to parse time, got error: %s", err))
- return
- }
- }
-
// Update API call logic
params := local.UserUpdateParams{
- SID: data.Sid.ValueString(),
- AccountExpires: accountExpires,
+ AccountExpires: accountExpiresValue,
Description: data.Description.ValueString(),
Enabled: data.Enabled.ValueBool(),
FullName: data.FullName.ValueString(),
Password: data.Password.ValueString(),
PasswordNeverExpires: data.PasswordNeverExpires.ValueBool(),
UserMayChangePassword: data.UserMayChangePassword.ValueBool(),
+ SID: data.Sid.ValueString(),
}
if err := r.client.Local.UserUpdate(ctx, params); err != nil {
@@ -190,18 +201,30 @@ func (r *localUserResource) Update(ctx context.Context, req resource.UpdateReque
}
// Set data
- data.Id = types.StringValue(winResp.SID.Value)
- data.Sid = types.StringValue(winResp.SID.Value)
- data.Name = types.StringValue(winResp.Name)
+ data.AccountExpires, diag = timetypes.NewRFC3339Value(winResp.AccountExpires.Format(time.RFC3339))
+ resp.Diagnostics.Append(diag...)
+
data.Description = types.StringValue(winResp.Description)
data.Enabled = types.BoolValue(winResp.Enabled)
- data.PasswordRequired = types.BoolValue(winResp.PasswordRequired)
- data.AccountExpires = types.StringValue(winResp.AccountExpires.Format(time.DateTime))
data.FullName = types.StringValue(winResp.FullName)
- data.LastLogin = types.StringValue(winResp.LastLogon.Format(time.DateTime))
- data.PasswordChangeableDate = types.StringValue(winResp.PasswordChangeableDate.Format(time.DateTime))
- data.PasswordExpires = types.StringValue(winResp.PasswordExpires.Format(time.DateTime))
- data.PasswordLastSet = types.StringValue(winResp.PasswordLastSet.Format(time.DateTime))
+ data.Id = types.StringValue(winResp.SID.Value)
+
+ data.LastLogon, diag = timetypes.NewRFC3339Value(winResp.LastLogon.Format(time.RFC3339))
+ resp.Diagnostics.Append(diag...)
+
+ data.Name = types.StringValue(winResp.Name)
+
+ data.PasswordChangeableDate, diag = timetypes.NewRFC3339Value(winResp.PasswordChangeableDate.Format(time.RFC3339))
+ resp.Diagnostics.Append(diag...)
+
+ data.PasswordExpires, diag = timetypes.NewRFC3339Value(winResp.PasswordExpires.Format(time.RFC3339))
+ resp.Diagnostics.Append(diag...)
+
+ data.PasswordLastSet, diag = timetypes.NewRFC3339Value(winResp.PasswordLastSet.Format(time.RFC3339))
+ resp.Diagnostics.Append(diag...)
+
+ data.PasswordRequired = types.BoolValue(winResp.PasswordRequired)
+ data.Sid = types.StringValue(winResp.SID.Value)
data.UserMayChangePassword = types.BoolValue(winResp.UserMayChangePassword)
// Save updated data into Terraform state
diff --git a/internal/provider/local/local_users_data_source.go b/internal/provider/local/local_users_data_source.go
new file mode 100644
index 0000000..8ba135e
--- /dev/null
+++ b/internal/provider/local/local_users_data_source.go
@@ -0,0 +1,96 @@
+package local
+
+import (
+ "context"
+ "fmt"
+ "terraform-provider-windows/internal/generate/datasource_local_users"
+ "time"
+
+ "github.com/d-strobel/gowindows"
+ "github.com/hashicorp/terraform-plugin-framework/datasource"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+)
+
+var _ datasource.DataSource = (*localUsersDataSource)(nil)
+
+func NewLocalUsersDataSource() datasource.DataSource {
+ return &localUsersDataSource{}
+}
+
+type localUsersDataSource struct {
+ client *gowindows.Client
+}
+
+func (d *localUsersDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_local_users"
+}
+
+func (d *localUsersDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
+ resp.Schema = datasource_local_users.LocalUsersDataSourceSchema(ctx)
+ resp.Schema.Description = `Retrieve a list of all local users.`
+}
+
+func (d *localUsersDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
+ if req.ProviderData == nil {
+ return
+ }
+
+ client, ok := req.ProviderData.(*gowindows.Client)
+ if !ok {
+ resp.Diagnostics.AddError(
+ "Unexpected Data Source Configure Type",
+ fmt.Sprintf("Expected *gowindows.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData),
+ )
+ return
+ }
+
+ d.client = client
+}
+
+func (d *localUsersDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
+ var data datasource_local_users.LocalUsersModel
+
+ // Read Terraform configuration data into the model
+ resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
+
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ // Read API call logic
+ winResp, err := d.client.Local.UserList(ctx)
+ if err != nil {
+ resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to read local users, got error: %s", err))
+ return
+ }
+
+ var usersValueList []datasource_local_users.UsersValue
+
+ for _, user := range winResp {
+ usersValue := datasource_local_users.UsersValue{
+ AccountExpires: types.StringValue(user.AccountExpires.Format(time.RFC3339)),
+ Description: types.StringValue(user.Description),
+ Enabled: types.BoolValue(user.Enabled),
+ FullName: types.StringValue(user.FullName),
+ Id: types.StringValue(user.SID.Value),
+ LastLogon: types.StringValue(user.LastLogon.Format(time.RFC3339)),
+ Name: types.StringValue(user.Name),
+ PasswordChangeableDate: types.StringValue(user.PasswordChangeableDate.Format(time.RFC3339)),
+ PasswordExpires: types.StringValue(user.PasswordExpires.Format(time.RFC3339)),
+ PasswordLastSet: types.StringValue(user.PasswordLastSet.Format(time.RFC3339)),
+ PasswordRequired: types.BoolValue(user.PasswordRequired),
+ Sid: types.StringValue(user.SID.Value),
+ UserMayChangePassword: types.BoolValue(user.UserMayChangePassword),
+ }
+
+ objVal, _ := usersValue.ToObjectValue(ctx)
+ newUsersValue, _ := datasource_local_users.NewUsersValue(objVal.AttributeTypes(ctx), objVal.Attributes())
+
+ usersValueList = append(usersValueList, newUsersValue)
+ }
+
+ data.Users, _ = types.ListValueFrom(ctx, datasource_local_users.UsersValue{}.Type(ctx), usersValueList)
+
+ // Save data into Terraform state
+ resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
+}
diff --git a/internal/provider/provider.go b/internal/provider/provider.go
index 2b14d72..2cbb642 100644
--- a/internal/provider/provider.go
+++ b/internal/provider/provider.go
@@ -263,6 +263,7 @@ func (p *WindowsProvider) DataSources(ctx context.Context) []func() datasource.D
local.NewLocalGroupDataSource,
local.NewLocalGroupsDataSource,
local.NewLocalUserDataSource,
+ local.NewLocalUsersDataSource,
}
}
diff --git a/internal/schema/local_datasources.json b/internal/schema/local_datasources.json
index 9ef5ec4..e0027c3 100644
--- a/internal/schema/local_datasources.json
+++ b/internal/schema/local_datasources.json
@@ -9,31 +9,31 @@
"schema": {
"attributes": [
{
- "name": "name",
+ "name": "description",
"string": {
- "computed_optional_required": "optional",
- "description": "Define the name of the local security group."
+ "computed_optional_required": "computed",
+ "description": "The description of the local security group."
}
},
{
- "name": "sid",
+ "name": "id",
"string": {
- "computed_optional_required": "optional",
- "description": "Define the security ID of the local security group."
+ "computed_optional_required": "computed",
+ "description": "The ID of the retrieved local security group. This is the same as the SID."
}
},
{
- "name": "description",
+ "name": "name",
"string": {
- "computed_optional_required": "computed",
- "description": "The description of the local security group."
+ "computed_optional_required": "optional",
+ "description": "Define the name of the local security group."
}
},
{
- "name": "id",
+ "name": "sid",
"string": {
- "computed_optional_required": "computed",
- "description": "The ID of the retrieved local security group. This is the same as the SID."
+ "computed_optional_required": "optional",
+ "description": "Define the security ID of the local security group."
}
}
]
@@ -50,31 +50,31 @@
"nested_object": {
"attributes": [
{
- "name": "name",
+ "name": "description",
"string": {
"computed_optional_required": "computed",
- "description": "The name of the local security group."
+ "description": "The description of the local security group."
}
},
{
- "name": "sid",
+ "name": "id",
"string": {
"computed_optional_required": "computed",
- "description": "The security ID of the local security group."
+ "description": "The ID of the retrieved local security group. This is the same as the SID."
}
},
{
- "name": "description",
+ "name": "name",
"string": {
"computed_optional_required": "computed",
- "description": "The description of the local security group."
+ "description": "The name of the local security group."
}
},
{
- "name": "id",
+ "name": "sid",
"string": {
"computed_optional_required": "computed",
- "description": "The ID of the retrieved local security group. This is the same as the SID."
+ "description": "The security ID of the local security group."
}
}
]
@@ -92,7 +92,14 @@
"name": "account_expires",
"string": {
"computed_optional_required": "computed",
- "description": "Retrieve the time where the local user account expires."
+ "description": "Retrieve the time where the local user account expires.",
+ "custom_type": {
+ "import": {
+ "path": "github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes"
+ },
+ "type": "timetypes.RFC3339Type{}",
+ "value_type": "timetypes.RFC3339"
+ }
}
},
{
@@ -117,52 +124,80 @@
}
},
{
- "name": "password_changeable_date",
+ "name": "id",
"string": {
"computed_optional_required": "computed",
- "description": "The password changeable date of the local user."
+ "description": "The ID of the retrieved local user. This is the same as the SID."
}
},
{
- "name": "password_expires",
+ "name": "last_logon",
"string": {
"computed_optional_required": "computed",
- "description": "The time when the password of the local user expires."
+ "description": "The last logon time of the local user.",
+ "custom_type": {
+ "import": {
+ "path": "github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes"
+ },
+ "type": "timetypes.RFC3339Type{}",
+ "value_type": "timetypes.RFC3339"
+ }
}
},
{
- "name": "user_may_change_password",
- "bool": {
- "computed_optional_required": "computed",
- "description": "If true the local user can change it's password."
+ "name": "name",
+ "string": {
+ "computed_optional_required": "required",
+ "description": "Define the name of the local user."
}
},
{
- "name": "password_required",
- "bool": {
+ "name": "password_changeable_date",
+ "string": {
"computed_optional_required": "computed",
- "description": "If true a password is required login with the local user."
+ "description": "The password changeable date of the local user.",
+ "custom_type": {
+ "import": {
+ "path": "github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes"
+ },
+ "type": "timetypes.RFC3339Type{}",
+ "value_type": "timetypes.RFC3339"
+ }
}
},
{
- "name": "password_last_set",
+ "name": "password_expires",
"string": {
"computed_optional_required": "computed",
- "description": "The last time when the password was set for the local user."
+ "description": "The time when the password of the local user expires.",
+ "custom_type": {
+ "import": {
+ "path": "github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes"
+ },
+ "type": "timetypes.RFC3339Type{}",
+ "value_type": "timetypes.RFC3339"
+ }
}
},
{
- "name": "last_login",
+ "name": "password_last_set",
"string": {
"computed_optional_required": "computed",
- "description": "The last login time of the local user."
+ "description": "The last time when the password was set for the local user.",
+ "custom_type": {
+ "import": {
+ "path": "github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes"
+ },
+ "type": "timetypes.RFC3339Type{}",
+ "value_type": "timetypes.RFC3339"
+ }
}
},
{
- "name": "name",
- "string": {
- "computed_optional_required": "required",
- "description": "Define the name of the local user."
+ "name": "password_required",
+ "bool": {
+ "computed_optional_required": "computed",
+ "description": "If true a password is required login with the local user."
}
},
{
@@ -173,10 +208,153 @@
}
},
{
- "name": "id",
- "string": {
+ "name": "user_may_change_password",
+ "bool": {
"computed_optional_required": "computed",
- "description": "The ID of the retrieved local user. This is the same as the SID."
+ "description": "If true the local user can change it's password."
+ }
+ }
+ ]
+ }
+ },
+ {
+ "name": "local_users",
+ "schema": {
+ "attributes": [
+ {
+ "name": "users",
+ "list_nested": {
+ "computed_optional_required": "computed",
+ "nested_object": {
+ "attributes": [
+ {
+ "name": "account_expires",
+ "string": {
+ "computed_optional_required": "computed",
+ "description": "Retrieve the time where the local user account expires.",
+ "custom_type": {
+ "import": {
+ "path": "github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes"
+ },
+ "type": "timetypes.RFC3339Type{}",
+ "value_type": "timetypes.RFC3339"
+ }
+ }
+ },
+ {
+ "name": "description",
+ "string": {
+ "computed_optional_required": "computed",
+ "description": "The description of the local user."
+ }
+ },
+ {
+ "name": "enabled",
+ "bool": {
+ "computed_optional_required": "computed",
+ "description": "Get the status of the local user."
+ }
+ },
+ {
+ "name": "full_name",
+ "string": {
+ "computed_optional_required": "computed",
+ "description": "The full name of the local user."
+ }
+ },
+ {
+ "name": "id",
+ "string": {
+ "computed_optional_required": "computed",
+ "description": "The ID of the retrieved local user. This is the same as the SID."
+ }
+ },
+ {
+ "name": "last_logon",
+ "string": {
+ "computed_optional_required": "computed",
+ "description": "The last logon time of the local user.",
+ "custom_type": {
+ "import": {
+ "path": "github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes"
+ },
+ "type": "timetypes.RFC3339Type{}",
+ "value_type": "timetypes.RFC3339"
+ }
+ }
+ },
+ {
+ "name": "name",
+ "string": {
+ "computed_optional_required": "required",
+ "description": "Define the name of the local user."
+ }
+ },
+ {
+ "name": "password_changeable_date",
+ "string": {
+ "computed_optional_required": "computed",
+ "description": "The password changeable date of the local user.",
+ "custom_type": {
+ "import": {
+ "path": "github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes"
+ },
+ "type": "timetypes.RFC3339Type{}",
+ "value_type": "timetypes.RFC3339"
+ }
+ }
+ },
+ {
+ "name": "password_expires",
+ "string": {
+ "computed_optional_required": "computed",
+ "description": "The time when the password of the local user expires.",
+ "custom_type": {
+ "import": {
+ "path": "github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes"
+ },
+ "type": "timetypes.RFC3339Type{}",
+ "value_type": "timetypes.RFC3339"
+ }
+ }
+ },
+ {
+ "name": "password_last_set",
+ "string": {
+ "computed_optional_required": "computed",
+ "description": "The last time when the password was set for the local user.",
+ "custom_type": {
+ "import": {
+ "path": "github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes"
+ },
+ "type": "timetypes.RFC3339Type{}",
+ "value_type": "timetypes.RFC3339"
+ }
+ }
+ },
+ {
+ "name": "password_required",
+ "bool": {
+ "computed_optional_required": "computed",
+ "description": "If true a password is required login with the local user."
+ }
+ },
+ {
+ "name": "sid",
+ "string": {
+ "computed_optional_required": "optional",
+ "description": "The security ID of the local user."
+ }
+ },
+ {
+ "name": "user_may_change_password",
+ "bool": {
+ "computed_optional_required": "computed",
+ "description": "If true the local user can change it's password."
+ }
+ }
+ ]
+ }
}
}
]
diff --git a/internal/schema/local_resources.json b/internal/schema/local_resources.json
index 92c7d04..b937075 100644
--- a/internal/schema/local_resources.json
+++ b/internal/schema/local_resources.json
@@ -8,56 +8,6 @@
"name": "local_group",
"schema": {
"attributes": [
- {
- "name": "name",
- "string": {
- "computed_optional_required": "required",
- "description": "Define the name for the local security group. The maximum length is 256 characters.",
- "validators": [
- {
- "custom": {
- "imports": [
- {
- "path": "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
- }
- ],
- "schema_definition": "stringvalidator.LengthBetween(1, 256)"
- }
- }
- ],
- "plan_modifiers": [
- {
- "custom": {
- "imports": [
- {
- "path": "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
- }
- ],
- "schema_definition": "stringplanmodifier.RequiresReplace()"
- }
- }
- ]
- }
- },
- {
- "name": "sid",
- "string": {
- "computed_optional_required": "computed",
- "description": "The security ID of the local security group.",
- "plan_modifiers": [
- {
- "custom": {
- "imports": [
- {
- "path": "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
- }
- ],
- "schema_definition": "stringplanmodifier.UseStateForUnknown()"
- }
- }
- ]
- }
- },
{
"name": "description",
"string": {
@@ -98,19 +48,12 @@
}
]
}
- }
- ]
- }
- },
- {
- "name": "local_user",
- "schema": {
- "attributes": [
+ },
{
"name": "name",
"string": {
"computed_optional_required": "required",
- "description": "Define the name for the local user. A user name can contain up to 20 uppercase characters or lowercase characters. A user name can't contain the following characters: `\"`, `/`, `\\`, `[`, `]`, `:`, `;`, `|`, `=`, `,`, `+`, `*`, `?`, `<`, `>`, `@`",
+ "description": "Define the name for the local security group. The maximum length is 256 characters.",
"validators": [
{
"custom": {
@@ -119,7 +62,7 @@
"path": "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
}
],
- "schema_definition": "stringvalidator.LengthBetween(1, 20)"
+ "schema_definition": "stringvalidator.LengthBetween(1, 256)"
}
}
],
@@ -141,7 +84,7 @@
"name": "sid",
"string": {
"computed_optional_required": "computed",
- "description": "The security ID of the local user.",
+ "description": "The security ID of the local security group.",
"plan_modifiers": [
{
"custom": {
@@ -155,13 +98,36 @@
}
]
}
+ }
+ ]
+ }
+ },
+ {
+ "name": "local_user",
+ "schema": {
+ "attributes": [
+ {
+ "name": "account_expires",
+ "string": {
+ "computed_optional_required": "computed_optional",
+ "description": "Define when the local user account expires. If not specified, the user account never expires.
The string time format is the following: `2023-07-25T20:43:16Z` (see [Terraform timetypes](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework-timetypes@v0.3.0/timetypes#RFC3339)).",
+ "custom_type": {
+ "import": {
+ "path": "github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes"
+ },
+ "type": "timetypes.RFC3339Type{}",
+ "value_type": "timetypes.RFC3339"
+ },
+ "default": {
+ "static": "0001-01-01T00:00:00Z"
+ }
+ }
},
{
- "name": "password",
+ "name": "description",
"string": {
- "computed_optional_required": "optional",
- "sensitive": true,
- "description": "Define a password for the local user. A password can contain up to 127 characters.",
+ "computed_optional_required": "computed_optional",
+ "description": "Define a description for the local user. The maximum length is 48 characters.",
"validators": [
{
"custom": {
@@ -170,10 +136,23 @@
"path": "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
}
],
- "schema_definition": "stringvalidator.LengthBetween(1, 127)"
+ "schema_definition": "stringvalidator.LengthAtMost(48)"
}
}
- ]
+ ],
+ "default": {
+ "static": ""
+ }
+ }
+ },
+ {
+ "name": "enabled",
+ "bool": {
+ "computed_optional_required": "computed_optional",
+ "description": "(Default: `true`)
Define whether the local user is enabled.",
+ "default": {
+ "static": true
+ }
}
},
{
@@ -181,6 +160,16 @@
"string": {
"computed_optional_required": "computed_optional",
"description": "Define the full name of the local user. The full name differs from the user name of the user account.",
+ "default": {
+ "static": ""
+ }
+ }
+ },
+ {
+ "name": "id",
+ "string": {
+ "computed_optional_required": "computed",
+ "description": "The ID of the retrieved local security group. This is the same as the SID.",
"plan_modifiers": [
{
"custom": {
@@ -196,41 +185,49 @@
}
},
{
- "name": "description",
+ "name": "last_logon",
"string": {
- "computed_optional_required": "computed_optional",
- "description": "Define a description for the local user. The maximum length is 48 characters.",
- "plan_modifiers": [
+ "computed_optional_required": "computed",
+ "description": "The last logon time of the local user.",
+ "custom_type": {
+ "import": {
+ "path": "github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes"
+ },
+ "type": "timetypes.RFC3339Type{}",
+ "value_type": "timetypes.RFC3339"
+ }
+ }
+ },
+ {
+ "name": "name",
+ "string": {
+ "computed_optional_required": "required",
+ "description": "Define the name for the local user. A user name can contain up to 20 uppercase characters or lowercase characters. A user name can't contain the following characters: `\"`, `/`, `\\`, `[`, `]`, `:`, `;`, `|`, `=`, `,`, `+`, `*`, `?`, `<`, `>`, `@`",
+ "validators": [
{
"custom": {
"imports": [
{
- "path": "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
+ "path": "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
}
],
- "schema_definition": "stringplanmodifier.UseStateForUnknown()"
+ "schema_definition": "stringvalidator.LengthBetween(1, 20)"
}
- }
- ],
- "validators": [
+ },
{
"custom": {
"imports": [
{
"path": "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
+ },
+ {
+ "path": "regexp"
}
],
- "schema_definition": "stringvalidator.LengthBetween(1, 48)"
+ "schema_definition": "stringvalidator.RegexMatches(regexp.MustCompile(`^[^\"\/\\[\\]:;|=,+*?<>\\@]+$`), `cannot contain the following characters: \"/\\[]:;|=,+*?<>@ `)"
}
}
- ]
- }
- },
- {
- "name": "id",
- "string": {
- "computed_optional_required": "computed",
- "description": "The ID of the retrieved local security group. This is the same as the SID.",
+ ],
"plan_modifiers": [
{
"custom": {
@@ -239,73 +236,82 @@
"path": "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
}
],
- "schema_definition": "stringplanmodifier.UseStateForUnknown()"
+ "schema_definition": "stringplanmodifier.RequiresReplace()"
}
}
]
}
},
{
- "name": "account_expires",
+ "name": "password",
"string": {
- "computed_optional_required": "computed_optional",
- "description": "Define when the local user account expires (UTC). If not specified, the user account never expires.
The string time format is the following: `yyyy-MM-dd hh:mm:ss` (see [go time package](https://pkg.go.dev/time#pkg-constants) `DateTime`).",
- "plan_modifiers": [
+ "computed_optional_required": "optional",
+ "sensitive": true,
+ "description": "Define a password for the local user. A password can contain up to 127 characters.",
+ "validators": [
{
"custom": {
"imports": [
{
- "path": "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
+ "path": "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
}
],
- "schema_definition": "stringplanmodifier.UseStateForUnknown()"
+ "schema_definition": "stringvalidator.LengthBetween(1, 127)"
}
}
]
}
},
{
- "name": "enabled",
- "bool": {
- "computed_optional_required": "computed_optional",
- "description": "(Default: `true`)
Define whether the local user is enabled.",
- "default": {
- "static": true
+ "name": "password_changeable_date",
+ "string": {
+ "computed_optional_required": "computed",
+ "description": "The password changeable date of the local user.",
+ "custom_type": {
+ "import": {
+ "path": "github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes"
+ },
+ "type": "timetypes.RFC3339Type{}",
+ "value_type": "timetypes.RFC3339"
}
}
},
{
- "name": "password_never_expires",
- "bool": {
- "computed_optional_required": "computed_optional",
- "description": "(Default: `true`)
Define whether the password of the local user.",
- "default": {
- "static": true
+ "name": "password_expires",
+ "string": {
+ "computed_optional_required": "computed",
+ "description": "The time when the password of the local user expires.",
+ "custom_type": {
+ "import": {
+ "path": "github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes"
+ },
+ "type": "timetypes.RFC3339Type{}",
+ "value_type": "timetypes.RFC3339"
}
}
},
{
- "name": "user_may_change_password",
+ "name": "password_never_expires",
"bool": {
"computed_optional_required": "computed_optional",
- "description": "(Default: `true`)
Define whether the local user can change it's own password.",
+ "description": "(Default: `true`)
Define whether the password of the local user.",
"default": {
"static": true
}
}
},
{
- "name": "password_changeable_date",
- "string": {
- "computed_optional_required": "computed",
- "description": "The password changeable date of the local user."
- }
- },
- {
- "name": "password_expires",
+ "name": "password_last_set",
"string": {
"computed_optional_required": "computed",
- "description": "The time when the password of the local user expires."
+ "description": "The last time when the password was set for the local user.",
+ "custom_type": {
+ "import": {
+ "path": "github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes"
+ },
+ "type": "timetypes.RFC3339Type{}",
+ "value_type": "timetypes.RFC3339"
+ }
}
},
{
@@ -316,17 +322,32 @@
}
},
{
- "name": "password_last_set",
+ "name": "sid",
"string": {
"computed_optional_required": "computed",
- "description": "The last time when the password was set for the local user."
+ "description": "The security ID of the local user.",
+ "plan_modifiers": [
+ {
+ "custom": {
+ "imports": [
+ {
+ "path": "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
+ }
+ ],
+ "schema_definition": "stringplanmodifier.UseStateForUnknown()"
+ }
+ }
+ ]
}
},
{
- "name": "last_login",
- "string": {
- "computed_optional_required": "computed",
- "description": "The last login time of the local user."
+ "name": "user_may_change_password",
+ "bool": {
+ "computed_optional_required": "computed_optional",
+ "description": "(Default: `true`)
Define whether the local user can change it's own password.",
+ "default": {
+ "static": true
+ }
}
}
]
diff --git a/internal/schema/provider_windows.json b/internal/schema/provider_windows.json
index 623ea23..22da447 100644
--- a/internal/schema/provider_windows.json
+++ b/internal/schema/provider_windows.json
@@ -12,135 +12,135 @@
}
},
{
- "name": "winrm",
+ "name": "kerberos",
"single_nested": {
"optional_required": "optional",
- "description": "Define the WinRM connection parameters. Exactly one of 'winrm' or 'ssh' must be set for the provider to connect to a Windows target system. Define an empty 'winrm' attribute if you wish to use the environment variables.",
+ "description": "Define the Kerberos connection parameters. Currently this can only be combined with a WinRM connection.",
"attributes": [
{
- "name": "username",
+ "name": "krb_config_file",
"string": {
"optional_required": "optional",
- "description": "(Env: `WIN_WINRM_USERNAME`)
Define the username to connect with the target Windows system. Required if winrm is set."
+ "description": "(Env: `WIN_KRB_CONFIG_FILE`)
Define the path to the kerberos configuration file. Required if kerberos is set."
}
},
{
- "name": "password",
+ "name": "realm",
"string": {
"optional_required": "optional",
- "description": "(Env: `WIN_WINRM_PASSWORD`)
Define the password to connect with the target Windows system. Required if winrm is set.",
- "sensitive": true
+ "description": "(Env: `WIN_KRB_REALM`)
Define the Kerberos realm. Required if kerberos is set."
}
- },
+ }
+ ]
+ }
+ },
+ {
+ "name": "ssh",
+ "single_nested": {
+ "optional_required": "optional",
+ "description": "Define the SSH connection parameters. Exactly one of 'winrm' or 'ssh' must be set for the provider to connect to a Windows target system. Define an empty 'ssh' attribute if you wish to use the environment variables.",
+ "attributes": [
{
- "name": "use_tls",
+ "name": "insecure",
"bool": {
"optional_required": "optional",
- "description": "(Env: `WIN_WINRM_USE_TLS`) (Default: `true`)
Define if TLS (https) should be used to connect with the target Windows system."
+ "description": "(Env: `WIN_SSH_INSECURE`) (Default: `false`)
Accept insecure SSH connections. This includes e.g. the acceptance of unknown or changed host keys."
}
},
{
- "name": "port",
- "int64": {
+ "name": "known_hosts_path",
+ "string": {
"optional_required": "optional",
- "description": "(Env: `WIN_WINRM_PORT`) (Default: `5986`)
Define the port to connect with the target Windows system."
+ "description": "(Env: `WIN_SSH_KNOWN_HOSTS_PATH`)
Define the path to the known hosts file to connect with the target Windows system."
}
},
{
- "name": "insecure",
- "bool": {
+ "name": "password",
+ "string": {
"optional_required": "optional",
- "description": "(Env: `WIN_WINRM_INSECURE`) (Default: `false`)
Accept insecure WinRM connection. This includes e.g. the acceptance of untrusted certificates."
+ "sensitive": true,
+ "description": "(Env: `WIN_SSH_PASSWORD`)
Define the password to connect with the target Windows system. Exactly one of 'password', 'private_key' or 'private_key_path' is required if ssh is set."
}
},
{
- "name": "timeout",
+ "name": "port",
"int64": {
"optional_required": "optional",
- "description": "(Env: `WIN_WINRM_TIMEOUT`) (Default: `0`)
Define the connection timeout in minutes for the target Windows system."
+ "description": "(Env: `WIN_SSH_PORT`) (Default: `22`)
Define the port to connect with the target Windows system."
}
- }
- ]
- }
- },
- {
- "name": "kerberos",
- "single_nested": {
- "optional_required": "optional",
- "description": "Define the Kerberos connection parameters. Currently this can only be combined with a WinRM connection.",
- "attributes": [
+ },
{
- "name": "realm",
+ "name": "private_key",
"string": {
"optional_required": "optional",
- "description": "(Env: `WIN_KRB_REALM`)
Define the Kerberos realm. Required if kerberos is set."
+ "sensitive": true,
+ "description": "(Env: `WIN_SSH_PRIVATE_KEY`)
Define the private key to connect with the target Windows system. Exactly one of 'password', 'private_key' or 'private_key_path' is required if ssh is set."
}
},
{
- "name": "krb_config_file",
+ "name": "private_key_path",
"string": {
"optional_required": "optional",
- "description": "(Env: `WIN_KRB_CONFIG_FILE`)
Define the path to the kerberos configuration file. Required if kerberos is set."
+ "description": "(Env: `WIN_SSH_PRIVATE_KEY_PATH`)
Define the path to the private key file to connect with the target Windows system. Exactly one of 'password', 'private_key' or 'private_key_path' is required if ssh is set."
+ }
+ },
+ {
+ "name": "username",
+ "string": {
+ "optional_required": "optional",
+ "description": "(Env: `WIN_SSH_USERNAME`)
Define the username to connect with the target Windows system. Required if ssh is set."
}
}
]
}
},
{
- "name": "ssh",
+ "name": "winrm",
"single_nested": {
"optional_required": "optional",
- "description": "Define the SSH connection parameters. Exactly one of 'winrm' or 'ssh' must be set for the provider to connect to a Windows target system. Define an empty 'ssh' attribute if you wish to use the environment variables.",
+ "description": "Define the WinRM connection parameters. Exactly one of 'winrm' or 'ssh' must be set for the provider to connect to a Windows target system. Define an empty 'winrm' attribute if you wish to use the environment variables.",
"attributes": [
{
- "name": "username",
- "string": {
+ "name": "insecure",
+ "bool": {
"optional_required": "optional",
- "description": "(Env: `WIN_SSH_USERNAME`)
Define the username to connect with the target Windows system. Required if ssh is set."
+ "description": "(Env: `WIN_WINRM_INSECURE`) (Default: `false`)
Accept insecure WinRM connection. This includes e.g. the acceptance of untrusted certificates."
}
},
{
"name": "password",
"string": {
"optional_required": "optional",
- "sensitive": true,
- "description": "(Env: `WIN_SSH_PASSWORD`)
Define the password to connect with the target Windows system. Exactly one of 'password', 'private_key' or 'private_key_path' is required if ssh is set."
- }
- },
- {
- "name": "private_key",
- "string": {
- "optional_required": "optional",
- "sensitive": true,
- "description": "(Env: `WIN_SSH_PRIVATE_KEY`)
Define the private key to connect with the target Windows system. Exactly one of 'password', 'private_key' or 'private_key_path' is required if ssh is set."
+ "description": "(Env: `WIN_WINRM_PASSWORD`)
Define the password to connect with the target Windows system. Required if winrm is set.",
+ "sensitive": true
}
},
{
- "name": "private_key_path",
- "string": {
+ "name": "port",
+ "int64": {
"optional_required": "optional",
- "description": "(Env: `WIN_SSH_PRIVATE_KEY_PATH`)
Define the path to the private key file to connect with the target Windows system. Exactly one of 'password', 'private_key' or 'private_key_path' is required if ssh is set."
+ "description": "(Env: `WIN_WINRM_PORT`) (Default: `5986`)
Define the port to connect with the target Windows system."
}
},
{
- "name": "known_hosts_path",
- "string": {
+ "name": "timeout",
+ "int64": {
"optional_required": "optional",
- "description": "(Env: `WIN_SSH_KNOWN_HOSTS_PATH`)
Define the path to the known hosts file to connect with the target Windows system."
+ "description": "(Env: `WIN_WINRM_TIMEOUT`) (Default: `0`)
Define the connection timeout in minutes for the target Windows system."
}
},
{
- "name": "insecure",
+ "name": "use_tls",
"bool": {
"optional_required": "optional",
- "description": "(Env: `WIN_SSH_INSECURE`) (Default: `false`)
Accept insecure SSH connections. This includes e.g. the acceptance of unknown or changed host keys."
+ "description": "(Env: `WIN_WINRM_USE_TLS`) (Default: `true`)
Define if TLS (https) should be used to connect with the target Windows system."
}
},
{
- "name": "port",
- "int64": {
+ "name": "username",
+ "string": {
"optional_required": "optional",
- "description": "(Env: `WIN_SSH_PORT`) (Default: `22`)
Define the port to connect with the target Windows system."
+ "description": "(Env: `WIN_WINRM_USERNAME`)
Define the username to connect with the target Windows system. Required if winrm is set."
}
}
]