mirror of
https://github.com/hanzokms/terraform-provider.git
synced 2026-10-30 20:29:45 +00:00
228 lines
8.2 KiB
Go
228 lines
8.2 KiB
Go
package resource
|
|
|
|
import (
|
|
"context"
|
|
kmsclient "github.com/hanzokms/terraform-provider/internal/client"
|
|
"strings"
|
|
|
|
"github.com/hashicorp/terraform-plugin-framework/attr"
|
|
"github.com/hashicorp/terraform-plugin-framework/diag"
|
|
"github.com/hashicorp/terraform-plugin-framework/resource"
|
|
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
|
|
"github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault"
|
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
|
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
|
|
)
|
|
|
|
// AppConnectionLdapCredentialsModel describes the data source data model.
|
|
type AppConnectionLdapCredentialsModel struct {
|
|
Provider types.String `tfsdk:"provider"`
|
|
Url types.String `tfsdk:"url"`
|
|
Dn types.String `tfsdk:"dn"`
|
|
Password types.String `tfsdk:"password"`
|
|
SslRejectUnauthorized types.Bool `tfsdk:"ssl_reject_unauthorized"`
|
|
SslCertificate types.String `tfsdk:"ssl_certificate"`
|
|
}
|
|
|
|
const AppConnectionLdapAuthMethodSimpleBind = "simple-bind"
|
|
|
|
func NewAppConnectionLdapResource() resource.Resource {
|
|
return &AppConnectionBaseResource{
|
|
App: kmsclient.AppConnectionAppLdap,
|
|
AppConnectionName: "LDAP",
|
|
ResourceTypeName: "_app_connection_ldap",
|
|
AllowedMethods: []string{AppConnectionLdapAuthMethodSimpleBind},
|
|
CredentialsAttributes: map[string]schema.Attribute{
|
|
"provider": schema.StringAttribute{
|
|
Required: true,
|
|
Description: "The LDAP provider (e.g., 'active-directory').",
|
|
},
|
|
"url": schema.StringAttribute{
|
|
Required: true,
|
|
Description: "The LDAP server URL (e.g., 'ldap://example.com:389' or 'ldaps://example.com:636').",
|
|
},
|
|
"dn": schema.StringAttribute{
|
|
Required: true,
|
|
Description: "The Distinguished Name (DN) or User Principal Name (UPN) of the principal to bind with (e.g., 'CN=John,CN=Users,DC=example,DC=com').",
|
|
},
|
|
"password": schema.StringAttribute{
|
|
Required: true,
|
|
Description: "The password to bind with for authentication.",
|
|
Sensitive: true,
|
|
},
|
|
"ssl_reject_unauthorized": schema.BoolAttribute{
|
|
Optional: true,
|
|
Computed: true,
|
|
Description: "Whether or not to reject unauthorized SSL certificates (true/false) when using ldaps://. Set to false only in test environments.",
|
|
Default: booldefault.StaticBool(true),
|
|
},
|
|
"ssl_certificate": schema.StringAttribute{
|
|
Optional: true,
|
|
Description: "The SSL certificate (PEM format) to use for secure connection when using ldaps:// with a self-signed certificate.",
|
|
},
|
|
},
|
|
ReadCredentialsForCreateFromPlan: func(ctx context.Context, plan AppConnectionBaseResourceModel) (map[string]any, diag.Diagnostics) {
|
|
credentialsConfig := make(map[string]any)
|
|
|
|
var credentials AppConnectionLdapCredentialsModel
|
|
diags := plan.Credentials.As(ctx, &credentials, basetypes.ObjectAsOptions{})
|
|
if diags.HasError() {
|
|
return nil, diags
|
|
}
|
|
|
|
if plan.Method.ValueString() != AppConnectionLdapAuthMethodSimpleBind {
|
|
diags.AddError(
|
|
"Unable to create LDAP app connection",
|
|
"Invalid method. Only simple-bind method is supported",
|
|
)
|
|
return nil, diags
|
|
}
|
|
|
|
credentialsConfig["provider"] = credentials.Provider.ValueString()
|
|
credentialsConfig["url"] = credentials.Url.ValueString()
|
|
credentialsConfig["dn"] = credentials.Dn.ValueString()
|
|
credentialsConfig["password"] = credentials.Password.ValueString()
|
|
|
|
// Validate SSL settings based on URL scheme
|
|
url := credentials.Url.ValueString()
|
|
isLdaps := strings.HasPrefix(strings.ToLower(url), "ldaps://")
|
|
|
|
if !isLdaps {
|
|
// For ldap:// URLs, SSL is not used
|
|
if !credentials.SslRejectUnauthorized.IsNull() && credentials.SslRejectUnauthorized.ValueBool() {
|
|
diags.AddError(
|
|
"Invalid SSL configuration",
|
|
"ssl_reject_unauthorized cannot be true for ldap:// URLs since they don't use SSL. Use ldaps:// for secure connections or set ssl_reject_unauthorized to false.",
|
|
)
|
|
return nil, diags
|
|
}
|
|
// Default to false for ldap:// URLs
|
|
credentialsConfig["sslRejectUnauthorized"] = false
|
|
} else {
|
|
credentialsConfig["sslRejectUnauthorized"] = credentials.SslRejectUnauthorized.ValueBool()
|
|
}
|
|
|
|
if !credentials.SslCertificate.IsNull() {
|
|
credentialsConfig["sslCertificate"] = credentials.SslCertificate.ValueString()
|
|
}
|
|
|
|
return credentialsConfig, diags
|
|
},
|
|
ReadCredentialsForUpdateFromPlan: func(ctx context.Context, plan AppConnectionBaseResourceModel, state AppConnectionBaseResourceModel) (map[string]any, diag.Diagnostics) {
|
|
credentialsConfig := make(map[string]any)
|
|
|
|
var credentialsFromPlan AppConnectionLdapCredentialsModel
|
|
diags := plan.Credentials.As(ctx, &credentialsFromPlan, basetypes.ObjectAsOptions{})
|
|
if diags.HasError() {
|
|
return nil, diags
|
|
}
|
|
|
|
var credentialsFromState AppConnectionLdapCredentialsModel
|
|
diags = state.Credentials.As(ctx, &credentialsFromState, basetypes.ObjectAsOptions{})
|
|
if diags.HasError() {
|
|
return nil, diags
|
|
}
|
|
|
|
if plan.Method.ValueString() != AppConnectionLdapAuthMethodSimpleBind {
|
|
diags.AddError(
|
|
"Unable to update LDAP app connection",
|
|
"Invalid method. Only simple-bind method is supported",
|
|
)
|
|
return nil, diags
|
|
}
|
|
|
|
provider := credentialsFromPlan.Provider
|
|
if credentialsFromPlan.Provider.IsUnknown() {
|
|
provider = credentialsFromState.Provider
|
|
}
|
|
if !provider.IsNull() {
|
|
credentialsConfig["provider"] = provider.ValueString()
|
|
}
|
|
|
|
url := credentialsFromPlan.Url
|
|
if credentialsFromPlan.Url.IsUnknown() {
|
|
url = credentialsFromState.Url
|
|
}
|
|
|
|
finalUrlString := ""
|
|
if !url.IsNull() {
|
|
finalUrlString = url.ValueString()
|
|
credentialsConfig["url"] = url.ValueString()
|
|
}
|
|
|
|
dn := credentialsFromPlan.Dn
|
|
if credentialsFromPlan.Dn.IsUnknown() {
|
|
dn = credentialsFromState.Dn
|
|
}
|
|
if !dn.IsNull() {
|
|
credentialsConfig["dn"] = dn.ValueString()
|
|
}
|
|
|
|
password := credentialsFromPlan.Password
|
|
if credentialsFromPlan.Password.IsUnknown() {
|
|
password = credentialsFromState.Password
|
|
}
|
|
if !password.IsNull() {
|
|
credentialsConfig["password"] = password.ValueString()
|
|
}
|
|
|
|
// Validate SSL settings based on URL scheme for updates
|
|
isLdaps := strings.HasPrefix(strings.ToLower(finalUrlString), "ldaps://")
|
|
|
|
sslRejectUnauthorized := credentialsFromPlan.SslRejectUnauthorized
|
|
if credentialsFromPlan.SslRejectUnauthorized.IsUnknown() {
|
|
sslRejectUnauthorized = credentialsFromState.SslRejectUnauthorized
|
|
}
|
|
|
|
if !isLdaps {
|
|
// For ldap:// URLs, SSL is not used
|
|
if !sslRejectUnauthorized.IsNull() && sslRejectUnauthorized.ValueBool() {
|
|
diags.AddError(
|
|
"Invalid SSL configuration",
|
|
"ssl_reject_unauthorized cannot be true for ldap:// URLs since they don't use SSL. Use ldaps:// for secure connections or set ssl_reject_unauthorized to false.",
|
|
)
|
|
return nil, diags
|
|
}
|
|
// Always set to false for ldap:// URLs, regardless of state
|
|
credentialsConfig["sslRejectUnauthorized"] = false
|
|
} else {
|
|
if !sslRejectUnauthorized.IsNull() {
|
|
credentialsConfig["sslRejectUnauthorized"] = sslRejectUnauthorized.ValueBool()
|
|
}
|
|
}
|
|
|
|
sslCertificate := credentialsFromPlan.SslCertificate
|
|
if credentialsFromPlan.SslCertificate.IsUnknown() {
|
|
sslCertificate = credentialsFromState.SslCertificate
|
|
}
|
|
if !sslCertificate.IsNull() {
|
|
credentialsConfig["sslCertificate"] = sslCertificate.ValueString()
|
|
}
|
|
|
|
return credentialsConfig, diags
|
|
},
|
|
OverwriteCredentialsFields: func(state *AppConnectionBaseResourceModel) diag.Diagnostics {
|
|
credentialsConfig := map[string]attr.Value{
|
|
"provider": types.StringNull(),
|
|
"url": types.StringNull(),
|
|
"dn": types.StringNull(),
|
|
"password": types.StringNull(),
|
|
"ssl_reject_unauthorized": types.BoolNull(),
|
|
"ssl_certificate": types.StringNull(),
|
|
}
|
|
|
|
var diags diag.Diagnostics
|
|
state.Credentials, diags = types.ObjectValue(map[string]attr.Type{
|
|
"provider": types.StringType,
|
|
"url": types.StringType,
|
|
"dn": types.StringType,
|
|
"password": types.StringType,
|
|
"ssl_reject_unauthorized": types.BoolType,
|
|
"ssl_certificate": types.StringType,
|
|
}, credentialsConfig)
|
|
|
|
return diags
|
|
},
|
|
}
|
|
}
|