diff --git a/docs/resources/directory_service_auth_provider.md b/docs/resources/directory_service_auth_provider.md
new file mode 100644
index 00000000..cbd0a186
--- /dev/null
+++ b/docs/resources/directory_service_auth_provider.md
@@ -0,0 +1,287 @@
+---
+# generated by https://github.com/hashicorp/terraform-plugin-docs
+page_title: "redfish_directory_service_auth_provider Resource - terraform-provider-redfish"
+subcategory: ""
+description: |-
+ This Terraform resource is used to configure Directory Service Auth Provider Active Directory and LDAP Service We can Read the existing configurations or modify them using this resource.
+---
+
+# redfish_directory_service_auth_provider (Resource)
+
+This Terraform resource is used to configure Directory Service Auth Provider Active Directory and LDAP Service We can Read the existing configurations or modify them using this resource.
+
+## Example Usage
+
+```terraform
+/*
+Copyright (c) 2024 Dell Inc., or its subsidiaries. All Rights Reserved.
+
+Licensed under the Mozilla Public License Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://mozilla.org/MPL/2.0/
+
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+data "local_file" "kerberos" {
+ # this is the path to the kerberos keytab file that we want to upload.
+ # this file must be base64 encoded format
+ filename = "/root/directoryservice/new/terraform-provider-redfish/test-data/kerberos_file.txt"
+}
+
+# redfish_directory_service_auth_provider Terraform resource is used to configure Directory Service Auth Provider Active Directory and LDAP Service
+# Available action: Create, Update (Active Directory, LDAP)
+# Active Directory (Create, Update): remote_role_mapping, service_addresses, service_enabled,authentication, active_directory_attributes
+# LDAP (Create, Update): remote_role_mapping, service_addresses, service_enabled,ldap_service, ldap_attributes
+resource "redfish_directory_service_auth_provider" "ds_auth" {
+ for_each = var.rack1
+
+ redfish_server {
+ user = each.value.user
+ password = each.value.password
+ endpoint = each.value.endpoint
+ ssl_insecure = each.value.ssl_insecure
+ }
+
+ #Note: `active_directory` is mutually inclusive with `active_directory_attributes`.
+ #Note: `ldap` is mutually inclusive with `ldap_attributes`.
+ #Note: `active_directory` is mutually exclusive with `ldap`.
+ #Note: `active_directory_attributes` is mutually exclusive with `ldap_attributes`.
+ active_directory = {
+ directory = {
+ # remote_role_mapping = [
+ # {
+ # local_role = "None",
+ # remote_group = "idracgroup"
+ # }
+ # ],
+ # service_addresses = [
+ # "yulanadhost11.yulan.pie.lab.emc.com"
+ # ],
+ service_enabled = true,
+ authentication = {
+ kerberos_key_tab_file = data.local_file.kerberos.content
+ }
+ }
+ }
+
+ active_directory_attributes = {
+ "ActiveDirectory.1.AuthTimeout" = "120",
+ "ActiveDirectory.1.CertValidationEnable" = "Enabled",
+ "ActiveDirectory.1.DCLookupEnable" = "Enabled",
+
+ # RacName and RacDomain can be configured when Schema is Extended Schema
+ "ActiveDirectory.1.RacDomain" = "test",
+ "ActiveDirectory.1.RacName" = "test",
+
+ # if SSOEnable is Enabled make sure ActiveDirectory Service is enabled and valid kerberos_key_tab_file is provided
+ "ActiveDirectory.1.SSOEnable" = "Disabled",
+
+ # Schema can be Extended Schema or Standard Schema
+ "ActiveDirectory.1.Schema" = "Extended Schema",
+ "UserDomain.1.Name" = "yulan.pie.lab.emc.com",
+
+ # DCLookupByUserDomain must be configured when DCLookupEnable is enabled
+ "ActiveDirectory.1.DCLookupByUserDomain" : "Enabled",
+
+ # DCLookupDomainName must be configured when DCLookupByUserDomain is Disabled and DCLookupEnable is Enabled
+ #"ActiveDirectory.1.DCLookupDomainName"="test",
+
+ #"ActiveDirectory.1.GCLookupEnable" = "Disabled"
+
+ # at least any one from GlobalCatalog1,GlobalCatalog2,GlobalCatalog3 must be configured when Schema is Standard and GCLookupEnable is Disabled
+ # "ActiveDirectory.1.GlobalCatalog1" = "yulanadhost11.yulan.pie.lab.emc.com",
+ # "ActiveDirectory.1.GlobalCatalog2" = "yulanadhost11.yulan.pie.lab.emc.com",
+ # "ActiveDirectory.1.GlobalCatalog3" = "yulanadhost11.yulan.pie.lab.emc.com",
+
+ # GCRootDomain can be configured when GCLookupEnable is Enabled
+ #"ActiveDirectory.1.GCRootDomain" = "test"
+
+ # RSA Secure configuration required Datacenter license
+ #"LDAP.1.RSASecurID2FALDAP":"Enabled",
+ #"RSASecurID2FA.1.RSASecurIDAccessKey": "●●1",
+ #"RSASecurID2FA.1.RSASecurIDClientID": "●●1",
+ #"RSASecurID2FA.1.RSASecurIDAuthenticationServer": "",
+ }
+
+
+
+ # ldap = {
+ # directory = {
+ # remote_role_mapping = [
+ # {
+ # local_role = "Administrator",
+ # remote_group = "cn = idracgroup,cn = users,dc = yulan,dc = pie,dc = lab,dc = emc,dc = com"
+ # }
+ # ],
+ # service_addresses = [
+ # "yulanadhost12.yulan.pie.lab.emc.com"
+ # ],
+ # service_enabled = false
+ # },
+ # ldap_service = {
+ # search_settings = {
+ # base_distinguished_names = [
+ # "dc = yulan,dc = pie,dc = lab,dc = emc,dc = com"
+ # ],
+ # group_name_attribute = "name",
+ # user_name_attribute = "member"
+ # }
+ # }
+ # }
+ #
+ # ldap_attributes = {
+ # "LDAP.1.GroupAttributeIsDN" = "Enabled"
+ # "LDAP.1.Port" = "636",
+ # "LDAP.1.BindDN" = "cn = adtester,cn = users,dc = yulan,dc = pie,dc = lab,dc = emc,dc = com",
+ # "LDAP.1.BindPassword" = "",
+ # "LDAP.1.SearchFilter" = "(objectclass = *)",
+ #
+ # #"LDAP.1.RSASecurID2FALDAP":"Enabled",
+ # #"RSASecurID2FA.1.RSASecurIDAccessKey": "●●1",
+ # #"RSASecurID2FA.1.RSASecurIDClientID": "●●1",
+ # #"RSASecurID2FA.1.RSASecurIDAuthenticationServer": "",
+ # }
+
+}
+```
+
+
+## Schema
+
+### Optional
+
+- `active_directory` (Attributes) Active DirectoryNote: `active_directory` is mutually inclusive with `active_directory_attributes`. , Note: `active_directory` is mutually exclusive with `ldap`. (see [below for nested schema](#nestedatt--active_directory))
+- `active_directory_attributes` (Map of String) ActiveDirectory.* attributes in Dell iDRAC attributes.Note: `active_directory` is mutually inclusive with `active_directory_attributes`. , Note: `active_directory_attributes` is mutually exclusive with `ldap_attributes`.
+- `ldap` (Attributes) LDAPNote: `ldap` is mutually inclusive with `ldap_attributes`. , Note: `active_directory` is mutually exclusive with `ldap`. (see [below for nested schema](#nestedatt--ldap))
+- `ldap_attributes` (Map of String) LDAP.* attributes in Dell iDRAC attributes.Note: `ldap` is mutually inclusive with `ldap_attributes`. , Note: `active_directory_attributes` is mutually exclusive with `ldap_attributes`.
+- `redfish_server` (Block List) List of server BMCs and their respective user credentials (see [below for nested schema](#nestedblock--redfish_server))
+
+### Read-Only
+
+- `id` (String) ID of the Directory Service Auth Provider resource
+
+
+### Nested Schema for `active_directory`
+
+Optional:
+
+- `authentication` (Attributes) Authentication information for the account provider. (see [below for nested schema](#nestedatt--active_directory--authentication))
+- `directory` (Attributes) Directory for Active Directory . (see [below for nested schema](#nestedatt--active_directory--directory))
+
+
+### Nested Schema for `active_directory.authentication`
+
+Optional:
+
+- `kerberos_key_tab_file` (String) KerberosKeytab is a Base64-encoded version of the Kerberos keytab for this Service
+
+
+
+### Nested Schema for `active_directory.directory`
+
+Optional:
+
+- `remote_role_mapping` (Attributes List) Mapping rules that are used to convert the account providers account information to the local Redfish role (see [below for nested schema](#nestedatt--active_directory--directory--remote_role_mapping))
+- `service_addresses` (List of String) ServiceAddresses of the account providers
+- `service_enabled` (Boolean) ServiceEnabled indicate whether this service is enabled.
+
+
+### Nested Schema for `active_directory.directory.remote_role_mapping`
+
+Optional:
+
+- `local_role` (String) Role Assigned to the Group.
+- `remote_group` (String) Name of the remote group.
+
+
+
+
+
+### Nested Schema for `ldap`
+
+Optional:
+
+- `directory` (Attributes) Directory for LDAP. (see [below for nested schema](#nestedatt--ldap--directory))
+- `ldap_service` (Attributes) LDAPService is any additional mapping information needed to parse a generic LDAP service. (see [below for nested schema](#nestedatt--ldap--ldap_service))
+
+
+### Nested Schema for `ldap.directory`
+
+Optional:
+
+- `remote_role_mapping` (Attributes List) Mapping rules that are used to convert the account providers account information to the local Redfish role (see [below for nested schema](#nestedatt--ldap--directory--remote_role_mapping))
+- `service_addresses` (List of String) ServiceAddresses of the account providers
+- `service_enabled` (Boolean) ServiceEnabled indicate whether this service is enabled.
+
+
+### Nested Schema for `ldap.directory.remote_role_mapping`
+
+Optional:
+
+- `local_role` (String) Role Assigned to the Group.
+- `remote_group` (String) Name of the remote group.
+
+
+
+
+### Nested Schema for `ldap.ldap_service`
+
+Optional:
+
+- `search_settings` (Attributes) SearchSettings is the required settings to search an external LDAP service. (see [below for nested schema](#nestedatt--ldap--ldap_service--search_settings))
+
+
+### Nested Schema for `ldap.ldap_service.search_settings`
+
+Optional:
+
+- `base_distinguished_names` (List of String) BaseDistinguishedNames is an array of base distinguished names to use to search an external LDAP service.
+- `group_name_attribute` (String) GroupNameAttribute is the attribute name that contains the LDAP group name.
+- `user_name_attribute` (String) UsernameAttribute is the attribute name that contains the LDAP user name.
+
+
+
+
+
+### Nested Schema for `redfish_server`
+
+Optional:
+
+- `endpoint` (String) Server BMC IP address or hostname
+- `password` (String, Sensitive) User password for login
+- `redfish_alias` (String) Alias name for server BMCs. The key in provider's `redfish_servers` map
+- `ssl_insecure` (Boolean) This field indicates whether the SSL/TLS certificate must be verified or not
+- `user` (String) User name for login
+
+## Import
+
+Import is supported using the following syntax:
+
+```shell
+/*
+Copyright (c) 2024 Dell Inc., or its subsidiaries. All Rights Reserved.
+
+Licensed under the Mozilla Public License Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://mozilla.org/MPL/2.0/
+
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+terraform import redfish_directory_service_auth_provider.ds_auth '{"username":"","password":"","endpoint":"","ssl_insecure":}'
+```
diff --git a/examples/resources/redfish_directory_service_auth_provider/import.sh b/examples/resources/redfish_directory_service_auth_provider/import.sh
new file mode 100644
index 00000000..9b8033fb
--- /dev/null
+++ b/examples/resources/redfish_directory_service_auth_provider/import.sh
@@ -0,0 +1,18 @@
+/*
+Copyright (c) 2024 Dell Inc., or its subsidiaries. All Rights Reserved.
+
+Licensed under the Mozilla Public License Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://mozilla.org/MPL/2.0/
+
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+terraform import redfish_directory_service_auth_provider.ds_auth '{"username":"","password":"","endpoint":"","ssl_insecure":}'
diff --git a/examples/resources/redfish_directory_service_auth_provider/provider.tf b/examples/resources/redfish_directory_service_auth_provider/provider.tf
new file mode 100644
index 00000000..5afaec72
--- /dev/null
+++ b/examples/resources/redfish_directory_service_auth_provider/provider.tf
@@ -0,0 +1,25 @@
+/*
+Copyright (c) 2024 Dell Inc., or its subsidiaries. All Rights Reserved.
+
+Licensed under the Mozilla Public License Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://mozilla.org/MPL/2.0/
+
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+terraform {
+ required_providers {
+ redfish = {
+ version = "1.5.0"
+ source = "registry.terraform.io/dell/redfish"
+ }
+ }
+}
\ No newline at end of file
diff --git a/examples/resources/redfish_directory_service_auth_provider/resource.tf b/examples/resources/redfish_directory_service_auth_provider/resource.tf
new file mode 100644
index 00000000..d0bb4626
--- /dev/null
+++ b/examples/resources/redfish_directory_service_auth_provider/resource.tf
@@ -0,0 +1,138 @@
+/*
+Copyright (c) 2024 Dell Inc., or its subsidiaries. All Rights Reserved.
+
+Licensed under the Mozilla Public License Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://mozilla.org/MPL/2.0/
+
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+data "local_file" "kerberos" {
+ # this is the path to the kerberos keytab file that we want to upload.
+ # this file must be base64 encoded format
+ filename = "/root/directoryservice/new/terraform-provider-redfish/test-data/kerberos_file.txt"
+}
+
+# redfish_directory_service_auth_provider Terraform resource is used to configure Directory Service Auth Provider Active Directory and LDAP Service
+# Available action: Create, Update (Active Directory, LDAP)
+# Active Directory (Create, Update): remote_role_mapping, service_addresses, service_enabled,authentication, active_directory_attributes
+# LDAP (Create, Update): remote_role_mapping, service_addresses, service_enabled,ldap_service, ldap_attributes
+resource "redfish_directory_service_auth_provider" "ds_auth" {
+ for_each = var.rack1
+
+ redfish_server {
+ user = each.value.user
+ password = each.value.password
+ endpoint = each.value.endpoint
+ ssl_insecure = each.value.ssl_insecure
+ }
+
+ #Note: `active_directory` is mutually inclusive with `active_directory_attributes`.
+ #Note: `ldap` is mutually inclusive with `ldap_attributes`.
+ #Note: `active_directory` is mutually exclusive with `ldap`.
+ #Note: `active_directory_attributes` is mutually exclusive with `ldap_attributes`.
+ active_directory = {
+ directory = {
+ # remote_role_mapping = [
+ # {
+ # local_role = "None",
+ # remote_group = "idracgroup"
+ # }
+ # ],
+ # service_addresses = [
+ # "yulanadhost11.yulan.pie.lab.emc.com"
+ # ],
+ service_enabled = true,
+ authentication = {
+ kerberos_key_tab_file = data.local_file.kerberos.content
+ }
+ }
+ }
+
+ active_directory_attributes = {
+ "ActiveDirectory.1.AuthTimeout" = "120",
+ "ActiveDirectory.1.CertValidationEnable" = "Enabled",
+ "ActiveDirectory.1.DCLookupEnable" = "Enabled",
+
+ # RacName and RacDomain can be configured when Schema is Extended Schema
+ "ActiveDirectory.1.RacDomain" = "test",
+ "ActiveDirectory.1.RacName" = "test",
+
+ # if SSOEnable is Enabled make sure ActiveDirectory Service is enabled and valid kerberos_key_tab_file is provided
+ "ActiveDirectory.1.SSOEnable" = "Disabled",
+
+ # Schema can be Extended Schema or Standard Schema
+ "ActiveDirectory.1.Schema" = "Extended Schema",
+ "UserDomain.1.Name" = "yulan.pie.lab.emc.com",
+
+ # DCLookupByUserDomain must be configured when DCLookupEnable is enabled
+ "ActiveDirectory.1.DCLookupByUserDomain" : "Enabled",
+
+ # DCLookupDomainName must be configured when DCLookupByUserDomain is Disabled and DCLookupEnable is Enabled
+ #"ActiveDirectory.1.DCLookupDomainName"="test",
+
+ #"ActiveDirectory.1.GCLookupEnable" = "Disabled"
+
+ # at least any one from GlobalCatalog1,GlobalCatalog2,GlobalCatalog3 must be configured when Schema is Standard and GCLookupEnable is Disabled
+ # "ActiveDirectory.1.GlobalCatalog1" = "yulanadhost11.yulan.pie.lab.emc.com",
+ # "ActiveDirectory.1.GlobalCatalog2" = "yulanadhost11.yulan.pie.lab.emc.com",
+ # "ActiveDirectory.1.GlobalCatalog3" = "yulanadhost11.yulan.pie.lab.emc.com",
+
+ # GCRootDomain can be configured when GCLookupEnable is Enabled
+ #"ActiveDirectory.1.GCRootDomain" = "test"
+
+ # RSA Secure configuration required Datacenter license
+ #"LDAP.1.RSASecurID2FALDAP":"Enabled",
+ #"RSASecurID2FA.1.RSASecurIDAccessKey": "●●1",
+ #"RSASecurID2FA.1.RSASecurIDClientID": "●●1",
+ #"RSASecurID2FA.1.RSASecurIDAuthenticationServer": "",
+ }
+
+
+
+ # ldap = {
+ # directory = {
+ # remote_role_mapping = [
+ # {
+ # local_role = "Administrator",
+ # remote_group = "cn = idracgroup,cn = users,dc = yulan,dc = pie,dc = lab,dc = emc,dc = com"
+ # }
+ # ],
+ # service_addresses = [
+ # "yulanadhost12.yulan.pie.lab.emc.com"
+ # ],
+ # service_enabled = false
+ # },
+ # ldap_service = {
+ # search_settings = {
+ # base_distinguished_names = [
+ # "dc = yulan,dc = pie,dc = lab,dc = emc,dc = com"
+ # ],
+ # group_name_attribute = "name",
+ # user_name_attribute = "member"
+ # }
+ # }
+ # }
+ #
+ # ldap_attributes = {
+ # "LDAP.1.GroupAttributeIsDN" = "Enabled"
+ # "LDAP.1.Port" = "636",
+ # "LDAP.1.BindDN" = "cn = adtester,cn = users,dc = yulan,dc = pie,dc = lab,dc = emc,dc = com",
+ # "LDAP.1.BindPassword" = "",
+ # "LDAP.1.SearchFilter" = "(objectclass = *)",
+ #
+ # #"LDAP.1.RSASecurID2FALDAP":"Enabled",
+ # #"RSASecurID2FA.1.RSASecurIDAccessKey": "●●1",
+ # #"RSASecurID2FA.1.RSASecurIDClientID": "●●1",
+ # #"RSASecurID2FA.1.RSASecurIDAuthenticationServer": "",
+ # }
+
+}
\ No newline at end of file
diff --git a/examples/resources/redfish_directory_service_auth_provider/terraform.tfvars b/examples/resources/redfish_directory_service_auth_provider/terraform.tfvars
new file mode 100644
index 00000000..f6645b4d
--- /dev/null
+++ b/examples/resources/redfish_directory_service_auth_provider/terraform.tfvars
@@ -0,0 +1,31 @@
+/*
+Copyright (c) 2024 Dell Inc., or its subsidiaries. All Rights Reserved.
+
+Licensed under the Mozilla Public License Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://mozilla.org/MPL/2.0/
+
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+rack1 = {
+ "my-server-1" = {
+ user = "admin"
+ password = "passw0rd"
+ endpoint = "https://my-server-1.myawesomecompany.org"
+ ssl_insecure = true
+ },
+ "my-server-2" = {
+ user = "admin"
+ password = "passw0rd"
+ endpoint = "https://my-server-2.myawesomecompany.org"
+ ssl_insecure = true
+ },
+}
diff --git a/examples/resources/redfish_directory_service_auth_provider/variables.tf b/examples/resources/redfish_directory_service_auth_provider/variables.tf
new file mode 100644
index 00000000..22d751f4
--- /dev/null
+++ b/examples/resources/redfish_directory_service_auth_provider/variables.tf
@@ -0,0 +1,25 @@
+/*
+Copyright (c) 2024 Dell Inc., or its subsidiaries. All Rights Reserved.
+
+Licensed under the Mozilla Public License Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://mozilla.org/MPL/2.0/
+
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+variable "rack1" {
+ type = map(object({
+ user = string
+ password = string
+ endpoint = string
+ ssl_insecure = bool
+ }))
+}
diff --git a/redfish/models/directory_service_auth_provider.go b/redfish/models/directory_service_auth_provider.go
index 49785060..68575df6 100644
--- a/redfish/models/directory_service_auth_provider.go
+++ b/redfish/models/directory_service_auth_provider.go
@@ -21,6 +21,53 @@ import (
"github.com/hashicorp/terraform-plugin-framework/types"
)
+// DirectoryServiceAuthProviderResource is the tfsdk model of DirectoryServiceAuthProviderResource
+type DirectoryServiceAuthProviderResource struct {
+ RedfishServer []RedfishServer `tfsdk:"redfish_server"`
+ ID types.String `tfsdk:"id"`
+ // Optional Param
+ ActiveDirectoryResource types.Object `tfsdk:"active_directory"`
+ LDAPResource types.Object `tfsdk:"ldap"`
+ ActiveDirectoryAttributes types.Map `tfsdk:"active_directory_attributes"`
+ LDAPAttributes types.Map `tfsdk:"ldap_attributes"`
+}
+
+// DirectoryResource is the tfsdk model of DirectoryResource
+type DirectoryResource struct {
+ RemoteRoleMapping types.List `tfsdk:"remote_role_mapping"`
+ ServiceAddresses []types.String `tfsdk:"service_addresses"`
+ ServiceEnabled types.Bool `tfsdk:"service_enabled"`
+}
+
+// ActiveDirectoryResource is the tfsdk model of ActiveDirectoryResource
+type ActiveDirectoryResource struct {
+ Directory types.Object `tfsdk:"directory"`
+ Authentication types.Object `tfsdk:"authentication"`
+}
+
+// AuthenticationResource is the tfsdk model of AuthenticationResource
+type AuthenticationResource struct {
+ KerberosKeytab types.String `tfsdk:"kerberos_key_tab_file"`
+}
+
+// LDAPResource is the tfsdk model of LDAPResource
+type LDAPResource struct {
+ Directory types.Object `tfsdk:"directory"`
+ LDAPService types.Object `tfsdk:"ldap_service"`
+}
+
+// LDAPServiceResource is the tfsdk model of LDAPServiceResource
+type LDAPServiceResource struct {
+ SearchSettings types.Object `tfsdk:"search_settings"`
+}
+
+// SearchSettingsResource is the tfsdk model of SearchSettingsResource
+type SearchSettingsResource struct {
+ BaseDistinguishedNames []types.String `tfsdk:"base_distinguished_names"`
+ UsernameAttribute types.String `tfsdk:"user_name_attribute"`
+ GroupNameAttribute types.String `tfsdk:"group_name_attribute"`
+}
+
// DirectoryServiceAuthProviderDatasource to construct terraform schema for the auth provider resource.
type DirectoryServiceAuthProviderDatasource struct {
ID types.String `tfsdk:"id"`
diff --git a/redfish/provider/provider.go b/redfish/provider/provider.go
index 85e0a3f2..edfc748a 100644
--- a/redfish/provider/provider.go
+++ b/redfish/provider/provider.go
@@ -171,6 +171,7 @@ func (*redfishProvider) Resources(_ context.Context) []func() resource.Resource
NewScpImportResource,
NewScpExportResource,
NewRedfishNICResource,
+ NewRedfishDirectoryServiceAuthProviderResource,
}
}
diff --git a/redfish/provider/resource_redfish_directory_service_auth_provider.go b/redfish/provider/resource_redfish_directory_service_auth_provider.go
new file mode 100644
index 00000000..925393b6
--- /dev/null
+++ b/redfish/provider/resource_redfish_directory_service_auth_provider.go
@@ -0,0 +1,446 @@
+/*
+Copyright (c) 2024 Dell Inc., or its subsidiaries. All Rights Reserved.
+
+Licensed under the Mozilla Public License Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://mozilla.org/MPL/2.0/
+
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package provider
+
+import (
+ "context"
+ "encoding/json"
+ "io"
+ "terraform-provider-redfish/redfish/models"
+
+ tfpath "github.com/hashicorp/terraform-plugin-framework/path"
+ "github.com/hashicorp/terraform-plugin-framework/resource"
+ "github.com/hashicorp/terraform-plugin-framework/resource/schema"
+
+ "github.com/hashicorp/terraform-plugin-framework/diag"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+ "github.com/hashicorp/terraform-plugin-log/tflog"
+ "github.com/stmcginnis/gofish"
+ "github.com/stmcginnis/gofish/redfish"
+)
+
+const (
+ noteMessageUpdateOneServiceOnly = "Please update one of active_directory or ldap at a time."
+ noteADMessageInclusive = "Note: `active_directory` is mutually inclusive with `active_directory_attributes`."
+ noteLDAPMessageInclusive = "Note: `ldap` is mutually inclusive with `ldap_attributes`."
+ noteMessageExclusive = "Note: `active_directory` is mutually exclusive with `ldap`."
+ noteAttributesMessageExclusive = "Note: `active_directory_attributes` is mutually exclusive with `ldap_attributes`."
+)
+
+// Ensure the implementation satisfies the expected interfaces.
+var (
+ _ resource.Resource = &RedfishDirectoryServiceAuthProviderResource{}
+)
+
+// NewRedfishDirectoryServiceAuthProviderResource is a helper function to simplify the provider implementation.
+func NewRedfishDirectoryServiceAuthProviderResource() resource.Resource {
+ return &RedfishDirectoryServiceAuthProviderResource{}
+}
+
+// RedfishDirectoryServiceAuthProviderResource is the resource implementation.
+type RedfishDirectoryServiceAuthProviderResource struct {
+ p *redfishProvider
+ ctx context.Context
+}
+
+// Configure implements resource.ResourceWithConfigure
+func (r *RedfishDirectoryServiceAuthProviderResource) Configure(_ context.Context, req resource.ConfigureRequest, _ *resource.ConfigureResponse) {
+ if req.ProviderData == nil {
+ return
+ }
+ r.p = req.ProviderData.(*redfishProvider)
+}
+
+// Metadata returns the resource type name.
+func (*RedfishDirectoryServiceAuthProviderResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "directory_service_auth_provider"
+}
+
+// Schema defines the schema for the resource.
+func (*RedfishDirectoryServiceAuthProviderResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
+ resp.Schema = schema.Schema{
+ MarkdownDescription: "This Terraform resource is used to configure Directory Service Auth Provider Active Directory and LDAP Service" +
+ " We can Read the existing configurations or modify them using this resource.",
+ Description: "This Terraform resource is used to configure Directory Service Auth Provider Active Directory and LDAP Service" +
+ " We can Read the existing configurations or modify them using this resource.",
+
+ Attributes: DirectoryServiceAuthProviderResourceSchema(),
+ Blocks: RedfishServerResourceBlockMap(),
+ }
+}
+
+// Create creates the resource and sets the initial Terraform state.
+func (r *RedfishDirectoryServiceAuthProviderResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
+ r.ctx = ctx
+ tflog.Trace(ctx, "resource_directory_service_auth_provider create : Started")
+ // Get Plan Data
+ var plan, emptyState models.DirectoryServiceAuthProviderResource
+ diags := req.Plan.Get(ctx, &plan)
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ api, err := NewConfig(r.p, &plan.RedfishServer)
+ if err != nil {
+ resp.Diagnostics.AddError("service error", err.Error())
+ return
+ }
+ service := api.Service
+ defer api.Logout()
+
+ activeServiceChanged := newActiveDirectoryChanged(ctx, &plan, &emptyState)
+ ldapServiceChanged := newLDAPChanged(ctx, &plan, &emptyState)
+
+ if activeServiceChanged && ldapServiceChanged {
+ resp.Diagnostics.AddError("Error when creating both of `ActiveDirectory` and `LDAP`",
+ noteMessageUpdateOneServiceOnly)
+ return
+ }
+ diags = r.updateRedfishDirectoryServiceAuth(ctx, service, &plan, &emptyState)
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ tflog.Trace(ctx, "resource_directory_service_auth_provider create: updating state finished, saving ...")
+ diags = r.readRedfishDirectoryServiceAuthProvider(ctx, service, &plan)
+ if resp.Diagnostics.Append(diags...); resp.Diagnostics.HasError() {
+ return
+ }
+ tflog.Trace(ctx, "resource_directory_service_auth_provider create: finished state update")
+
+ // Save into State
+ diags = resp.State.Set(ctx, &plan)
+ resp.Diagnostics.Append(diags...)
+ tflog.Trace(ctx, "resource_directory_service_auth_provider create: finish")
+}
+
+// Read refreshes the Terraform state with the latest data.
+func (r *RedfishDirectoryServiceAuthProviderResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
+ tflog.Trace(ctx, "resource_directory_service_auth_provider read: started")
+ r.ctx = ctx
+ var state models.DirectoryServiceAuthProviderResource
+ diags := req.State.Get(ctx, &state)
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ api, err := NewConfig(r.p, &state.RedfishServer)
+ if err != nil {
+ resp.Diagnostics.AddError("service error", err.Error())
+ return
+ }
+ service := api.Service
+ defer api.Logout()
+
+ diags = r.readRedfishDirectoryServiceAuthProvider(ctx, service, &state)
+ if diags.HasError() {
+ diags.AddError("Error running job", "error in reading the directory service")
+ }
+
+ var idracAttribute models.DellIdracAttributes
+ diags = readRedfishDellIdracAttributes(ctx, service, &idracAttribute)
+ resp.Diagnostics.Append(diags...)
+
+ tflog.Trace(ctx, "resource_directory_service_auth_provider read: finished reading state")
+ // Save into State
+ diags = resp.State.Set(ctx, &state)
+ resp.Diagnostics.Append(diags...)
+ tflog.Trace(ctx, "resource_directory_service_auth_provider read: finished")
+}
+
+// Update updates the resource and sets the updated Terraform state on success.
+func (r *RedfishDirectoryServiceAuthProviderResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
+ r.ctx = ctx
+ var state, plan models.DirectoryServiceAuthProviderResource
+ // Get state Data
+ tflog.Trace(ctx, "resource_directory_service_auth_provider update: started")
+ diags := req.State.Get(ctx, &state)
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ // Get plan Data
+ diags = req.Plan.Get(ctx, &plan)
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ api, err := NewConfig(r.p, &plan.RedfishServer)
+ if err != nil {
+ resp.Diagnostics.AddError("service error", err.Error())
+ return
+ }
+ service := api.Service
+ defer api.Logout()
+
+ activeServiceChanged := newActiveDirectoryChanged(ctx, &plan, &state)
+ ldapServiceChanged := newLDAPChanged(ctx, &plan, &state)
+ if activeServiceChanged && ldapServiceChanged {
+ resp.Diagnostics.AddError("Error when updating both of `ActiveDirectory` and `LDAP`",
+ "Please update one of active_directory or ldap at a time.")
+ return
+ }
+ diags = r.updateRedfishDirectoryServiceAuth(ctx, service, &plan, &state)
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ tflog.Trace(ctx, "resource_directory_service_auth_provider update: finished state update")
+ // Save into State
+ diags = r.readRedfishDirectoryServiceAuthProvider(ctx, service, &plan)
+ if diags.HasError() {
+ diags.AddError("Error running job", "error in reading the directory service")
+ }
+ diags = resp.State.Set(ctx, &plan)
+ resp.Diagnostics.Append(diags...)
+ tflog.Trace(ctx, "resource_directory_service_auth_provider update: finished")
+}
+
+// Delete deletes the resource and removes the Terraform state on success.
+func (*RedfishDirectoryServiceAuthProviderResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
+ tflog.Trace(ctx, "resource_directory_service_auth_provider delete: started")
+ // Get State Data
+ var state models.DirectoryServiceAuthProviderResource
+ diags := req.State.Get(ctx, &state)
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ resp.State.RemoveResource(ctx)
+ tflog.Trace(ctx, "resource_directory_service_auth_provider delete: finished")
+}
+
+// ImportState import state for existing resource
+// nolint:revive
+func (*RedfishDirectoryServiceAuthProviderResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
+ type creds struct {
+ Username string `json:"username"`
+ Password string `json:"password"`
+ Endpoint string `json:"endpoint"`
+ SslInsecure bool `json:"ssl_insecure"`
+ RedfishAlias string `json:"redfish_alias"`
+ }
+
+ var c creds
+ err := json.Unmarshal([]byte(req.ID), &c)
+ if err != nil {
+ resp.Diagnostics.AddError("Error while unmarshalling id", err.Error())
+ }
+
+ server := models.RedfishServer{
+ User: types.StringValue(c.Username),
+ Password: types.StringValue(c.Password),
+ Endpoint: types.StringValue(c.Endpoint),
+ SslInsecure: types.BoolValue(c.SslInsecure),
+ RedfishAlias: types.StringValue(c.RedfishAlias),
+ }
+
+ redfishServer := tfpath.Root("redfish_server")
+ resp.Diagnostics.Append(resp.State.SetAttribute(ctx, tfpath.Root("id"), "importId")...)
+ resp.Diagnostics.Append(resp.State.SetAttribute(ctx, redfishServer, []models.RedfishServer{server})...)
+}
+
+// nolint: gofumpt
+func (*RedfishDirectoryServiceAuthProviderResource) updateRedfishDirectoryServiceAuth(ctx context.Context, service *gofish.Service, plan,
+ state *models.DirectoryServiceAuthProviderResource) diag.Diagnostics {
+ var diags diag.Diagnostics
+ // Lock the mutex to avoid race conditions with other resources
+ redfishMutexKV.Lock(plan.RedfishServer[0].Endpoint.ValueString())
+ defer redfishMutexKV.Unlock(plan.RedfishServer[0].Endpoint.ValueString())
+
+ activeServiceChanged := newActiveDirectoryChanged(ctx, plan, state)
+ ldapServiceChanged := newLDAPChanged(ctx, plan, state)
+
+ // get the account service resource and ODATA_ID will be used to make a patch call
+ accountService, err := service.AccountService()
+ if err != nil {
+ diags.AddError("error fetching accountservice resource", err.Error())
+ return diags
+ }
+
+ accountServiceURI := accountService.ODataID
+
+ if activeServiceChanged {
+ if diags = updateActiveDirectory(ctx, accountServiceURI, service, plan); diags.HasError() {
+ return diags
+ }
+ } else if ldapServiceChanged {
+ if diags = updateLDAP(ctx, accountServiceURI, service, plan); diags.HasError() {
+ return diags
+ }
+ }
+ return diags
+}
+
+func getAccountServiceDetails(service *gofish.Service) (*redfish.AccountService, error) {
+ accountService, err := service.AccountService()
+ if err != nil {
+ return nil, err
+ }
+
+ return accountService, nil
+}
+
+// nolint: revive
+func (*RedfishDirectoryServiceAuthProviderResource) readRedfishDirectoryServiceAuthProvider(ctx context.Context, service *gofish.Service, state *models.DirectoryServiceAuthProviderResource) (diags diag.Diagnostics) {
+ // var diags diag.Diagnostics
+ accountService, err := getAccountServiceDetails(service)
+ if err != nil {
+ diags.AddError("Error fetching Account Service", err.Error())
+ return diags
+ }
+
+ if diags = parseActiveDirectoryIntoState(ctx, accountService, service, state); diags.HasError() {
+ diags.AddError("ActiveDir state null", "ActiveDirectory state null")
+ return diags
+ }
+ if diags = parseLDAPIntoState(ctx, accountService, service, state); diags.HasError() {
+ diags.AddError("oldLDAPState state null", "oldLDAPState state null")
+ return diags
+ }
+ state.ID = types.StringValue("redfish_directory_service_auth_provider")
+ return diags
+}
+
+// nolint: revive
+func updateActiveDirectory(ctx context.Context, serviceURI string, service *gofish.Service, plan *models.DirectoryServiceAuthProviderResource) (diags diag.Diagnostics) {
+ // var diags diag.Diagnostic
+
+ // Check for all valid scenario
+ if authTimeOutCheck, diags := isValidAuthTime(ActiveDirectory, ".AuthTimeout", plan); diags.HasError() || !authTimeOutCheck {
+ return diags
+ }
+
+ if ssoCheck, diags := isSSOEnabledWithValidFile(ctx, ActiveDirectory, "SSOEnable", plan); diags.HasError() || !ssoCheck {
+ return diags
+ }
+
+ dcLookupDomainCheck, diags := isValidDCLookupDomainConfig(ctx, ActiveDirectory, "DCLookupEnable", plan)
+ if diags.HasError() || !dcLookupDomainCheck {
+ return diags
+ }
+ if schemacheck, diags := isValidSchemaSelection(ctx, ActiveDirectory, "Schema", plan); diags.HasError() || !schemacheck {
+ return diags
+ }
+
+ if authFactorCheck, diags := isValid2FactorAuth(plan.ActiveDirectoryAttributes); diags.HasError() || !authFactorCheck {
+ return diags
+ }
+
+ patchBody := make(map[string]interface{})
+ if patchBody[ActiveDirectory], diags = getActiveDirectoryPatchBody(ctx, plan); diags.HasError() {
+ return diags
+ }
+
+ // make a patch call to update the account service activeDirectory configuration
+ response, err := service.GetClient().Patch(serviceURI, patchBody)
+ if err != nil {
+ diags.AddError("There was an error while creating/ updating Active Directory",
+ "There was an error while creating/ updating Active Directory "+err.Error())
+ return diags
+ }
+ if response != nil {
+ body, err := io.ReadAll(response.Body)
+ if err != nil {
+ diags.AddError("error reading response body", "error "+string(body))
+ return diags
+ }
+ readResponse := make(map[string]json.RawMessage)
+ err = json.Unmarshal(body, &readResponse)
+ if err != nil {
+ diags.AddError("Error unmarshalling response body", err.Error())
+ return diags
+ }
+
+ // check for extended error message in response
+ errorMsg, ok := readResponse["error"]
+ if ok {
+ diags.AddError("Error updating AccountService Details", string(errorMsg))
+ return diags
+ }
+ }
+
+ defer response.Body.Close()
+ var idracAttributesPlan models.DellIdracAttributes
+ idracAttributesPlan.Attributes = plan.ActiveDirectoryAttributes
+ idracAttributesPlan.ID = plan.ID
+ idracAttributesPlan.RedfishServer = plan.RedfishServer
+ diags = updateRedfishDellIdracAttributes(ctx, service, &idracAttributesPlan)
+ if diags.HasError() {
+ return diags
+ }
+ plan.ActiveDirectoryAttributes = idracAttributesPlan.Attributes
+ return diags
+}
+
+// nolint: revive
+func updateLDAP(ctx context.Context, serviceURI string, service *gofish.Service, plan *models.DirectoryServiceAuthProviderResource) (diags diag.Diagnostics) {
+ if authFactorCheck, diags := isValid2FactorAuth(plan.LDAPAttributes); diags.HasError() || !authFactorCheck {
+ return diags
+ }
+
+ patchBody := make(map[string]interface{})
+ if patchBody["LDAP"], diags = getLDAPPatchBody(ctx, plan); diags.HasError() {
+ return diags
+ }
+
+ // make a patch call to update the account service activeDirectory configuration
+ response, err := service.GetClient().Patch(serviceURI, patchBody)
+ if err != nil {
+ diags.AddError("There was an error while creating/ updating LDAP", "There was an error while creating/ updating LDAP")
+ return diags
+ }
+
+ if response != nil {
+ body, err := io.ReadAll(response.Body)
+ if err != nil {
+ return diags
+ }
+ readResponse := make(map[string]json.RawMessage)
+ err = json.Unmarshal(body, &readResponse)
+ if err != nil {
+ diags.AddError("Error unmarshalling response body", err.Error())
+ return diags
+ }
+ // check for extended error message in response
+ errorMsg, ok := readResponse["error"]
+ if ok {
+ diags.AddError("Error updating AccountService Details", string(errorMsg))
+ return diags
+ }
+ }
+ defer response.Body.Close()
+ var idracAttributesPlan models.DellIdracAttributes
+ idracAttributesPlan.Attributes = plan.LDAPAttributes
+ idracAttributesPlan.ID = plan.ID
+ idracAttributesPlan.RedfishServer = plan.RedfishServer
+ diags = updateRedfishDellIdracAttributes(ctx, service, &idracAttributesPlan)
+ // resp.Diagnostics.Append(diags...)
+ if diags.HasError() {
+ diags.AddError("Idrac update fail", "Idrac update fail due to invalid LDAP configuration")
+ return diags
+ }
+
+ plan.LDAPAttributes = idracAttributesPlan.Attributes
+ return diags
+}
diff --git a/redfish/provider/resource_redfish_directory_service_auth_provider_helper.go b/redfish/provider/resource_redfish_directory_service_auth_provider_helper.go
new file mode 100644
index 00000000..6d28e859
--- /dev/null
+++ b/redfish/provider/resource_redfish_directory_service_auth_provider_helper.go
@@ -0,0 +1,545 @@
+/*
+Copyright (c) 2024 Dell Inc., or its subsidiaries. All Rights Reserved.
+
+Licensed under the Mozilla Public License Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://mozilla.org/MPL/2.0/
+
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package provider
+
+import (
+ "context"
+ "strconv"
+ "strings"
+ "terraform-provider-redfish/redfish/models"
+
+ "github.com/hashicorp/terraform-plugin-framework/diag"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+ "github.com/hashicorp/terraform-plugin-framework/types/basetypes"
+)
+
+const (
+ // RSASecurID2FA is rsa Secure Id 2 factor authentication
+ RSASecurID2FA = "RSASecurID2FA"
+ // Disabled disable the service
+ Disabled = "Disabled"
+ // Enabled enable the service
+ Enabled = "Enabled"
+
+ lowerLimit = 15
+ upperLimit = 300
+)
+
+// nolint: gocyclo,revive
+func newActiveDirectoryChanged(ctx context.Context, plan, state *models.DirectoryServiceAuthProviderResource) bool {
+ objectAsOptions := basetypes.ObjectAsOptions{UnhandledNullAsEmpty: true, UnhandledUnknownAsEmpty: true}
+
+ if plan.ActiveDirectoryResource.IsNull() || plan.ActiveDirectoryResource.IsUnknown() {
+ return false
+ }
+ var activeDirectoryPlan models.ActiveDirectoryResource
+ if !plan.ActiveDirectoryResource.IsNull() && !plan.ActiveDirectoryResource.IsUnknown() {
+ if diags := plan.ActiveDirectoryResource.As(ctx, &activeDirectoryPlan, objectAsOptions); diags.HasError() {
+ return false
+ }
+ }
+
+ var activeDirectoryState models.ActiveDirectoryResource
+ if !state.ActiveDirectoryResource.IsNull() && !state.ActiveDirectoryResource.IsUnknown() {
+ if diags := state.ActiveDirectoryResource.As(ctx, &activeDirectoryState, objectAsOptions); diags.HasError() {
+ return false
+ }
+ }
+
+ var directoryPlan models.DirectoryResource
+ if !activeDirectoryPlan.Directory.IsNull() && !activeDirectoryPlan.Directory.IsUnknown() {
+ if diags := activeDirectoryPlan.Directory.As(ctx, &directoryPlan, objectAsOptions); diags.HasError() {
+ return false
+ }
+ }
+
+ var directoryState models.DirectoryResource
+ if !activeDirectoryState.Directory.IsNull() && !activeDirectoryState.Directory.IsUnknown() {
+ if diags := activeDirectoryState.Directory.As(ctx, &directoryState, objectAsOptions); diags.HasError() {
+ return false
+ }
+ }
+
+ if directoryPlan.RemoteRoleMapping.String() != "" && directoryPlan.RemoteRoleMapping.String() != directoryState.RemoteRoleMapping.String() {
+ return true
+ }
+
+ if len(directoryPlan.ServiceAddresses) != len(directoryState.ServiceAddresses) {
+ return true
+ }
+
+ if checkListMatching(directoryPlan.ServiceAddresses, directoryState.ServiceAddresses) {
+ return true
+ }
+
+ var authenticationPlan models.AuthenticationResource
+ if !activeDirectoryPlan.Authentication.IsNull() && !activeDirectoryPlan.Authentication.IsUnknown() {
+ if diags := activeDirectoryPlan.Authentication.As(ctx, &authenticationPlan, objectAsOptions); diags.HasError() {
+ return false
+ }
+ if !authenticationPlan.KerberosKeytab.IsNull() && !authenticationPlan.KerberosKeytab.IsUnknown() {
+ return true
+ }
+ }
+
+ return newAttributesChanged(plan.ActiveDirectoryAttributes, state.ActiveDirectoryAttributes)
+}
+
+// nolint: gocyclo,revive
+func newLDAPChanged(ctx context.Context, plan, state *models.DirectoryServiceAuthProviderResource) bool {
+ objectAsOptions := basetypes.ObjectAsOptions{UnhandledNullAsEmpty: true, UnhandledUnknownAsEmpty: true}
+
+ if plan.LDAPResource.IsNull() || plan.LDAPResource.IsUnknown() {
+ return false
+ }
+ var ldapPlan models.LDAPResource
+ if !plan.LDAPResource.IsNull() && !plan.LDAPResource.IsUnknown() {
+ if diags := plan.LDAPResource.As(ctx, &ldapPlan, objectAsOptions); diags.HasError() {
+ return false
+ }
+ }
+ var ldapState models.LDAPResource
+ if !state.LDAPResource.IsNull() && !state.LDAPResource.IsUnknown() {
+ if diags := state.LDAPResource.As(ctx, &ldapState, objectAsOptions); diags.HasError() {
+ return false
+ }
+ }
+ var directoryPlan models.DirectoryResource
+ if !ldapPlan.Directory.IsNull() && !ldapPlan.Directory.IsUnknown() {
+ if diags := ldapPlan.Directory.As(ctx, &directoryPlan, objectAsOptions); diags.HasError() {
+ return false
+ }
+ }
+
+ var directoryState models.DirectoryResource
+ if !ldapState.Directory.IsNull() && !ldapState.Directory.IsUnknown() {
+ if diags := ldapState.Directory.As(ctx, &directoryState, objectAsOptions); diags.HasError() {
+ return false
+ }
+ }
+
+ if directoryPlan.RemoteRoleMapping.String() != "" && directoryPlan.RemoteRoleMapping.String() != directoryState.RemoteRoleMapping.String() {
+ return true
+ }
+
+ if len(directoryPlan.ServiceAddresses) != len(directoryState.ServiceAddresses) {
+ return true
+ }
+
+ if checkListMatching(directoryPlan.ServiceAddresses, directoryState.ServiceAddresses) {
+ return true
+ }
+
+ var ldapServicePlan models.LDAPServiceResource
+ if !ldapPlan.LDAPService.IsNull() && !ldapPlan.LDAPService.IsUnknown() {
+ if diags := ldapPlan.LDAPService.As(ctx, &ldapServicePlan, objectAsOptions); diags.HasError() {
+ return false
+ }
+ }
+
+ var ldapServiceState models.LDAPServiceResource
+ if !ldapState.LDAPService.IsNull() && !ldapState.LDAPService.IsUnknown() {
+ if diags := ldapState.LDAPService.As(ctx, &ldapServiceState, objectAsOptions); diags.HasError() {
+ return false
+ }
+ }
+
+ var ldapSearchSettingsPlan models.SearchSettingsResource
+ if !ldapServicePlan.SearchSettings.IsNull() && !ldapServicePlan.SearchSettings.IsUnknown() {
+ if diags := ldapServicePlan.SearchSettings.As(ctx, &ldapSearchSettingsPlan, objectAsOptions); diags.HasError() {
+ return false
+ }
+ }
+
+ var ldapSearchSettingsState models.SearchSettingsResource
+ if !ldapServiceState.SearchSettings.IsNull() && !ldapServiceState.SearchSettings.IsUnknown() {
+ if diags := ldapServiceState.SearchSettings.As(ctx, &ldapSearchSettingsState, objectAsOptions); diags.HasError() {
+ return false
+ }
+ }
+
+ if ldapSearchSettingsPlan.GroupNameAttribute.ValueString() != "" &&
+ ldapSearchSettingsPlan.GroupNameAttribute.ValueString() != ldapSearchSettingsState.GroupNameAttribute.ValueString() {
+ return true
+ }
+ if ldapSearchSettingsPlan.UsernameAttribute.ValueString() != "" &&
+ ldapSearchSettingsPlan.UsernameAttribute.ValueString() != ldapSearchSettingsState.UsernameAttribute.ValueString() {
+ return true
+ }
+
+ if len(ldapSearchSettingsPlan.BaseDistinguishedNames) != len(ldapSearchSettingsState.BaseDistinguishedNames) {
+ return true
+ }
+
+ if checkListMatching(ldapSearchSettingsPlan.BaseDistinguishedNames, ldapSearchSettingsState.BaseDistinguishedNames) {
+ return true
+ }
+
+ return newAttributesChanged(plan.LDAPAttributes, state.LDAPAttributes)
+}
+
+func newAttributesChanged(attrsPlan, attrsState types.Map) bool {
+ if attrsPlan.IsNull() || attrsPlan.IsUnknown() {
+ return false
+ }
+
+ if attrsPlan.String() != "" && attrsPlan.String() == attrsState.String() {
+ return false
+ }
+ return true
+}
+
+func checkListMatching(planList []types.String, stateList []types.String) bool {
+ changed := false
+ for _, planTarget := range planList {
+ changed = true
+ for _, stateTarget := range stateList {
+ if planTarget.String() == stateTarget.String() {
+ changed = false
+ break
+ }
+ }
+ }
+ return changed
+}
+
+func checkAttributeskeyPresent(attributes types.Map, prefix string, suffix string) bool {
+ for k := range attributes.Elements() {
+ if strings.HasPrefix(k, prefix) && strings.HasSuffix(k, suffix) {
+ return true
+ }
+ }
+ return false
+}
+
+func getkAttributeskeyValue(attributes types.Map, prefix string, suffix string) string {
+ for k, v := range attributes.Elements() {
+ if strings.HasPrefix(k, prefix) && strings.HasSuffix(k, suffix) {
+ value := v.String()
+ value = value[1 : len(value)-1]
+ return value
+ }
+ }
+ return ""
+}
+
+func isValid2FactorAuth(attributes types.Map) (bool, diag.Diagnostics) {
+ var diags diag.Diagnostics
+ // attributes := attrsState.ActiveDirectoryAttributes
+ checkey2FA := checkAttributeskeyPresent(attributes, RSASecurID2FA, "RSASecurIDAccessKey")
+ checkID2FA := checkAttributeskeyPresent(attributes, RSASecurID2FA, "RSASecurIDClientID")
+ checkServer2FA := checkAttributeskeyPresent(attributes, RSASecurID2FA, "RSASecurIDAuthenticationServer")
+
+ if checkey2FA || checkID2FA || checkServer2FA {
+ checkey2FAValue := getkAttributeskeyValue(attributes, RSASecurID2FA, "RSASecurIDAccessKey")
+ checID2FAValue := getkAttributeskeyValue(attributes, RSASecurID2FA, "RSASecurIDClientID")
+ checkServer2FAValue := getkAttributeskeyValue(attributes, RSASecurID2FA, "RSASecurIDAuthenticationServer")
+
+ if checkey2FAValue == "" || checID2FAValue == "" || checkServer2FAValue == "" {
+ diags.AddError("Missing RSASecurID2FA required params", "Please provide all the required configuration for 2 factor autentication")
+ return false, diags
+ }
+ }
+
+ return true, diags
+}
+
+func isValidAuthTime(prefix string, suffix string, attrsState *models.DirectoryServiceAuthProviderResource) (bool, diag.Diagnostics) {
+ var diags diag.Diagnostics
+ attributes := attrsState.ActiveDirectoryAttributes
+ check := checkAttributeskeyPresent(attributes, prefix, suffix)
+
+ if !check {
+ diags.AddError("Invalid AuthTimeout, Please provide all the required configuration", "Please provide all the required configuration")
+ return false, diags
+ }
+ value := getkAttributeskeyValue(attributes, prefix, suffix)
+
+ intValue, err := strconv.Atoi(value)
+ if err != nil {
+ diags.AddError("Invalid AuthTimeout", "Invalid AuthTimeout")
+ return false, diags
+ }
+
+ if intValue < lowerLimit || intValue > upperLimit {
+ diags.AddError("Invalid AuthTimeout, AuthTimeout must be between 15 and 300", "AuthTimeout must be between 15 and 300")
+ return false, diags
+ }
+
+ return true, nil
+}
+
+// nolint: revive
+func isSSOEnabledWithValidFile(ctx context.Context, prefix string, suffix string, attrsState *models.DirectoryServiceAuthProviderResource) (bool, diag.Diagnostics) {
+ var diags diag.Diagnostics
+
+ attributes := attrsState.ActiveDirectoryAttributes
+ check := checkAttributeskeyPresent(attributes, prefix, suffix)
+
+ if check {
+ value := getkAttributeskeyValue(attributes, prefix, suffix)
+ if value == Enabled {
+ objectAsOptions := basetypes.ObjectAsOptions{UnhandledNullAsEmpty: true, UnhandledUnknownAsEmpty: true}
+ var activeDirectoryPlan models.ActiveDirectoryResource
+ if !attrsState.ActiveDirectoryResource.IsNull() && !attrsState.ActiveDirectoryResource.IsUnknown() {
+ if diags := attrsState.ActiveDirectoryResource.As(ctx, &activeDirectoryPlan, objectAsOptions); diags.HasError() {
+ return false, diags
+ }
+ }
+
+ var directoryPlan models.DirectoryResource
+ if !activeDirectoryPlan.Directory.IsNull() && !activeDirectoryPlan.Directory.IsUnknown() {
+ if diags := activeDirectoryPlan.Directory.As(ctx, &directoryPlan, objectAsOptions); diags.HasError() {
+ return false, diags
+ }
+ }
+
+ if !directoryPlan.ServiceEnabled.ValueBool() {
+ diags.AddError("Please provide valid Configuration for SSO", "SSO can't be enabled when Active Directory service is Disabled")
+ return false, diags
+ }
+ var authenticationPlan models.AuthenticationResource
+ if !activeDirectoryPlan.Authentication.IsNull() && !activeDirectoryPlan.Authentication.IsUnknown() {
+ if diags := activeDirectoryPlan.Authentication.As(ctx, &authenticationPlan, objectAsOptions); diags.HasError() {
+ return false, diags
+ }
+ }
+
+ if activeDirectoryPlan.Authentication.IsNull() || activeDirectoryPlan.Authentication.IsUnknown() ||
+ authenticationPlan.KerberosKeytab.IsNull() || authenticationPlan.KerberosKeytab.IsUnknown() {
+ diags.AddError("Please provide valid kerberos key tab file when SSO is enabled",
+ "Please provide valid kerberos key tab file when SSO is enabled")
+ return false, diags
+ }
+
+ return true, diags
+ }
+
+ if value == Disabled {
+ diags.AddWarning("Disabled ", "inside Disabled")
+ return true, diags
+ }
+ }
+
+ return true, diags
+}
+
+// nolint: gocyclo, revive
+func isValidSchemaSelection(ctx context.Context, prefix string, suffix string, attrsState *models.DirectoryServiceAuthProviderResource) (bool, diag.Diagnostics) {
+ var diags diag.Diagnostics
+ attributes := attrsState.ActiveDirectoryAttributes
+ check := checkAttributeskeyPresent(attributes, prefix, suffix)
+ if check {
+ value := getkAttributeskeyValue(attributes, prefix, suffix)
+ iDRAcName := checkAttributeskeyPresent(attributes, ActiveDirectory, "RacName")
+ iDRAcDomain := checkAttributeskeyPresent(attributes, ActiveDirectory, "RacDomain")
+ groupDomain := checkAttributeskeyPresent(attributes, "ADGroup", "Domain")
+ gcLookupEnable := checkAttributeskeyPresent(attributes, ActiveDirectory, "GCLookupEnable")
+ gc1 := checkAttributeskeyPresent(attributes, ActiveDirectory, "GlobalCatalog1")
+ gc2 := checkAttributeskeyPresent(attributes, ActiveDirectory, "GlobalCatalog2")
+ gc3 := checkAttributeskeyPresent(attributes, ActiveDirectory, "GlobalCatalog3")
+ objectAsOptions := basetypes.ObjectAsOptions{UnhandledNullAsEmpty: true, UnhandledUnknownAsEmpty: true}
+ var activeDirectoryPlan models.ActiveDirectoryResource
+ if !attrsState.ActiveDirectoryResource.IsNull() && !attrsState.ActiveDirectoryResource.IsUnknown() {
+ if diags := attrsState.ActiveDirectoryResource.As(ctx, &activeDirectoryPlan, objectAsOptions); diags.HasError() {
+ return false, diags
+ }
+ }
+
+ var directoryPlan models.DirectoryResource
+ if !activeDirectoryPlan.Directory.IsNull() && !activeDirectoryPlan.Directory.IsUnknown() {
+ if diags := activeDirectoryPlan.Directory.As(ctx, &directoryPlan, objectAsOptions); diags.HasError() {
+ return false, diags
+ }
+ }
+
+ var remoteRoleMapping []models.RemoteRoleMapping
+ if diags := directoryPlan.RemoteRoleMapping.ElementsAs(ctx, &remoteRoleMapping, true); diags.HasError() {
+ return false, diags
+ }
+
+ if value == "Extended Schema" {
+ if !iDRAcName || !iDRAcDomain {
+ diags.AddError("Please provide valid config for RacName and RacDomain",
+ "RacName and RacDomain must be configured for Extended Schema")
+ return false, diags
+ }
+ iDRAcNameValue := getkAttributeskeyValue(attributes, ActiveDirectory, "RacName")
+ iDRAcDomainValue := getkAttributeskeyValue(attributes, ActiveDirectory, "RacDomain")
+ if iDRAcNameValue == "" || iDRAcDomainValue == "" {
+ diags.AddError("RacName and RacDomain can not be null for Extended Schema",
+ "Please provide valid configuration for RacName and RacDomain")
+ return false, diags
+ }
+ if gcLookupEnable || gc1 || gc2 || gc3 {
+ diags.AddError("GCLookupEnable, GlobalCatalog1, GlobalCatalog2, GlobalCatalog3 can not be configured for Extended Schema",
+ "GCLookupEnable, GlobalCatalog1, GlobalCatalog2, GlobalCatalog3 can not be configured for Extended Schema")
+ return false, diags
+ }
+
+ if !activeDirectoryPlan.Directory.IsNull() && !activeDirectoryPlan.Directory.IsUnknown() {
+ if len(remoteRoleMapping) != 0 {
+ diags.AddError("RemoteRoleMapping can not be configured for Extended Schema",
+ "RemoteRoleMapping can not be configured for Extended Schema")
+ return false, diags
+
+ }
+ }
+
+ if groupDomain {
+ diags.AddError("Domain can not be configured for Extended Schema", "Domain can not be configured for Extended Schema")
+ return false, diags
+ }
+ }
+ if value == "Standard Schema" {
+ if iDRAcName || iDRAcDomain {
+ diags.AddError("RacName and RacDomain can not be configured for Standard Schema",
+ "RacName and RacDomain can not be configured for Standard Schema")
+ return false, diags
+ }
+ if !gcLookupEnable {
+ diags.AddError("GCLookupEnable must be configured for Standard Schema", "GCLookupEnable must be configured for Standard Schema")
+ return false, diags
+ }
+ gcLookupEnableValue := getkAttributeskeyValue(attributes, ActiveDirectory, "GCLookupEnable")
+
+ if gcLookupEnableValue == Enabled {
+ gcRootDomain := checkAttributeskeyPresent(attributes, ActiveDirectory, "GCRootDomain")
+ if !gcRootDomain || getkAttributeskeyValue(attributes, ActiveDirectory, "GCRootDomain") == "" {
+ diags.AddError("GCRootDomain must be configured for Enabled GCLookupEnable",
+ "GCRootDomain must be configured for Enabled GCLookupEnable")
+ return false, diags
+ }
+
+ if gc1 || gc2 || gc3 {
+ diags.AddError("GlobalCatalog can not be configured for Enabled GCLookupEnable",
+ " GlobalCatalog can not be configured for Enabled GCLookupEnable")
+ return false, diags
+ }
+ } else if gcLookupEnableValue == Disabled {
+ gc1Value := getkAttributeskeyValue(attributes, ActiveDirectory, "GlobalCatalog1")
+ gc2Value := getkAttributeskeyValue(attributes, ActiveDirectory, "GlobalCatalog2")
+ gc3Value := getkAttributeskeyValue(attributes, ActiveDirectory, "GlobalCatalog3")
+
+ if gc1Value == "" && gc2Value == "" && gc3Value == "" {
+ diags.AddError("Invalid GlobalCatalog configuration for Standard Schema",
+ "Atleast any one from GlobalCatalog1, GlobalCatalog2, GlobalCatalog3 must be configured for Disabled GCLookupEnable")
+ return false, diags
+ }
+
+ gcRootDomain := checkAttributeskeyPresent(attributes, ActiveDirectory, "GCRootDomain")
+ if gcRootDomain {
+ diags.AddError("GCRootDomain can not be configured for Disabled GCLookupEnable",
+ "GCRootDomain can not be configured for Disabled GCLookupEnable")
+ return false, diags
+ }
+ } else {
+ diags.AddError("Invalid configuration for Standard Schema", "Please provide valid configuration for Standard Schema")
+ return false, diags
+ }
+ }
+ }
+ return true, diags
+}
+
+// nolint: gocyclo, revive
+func isValidDCLookupDomainConfig(ctx context.Context, prefix string, suffix string, attrsState *models.DirectoryServiceAuthProviderResource) (bool, diag.Diagnostics) {
+ var diags diag.Diagnostics
+ attributes := attrsState.ActiveDirectoryAttributes
+ check := checkAttributeskeyPresent(attributes, prefix, suffix)
+ if check {
+ objectAsOptions := basetypes.ObjectAsOptions{UnhandledNullAsEmpty: true, UnhandledUnknownAsEmpty: true}
+ var activeDirectoryPlan models.ActiveDirectoryResource
+ if !attrsState.ActiveDirectoryResource.IsNull() && !attrsState.ActiveDirectoryResource.IsUnknown() {
+ if diags := attrsState.ActiveDirectoryResource.As(ctx, &activeDirectoryPlan, objectAsOptions); diags.HasError() {
+ return false, diags
+ }
+ }
+
+ var directoryPlan models.DirectoryResource
+ if !activeDirectoryPlan.Directory.IsNull() && !activeDirectoryPlan.Directory.IsUnknown() {
+ if diags := activeDirectoryPlan.Directory.As(ctx, &directoryPlan, objectAsOptions); diags.HasError() {
+ return false, diags
+ }
+ }
+ dcLookupEnableValue := getkAttributeskeyValue(attributes, ActiveDirectory, "DCLookupEnable")
+ serviceAddress := directoryPlan.ServiceAddresses
+
+ serviceAddressList := make([]interface{}, 0)
+ for _, target := range serviceAddress {
+ serviceAddressList = append(serviceAddressList, target.ValueString())
+ }
+ userDomain := checkAttributeskeyPresent(attributes, ActiveDirectory, "DCLookupByUserDomain")
+ specifyDomain := checkAttributeskeyPresent(attributes, ActiveDirectory, "DCLookupDomainName")
+ if dcLookupEnableValue == Disabled {
+ // diags.AddError("Invalid configuration for DCLookUp", "Service address must be configured for DCLookUp"+strconv.Itoa(len(serviceAddressList)))
+ if len(serviceAddressList) == 0 {
+ diags.AddError("ServiceAddresses is not Configured for Disabled DCLookUp",
+ "Atleast one Service address must be configured for Disabled DCLookUp")
+ return false, diags
+ }
+ if userDomain {
+ diags.AddError("DCLookupByUserDomain can not be Configured for Disabled DCLookUp",
+ "DCLookupByUserDomain can not be Configured for Disabled DCLookUp")
+ return false, diags
+ }
+ if specifyDomain {
+ diags.AddError("DCLookupDomainName can not be configured for Disabled DCLookUp",
+ "DCLookupDomainName can not be configured for Disabled DCLookUp")
+ return false, diags
+ }
+ } else if dcLookupEnableValue == Enabled {
+ if len(serviceAddressList) != 0 {
+ diags.AddError("Service address can not be configured for Enabled DCLookUp", "Service address can not be configured for Enabled DCLookUp")
+ return false, diags
+ }
+ if !userDomain {
+ diags.AddError("DCLookupByUserDomain must be configured for Enabled DCLookUp",
+ "DCLookupByUserDomain must be configured for Enabled DCLookUp")
+ return false, diags
+ }
+ userDomainValue := getkAttributeskeyValue(attributes, ActiveDirectory, "DCLookupByUserDomain")
+ if userDomainValue == Disabled {
+ if !specifyDomain {
+ diags.AddError("DCLookupDomainName must be configured for Disabled DCLookupByUserDomain",
+ "DCLookupDomainName must be configured for Disabled DCLookupByUserDomain")
+ return false, diags
+ }
+ specifyDomainValue := getkAttributeskeyValue(attributes, ActiveDirectory, "DCLookupDomainName")
+ if specifyDomainValue == "" {
+ diags.AddError("DCLookupDomainName must be configured for Disabled DCLookupByUserDomain",
+ "DCLookupDomainName must be configured for Disabled DCLookupByUserDomain")
+ return false, diags
+ }
+ } else if userDomainValue == Enabled {
+ specifyDomain := checkAttributeskeyPresent(attributes, ActiveDirectory, "DCLookupDomainName")
+ if specifyDomain {
+ diags.AddError("DCLookupDomainName can not be configured for Enabled DCLookupByUserDomain",
+ "DCLookupDomainName can not be configured for Enabled DCLookupByUserDomain")
+ return false, diags
+ }
+ }
+ return true, diags
+
+ } else {
+ diags.AddError("Invalid configuration for DCLookUp", "Please provide valid configuration for DCLookUp")
+ return false, diags
+ }
+ }
+ return true, diags
+}
diff --git a/redfish/provider/resource_redfish_directory_service_auth_provider_schema.go b/redfish/provider/resource_redfish_directory_service_auth_provider_schema.go
new file mode 100644
index 00000000..5326d5a1
--- /dev/null
+++ b/redfish/provider/resource_redfish_directory_service_auth_provider_schema.go
@@ -0,0 +1,244 @@
+/*
+Copyright (c) 2024 Dell Inc., or its subsidiaries. All Rights Reserved.
+
+Licensed under the Mozilla Public License Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://mozilla.org/MPL/2.0/
+
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package provider
+
+import (
+ "github.com/hashicorp/terraform-plugin-framework-validators/mapvalidator"
+ "github.com/hashicorp/terraform-plugin-framework-validators/objectvalidator"
+ "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
+ "github.com/hashicorp/terraform-plugin-framework/path"
+ "github.com/hashicorp/terraform-plugin-framework/resource/schema"
+ "github.com/hashicorp/terraform-plugin-framework/schema/validator"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+)
+
+const (
+ comma = " , "
+)
+
+// DirectoryServiceAuthProviderResourceSchema defines the schema for the resource.
+func DirectoryServiceAuthProviderResourceSchema() map[string]schema.Attribute {
+ return map[string]schema.Attribute{
+ "id": schema.StringAttribute{
+ MarkdownDescription: "ID of the Directory Service Auth Provider resource",
+ Description: "ID of the Directory Service Auth Provider resource",
+ Computed: true,
+ },
+ "active_directory": schema.SingleNestedAttribute{
+ MarkdownDescription: "Active Directory" + noteADMessageInclusive + comma + noteMessageExclusive,
+ Description: "Active Directory" + noteADMessageInclusive + comma + noteMessageExclusive,
+ Attributes: ActiveDirectoryResourceSchema(),
+ Computed: true,
+ Optional: true,
+ Validators: []validator.Object{
+ objectvalidator.AtLeastOneOf(
+ path.MatchRoot("ldap")),
+ objectvalidator.AlsoRequires(
+ path.MatchRoot("active_directory_attributes")),
+ },
+ },
+ "ldap": schema.SingleNestedAttribute{
+ MarkdownDescription: "LDAP" + noteLDAPMessageInclusive + comma + noteMessageExclusive,
+ Description: "LDAP" + noteLDAPMessageInclusive + comma + noteMessageExclusive,
+ Attributes: LDAPResourceSchema(),
+ Computed: true,
+ Optional: true,
+ Validators: []validator.Object{
+ objectvalidator.AtLeastOneOf(
+ path.MatchRoot("active_directory")),
+ objectvalidator.AlsoRequires(
+ path.MatchRoot("ldap_attributes")),
+ },
+ },
+ "active_directory_attributes": schema.MapAttribute{
+ MarkdownDescription: "ActiveDirectory.* attributes in Dell iDRAC attributes." + noteADMessageInclusive + comma +
+ noteAttributesMessageExclusive,
+ Description: "ActiveDirectory.* attributes in Dell iDRAC attributes." + noteADMessageInclusive + comma +
+ noteAttributesMessageExclusive,
+ ElementType: types.StringType,
+ Computed: true,
+ Optional: true,
+ Validators: []validator.Map{
+ mapvalidator.AlsoRequires(
+ path.MatchRoot("active_directory")),
+ mapvalidator.AtLeastOneOf(
+ path.MatchRoot("ldap_attributes")),
+ },
+ },
+ "ldap_attributes": schema.MapAttribute{
+ MarkdownDescription: "LDAP.* attributes in Dell iDRAC attributes." + noteLDAPMessageInclusive + comma + noteAttributesMessageExclusive,
+ Description: "LDAP.* attributes in Dell iDRAC attributes." + noteLDAPMessageInclusive + comma + noteAttributesMessageExclusive,
+ ElementType: types.StringType,
+ Computed: true,
+ Optional: true,
+ Validators: []validator.Map{
+ mapvalidator.AlsoRequires(
+ path.MatchRoot("ldap")),
+ mapvalidator.AtLeastOneOf(
+ path.MatchRoot("active_directory_attributes")),
+ },
+ },
+ }
+}
+
+// ActiveDirectoryResourceSchema is a function that returns the schema for Active Directory Resource
+func ActiveDirectoryResourceSchema() map[string]schema.Attribute {
+ return map[string]schema.Attribute{
+ "directory": schema.SingleNestedAttribute{
+ MarkdownDescription: "Directory for Active Directory .",
+ Description: "Directory for Active Directory",
+ Attributes: DirectoryResourceSchema(),
+ Computed: true,
+ Optional: true,
+ },
+ "authentication": schema.SingleNestedAttribute{
+ MarkdownDescription: "Authentication information for the account provider.",
+ Description: "Authentication information for the account provider.",
+ Attributes: AuthenticationResourceSchema(),
+ Computed: true,
+ Optional: true,
+ },
+ }
+}
+
+// AuthenticationResourceSchema is a function that returns the schema for Authentication Resource
+func AuthenticationResourceSchema() map[string]schema.Attribute {
+ return map[string]schema.Attribute{
+ "kerberos_key_tab_file": schema.StringAttribute{
+ MarkdownDescription: "KerberosKeytab is a Base64-encoded version of the Kerberos keytab for this Service",
+ Description: "KerberosKeytab is a Base64-encoded version of the Kerberos keytab for this Service",
+ Computed: true,
+ Optional: true,
+ },
+ }
+}
+
+// RemoteRoleMappingResourceSchema is a function that returns the schema for Remote Role Mapping
+func RemoteRoleMappingResourceSchema() map[string]schema.Attribute {
+ return map[string]schema.Attribute{
+ "remote_group": schema.StringAttribute{
+ MarkdownDescription: "Name of the remote group.",
+ Description: "Name of the remote group.",
+ Computed: true,
+ Optional: true,
+ },
+ "local_role": schema.StringAttribute{
+ MarkdownDescription: "Role Assigned to the Group.",
+ Description: "Role Assigned to the Group.",
+ Computed: true,
+ Optional: true,
+ Validators: []validator.String{
+ stringvalidator.LengthAtLeast(1),
+ stringvalidator.OneOf([]string{
+ string("Administrator"),
+ string("Operator"),
+ string("ReadOnly"),
+ string("None"),
+ }...),
+ },
+ },
+ }
+}
+
+// DirectoryResourceSchema is a function that returns the schema for Directory Resource
+func DirectoryResourceSchema() map[string]schema.Attribute {
+ return map[string]schema.Attribute{
+ "remote_role_mapping": schema.ListNestedAttribute{
+ MarkdownDescription: "Mapping rules that are used to convert the account providers account information to the local Redfish role",
+ Description: "Mapping rules that are used to convert the account providers account information to the local Redfish role",
+ NestedObject: schema.NestedAttributeObject{
+ Attributes: RemoteRoleMappingResourceSchema(),
+ },
+ Computed: true,
+ Optional: true,
+ },
+ "service_addresses": schema.ListAttribute{
+ MarkdownDescription: "ServiceAddresses of the account providers",
+ Description: "ServiceAddresses of the account providers",
+ Computed: true,
+ Optional: true,
+ ElementType: types.StringType,
+ },
+ "service_enabled": schema.BoolAttribute{
+ MarkdownDescription: "ServiceEnabled indicate whether this service is enabled.",
+ Description: "ServiceEnabled indicate whether this service is enabled.",
+ Computed: true,
+ Optional: true,
+ },
+ }
+}
+
+// LDAPResourceSchema is a function that returns the schema for LDAPResource
+func LDAPResourceSchema() map[string]schema.Attribute {
+ return map[string]schema.Attribute{
+ "ldap_service": schema.SingleNestedAttribute{
+ MarkdownDescription: "LDAPService is any additional mapping information needed to parse a generic LDAP service.",
+ Description: "LDAPService is any additional mapping information needed to parse a generic LDAP service.",
+ Attributes: LDAPServiceResourceSchema(),
+ Computed: true,
+ Optional: true,
+ },
+ "directory": schema.SingleNestedAttribute{
+ MarkdownDescription: "Directory for LDAP.",
+ Description: "Directory for LDAP",
+ Attributes: DirectoryResourceSchema(),
+ Computed: true,
+ Optional: true,
+ },
+ }
+}
+
+// LDAPServiceResourceSchema is a function that returns the schema for LDAPService Resource
+func LDAPServiceResourceSchema() map[string]schema.Attribute {
+ return map[string]schema.Attribute{
+ "search_settings": schema.SingleNestedAttribute{
+ MarkdownDescription: "SearchSettings is the required settings to search an external LDAP service.",
+ Description: "SearchSettings is the required settings to search an external LDAP service.",
+ Attributes: SearchSettingsResourceSchema(),
+ Computed: true,
+ Optional: true,
+ },
+ }
+}
+
+// SearchSettingsResourceSchema is a function that returns the schema for SearchSettings Resource
+func SearchSettingsResourceSchema() map[string]schema.Attribute {
+ return map[string]schema.Attribute{
+ "base_distinguished_names": schema.ListAttribute{
+ MarkdownDescription: "BaseDistinguishedNames is an array of base distinguished names to use to search an external LDAP service.",
+ Description: "BaseDistinguishedNames is an array of base distinguished names to use to search an external LDAP service.",
+ Computed: true,
+ Optional: true,
+ ElementType: types.StringType,
+ },
+
+ "user_name_attribute": schema.StringAttribute{
+ MarkdownDescription: "UsernameAttribute is the attribute name that contains the LDAP user name.",
+ Description: "UsernameAttribute is the attribute name that contains the LDAP user name.",
+ Computed: true,
+ Optional: true,
+ },
+
+ "group_name_attribute": schema.StringAttribute{
+ MarkdownDescription: "GroupNameAttribute is the attribute name that contains the LDAP group name.",
+ Description: "GroupNameAttribute is the attribute name that contains the LDAP group name.",
+ Computed: true,
+ Optional: true,
+ },
+ }
+}
diff --git a/redfish/provider/resource_redfish_directory_service_auth_provider_schema_helper.go b/redfish/provider/resource_redfish_directory_service_auth_provider_schema_helper.go
new file mode 100644
index 00000000..8228a7f9
--- /dev/null
+++ b/redfish/provider/resource_redfish_directory_service_auth_provider_schema_helper.go
@@ -0,0 +1,723 @@
+/*
+Copyright (c) 2024 Dell Inc., or its subsidiaries. All Rights Reserved.
+
+Licensed under the Mozilla Public License Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://mozilla.org/MPL/2.0/
+
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package provider
+
+import (
+ "context"
+ "fmt"
+ "strings"
+ "terraform-provider-redfish/redfish/models"
+
+ "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-log/tflog"
+ "github.com/stmcginnis/gofish"
+ "github.com/stmcginnis/gofish/redfish"
+)
+
+const (
+ ldapService = "ldap_service"
+ baseDistinguishedNames = "base_distinguished_names"
+ authentication = "authentication"
+ kerberosKeyTabFile = "kerberos_key_tab_file"
+ localRole = "local_role"
+ remoteGroup = "remote_group"
+ directory = "directory"
+ remoteRoleMapping = "remote_role_mapping"
+ serviceAddresses = "service_addresses"
+ serviceEnabled = "service_enabled"
+ searchSettings = "search_settings"
+)
+
+func getActiveDirectoryModelType() map[string]attr.Type {
+ return map[string]attr.Type{
+ directory: types.ObjectType{AttrTypes: getDirectoryModelType()},
+ authentication: types.ObjectType{AttrTypes: getAuthentcationModelType()},
+ }
+}
+
+func getLDAPModelType() map[string]attr.Type {
+ return map[string]attr.Type{
+ directory: types.ObjectType{AttrTypes: getDirectoryModelType()},
+ ldapService: types.ObjectType{AttrTypes: getLDAPServiceModelType()},
+ }
+}
+
+func getAuthentcationModelType() map[string]attr.Type {
+ return map[string]attr.Type{
+ kerberosKeyTabFile: types.StringType,
+ }
+}
+
+func getDirectoryModelType() map[string]attr.Type {
+ return map[string]attr.Type{
+ remoteRoleMapping: types.ListType{ElemType: types.ObjectType{AttrTypes: getRemoteRoleMappingModelType()}},
+ serviceAddresses: types.ListType{ElemType: types.StringType},
+ serviceEnabled: types.BoolType,
+ }
+}
+
+func getLDAPServiceModelType() map[string]attr.Type {
+ return map[string]attr.Type{
+ searchSettings: types.ObjectType{AttrTypes: getSearchSettingsModelType()},
+ }
+}
+
+func getSearchSettingsModelType() map[string]attr.Type {
+ return map[string]attr.Type{
+ baseDistinguishedNames: types.ListType{ElemType: types.StringType},
+ "user_name_attribute": types.StringType,
+ "group_name_attribute": types.StringType,
+ }
+}
+
+func getRemoteRoleMappingModelType() map[string]attr.Type {
+ return map[string]attr.Type{
+ remoteGroup: types.StringType,
+ localRole: types.StringType,
+ }
+}
+
+// nolint: revive
+func getRemoteRoleMappingObjectValue(ctx context.Context, service []redfish.RoleMapping, state *models.DirectoryResource) ([]attr.Value, diag.Diagnostics) {
+ var diags diag.Diagnostics
+ remoteRoleMapList := make([]attr.Value, 0)
+ var oldRemoteRolMap []models.RemoteRoleMapping
+ if !state.RemoteRoleMapping.IsNull() && !state.RemoteRoleMapping.IsUnknown() {
+ if diags := state.RemoteRoleMapping.ElementsAs(ctx, &oldRemoteRolMap, true); diags.HasError() {
+ diags.AddError("oldRemoteRolMap nil ", "oldRemoteRolMap nil")
+ return remoteRoleMapList, diags
+ }
+ }
+
+ for _, oldElement := range oldRemoteRolMap {
+ for _, serviceElement := range service {
+ if serviceElement.LocalRole == oldElement.LocalRole.ValueString() && serviceElement.RemoteGroup == oldElement.RemoteGroup.ValueString() {
+ remoteRoleItemMap := map[string]attr.Value{
+ remoteGroup: types.StringValue(serviceElement.RemoteGroup),
+ localRole: types.StringValue(serviceElement.LocalRole),
+ }
+ remoteRoleItemObj, diags := types.ObjectValue(getRemoteRoleMappingModelType(), remoteRoleItemMap)
+ if diags.HasError() {
+ return remoteRoleMapList, diags
+ }
+ remoteRoleMapList = append(remoteRoleMapList, remoteRoleItemObj)
+ break
+ }
+ }
+ }
+ if len(remoteRoleMapList) == 0 {
+ for _, serviceElement := range service {
+ remoteRoleItemMap := map[string]attr.Value{
+ remoteGroup: types.StringValue(serviceElement.RemoteGroup),
+ localRole: types.StringValue(serviceElement.LocalRole),
+ }
+ remoteRoleItemObj, diags := types.ObjectValue(getRemoteRoleMappingModelType(), remoteRoleItemMap)
+ if diags.HasError() {
+ return remoteRoleMapList, diags
+ }
+ remoteRoleMapList = append(remoteRoleMapList, remoteRoleItemObj)
+ }
+ }
+
+ return remoteRoleMapList, diags
+}
+
+// nolint: revive
+func getActiveDirectoryObjectValue(ctx context.Context, service *redfish.AccountService, state *models.DirectoryServiceAuthProviderResource, objectAsOptions basetypes.ObjectAsOptions) (basetypes.ObjectValue, diag.Diagnostics) {
+ emptyObj := types.ObjectNull(getDirectoryModelType())
+ var oldActiveDirRes models.ActiveDirectoryResource
+ if !state.ActiveDirectoryResource.IsNull() && !state.ActiveDirectoryResource.IsUnknown() {
+ if diags := state.ActiveDirectoryResource.As(ctx, &oldActiveDirRes, objectAsOptions); diags.HasError() {
+ diags.AddError("oldActiveDirRes nill ", "oldActiveDirRes nil")
+ return emptyObj, diags
+ }
+ }
+ var directoryPlan models.DirectoryResource
+ if !oldActiveDirRes.Directory.IsNull() && !oldActiveDirRes.Directory.IsUnknown() {
+ if diags := oldActiveDirRes.Directory.As(ctx, &directoryPlan, objectAsOptions); diags.HasError() {
+ diags.AddError("directoryPlan nill ", "directoryPlan nil")
+ return emptyObj, diags
+ }
+ }
+ serviceAddress := directoryPlan.ServiceAddresses
+ activeDIrectoryRoleMappingList := service.ActiveDirectory.RemoteRoleMapping
+ remoteRoleMappingObj, diags := getRemoteRoleMappingObjectValue(ctx, activeDIrectoryRoleMappingList, &directoryPlan)
+ if diags.HasError() {
+ return emptyObj, diags
+ }
+
+ remoteRoleList, diags := types.ListValue(types.ObjectType{AttrTypes: getRemoteRoleMappingModelType()}, remoteRoleMappingObj)
+
+ if diags.HasError() {
+ return emptyObj, diags
+ }
+ serviceAddressList, diags := getConfigDataList(service.ActiveDirectory.ServiceAddresses, serviceAddress)
+
+ if diags.HasError() {
+ return emptyObj, diags
+ }
+
+ directoryMap := map[string]attr.Value{
+ remoteRoleMapping: remoteRoleList,
+ serviceAddresses: serviceAddressList,
+ serviceEnabled: types.BoolValue(service.ActiveDirectory.ServiceEnabled),
+ }
+ return types.ObjectValue(getDirectoryModelType(), directoryMap)
+}
+
+func getConfigDataList(input []string, stateServiceAddress []types.String) (basetypes.ListValue, diag.Diagnostics) {
+ out := make([]attr.Value, 0)
+ if len(stateServiceAddress) != 0 {
+ for _, stateInput := range stateServiceAddress {
+ for _, i := range input {
+ if stateInput.ValueString() == i {
+ out = append(out, types.StringValue(i))
+ break
+ }
+ }
+ }
+ }
+
+ if len(out) == 0 {
+ for _, target := range input {
+ out = append(out, types.StringValue(target))
+ }
+ }
+
+ return types.ListValue(types.StringType, out)
+}
+
+// nolint: revive
+func getLDAPDirectoryObjectValue(ctx context.Context, service *redfish.AccountService, state *models.DirectoryServiceAuthProviderResource, objectAsOptions basetypes.ObjectAsOptions) (basetypes.ObjectValue, diag.Diagnostics) {
+ emptyObj := types.ObjectNull(getDirectoryModelType())
+
+ var oldLDAPRes models.LDAPResource
+ if !state.LDAPResource.IsNull() && !state.LDAPResource.IsUnknown() {
+ if diags := state.LDAPResource.As(ctx, &oldLDAPRes, objectAsOptions); diags.HasError() {
+ return emptyObj, diags
+ }
+ }
+
+ var directoryPlan models.DirectoryResource
+ if !oldLDAPRes.Directory.IsNull() && !oldLDAPRes.Directory.IsUnknown() {
+ if diags := oldLDAPRes.Directory.As(ctx, &directoryPlan, objectAsOptions); diags.HasError() {
+ return emptyObj, diags
+ }
+ }
+
+ serviceAddress := directoryPlan.ServiceAddresses
+ ldapRemoteRoleList := service.LDAP.RemoteRoleMapping
+
+ remoteRoleMappingObj, diags := getRemoteRoleMappingObjectValue(ctx, ldapRemoteRoleList, &directoryPlan)
+ if diags.HasError() {
+ return emptyObj, diags
+ }
+
+ remoteRoleList, diags := types.ListValue(types.ObjectType{AttrTypes: getRemoteRoleMappingModelType()}, remoteRoleMappingObj)
+
+ if diags.HasError() {
+ return emptyObj, diags
+ }
+
+ serviceAddressList, diags := getConfigDataList(service.LDAP.ServiceAddresses, serviceAddress)
+ if diags.HasError() {
+ return emptyObj, diags
+ }
+
+ directoryMap := map[string]attr.Value{
+ remoteRoleMapping: remoteRoleList,
+ serviceAddresses: serviceAddressList,
+ serviceEnabled: types.BoolValue(service.LDAP.ServiceEnabled),
+ }
+
+ return types.ObjectValue(getDirectoryModelType(), directoryMap)
+}
+
+// nolint: revive
+func getLDAPServiceObjectValue(ctx context.Context, service *redfish.AccountService, state *models.DirectoryServiceAuthProviderResource, objectAsOptions basetypes.ObjectAsOptions) (basetypes.ObjectValue, diag.Diagnostics) {
+ emptyObj := types.ObjectNull(getLDAPServiceModelType())
+
+ var oldLDAPRes models.LDAPResource
+ if !state.LDAPResource.IsNull() && !state.LDAPResource.IsUnknown() {
+ if diags := state.LDAPResource.As(ctx, &oldLDAPRes, objectAsOptions); diags.HasError() {
+ return emptyObj, diags
+ }
+ }
+
+ var oldLDAPService models.LDAPService
+ if !oldLDAPRes.LDAPService.IsNull() && !oldLDAPRes.LDAPService.IsUnknown() {
+ if diags := oldLDAPRes.LDAPService.As(ctx, &oldLDAPService, objectAsOptions); diags.HasError() {
+ return emptyObj, diags
+ }
+ }
+ ldapSearchSetting, diags := getLDAPSearchSettingsObjectValue(ctx, service, state, objectAsOptions)
+
+ if diags.HasError() {
+ return emptyObj, diags
+ }
+
+ ldapServiceMap := map[string]attr.Value{
+ searchSettings: ldapSearchSetting,
+ }
+
+ return types.ObjectValue(getLDAPServiceModelType(), ldapServiceMap)
+}
+
+// nolint: revive
+func getLDAPSearchSettingsObjectValue(ctx context.Context, service *redfish.AccountService, state *models.DirectoryServiceAuthProviderResource, objectAsOptions basetypes.ObjectAsOptions) (basetypes.ObjectValue, diag.Diagnostics) {
+ emptyObj := types.ObjectNull(getSearchSettingsModelType())
+ var oldLDAPRes models.LDAPResource
+ if !state.LDAPResource.IsNull() && !state.LDAPResource.IsUnknown() {
+ if diags := state.LDAPResource.As(ctx, &oldLDAPRes, objectAsOptions); diags.HasError() {
+ return emptyObj, diags
+ }
+ }
+ var oldLDAPService models.LDAPServiceResource
+ if !oldLDAPRes.LDAPService.IsNull() && !oldLDAPRes.LDAPService.IsUnknown() {
+ if diags := oldLDAPRes.LDAPService.As(ctx, &oldLDAPService, objectAsOptions); diags.HasError() {
+ return emptyObj, diags
+ }
+ }
+ var oldSearchSettings models.SearchSettingsResource
+ if !oldLDAPService.SearchSettings.IsNull() && !oldLDAPService.SearchSettings.IsUnknown() {
+ if diags := oldLDAPService.SearchSettings.As(ctx, &oldSearchSettings, objectAsOptions); diags.HasError() {
+ return emptyObj, diags
+ }
+ }
+
+ baseDistinguished := oldSearchSettings.BaseDistinguishedNames
+ baseDistinguishedList, diags := getConfigDataList(service.LDAP.LDAPService.SearchSettings.BaseDistinguishedNames, baseDistinguished)
+ if diags.HasError() {
+ return emptyObj, diags
+ }
+
+ searchSettingsMap := map[string]attr.Value{
+ baseDistinguishedNames: baseDistinguishedList,
+ "user_name_attribute": types.StringValue(service.LDAP.LDAPService.SearchSettings.UsernameAttribute),
+ "group_name_attribute": types.StringValue(service.LDAP.LDAPService.SearchSettings.GroupNameAttribute),
+ }
+
+ return types.ObjectValue(getSearchSettingsModelType(), searchSettingsMap)
+}
+
+// nolint: revive
+func getAuthentcationObjectValue(ctx context.Context, service *redfish.AccountService, directoryPlan models.ActiveDirectoryResource, objectAsOptions basetypes.ObjectAsOptions) (basetypes.ObjectValue, diag.Diagnostics) {
+ var authenticationPlan models.AuthenticationResource
+ var authentication map[string]attr.Value
+ emptyObj := types.ObjectNull(getAuthentcationModelType())
+ if !directoryPlan.Authentication.IsNull() && !directoryPlan.Authentication.IsUnknown() {
+ diags := directoryPlan.Authentication.As(ctx, &authenticationPlan, objectAsOptions)
+ if diags.HasError() {
+ return emptyObj, diags
+ }
+ authentication = map[string]attr.Value{
+ kerberosKeyTabFile: types.StringValue(authenticationPlan.KerberosKeytab.ValueString()),
+ }
+ }
+
+ if directoryPlan.Authentication.IsNull() || directoryPlan.Authentication.IsUnknown() {
+ authentication = map[string]attr.Value{
+ kerberosKeyTabFile: types.StringValue(service.ActiveDirectory.Authentication.KerberosKeytab),
+ }
+ }
+ return types.ObjectValue(getAuthentcationModelType(), authentication)
+}
+
+// nolint: gocyclo, revive
+func parseActiveDirectoryIntoState(ctx context.Context, acctService *redfish.AccountService, service *gofish.Service, state *models.DirectoryServiceAuthProviderResource) (diags diag.Diagnostics) {
+ objectAsOptions := basetypes.ObjectAsOptions{UnhandledNullAsEmpty: true, UnhandledUnknownAsEmpty: true}
+ var oldActiveDirectory models.ActiveDirectoryResource
+ if !state.ActiveDirectoryResource.IsNull() && !state.ActiveDirectoryResource.IsUnknown() {
+ diags = state.ActiveDirectoryResource.As(ctx, &oldActiveDirectory, objectAsOptions)
+ if diags.HasError() {
+ return diags
+ }
+
+ }
+ directoryObj, diags := getActiveDirectoryObjectValue(ctx, acctService, state, objectAsOptions)
+ if diags.HasError() {
+ return diags
+ }
+
+ authenticationObj, diags := getAuthentcationObjectValue(ctx, acctService, oldActiveDirectory, objectAsOptions)
+ if diags.HasError() {
+ return diags
+ }
+ var idracAttributesPlan models.DellIdracAttributes
+ if !state.ActiveDirectoryAttributes.IsNull() && !state.ActiveDirectoryAttributes.IsUnknown() {
+ idracAttributesPlan.Attributes = state.ActiveDirectoryAttributes
+ }
+ if diags := readRedfishDellIdracAttributes(ctx, service, &idracAttributesPlan); diags.HasError() {
+ return diags
+ }
+ var activeDirAttributes types.Map
+ if !state.ActiveDirectoryAttributes.IsNull() && !state.ActiveDirectoryAttributes.IsUnknown() {
+ activeDirAttributes = state.ActiveDirectoryAttributes
+ }
+
+ if state.ActiveDirectoryAttributes.IsNull() || state.ActiveDirectoryAttributes.IsUnknown() {
+ // nolint: gocyclo, gocognit,revive
+ activeDirectoryAttributes := []string{".CertValidationEnable", ".SSOEnable", ".AuthTimeout", ".DCLookupEnable", ".DCLookupByUserDomain", ".DCLookupDomainName", ".Schema", ".GCLookupEnable", ".GCRootDomain", ".GlobalCatalog1", ".GlobalCatalog2", ".GlobalCatalog3", ".RacName", ".RacDomain", ".RSASecurID2FAAD"}
+
+ attributesToReturn := make(map[string]attr.Value)
+ for k, v := range idracAttributesPlan.Attributes.Elements() {
+ if strings.HasPrefix(k, "ActiveDirectory.") {
+ for _, input := range activeDirectoryAttributes {
+ if strings.HasSuffix(k, input) {
+ attributesToReturn[k] = v
+ }
+ }
+ }
+ // nolint: revive
+ if (strings.HasPrefix(k, "UserDomain.") && strings.HasSuffix(k, ".Name")) || (strings.HasPrefix(k, "ADGroup.") && strings.HasSuffix(k, ".Name")) {
+ attributesToReturn[k] = v
+ }
+
+ if strings.HasPrefix(k, "RSASecurID2FA.") && (strings.HasSuffix(k, ".RSASecurIDAuthenticationServer") || strings.HasSuffix(k, ".RSASecurIDAccessKey") || strings.HasSuffix(k, ".RSASecurIDClientID")) {
+ attributesToReturn[k] = v
+ }
+ }
+
+ activeDirAttributes = types.MapValueMust(types.StringType, attributesToReturn)
+ }
+ activeDirectoryMap := map[string]attr.Value{
+ directory: directoryObj,
+ authentication: authenticationObj,
+ }
+ state.ActiveDirectoryAttributes = activeDirAttributes
+ state.ActiveDirectoryResource, diags = types.ObjectValue(getActiveDirectoryModelType(), activeDirectoryMap)
+
+ return diags
+}
+
+// nolint:gocyclo, revive
+func parseLDAPIntoState(ctx context.Context, acctService *redfish.AccountService, service *gofish.Service, state *models.DirectoryServiceAuthProviderResource) (diags diag.Diagnostics) {
+ objectAsOptions := basetypes.ObjectAsOptions{UnhandledNullAsEmpty: true, UnhandledUnknownAsEmpty: true}
+ var oldLDAP models.LDAPResource
+ if !state.LDAPResource.IsNull() && !state.LDAPResource.IsUnknown() {
+ if diags := state.LDAPResource.As(ctx, &oldLDAP, objectAsOptions); diags.HasError() {
+ return diags
+ }
+ }
+
+ directoryObj, diags := getLDAPDirectoryObjectValue(ctx, acctService, state, objectAsOptions)
+ if diags.HasError() {
+ return diags
+ }
+
+ ldapServiceObj, diags := getLDAPServiceObjectValue(ctx, acctService, state, objectAsOptions)
+
+ if diags.HasError() {
+ return diags
+ }
+ var idracAttributesPlan models.DellIdracAttributes
+ if !state.LDAPAttributes.IsNull() && !state.LDAPAttributes.IsUnknown() {
+ idracAttributesPlan.Attributes = state.LDAPAttributes
+ }
+
+ if diags = readRedfishDellIdracAttributes(ctx, service, &idracAttributesPlan); diags.HasError() {
+ return diags
+ }
+
+ var ldapDirAttributes types.Map
+ if !state.LDAPAttributes.IsNull() && !state.LDAPAttributes.IsUnknown() {
+ ldapDirAttributes = state.LDAPAttributes
+ }
+
+ if state.LDAPAttributes.IsNull() || state.LDAPAttributes.IsUnknown() {
+ // nolint: gocyclo, gocognit,revive
+ ldapAttributes := []string{".CertValidationEnable", ".GroupAttributeIsDN", ".Port", ".BindDN", ".BindPassword", ".SearchFilter", ".RSASecurID2FALDAP"}
+ attributesToReturn := make(map[string]attr.Value)
+ for k, v := range idracAttributesPlan.Attributes.Elements() {
+ if strings.HasPrefix(k, "LDAP.") {
+ for _, input := range ldapAttributes {
+ if strings.HasSuffix(k, input) {
+ attributesToReturn[k] = v
+ }
+ }
+ }
+
+ if strings.HasPrefix(k, "RSASecurID2FA.") && (strings.HasSuffix(k, ".RSASecurIDAuthenticationServer") ||
+ strings.HasSuffix(k, ".RSASecurIDAccessKey") || strings.HasSuffix(k, ".RSASecurIDClientID")) {
+ attributesToReturn[k] = v
+ }
+ }
+ ldapDirAttributes = types.MapValueMust(types.StringType, attributesToReturn)
+ }
+ ldapMap := map[string]attr.Value{
+ directory: directoryObj,
+ ldapService: ldapServiceObj,
+ }
+ state.LDAPResource, diags = types.ObjectValue(getLDAPModelType(), ldapMap)
+ state.LDAPAttributes = ldapDirAttributes
+ return diags
+}
+
+// nolint: gocyclo, revive
+func getActiveDirectoryPatchBody(ctx context.Context, attrsState *models.DirectoryServiceAuthProviderResource) (map[string]interface{}, diag.Diagnostics) {
+ // var diags diag.Diagnostics
+ supportedActiveDirectory := map[string]string{
+ serviceEnabled: "ServiceEnabled",
+ serviceAddresses: "ServiceAddresses",
+ remoteRoleMapping: "RemoteRoleMapping",
+ authentication: "Authentication",
+ }
+ supportedRemoteRoleMappingParams := map[string]string{
+ remoteGroup: "RemoteGroup",
+ localRole: "LocalRole",
+ }
+
+ supportedAuthentication := map[string]string{
+ kerberosKeyTabFile: "KerberosKeytab",
+ }
+
+ objectAsOptions := basetypes.ObjectAsOptions{UnhandledNullAsEmpty: true, UnhandledUnknownAsEmpty: true}
+
+ var activeDirectoryPlan models.ActiveDirectoryResource
+ if !attrsState.ActiveDirectoryResource.IsNull() && !attrsState.ActiveDirectoryResource.IsUnknown() {
+ if diags := attrsState.ActiveDirectoryResource.As(ctx, &activeDirectoryPlan, objectAsOptions); diags.HasError() {
+ return nil, diags
+ }
+ }
+
+ var directoryPlan models.DirectoryResource
+ if !activeDirectoryPlan.Directory.IsNull() && !activeDirectoryPlan.Directory.IsUnknown() {
+ if diags := activeDirectoryPlan.Directory.As(ctx, &directoryPlan, objectAsOptions); diags.HasError() {
+ return nil, diags
+ }
+ }
+ var authenticationPlan models.AuthenticationResource
+ if !activeDirectoryPlan.Authentication.IsNull() && !activeDirectoryPlan.Authentication.IsUnknown() {
+ if diags := activeDirectoryPlan.Authentication.As(ctx, &authenticationPlan, objectAsOptions); diags.HasError() {
+ return nil, diags
+ }
+ }
+
+ patchBody := make(map[string]interface{})
+ if !activeDirectoryPlan.Directory.IsNull() && !activeDirectoryPlan.Directory.IsUnknown() {
+ for key, value := range activeDirectoryPlan.Directory.Attributes() {
+ if !value.IsUnknown() && !value.IsNull() {
+ goValue, err := convertTerraformValueToGoBasicValue(ctx, value)
+ if err != nil {
+ tflog.Trace(ctx, fmt.Sprintf("Failed to convert Ethernet value to go value: %s", err.Error()))
+ continue
+ }
+ if fieldName, ok := supportedActiveDirectory[key]; ok {
+ patchBody[fieldName] = goValue
+ }
+ }
+ }
+ }
+
+ // get list of remote role mapping
+ if !directoryPlan.RemoteRoleMapping.IsNull() && !directoryPlan.RemoteRoleMapping.IsUnknown() {
+ var remoteRoleMappingModel []models.RemoteRoleMapping
+
+ if diags := directoryPlan.RemoteRoleMapping.ElementsAs(ctx, &remoteRoleMappingModel, true); diags.HasError() {
+ return nil, diags
+ }
+
+ remoteRoleMappingList := make([]interface{}, 0)
+ for _, target := range remoteRoleMappingModel {
+ remoteRoleMappingBody := make(map[string]interface{})
+ if !target.LocalRole.IsNull() && !target.LocalRole.IsUnknown() {
+ remoteRoleMappingBody[supportedRemoteRoleMappingParams[localRole]] = target.LocalRole.ValueString()
+ }
+ if !target.RemoteGroup.IsNull() && !target.RemoteGroup.IsUnknown() {
+ remoteRoleMappingBody[supportedRemoteRoleMappingParams[remoteGroup]] = target.RemoteGroup.ValueString()
+ }
+ if len(remoteRoleMappingBody) > 0 {
+ remoteRoleMappingList = append(remoteRoleMappingList, remoteRoleMappingBody)
+ }
+ }
+
+ patchBody[supportedActiveDirectory[remoteRoleMapping]] = remoteRoleMappingList
+ }
+
+ serviceAddress := directoryPlan.ServiceAddresses
+ serviceAddressList := make([]interface{}, 0)
+ for _, target := range serviceAddress {
+ serviceAddressList = append(serviceAddressList, target.ValueString())
+ }
+ if len(serviceAddressList) != 0 {
+ patchBody[supportedActiveDirectory[serviceAddresses]] = serviceAddressList
+ }
+
+ // get directory patch body
+ if !activeDirectoryPlan.Authentication.IsNull() && !activeDirectoryPlan.Authentication.IsUnknown() {
+ authenticationPatchBody := make(map[string]interface{})
+ for key, value := range activeDirectoryPlan.Authentication.Attributes() {
+ if !value.IsUnknown() && !value.IsNull() {
+ goValue, err := convertTerraformValueToGoBasicValue(ctx, value)
+ if err != nil {
+ tflog.Trace(ctx, fmt.Sprintf("Failed to convert VLAN value to go value: %s", err.Error()))
+ continue
+ }
+ if fieldName, ok := supportedAuthentication[key]; ok {
+ authenticationPatchBody[fieldName] = goValue
+ }
+ }
+ }
+ patchBody[supportedActiveDirectory[authentication]] = authenticationPatchBody
+ }
+
+ return patchBody, nil
+}
+
+// nolint: gocyclo, revive
+func getLDAPPatchBody(ctx context.Context, attrsState *models.DirectoryServiceAuthProviderResource) (map[string]interface{}, diag.Diagnostics) {
+ // var diags diag.Diagnostics
+ supportedLDAP := map[string]string{
+ serviceEnabled: "ServiceEnabled",
+ serviceAddresses: "ServiceAddresses",
+ remoteRoleMapping: "RemoteRoleMapping",
+ ldapService: "LDAPService",
+ }
+ supportedRemoteRoleMappingParams := map[string]string{
+ remoteGroup: "RemoteGroup",
+ localRole: "LocalRole",
+ }
+
+ supportedLDAPService := map[string]string{
+ searchSettings: "SearchSettings",
+ }
+
+ supportedSearchSetting := map[string]string{
+ baseDistinguishedNames: "BaseDistinguishedNames",
+ "user_name_attribute": "UsernameAttribute",
+ "group_name_attribute": "GroupNameAttribute",
+ }
+
+ objectAsOptions := basetypes.ObjectAsOptions{UnhandledNullAsEmpty: true, UnhandledUnknownAsEmpty: true}
+
+ var ldapPlan models.LDAPResource
+ if !attrsState.LDAPResource.IsNull() && !attrsState.LDAPResource.IsUnknown() {
+ if diags := attrsState.LDAPResource.As(ctx, &ldapPlan, objectAsOptions); diags.HasError() {
+ return nil, diags
+ }
+ }
+
+ var ldapServicePlan models.LDAPServiceResource
+ if !ldapPlan.LDAPService.IsNull() && !ldapPlan.LDAPService.IsUnknown() {
+ if diags := ldapPlan.LDAPService.As(ctx, &ldapServicePlan, objectAsOptions); diags.HasError() {
+ return nil, diags
+ }
+ }
+
+ var ldapSearchSettingsPlan models.SearchSettingsResource
+ if !ldapServicePlan.SearchSettings.IsNull() && !ldapServicePlan.SearchSettings.IsUnknown() {
+ if diags := ldapServicePlan.SearchSettings.As(ctx, &ldapSearchSettingsPlan, objectAsOptions); diags.HasError() {
+ return nil, diags
+ }
+ }
+ var directoryPlan models.DirectoryResource
+ if !ldapPlan.Directory.IsNull() && !ldapPlan.Directory.IsUnknown() {
+ if diags := ldapPlan.Directory.As(ctx, &directoryPlan, objectAsOptions); diags.HasError() {
+ return nil, diags
+ }
+ }
+ patchBody := make(map[string]interface{})
+ if !ldapPlan.Directory.IsNull() && !ldapPlan.Directory.IsUnknown() {
+ for key, value := range ldapPlan.Directory.Attributes() {
+ if !value.IsUnknown() && !value.IsNull() {
+ goValue, err := convertTerraformValueToGoBasicValue(ctx, value)
+ if err != nil {
+ tflog.Trace(ctx, fmt.Sprintf("Failed to convert Ethernet value to go value: %s", err.Error()))
+ continue
+ }
+ if fieldName, ok := supportedLDAP[key]; ok {
+ patchBody[fieldName] = goValue
+ }
+ }
+ }
+ }
+
+ if !ldapPlan.LDAPService.IsNull() && !ldapPlan.LDAPService.IsUnknown() {
+ ldapServicepatchBody := make(map[string]interface{})
+ for key1, value1 := range ldapPlan.LDAPService.Attributes() {
+ if !value1.IsUnknown() && !value1.IsNull() {
+ if !ldapServicePlan.SearchSettings.IsNull() && !ldapServicePlan.SearchSettings.IsUnknown() {
+ ldapSearchSettingPatchBody := make(map[string]interface{})
+ for key, value := range ldapServicePlan.SearchSettings.Attributes() {
+ if !value.IsUnknown() && !value.IsNull() {
+ goValue, err := convertTerraformValueToGoBasicValue(ctx, value)
+ if err != nil {
+ tflog.Trace(ctx, fmt.Sprintf("Failed to convert Ethernet value to go value: %s", err.Error()))
+ continue
+ }
+ if fieldName, ok := supportedSearchSetting[key]; ok {
+ ldapSearchSettingPatchBody[fieldName] = goValue
+ }
+ }
+ }
+ baseDiss := ldapSearchSettingsPlan.BaseDistinguishedNames
+ baseDissList := make([]interface{}, 0)
+ for _, target := range baseDiss {
+ baseDissList = append(baseDissList, target.ValueString())
+ }
+ if len(baseDissList) != 0 {
+ ldapSearchSettingPatchBody[supportedSearchSetting[baseDistinguishedNames]] = baseDissList
+ }
+
+ if fieldName, ok := supportedLDAPService[key1]; ok {
+ ldapServicepatchBody[fieldName] = ldapSearchSettingPatchBody
+ }
+ }
+ }
+ }
+ patchBody[supportedLDAP[ldapService]] = ldapServicepatchBody
+ }
+
+ // get list of remote role mapping
+ if !directoryPlan.RemoteRoleMapping.IsNull() && !directoryPlan.RemoteRoleMapping.IsUnknown() {
+ var remoteRoleMappingModel []models.RemoteRoleMapping
+
+ if diags := directoryPlan.RemoteRoleMapping.ElementsAs(ctx, &remoteRoleMappingModel, true); diags.HasError() {
+ return nil, diags
+ }
+
+ remoteRoleMappingList := make([]interface{}, 0)
+ for _, target := range remoteRoleMappingModel {
+ remoteRoleMappingBody := make(map[string]interface{})
+ if !target.LocalRole.IsNull() && !target.LocalRole.IsUnknown() {
+ remoteRoleMappingBody[supportedRemoteRoleMappingParams[localRole]] = target.LocalRole.ValueString()
+ }
+ if !target.RemoteGroup.IsNull() && !target.RemoteGroup.IsUnknown() {
+ remoteRoleMappingBody[supportedRemoteRoleMappingParams[remoteGroup]] = target.RemoteGroup.ValueString()
+ }
+ if len(remoteRoleMappingBody) > 0 {
+ remoteRoleMappingList = append(remoteRoleMappingList, remoteRoleMappingBody)
+ }
+ }
+
+ patchBody[supportedLDAP[remoteRoleMapping]] = remoteRoleMappingList
+ }
+
+ serviceAddress := directoryPlan.ServiceAddresses
+ serviceAddressList := make([]interface{}, 0)
+ for _, target := range serviceAddress {
+ serviceAddressList = append(serviceAddressList, target.ValueString())
+ }
+ if len(serviceAddressList) != 0 {
+ patchBody[supportedLDAP[serviceAddresses]] = serviceAddressList
+ }
+ return patchBody, nil
+}
diff --git a/redfish/provider/resource_redfish_directory_service_auth_provider_test.go b/redfish/provider/resource_redfish_directory_service_auth_provider_test.go
new file mode 100644
index 00000000..d9c28f93
--- /dev/null
+++ b/redfish/provider/resource_redfish_directory_service_auth_provider_test.go
@@ -0,0 +1,1269 @@
+/*
+Copyright (c) 2024 Dell Inc., or its subsidiaries. All Rights Reserved.
+
+Licensed under the Mozilla Public License Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://mozilla.org/MPL/2.0/
+
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package provider
+
+import (
+ "fmt"
+ "regexp"
+ "testing"
+
+ "github.com/hashicorp/terraform-plugin-testing/helper/resource"
+)
+
+func TestAccRedfishDirectoryServiceAuthProviderBasic(t *testing.T) {
+ terraformDSAuthProviderResourceName := "redfish_directory_service_auth_provider.ds_auth"
+ resource.Test(t, resource.TestCase{
+ PreCheck: func() { testAccPreCheck(t) },
+ ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
+ Steps: []resource.TestStep{
+ {
+ // error create with both `ActiveDirectory` and `LDAP`
+ Config: testAccRedfishDirectoryServiceAuthProviderErrorConfig(creds),
+ ExpectError: regexp.MustCompile("Error when creating both of `ActiveDirectory` and `LDAP`"),
+ },
+
+ {
+ // create with `ActiveDirectory`
+ Config: testAccRedfishDirectoryServiceAuthProviderADConfig(creds),
+ Check: resource.ComposeAggregateTestCheckFunc(
+ resource.TestCheckResourceAttr(terraformDSAuthProviderResourceName, "active_directory.directory.service_enabled", "true"),
+ ),
+ },
+
+ {
+ // update with `LDAP`
+ Config: testAccRedfishDirectoryServiceAuthProviderLDAPConfig(creds),
+ Check: resource.ComposeAggregateTestCheckFunc(
+ resource.TestCheckResourceAttr(terraformDSAuthProviderResourceName, "ldap.directory.service_enabled", "false"),
+ ),
+ },
+ {
+ // update with `ActiveDirectory`
+ Config: testAccRedfishDirectoryServiceAuthProviderAD_UpdateConfig(creds),
+ Check: resource.ComposeAggregateTestCheckFunc(
+ resource.TestCheckResourceAttr(terraformDSAuthProviderResourceName, "active_directory.directory.service_enabled", "false"),
+ resource.TestCheckResourceAttr(terraformDSAuthProviderResourceName, "active_directory_attributes.ActiveDirectory.1.AuthTimeout", "130"),
+ ),
+ },
+ },
+ })
+}
+
+func TestAccRedfishDirectoryServiceAuthProviderInvalidCase(t *testing.T) {
+ resource.Test(t, resource.TestCase{
+ PreCheck: func() { testAccPreCheck(t) },
+ ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
+ Steps: []resource.TestStep{
+ {
+ // error for empty AuthTimeout in ActiveDirectory
+ Config: testAccRedfishDirectoryServiceAuthProviderEmptyAuth(creds),
+ ExpectError: regexp.MustCompile("Invalid AuthTimeout, Please provide all the required configuration"),
+ },
+
+ {
+ // error for Invalid AuthTimeout in ActiveDirectory
+ Config: testAccRedfishDirectoryServiceAuthProviderInvalidAuth(creds),
+ ExpectError: regexp.MustCompile("Invalid AuthTimeout, AuthTimeout must be between 15 and 300"),
+ },
+ {
+ // error ActiveDirectoryService Disabled and SSOEnable Enabled
+ Config: testAccRedfishDirectoryServiceAuthProviderADDisableSSOEnable(creds),
+ ExpectError: regexp.MustCompile("Please provide valid Configuration for SSO"),
+ },
+
+ {
+ // error ActiveDirectoryService Enabled and SSOEnable Enabled and no Kerberos key tab
+ Config: testAccRedfishDirectoryServiceAuthProviderADEnSSOEnNoKb(creds),
+ ExpectError: regexp.MustCompile("Please provide valid kerberos key tab file when SSO is enabled "),
+ },
+
+ {
+ // error DCLookupEnable Enabled and service address as empty
+ Config: testAccRedfishDirectoryServiceAuthProviderDClookUpEnServiceAddEmpty(creds),
+ ExpectError: regexp.MustCompile("ServiceAddresses is not Configured for Disabled DCLookUp"),
+ },
+
+ {
+ // error DCLookupEnable Disabled and DCLookupByUserDomain config
+ Config: testAccRedfishDirectoryServiceAuthProviderDCLookupByUserDomainConfig(creds),
+ ExpectError: regexp.MustCompile("DCLookupByUserDomain can not be Configured for Disabled DCLookUp"),
+ },
+
+ {
+ // error DCLookupEnable Disabled and DCLookupDomainName config
+ Config: testAccRedfishDirectoryServiceAuthProviderDCLookupDomainNameConfig(creds),
+ ExpectError: regexp.MustCompile("DCLookupDomainName can not be configured for Disabled DCLookUp"),
+ },
+
+ {
+ // error DCLookupEnable Enabled and ServiceAddress non empty
+ Config: testAccRedfishDirectoryServiceAuthProviderDDCLookupEnableNoServiceAddConfig(creds),
+ ExpectError: regexp.MustCompile("Service address can not be configured for Enabled DCLookUp"),
+ },
+
+ {
+ // error DCLookupEnable Enabled and DCLookupByUserDomain does not exist
+ Config: testAccRedfishDirectoryServiceAuthProviderDCLookupByUserDomainEmptyConfig(creds),
+ ExpectError: regexp.MustCompile("DCLookupByUserDomain must be configured for Enabled DCLookUp"),
+ },
+
+ {
+ // error DCLookupEnable Enabled, DCLookupByUserDomain Disabled and DCLookupDomainName Empty
+ Config: testAccRedfishDirectoryServiceAuthProviderDCLookupDomainNameEmptyConfig(creds),
+ ExpectError: regexp.MustCompile("DCLookupDomainName must be configured for Disabled DCLookupByUserDomain"),
+ },
+
+ {
+ // error DCLookupEnable Enabled DCLookupByUserDomain Enabled and DCLookupDomainName non Empty
+ Config: testAccRedfishDirectoryServiceAuthProviderDCLookupEnableDCLookupDomainNameConfig(creds),
+ ExpectError: regexp.MustCompile("DCLookupDomainName can not be configured for Enabled DCLookupByUserDomain"),
+ },
+ },
+ })
+}
+
+func TestAccRedfishDirectoryServiceAuthProviderInvalidSchema_Config(t *testing.T) {
+ resource.Test(t, resource.TestCase{
+ PreCheck: func() { testAccPreCheck(t) },
+ ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
+ Steps: []resource.TestStep{
+ {
+ // error Extended Schema without RacName and RacDomain
+ Config: testAccRedfishDirectoryServiceAuthProviderExtendedNoRacConfig(creds),
+ ExpectError: regexp.MustCompile("Please provide valid config for RacName and RacDomain"),
+ },
+ {
+ // error Extended Schema with empty RacName and RacDomain
+ Config: testAccRedfishDirectoryServiceAuthProviderExtendedEmptyRacConfig(creds),
+ ExpectError: regexp.MustCompile("RacName and RacDomain can not be null for Extended Schema"),
+ },
+ {
+ // error Extended Schema with GCLookup config
+ Config: testAccRedfishDirectoryServiceAuthProviderExtendedGCLookUpConfig(creds),
+ ExpectError: regexp.MustCompile("GCLookupEnable, GlobalCatalog1, GlobalCatalog2, GlobalCatalog3 can not be configured for Extended Schema"),
+ },
+
+ {
+ // error Extended Schema with remote role mapping config
+ Config: testAccRedfishDirectoryServiceAuthProviderExtendedRemoteRoleConfig(creds),
+ ExpectError: regexp.MustCompile("RemoteRoleMapping can not be configured for Extended Schema"),
+ },
+ {
+ // error Extended Schema with groupdomain config
+ Config: testAccRedfishDirectoryServiceAuthProviderExtendedADGroupDomainConfig(creds),
+ ExpectError: regexp.MustCompile("Domain can not be configured for Extended Schema"),
+ },
+ {
+ // error Standard Schema with RacName and RacDomain
+ Config: testAccRedfishDirectoryServiceAuthProviderStandardSchemaAndRacConfig(creds),
+ ExpectError: regexp.MustCompile("RacName and RacDomain can not be configured for Standard Schema"),
+ },
+ {
+ // error Standard Schema without GCLookup config
+ Config: testAccRedfishDirectoryServiceAuthProviderStandardSchemaNoGCLookUpConfig(creds),
+ ExpectError: regexp.MustCompile("GCLookupEnable must be configured for Standard Schema"),
+ },
+ {
+ // error Standard Schema, GCLookup Enabled, no GCRootDomain
+ Config: testAccRedfishDirectoryServiceAuthProviderStandardSchemaNoGCRootConfig(creds),
+ ExpectError: regexp.MustCompile("GCRootDomain must be configured for Enabled GCLookupEnable"),
+ },
+ {
+ // error Standard Schema GCLookup Enabled, with global catalog config
+ Config: testAccRedfishDirectoryServiceAuthProviderStandardSchemaGlobalCatalogConfig(creds),
+ ExpectError: regexp.MustCompile("GlobalCatalog can not be configured for Enabled GCLookupEnable"),
+ },
+ {
+ // error Standard Schema GCLookup Disabled with no Globalcatalog config
+ Config: testAccRedfishDirectoryServiceAuthProviderStandardSchemaNoGlobalCatalogConfig(creds),
+ ExpectError: regexp.MustCompile("Invalid GlobalCatalog configuration for Standard Schema"),
+ },
+ {
+ // error Standard Schema GCLookup Disabled with GcRootDomain config
+ Config: testAccRedfishDirectoryServiceAuthProviderStandardSchemaGCRootConfig(creds),
+ ExpectError: regexp.MustCompile("GCRootDomain can not be configured for Disabled GCLookupEnable"),
+ },
+ },
+ })
+}
+
+func TestAccRedfishDirectoryServiceAuthProviderImport(t *testing.T) {
+ resource.Test(t, resource.TestCase{
+ PreCheck: func() { testAccPreCheck(t) },
+ ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
+ Steps: []resource.TestStep{
+ {
+ Config: `resource "redfish_directory_service_auth_provider" "ds_auth" {
+ }`,
+ ResourceName: "redfish_directory_service_auth_provider.ds_auth",
+ ImportState: true,
+ ImportStateId: "{\"username\":\"" + creds.Username + "\",\"password\":\"" + creds.Password + "\",\"endpoint\":\"https://" + creds.Endpoint + "\",\"ssl_insecure\":true}",
+ ExpectError: nil,
+ },
+ },
+ })
+}
+
+func testAccRedfishDirectoryServiceAuthProviderErrorConfig(testingInfo TestingServerCredentials) string {
+ return fmt.Sprintf(`
+ resource "redfish_directory_service_auth_provider" "ds_auth" {
+ redfish_server {
+ user = "%s"
+ password = "%s"
+ endpoint = "https://%s"
+ ssl_insecure = true
+ }
+
+ active_directory = {
+ directory = {
+ remote_role_mapping = [
+ {
+ local_role = "Administrator",
+ remote_group = "xxxx"
+ }
+ ],
+ service_addresses = [
+ "yulanadhost11.yulan.pie.lab.emc.com"
+ ],
+ service_enabled = true
+ }
+ }
+
+ active_directory_attributes = {
+ "ActiveDirectory.1.AuthTimeout"= "120",
+ "ActiveDirectory.1.CertValidationEnable"= "Enabled",
+ "ActiveDirectory.1.DCLookupEnable"= "Disabled",
+ "ActiveDirectory.1.RacDomain"= "test",
+ "ActiveDirectory.1.RacName"= "test",
+ "ActiveDirectory.1.SSOEnable"= "Enabled",
+ "ActiveDirectory.1.Schema"= "Extended Schema",
+ "UserDomain.1.Name"= "yulan.pie.lab.emc.com"
+ }
+
+ ldap = {
+ directory = {
+ remote_role_mapping = [
+ {
+ local_role = "Administrator",
+ remote_group = "cn = idracgroup,cn = users,dc = yulan,dc = pie,dc = lab,dc = emc,dc = com"
+ }
+ ],
+ service_addresses = [
+ "yulanadhost12.yulan.pie.lab.emc.com"
+ ],
+ service_enabled = false
+ },
+ ldap_service = {
+ search_settings = {
+ base_distinguished_names = [
+ "dc = yulan,dc = pie,dc = lab,dc = emc,dc = com"
+ ],
+ group_name_attribute = "name",
+ user_name_attribute = "member"
+ }
+ }
+ }
+
+ ldap_attributes = {
+ "LDAP.1.GroupAttributeIsDN" = "Enabled"
+ "LDAP.1.Port" = "636",
+ "LDAP.1.BindDN" = "cn = adtester,cn = users,dc = yulan,dc = pie,dc = lab,dc = emc,dc = com",
+ "LDAP.1.BindPassword" = "",
+ "LDAP.1.SearchFilter" = "(objectclass = *)"
+ }
+ }
+ `,
+ testingInfo.Username,
+ testingInfo.Password,
+ testingInfo.Endpoint,
+ )
+}
+
+func testAccRedfishDirectoryServiceAuthProviderADConfig(testingInfo TestingServerCredentials) string {
+ return fmt.Sprintf(`
+ resource "redfish_directory_service_auth_provider" "ds_auth" {
+ redfish_server {
+ user = "%s"
+ password = "%s"
+ endpoint = "https://%s"
+ ssl_insecure = true
+ }
+ active_directory = {
+ directory = {
+ service_enabled = true
+
+ }
+ }
+
+ active_directory_attributes = {
+ "ActiveDirectory.1.AuthTimeout"= "120",
+ "ActiveDirectory.1.CertValidationEnable"= "Enabled",
+ "ActiveDirectory.1.DCLookupEnable"= "Enabled",
+ "ActiveDirectory.1.RacDomain"= "test",
+ "ActiveDirectory.1.RacName"= "test",
+ "ActiveDirectory.1.SSOEnable"= "Disabled",
+ "ActiveDirectory.1.Schema"= "Extended Schema",
+ "UserDomain.1.Name"= "yulan.pie.lab.emc.com",
+ "ActiveDirectory.1.DCLookupByUserDomain":"Enabled",
+ }
+ }
+ `,
+ testingInfo.Username,
+ testingInfo.Password,
+ testingInfo.Endpoint,
+ )
+}
+
+func testAccRedfishDirectoryServiceAuthProviderLDAPConfig(testingInfo TestingServerCredentials) string {
+ return fmt.Sprintf(`
+ resource "redfish_directory_service_auth_provider" "ds_auth" {
+ redfish_server {
+ user = "%s"
+ password = "%s"
+ endpoint = "https://%s"
+ ssl_insecure = true
+ }
+ ldap = {
+ directory = {
+ remote_role_mapping = [
+ {
+ local_role = "Administrator",
+ remote_group = "cn = idracgroup,cn = users,dc = yulan,dc = pie,dc = lab,dc = emc,dc = com"
+ }
+ ],
+ service_addresses = [
+ "yulanadhost12.yulan.pie.lab.emc.com"
+ ],
+ service_enabled = false
+ },
+ ldap_service = {
+ search_settings = {
+ base_distinguished_names = [
+ "dc = yulan,dc = pie,dc = lab,dc = emc,dc = com"
+ ],
+ group_name_attribute = "name",
+ user_name_attribute = "member"
+ }
+ }
+ }
+
+ ldap_attributes = {
+ "LDAP.1.GroupAttributeIsDN" = "Enabled"
+ "LDAP.1.Port" = "636",
+ "LDAP.1.BindDN" = "cn = adtester,cn = users,dc = yulan,dc = pie,dc = lab,dc = emc,dc = com",
+ "LDAP.1.BindPassword" = "",
+ "LDAP.1.SearchFilter" = "(objectclass = *)"
+ }
+ }
+ `,
+ testingInfo.Username,
+ testingInfo.Password,
+ testingInfo.Endpoint,
+ )
+}
+
+func testAccRedfishDirectoryServiceAuthProviderAD_UpdateConfig(testingInfo TestingServerCredentials) string {
+ return fmt.Sprintf(`
+ resource "redfish_directory_service_auth_provider" "ds_auth" {
+ redfish_server {
+ user = "%s"
+ password = "%s"
+ endpoint = "https://%s"
+ ssl_insecure = true
+ }
+
+ active_directory = {
+ directory = {
+ service_enabled = false,
+ authentication = {
+ kerberos_key_tab_file = ""
+ }
+ }
+ }
+
+ active_directory_attributes = {
+ "ActiveDirectory.1.AuthTimeout"= "130",
+ "ActiveDirectory.1.CertValidationEnable"= "Enabled",
+ "ActiveDirectory.1.DCLookupEnable"= "Enabled",
+ "ActiveDirectory.1.RacDomain"= "test",
+ "ActiveDirectory.1.RacName"= "test",
+ "ActiveDirectory.1.SSOEnable"= "Disabled",
+ "ActiveDirectory.1.Schema"= "Extended Schema",
+ "UserDomain.1.Name"= "yulan.pie.lab.emc.com",
+ "ActiveDirectory.1.DCLookupByUserDomain":"Enabled",
+ }
+ }
+ `,
+ testingInfo.Username,
+ testingInfo.Password,
+ testingInfo.Endpoint,
+ )
+}
+
+func testAccRedfishDirectoryServiceAuthProviderEmptyAuth(testingInfo TestingServerCredentials) string {
+ return fmt.Sprintf(`
+ resource "redfish_directory_service_auth_provider" "ds_auth" {
+ redfish_server {
+ user = "%s"
+ password = "%s"
+ endpoint = "https://%s"
+ ssl_insecure = true
+ }
+
+ active_directory = {
+ directory = {
+
+ service_addresses = [
+ "yulanadhost11.yulan.pie.lab.emc.com"
+ ],
+ service_enabled = true
+ }
+ }
+
+ active_directory_attributes = {
+ "ActiveDirectory.1.CertValidationEnable"= "Enabled",
+ "ActiveDirectory.1.DCLookupEnable"= "Disabled",
+ "ActiveDirectory.1.RacDomain"= "test",
+ "ActiveDirectory.1.RacName"= "test",
+ "ActiveDirectory.1.SSOEnable"= "Disabled",
+ "ActiveDirectory.1.Schema"= "Extended Schema",
+ "UserDomain.1.Name"= "yulan.pie.lab.emc.com"
+ }
+ }
+ `,
+ testingInfo.Username,
+ testingInfo.Password,
+ testingInfo.Endpoint,
+ )
+}
+
+func testAccRedfishDirectoryServiceAuthProviderInvalidAuth(testingInfo TestingServerCredentials) string {
+ return fmt.Sprintf(`
+ resource "redfish_directory_service_auth_provider" "ds_auth" {
+ redfish_server {
+ user = "%s"
+ password = "%s"
+ endpoint = "https://%s"
+ ssl_insecure = true
+ }
+
+ active_directory = {
+ directory = {
+
+ service_addresses = [
+ "yulanadhost11.yulan.pie.lab.emc.com"
+ ],
+ service_enabled = true
+ }
+ }
+
+ active_directory_attributes = {
+ "ActiveDirectory.1.AuthTimeout"= "12",
+ "ActiveDirectory.1.CertValidationEnable"= "Enabled",
+ "ActiveDirectory.1.DCLookupEnable"= "Disabled",
+ "ActiveDirectory.1.RacDomain"= "test",
+ "ActiveDirectory.1.RacName"= "test",
+ "ActiveDirectory.1.SSOEnable"= "Disabled",
+ "ActiveDirectory.1.Schema"= "Extended Schema",
+ #"ADGroup.1.Domain" = "yulan.pie.lab.emc.com",
+ "UserDomain.1.Name"= "yulan.pie.lab.emc.com"
+ }
+ }
+ `,
+ testingInfo.Username,
+ testingInfo.Password,
+ testingInfo.Endpoint,
+ )
+}
+
+func testAccRedfishDirectoryServiceAuthProviderADDisableSSOEnable(testingInfo TestingServerCredentials) string {
+ return fmt.Sprintf(`
+ resource "redfish_directory_service_auth_provider" "ds_auth" {
+ redfish_server {
+ user = "%s"
+ password = "%s"
+ endpoint = "https://%s"
+ ssl_insecure = true
+ }
+
+ active_directory = {
+ directory = {
+
+ service_addresses = [
+ "yulanadhost11.yulan.pie.lab.emc.com"
+ ],
+ service_enabled = false
+ }
+ }
+
+ active_directory_attributes = {
+ "ActiveDirectory.1.AuthTimeout"= "120",
+ "ActiveDirectory.1.CertValidationEnable"= "Enabled",
+ "ActiveDirectory.1.DCLookupEnable"= "Disabled",
+ "ActiveDirectory.1.RacDomain"= "test",
+ "ActiveDirectory.1.RacName"= "test",
+ "ActiveDirectory.1.SSOEnable"= "Enabled",
+ "ActiveDirectory.1.Schema"= "Extended Schema",
+ #"ADGroup.1.Domain" = "yulan.pie.lab.emc.com",
+ "UserDomain.1.Name"= "yulan.pie.lab.emc.com"
+ }
+ }
+ `,
+ testingInfo.Username,
+ testingInfo.Password,
+ testingInfo.Endpoint,
+ )
+}
+
+func testAccRedfishDirectoryServiceAuthProviderADEnSSOEnNoKb(testingInfo TestingServerCredentials) string {
+ return fmt.Sprintf(`
+ resource "redfish_directory_service_auth_provider" "ds_auth" {
+ redfish_server {
+ user = "%s"
+ password = "%s"
+ endpoint = "https://%s"
+ ssl_insecure = true
+ }
+
+ active_directory = {
+ directory = {
+
+ service_addresses = [
+ "yulanadhost11.yulan.pie.lab.emc.com"
+ ],
+ service_enabled = true
+ }
+ }
+
+ active_directory_attributes = {
+ "ActiveDirectory.1.AuthTimeout"= "120",
+ "ActiveDirectory.1.CertValidationEnable"= "Enabled",
+ "ActiveDirectory.1.DCLookupEnable"= "Disabled",
+ "ActiveDirectory.1.RacDomain"= "test",
+ "ActiveDirectory.1.RacName"= "test",
+ "ActiveDirectory.1.SSOEnable"= "Enabled",
+ "ActiveDirectory.1.Schema"= "Extended Schema",
+ "UserDomain.1.Name"= "yulan.pie.lab.emc.com"
+ }
+ }
+ `,
+ testingInfo.Username,
+ testingInfo.Password,
+ testingInfo.Endpoint,
+ )
+}
+
+func testAccRedfishDirectoryServiceAuthProviderDClookUpEnServiceAddEmpty(testingInfo TestingServerCredentials) string {
+ return fmt.Sprintf(`
+ resource "redfish_directory_service_auth_provider" "ds_auth" {
+ redfish_server {
+ user = "%s"
+ password = "%s"
+ endpoint = "https://%s"
+ ssl_insecure = true
+ }
+
+ active_directory = {
+ directory = {
+ service_enabled = true,
+ }
+ }
+
+ active_directory_attributes = {
+ "ActiveDirectory.1.AuthTimeout"= "120",
+ "ActiveDirectory.1.CertValidationEnable"= "Enabled",
+ "ActiveDirectory.1.DCLookupEnable"= "Disabled",
+ "ActiveDirectory.1.RacDomain"= "test",
+ "ActiveDirectory.1.RacName"= "test",
+ "ActiveDirectory.1.SSOEnable"= "Disabled",
+ "ActiveDirectory.1.Schema"= "Extended Schema",
+ "UserDomain.1.Name"= "yulan.pie.lab.emc.com"
+ }
+ }
+ `,
+ testingInfo.Username,
+ testingInfo.Password,
+ testingInfo.Endpoint,
+ )
+}
+
+func testAccRedfishDirectoryServiceAuthProviderDCLookupByUserDomainConfig(testingInfo TestingServerCredentials) string {
+ return fmt.Sprintf(`
+ resource "redfish_directory_service_auth_provider" "ds_auth" {
+ redfish_server {
+ user = "%s"
+ password = "%s"
+ endpoint = "https://%s"
+ ssl_insecure = true
+ }
+
+ active_directory = {
+ directory = {
+ service_addresses = [
+ "yulanadhost12.yulan.pie.lab.emc.com"
+ ],
+ service_enabled = true,
+ authentication = {
+ kerberos_key_tab_file = ""
+ }
+ }
+ }
+
+ active_directory_attributes = {
+ "ActiveDirectory.1.AuthTimeout"= "120",
+ "ActiveDirectory.1.CertValidationEnable"= "Enabled",
+ "ActiveDirectory.1.DCLookupEnable"= "Disabled",
+ "ActiveDirectory.1.RacDomain"= "test",
+ "ActiveDirectory.1.RacName"= "test",
+ "ActiveDirectory.1.SSOEnable"= "Disabled",
+ "ActiveDirectory.1.Schema"= "Extended Schema",
+ "UserDomain.1.Name"= "yulan.pie.lab.emc.com",
+ "ActiveDirectory.1.DCLookupByUserDomain":"Disabled",
+ }
+ }
+ `,
+ testingInfo.Username,
+ testingInfo.Password,
+ testingInfo.Endpoint,
+ )
+}
+
+func testAccRedfishDirectoryServiceAuthProviderDCLookupDomainNameConfig(testingInfo TestingServerCredentials) string {
+ return fmt.Sprintf(`
+ resource "redfish_directory_service_auth_provider" "ds_auth" {
+ redfish_server {
+ user = "%s"
+ password = "%s"
+ endpoint = "https://%s"
+ ssl_insecure = true
+ }
+
+ active_directory = {
+ directory = {
+ service_addresses = [
+ "yulanadhost12.yulan.pie.lab.emc.com"
+ ],
+ service_enabled = true,
+ authentication = {
+ kerberos_key_tab_file = ""
+ }
+ }
+ }
+
+ active_directory_attributes = {
+ "ActiveDirectory.1.AuthTimeout"= "120",
+ "ActiveDirectory.1.CertValidationEnable"= "Enabled",
+ "ActiveDirectory.1.DCLookupEnable"= "Disabled",
+ "ActiveDirectory.1.RacDomain"= "test",
+ "ActiveDirectory.1.RacName"= "test",
+ "ActiveDirectory.1.SSOEnable"= "Disabled",
+ "ActiveDirectory.1.Schema"= "Extended Schema",
+ "UserDomain.1.Name"= "yulan.pie.lab.emc.com",
+ #"ActiveDirectory.1.DCLookupByUserDomain":"Disabled",
+ "ActiveDirectory.1.DCLookupDomainName"="test",
+ }
+ }
+ `,
+ testingInfo.Username,
+ testingInfo.Password,
+ testingInfo.Endpoint,
+ )
+}
+
+func testAccRedfishDirectoryServiceAuthProviderDDCLookupEnableNoServiceAddConfig(testingInfo TestingServerCredentials) string {
+ return fmt.Sprintf(`
+ resource "redfish_directory_service_auth_provider" "ds_auth" {
+ redfish_server {
+ user = "%s"
+ password = "%s"
+ endpoint = "https://%s"
+ ssl_insecure = true
+ }
+
+ active_directory = {
+ directory = {
+ service_addresses = [
+ "yulanadhost12.yulan.pie.lab.emc.com"
+ ],
+ service_enabled = true,
+ authentication = {
+ kerberos_key_tab_file = ""
+ }
+ }
+ }
+
+ active_directory_attributes = {
+ "ActiveDirectory.1.AuthTimeout"= "120",
+ "ActiveDirectory.1.CertValidationEnable"= "Enabled",
+ "ActiveDirectory.1.DCLookupEnable"= "Enabled",
+ "ActiveDirectory.1.RacDomain"= "test",
+ "ActiveDirectory.1.RacName"= "test",
+ "ActiveDirectory.1.SSOEnable"= "Disabled",
+ "ActiveDirectory.1.Schema"= "Extended Schema",
+ "UserDomain.1.Name"= "yulan.pie.lab.emc.com",
+ "ActiveDirectory.1.DCLookupByUserDomain":"Disabled",
+ "ActiveDirectory.1.DCLookupDomainName"="test",
+ }
+ }
+ `,
+ testingInfo.Username,
+ testingInfo.Password,
+ testingInfo.Endpoint,
+ )
+}
+
+func testAccRedfishDirectoryServiceAuthProviderDCLookupByUserDomainEmptyConfig(testingInfo TestingServerCredentials) string {
+ return fmt.Sprintf(`
+ resource "redfish_directory_service_auth_provider" "ds_auth" {
+ redfish_server {
+ user = "%s"
+ password = "%s"
+ endpoint = "https://%s"
+ ssl_insecure = true
+ }
+
+ active_directory = {
+ directory = {
+ service_enabled = true,
+ authentication = {
+ kerberos_key_tab_file = ""
+ }
+ }
+ }
+
+ active_directory_attributes = {
+ "ActiveDirectory.1.AuthTimeout"= "120",
+ "ActiveDirectory.1.CertValidationEnable"= "Enabled",
+ "ActiveDirectory.1.DCLookupEnable"= "Enabled",
+ "ActiveDirectory.1.RacDomain"= "test",
+ "ActiveDirectory.1.RacName"= "test",
+ "ActiveDirectory.1.SSOEnable"= "Disabled",
+ "ActiveDirectory.1.Schema"= "Extended Schema",
+ "UserDomain.1.Name"= "yulan.pie.lab.emc.com",
+ "ActiveDirectory.1.DCLookupDomainName"="test",
+ }
+ }
+ `,
+ testingInfo.Username,
+ testingInfo.Password,
+ testingInfo.Endpoint,
+ )
+}
+
+func testAccRedfishDirectoryServiceAuthProviderDCLookupDomainNameEmptyConfig(testingInfo TestingServerCredentials) string {
+ return fmt.Sprintf(`
+ resource "redfish_directory_service_auth_provider" "ds_auth" {
+ redfish_server {
+ user = "%s"
+ password = "%s"
+ endpoint = "https://%s"
+ ssl_insecure = true
+ }
+
+ active_directory = {
+ directory = {
+ service_enabled = true,
+ authentication = {
+ kerberos_key_tab_file = ""
+ }
+ }
+ }
+
+ active_directory_attributes = {
+ "ActiveDirectory.1.AuthTimeout"= "120",
+ "ActiveDirectory.1.CertValidationEnable"= "Enabled",
+ "ActiveDirectory.1.DCLookupEnable"= "Enabled",
+ "ActiveDirectory.1.RacDomain"= "test",
+ "ActiveDirectory.1.RacName"= "test",
+ "ActiveDirectory.1.SSOEnable"= "Disabled",
+ "ActiveDirectory.1.Schema"= "Extended Schema",
+ "UserDomain.1.Name"= "yulan.pie.lab.emc.com",
+ "ActiveDirectory.1.DCLookupByUserDomain":"Disabled",
+
+ }
+ }
+ `,
+ testingInfo.Username,
+ testingInfo.Password,
+ testingInfo.Endpoint,
+ )
+}
+
+func testAccRedfishDirectoryServiceAuthProviderDCLookupEnableDCLookupDomainNameConfig(testingInfo TestingServerCredentials) string {
+ return fmt.Sprintf(`
+ resource "redfish_directory_service_auth_provider" "ds_auth" {
+ redfish_server {
+ user = "%s"
+ password = "%s"
+ endpoint = "https://%s"
+ ssl_insecure = true
+ }
+
+ active_directory = {
+ directory = {
+ service_enabled = true,
+ authentication = {
+ kerberos_key_tab_file = ""
+ }
+ }
+ }
+
+ active_directory_attributes = {
+ "ActiveDirectory.1.AuthTimeout"= "120",
+ "ActiveDirectory.1.CertValidationEnable"= "Enabled",
+ "ActiveDirectory.1.DCLookupEnable"= "Enabled",
+ "ActiveDirectory.1.RacDomain"= "test",
+ "ActiveDirectory.1.RacName"= "test",
+ "ActiveDirectory.1.SSOEnable"= "Disabled",
+ "ActiveDirectory.1.Schema"= "Extended Schema",
+ "UserDomain.1.Name"= "yulan.pie.lab.emc.com",
+ "ActiveDirectory.1.DCLookupByUserDomain":"Enabled",
+ "ActiveDirectory.1.DCLookupDomainName"="test",
+ }
+ }
+ `,
+ testingInfo.Username,
+ testingInfo.Password,
+ testingInfo.Endpoint,
+ )
+}
+
+func testAccRedfishDirectoryServiceAuthProviderExtendedNoRacConfig(testingInfo TestingServerCredentials) string {
+ return fmt.Sprintf(`
+ resource "redfish_directory_service_auth_provider" "ds_auth" {
+ redfish_server {
+ user = "%s"
+ password = "%s"
+ endpoint = "https://%s"
+ ssl_insecure = true
+ }
+
+ active_directory = {
+ directory = {
+ service_enabled = true,
+ authentication = {
+ kerberos_key_tab_file = ""
+ }
+ }
+ }
+
+ active_directory_attributes = {
+ "ActiveDirectory.1.AuthTimeout"= "120",
+ "ActiveDirectory.1.CertValidationEnable"= "Enabled",
+ "ActiveDirectory.1.DCLookupEnable"= "Enabled",
+ "ActiveDirectory.1.SSOEnable"= "Disabled",
+ "ActiveDirectory.1.Schema"= "Extended Schema",
+ "UserDomain.1.Name"= "yulan.pie.lab.emc.com",
+ "ActiveDirectory.1.DCLookupByUserDomain":"Enabled",
+ }
+ }
+ `,
+ testingInfo.Username,
+ testingInfo.Password,
+ testingInfo.Endpoint,
+ )
+}
+
+func testAccRedfishDirectoryServiceAuthProviderExtendedEmptyRacConfig(testingInfo TestingServerCredentials) string {
+ return fmt.Sprintf(`
+ resource "redfish_directory_service_auth_provider" "ds_auth" {
+ redfish_server {
+ user = "%s"
+ password = "%s"
+ endpoint = "https://%s"
+ ssl_insecure = true
+ }
+
+ active_directory = {
+ directory = {
+ service_enabled = true,
+ authentication = {
+ kerberos_key_tab_file = ""
+ }
+ }
+ }
+
+ active_directory_attributes = {
+ "ActiveDirectory.1.AuthTimeout"= "120",
+ "ActiveDirectory.1.CertValidationEnable"= "Enabled",
+ "ActiveDirectory.1.DCLookupEnable"= "Enabled",
+ "ActiveDirectory.1.SSOEnable"= "Disabled",
+ "ActiveDirectory.1.Schema"= "Extended Schema",
+ "ActiveDirectory.1.RacDomain"= "",
+ "ActiveDirectory.1.RacName"= "",
+ "UserDomain.1.Name"= "yulan.pie.lab.emc.com",
+ "ActiveDirectory.1.DCLookupByUserDomain":"Enabled",
+ }
+ }
+ `,
+ testingInfo.Username,
+ testingInfo.Password,
+ testingInfo.Endpoint,
+ )
+}
+
+func testAccRedfishDirectoryServiceAuthProviderExtendedGCLookUpConfig(testingInfo TestingServerCredentials) string {
+ return fmt.Sprintf(`
+ resource "redfish_directory_service_auth_provider" "ds_auth" {
+ redfish_server {
+ user = "%s"
+ password = "%s"
+ endpoint = "https://%s"
+ ssl_insecure = true
+ }
+
+ active_directory = {
+ directory = {
+ service_enabled = true,
+ authentication = {
+ kerberos_key_tab_file = ""
+ }
+ }
+ }
+
+ active_directory_attributes = {
+ "ActiveDirectory.1.AuthTimeout"= "120",
+ "ActiveDirectory.1.CertValidationEnable"= "Enabled",
+ "ActiveDirectory.1.DCLookupEnable"= "Enabled",
+ "ActiveDirectory.1.SSOEnable"= "Disabled",
+ "ActiveDirectory.1.Schema"= "Extended Schema",
+ "ActiveDirectory.1.RacDomain"= "test",
+ "ActiveDirectory.1.RacName"= "test",
+ "UserDomain.1.Name"= "yulan.pie.lab.emc.com",
+ "ActiveDirectory.1.DCLookupByUserDomain":"Enabled",
+ "ActiveDirectory.1.GCLookupEnable" = "Disabled",
+ }
+ }
+ `,
+ testingInfo.Username,
+ testingInfo.Password,
+ testingInfo.Endpoint,
+ )
+}
+
+func testAccRedfishDirectoryServiceAuthProviderExtendedRemoteRoleConfig(testingInfo TestingServerCredentials) string {
+ return fmt.Sprintf(`
+ resource "redfish_directory_service_auth_provider" "ds_auth" {
+ redfish_server {
+ user = "%s"
+ password = "%s"
+ endpoint = "https://%s"
+ ssl_insecure = true
+ }
+
+ active_directory = {
+ directory = {
+ remote_role_mapping = [
+ {
+ local_role = "Administrator",
+ remote_group = "xxxx"
+ }
+ ],
+ service_enabled = true,
+ authentication = {
+ kerberos_key_tab_file = ""
+ }
+ }
+ }
+
+ active_directory_attributes = {
+ "ActiveDirectory.1.AuthTimeout"= "120",
+ "ActiveDirectory.1.CertValidationEnable"= "Enabled",
+ "ActiveDirectory.1.DCLookupEnable"= "Enabled",
+ "ActiveDirectory.1.SSOEnable"= "Disabled",
+ "ActiveDirectory.1.Schema"= "Extended Schema",
+ "ActiveDirectory.1.RacDomain"= "test",
+ "ActiveDirectory.1.RacName"= "test",
+ "UserDomain.1.Name"= "yulan.pie.lab.emc.com",
+ "ActiveDirectory.1.DCLookupByUserDomain":"Enabled",
+
+ }
+ }
+ `,
+ testingInfo.Username,
+ testingInfo.Password,
+ testingInfo.Endpoint,
+ )
+}
+
+func testAccRedfishDirectoryServiceAuthProviderExtendedADGroupDomainConfig(testingInfo TestingServerCredentials) string {
+ return fmt.Sprintf(`
+ resource "redfish_directory_service_auth_provider" "ds_auth" {
+ redfish_server {
+ user = "%s"
+ password = "%s"
+ endpoint = "https://%s"
+ ssl_insecure = true
+ }
+
+ active_directory = {
+ directory = {
+ service_enabled = true,
+ authentication = {
+ kerberos_key_tab_file = ""
+ }
+ }
+ }
+
+ active_directory_attributes = {
+ "ActiveDirectory.1.AuthTimeout"= "120",
+ "ActiveDirectory.1.CertValidationEnable"= "Enabled",
+ "ActiveDirectory.1.DCLookupEnable"= "Enabled",
+ "ActiveDirectory.1.SSOEnable"= "Disabled",
+ "ActiveDirectory.1.Schema"= "Extended Schema",
+ "ActiveDirectory.1.RacDomain"= "test",
+ "ActiveDirectory.1.RacName"= "test",
+ "UserDomain.1.Name"= "yulan.pie.lab.emc.com",
+ "ActiveDirectory.1.DCLookupByUserDomain":"Enabled",
+ "ADGroup.1.Domain" = "yulan.pie.lab.emc.com",
+
+ }
+ }
+ `,
+ testingInfo.Username,
+ testingInfo.Password,
+ testingInfo.Endpoint,
+ )
+}
+
+func testAccRedfishDirectoryServiceAuthProviderStandardSchemaAndRacConfig(testingInfo TestingServerCredentials) string {
+ return fmt.Sprintf(`
+ resource "redfish_directory_service_auth_provider" "ds_auth" {
+ redfish_server {
+ user = "%s"
+ password = "%s"
+ endpoint = "https://%s"
+ ssl_insecure = true
+ }
+
+ active_directory = {
+ directory = {
+ service_enabled = true,
+ authentication = {
+ kerberos_key_tab_file = ""
+ }
+ }
+ }
+
+ active_directory_attributes = {
+ "ActiveDirectory.1.AuthTimeout"= "120",
+ "ActiveDirectory.1.CertValidationEnable"= "Enabled",
+ "ActiveDirectory.1.DCLookupEnable"= "Enabled",
+ "ActiveDirectory.1.SSOEnable"= "Disabled",
+ "ActiveDirectory.1.Schema"= "Standard Schema",
+ "ActiveDirectory.1.RacDomain"= "test",
+ "ActiveDirectory.1.RacName"= "test",
+ "UserDomain.1.Name"= "yulan.pie.lab.emc.com",
+ "ActiveDirectory.1.DCLookupByUserDomain":"Enabled",
+ }
+ }
+ `,
+ testingInfo.Username,
+ testingInfo.Password,
+ testingInfo.Endpoint,
+ )
+}
+
+func testAccRedfishDirectoryServiceAuthProviderStandardSchemaNoGCLookUpConfig(testingInfo TestingServerCredentials) string {
+ return fmt.Sprintf(`
+ resource "redfish_directory_service_auth_provider" "ds_auth" {
+ redfish_server {
+ user = "%s"
+ password = "%s"
+ endpoint = "https://%s"
+ ssl_insecure = true
+ }
+
+ active_directory = {
+ directory = {
+ service_enabled = true,
+ authentication = {
+ kerberos_key_tab_file = ""
+ }
+ }
+ }
+
+ active_directory_attributes = {
+ "ActiveDirectory.1.AuthTimeout"= "120",
+ "ActiveDirectory.1.CertValidationEnable"= "Enabled",
+ "ActiveDirectory.1.DCLookupEnable"= "Enabled",
+ "ActiveDirectory.1.SSOEnable"= "Disabled",
+ "ActiveDirectory.1.Schema"= "Standard Schema",
+ "UserDomain.1.Name"= "yulan.pie.lab.emc.com",
+ "ActiveDirectory.1.DCLookupByUserDomain":"Enabled",
+ }
+ }
+ `,
+ testingInfo.Username,
+ testingInfo.Password,
+ testingInfo.Endpoint,
+ )
+}
+
+func testAccRedfishDirectoryServiceAuthProviderStandardSchemaNoGCRootConfig(testingInfo TestingServerCredentials) string {
+ return fmt.Sprintf(`
+ resource "redfish_directory_service_auth_provider" "ds_auth" {
+ redfish_server {
+ user = "%s"
+ password = "%s"
+ endpoint = "https://%s"
+ ssl_insecure = true
+ }
+
+ active_directory = {
+ directory = {
+ service_enabled = true,
+ authentication = {
+ kerberos_key_tab_file = ""
+ }
+ }
+ }
+
+ active_directory_attributes = {
+ "ActiveDirectory.1.AuthTimeout"= "120",
+ "ActiveDirectory.1.CertValidationEnable"= "Enabled",
+ "ActiveDirectory.1.DCLookupEnable"= "Enabled",
+ "ActiveDirectory.1.SSOEnable"= "Disabled",
+ "ActiveDirectory.1.Schema"= "Standard Schema",
+ "UserDomain.1.Name"= "yulan.pie.lab.emc.com",
+ "ActiveDirectory.1.DCLookupByUserDomain":"Enabled",
+ "ActiveDirectory.1.GCLookupEnable" = "Enabled",
+ }
+ }
+ `,
+ testingInfo.Username,
+ testingInfo.Password,
+ testingInfo.Endpoint,
+ )
+}
+
+func testAccRedfishDirectoryServiceAuthProviderStandardSchemaGlobalCatalogConfig(testingInfo TestingServerCredentials) string {
+ return fmt.Sprintf(`
+ resource "redfish_directory_service_auth_provider" "ds_auth" {
+ redfish_server {
+ user = "%s"
+ password = "%s"
+ endpoint = "https://%s"
+ ssl_insecure = true
+ }
+
+ active_directory = {
+ directory = {
+ service_enabled = true,
+ authentication = {
+ kerberos_key_tab_file = ""
+ }
+ }
+ }
+
+ active_directory_attributes = {
+ "ActiveDirectory.1.AuthTimeout"= "120",
+ "ActiveDirectory.1.CertValidationEnable"= "Enabled",
+ "ActiveDirectory.1.DCLookupEnable"= "Enabled",
+ "ActiveDirectory.1.SSOEnable"= "Disabled",
+ "ActiveDirectory.1.Schema"= "Standard Schema",
+ "UserDomain.1.Name"= "yulan.pie.lab.emc.com",
+ "ActiveDirectory.1.DCLookupByUserDomain":"Enabled",
+ "ActiveDirectory.1.GCLookupEnable" = "Enabled",
+ "ActiveDirectory.1.GCRootDomain" = "test",
+ "ActiveDirectory.1.GlobalCatalog1" = "yulanadhost11.yulan.pie.lab.emc.com",
+ }
+ }
+ `,
+ testingInfo.Username,
+ testingInfo.Password,
+ testingInfo.Endpoint,
+ )
+}
+
+func testAccRedfishDirectoryServiceAuthProviderStandardSchemaNoGlobalCatalogConfig(testingInfo TestingServerCredentials) string {
+ return fmt.Sprintf(`
+ resource "redfish_directory_service_auth_provider" "ds_auth" {
+ redfish_server {
+ user = "%s"
+ password = "%s"
+ endpoint = "https://%s"
+ ssl_insecure = true
+ }
+
+ active_directory = {
+ directory = {
+ service_enabled = true,
+ authentication = {
+ kerberos_key_tab_file = ""
+ }
+ }
+ }
+
+ active_directory_attributes = {
+ "ActiveDirectory.1.AuthTimeout"= "120",
+ "ActiveDirectory.1.CertValidationEnable"= "Enabled",
+ "ActiveDirectory.1.DCLookupEnable"= "Enabled",
+ "ActiveDirectory.1.SSOEnable"= "Disabled",
+ "ActiveDirectory.1.Schema"= "Standard Schema",
+ "UserDomain.1.Name"= "yulan.pie.lab.emc.com",
+ "ActiveDirectory.1.DCLookupByUserDomain":"Enabled",
+ "ActiveDirectory.1.GCLookupEnable" = "Disabled",
+ "ActiveDirectory.1.GlobalCatalog1" = "",
+ }
+ }
+ `,
+ testingInfo.Username,
+ testingInfo.Password,
+ testingInfo.Endpoint,
+ )
+}
+
+func testAccRedfishDirectoryServiceAuthProviderStandardSchemaGCRootConfig(testingInfo TestingServerCredentials) string {
+ return fmt.Sprintf(`
+ resource "redfish_directory_service_auth_provider" "ds_auth" {
+ redfish_server {
+ user = "%s"
+ password = "%s"
+ endpoint = "https://%s"
+ ssl_insecure = true
+ }
+
+ active_directory = {
+ directory = {
+ service_enabled = true,
+ authentication = {
+ kerberos_key_tab_file = ""
+ }
+ }
+ }
+
+ active_directory_attributes = {
+ "ActiveDirectory.1.AuthTimeout"= "120",
+ "ActiveDirectory.1.CertValidationEnable"= "Enabled",
+ "ActiveDirectory.1.DCLookupEnable"= "Enabled",
+ "ActiveDirectory.1.SSOEnable"= "Disabled",
+ "ActiveDirectory.1.Schema"= "Standard Schema",
+ "UserDomain.1.Name"= "yulan.pie.lab.emc.com",
+ "ActiveDirectory.1.DCLookupByUserDomain":"Enabled",
+ "ActiveDirectory.1.GCLookupEnable" = "Disabled",
+ "ActiveDirectory.1.GCRootDomain" = "test",
+ "ActiveDirectory.1.GlobalCatalog1" = "yulanadhost11.yulan.pie.lab.emc.com",
+ }
+ }
+ `,
+ testingInfo.Username,
+ testingInfo.Password,
+ testingInfo.Endpoint,
+ )
+}