Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updating test coverage for DSAP and LC attributes #274

Merged
merged 2 commits into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 1 addition & 11 deletions docs/resources/directory_service_auth_provider.md
Original file line number Diff line number Diff line change
Expand Up @@ -224,13 +224,7 @@ resource "redfish_directory_service_auth_provider" "ds_auth" {
# "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": "",
#"ActiveDirectory.1.GCRootDomain" = "test"
}


Expand Down Expand Up @@ -266,10 +260,6 @@ resource "redfish_directory_service_auth_provider" "ds_auth" {
# "LDAP.1.BindPassword" = "",
# "LDAP.1.SearchFilter" = "(objectclass = *)",
#
# #"LDAP.1.RSASecurID2FALDAP":"Enabled",
# #"RSASecurID2FA.1.RSASecurIDAccessKey": "●●1",
# #"RSASecurID2FA.1.RSASecurIDClientID": "●●1",
# #"RSASecurID2FA.1.RSASecurIDAuthenticationServer": "",
# }

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,13 +92,7 @@ resource "redfish_directory_service_auth_provider" "ds_auth" {
# "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": "",
#"ActiveDirectory.1.GCRootDomain" = "test"
}


Expand Down Expand Up @@ -134,10 +128,6 @@ resource "redfish_directory_service_auth_provider" "ds_auth" {
# "LDAP.1.BindPassword" = "",
# "LDAP.1.SearchFilter" = "(objectclass = *)",
#
# #"LDAP.1.RSASecurID2FALDAP":"Enabled",
# #"RSASecurID2FA.1.RSASecurIDAccessKey": "●●1",
# #"RSASecurID2FA.1.RSASecurIDClientID": "●●1",
# #"RSASecurID2FA.1.RSASecurIDAuthenticationServer": "",
# }

}
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ func loadActiveDirectoryAttributesState(service *gofish.Service, d *models.Direc
}

// nolint: gocyclo, gocognit,revive
activeDirectoryAttributes := []string{".CertValidationEnable", ".SSOEnable", ".AuthTimeout", ".DCLookupEnable", ".DCLookupByUserDomain", ".DCLookupDomainName", ".Schema", ".GCLookupEnable", ".GCRootDomain", ".GlobalCatalog1", ".GlobalCatalog2", ".GlobalCatalog3", ".RacName", ".RacDomain", ".RSASecurID2FAAD"}
activeDirectoryAttributes := []string{".CertValidationEnable", ".SSOEnable", ".AuthTimeout", ".DCLookupEnable", ".DCLookupByUserDomain", ".DCLookupDomainName", ".Schema", ".GCLookupEnable", ".GCRootDomain", ".GlobalCatalog1", ".GlobalCatalog2", ".GlobalCatalog3", ".RacName", ".RacDomain"}
attributesToReturn := make(map[string]attr.Value)
for k, v := range idracAttributesState.Attributes.Elements() {
if strings.HasPrefix(k, "ActiveDirectory.") {
Expand All @@ -180,7 +180,7 @@ func loadActiveDirectoryAttributesState(service *gofish.Service, d *models.Direc
}
}
// nolint: revive
if (strings.HasPrefix(k, "UserDomain.") && strings.HasSuffix(k, ".Name")) || (strings.HasPrefix(k, "ADGroup.") && strings.HasSuffix(k, ".Name")) || (strings.HasPrefix(k, "RSASecurID2FA.") && strings.HasSuffix(k, ".RSASecurIDAuthenticationServer")) {
if (strings.HasPrefix(k, "UserDomain.") && strings.HasSuffix(k, ".Name")) || (strings.HasPrefix(k, "ADGroup.") && strings.HasSuffix(k, ".Name")) {
attributesToReturn[k] = v
}
}
Expand All @@ -196,7 +196,7 @@ func loadLDAPAttributesState(service *gofish.Service, d *models.DirectoryService
}

// nolint: gocyclo, gocognit,revive
ldapAttributes := []string{".CertValidationEnable", ".GroupAttributeIsDN", ".Port", ".BindDN", ".BindPassword", ".SearchFilter", ".RSASecurID2FALDAP"}
ldapAttributes := []string{".CertValidationEnable", ".GroupAttributeIsDN", ".Port", ".BindDN", ".BindPassword", ".SearchFilter"}
attributesToReturn := make(map[string]attr.Value)
for k, v := range idracAttributesState.Attributes.Elements() {
if strings.HasPrefix(k, "LDAP.") {
Expand All @@ -206,9 +206,6 @@ func loadLDAPAttributesState(service *gofish.Service, d *models.DirectoryService
}
}
}
if strings.HasPrefix(k, "RSASecurID2FA.") && strings.HasSuffix(k, ".RSASecurIDAuthenticationServer") {
attributesToReturn[k] = v
}
}

d.LDAPAttributes = types.MapValueMust(types.StringType, attributesToReturn)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ package provider
import (
"context"
"encoding/json"
"errors"
"fmt"
"io"
"slices"
Expand Down Expand Up @@ -305,6 +306,12 @@ func updateRedfishDellLCAttributes(ctx context.Context, service *gofish.Service,
diags.AddError(idracError, err.Error())
return diags
}
err = assertLCAttributes(attributesTf, managerAttributeRegistry)
if err != nil {
diags.AddError(fmt.Sprintf("%s: LCAttributes registry from iDRAC does not match input", idracError), err.Error())
return diags
}

// Set right attributes to patch (values from map are all string. It needs int and string)
attributesToPatch, err := setManagerAttributesRightType(attributesTf, managerAttributeRegistry)
if err != nil {
Expand Down Expand Up @@ -454,3 +461,27 @@ func getLCAttributes(attributes []*dell.Attributes) (*dell.Attributes, error) {
}
return nil, fmt.Errorf("couldn't find LCAttributes")
}

func assertLCAttributes(rawAttributes map[string]string, managerAttributeRegistry *dell.ManagerAttributeRegistry) error {
var err error
// make map of name to ID of attributes
attributes := make(map[string]string)
for _, dellAttr := range managerAttributeRegistry.Attributes {
attributes[dellAttr.AttributeName] = dellAttr.ID
}

// check if all input attributes are present in registry
// if present, make sure that its ID starts with LifecycleController, ie. it is a LC attribute
for k := range rawAttributes {
attrID, ok := attributes[k]
if !ok {
err = errors.Join(err, fmt.Errorf("couldn't find manager attribute %s", k))
continue
}
// check if attribute is a system attribute
if !strings.HasPrefix(attrID, "LifecycleController.Embedded.1") {
err = errors.Join(err, fmt.Errorf("attribute %s is not a LCAttributes, its ID is %s", k, attrID))
}
}
return err
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"regexp"
"testing"

"github.com/bytedance/mockey"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
)

Expand Down Expand Up @@ -59,10 +60,58 @@ func TestAccRedfishLCAttributesInvalidAttribute(t *testing.T) {
creds),
ExpectError: regexp.MustCompile("there was an issue when creating/updating LC attributes"),
},
{
Config: testAccRedfishResourceLCConfigInvalidData(
creds),
ExpectError: regexp.MustCompile("there was an issue when creating/updating LC attributes"),
},
{
Config: testAccRedfishResourceLCEmptyConfig(
creds),
ExpectError: regexp.MustCompile("there was an issue when creating/updating LC attributes"),
},
},
})
}

func TestAccRedfishLCAttributesInvalidAttribute_mocky(t *testing.T) {
var funcMocker1 *mockey.Mocker
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
Config: testAccRedfishResourceLCAttributesConfig(
creds),
},
{
PreConfig: func() {
FunctionMocker = mockey.Mock(assertLCAttributes).Return(fmt.Errorf("mock error")).Build()
},
Config: testAccRedfishResourceLCConfigInvalid(creds),
ExpectError: regexp.MustCompile(`.*mock error*.`),
},
{
PreConfig: func() {
if FunctionMocker != nil {
FunctionMocker.Release()
funcMocker1 = mockey.Mock(assertLCAttributes).Return(nil).Build()
FunctionMocker = mockey.Mock(setManagerAttributesRightType).Return(nil, fmt.Errorf("mock error")).Build()
}
},
Config: testAccRedfishResourceLCAttributesTypeInvalid(creds),
ExpectError: regexp.MustCompile(`.*mock error*.`),
},
},
})
if funcMocker1 != nil {
funcMocker1.Release()
}
if FunctionMocker != nil {
FunctionMocker.Release()
}
}

func TestAccRedfishLCAttributesUpdate(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Expand All @@ -86,6 +135,47 @@ func TestAccRedfishLCAttributesUpdate(t *testing.T) {
})
}

func TestAccRedfishLCAttributesCreateConfigErr(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
PreConfig: func() {
FunctionMocker = mockey.Mock(NewConfig).Return(nil, fmt.Errorf("mock error")).Build()
},
Config: testAccRedfishResourceLCAttributesConfig(creds),
ExpectError: regexp.MustCompile(`.*mock error*.`),
},
},
})
if FunctionMocker != nil {
FunctionMocker.Release()
}
}

func TestAccRedfishLCAttributesReadConfigErr(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
Config: testAccRedfishResourceLCAttributesConfig(creds),
},
{
PreConfig: func() {
FunctionMocker = mockey.Mock(NewConfig).Return(nil, fmt.Errorf("mock error")).Build()
},
Config: testAccRedfishResourceLCAttributesConfig(creds),
ExpectError: regexp.MustCompile(`.*mock error*.`),
},
},
})
if FunctionMocker != nil {
FunctionMocker.Release()
}
}

func TestAccRedfishLCAttributeImport(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Expand All @@ -103,6 +193,29 @@ func TestAccRedfishLCAttributeImport(t *testing.T) {
})
}

func TestAccRedfishLCAttributeImportCheck(t *testing.T) {
var lcAttributeResourceName = "redfish_dell_lc_attributes.lc"
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
Config: testAccRedfishResourceLCAttributesConfig(creds),
},
{
Config: testAccRedfishResourceLCAttributesConfig(creds),
ResourceName: lcAttributeResourceName,
ImportState: true,
ExpectError: nil,
ImportStateId: "{\"username\":\"" + creds.Username + "\",\"password\":\"" + creds.Password + "\",\"endpoint\":\"" + creds.Endpoint + "\",\"attributes\":[\"LCAttributes.1.CollectSystemInventoryOnRestart\",\"LCAttributes.1.IgnoreCertWarning\"],\"ssl_insecure\":true}",
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("redfish_dell_lc_attributes.lc", "attributes.LCAttributes.1.IgnoreCertWarning", "On"),
resource.TestCheckResourceAttr("redfish_dell_lc_attributes.lc", "attributes.LCAttributes.1.CollectSystemInventoryOnRestart", "Disabled"),
),
},
},
})
}
func testAccRedfishResourceLCAttributesConfig(testingInfo TestingServerCredentials) string {
return fmt.Sprintf(`
resource "redfish_dell_lc_attributes" "lc" {
Expand Down Expand Up @@ -170,3 +283,66 @@ func testAccRedfishResourceLCConfigInvalid(testingInfo TestingServerCredentials)
testingInfo.Endpoint,
)
}

func testAccRedfishResourceLCConfigInvalidData(testingInfo TestingServerCredentials) string {
return fmt.Sprintf(`
resource "redfish_dell_lc_attributes" "lc" {
redfish_server {
user = "%s"
password = "%s"
endpoint = "%s"
ssl_insecure = true
}

attributes = {
"LCAttributes.1.CollectSystemInventoryOnRestart" = "Disabled",
"LCAttributes.1.IgnoreCertWarning" = 1,
}
}
`,
testingInfo.Username,
testingInfo.Password,
testingInfo.Endpoint,
)
}

func testAccRedfishResourceLCEmptyConfig(testingInfo TestingServerCredentials) string {
return fmt.Sprintf(`
resource "redfish_dell_lc_attributes" "lc" {
redfish_server {
user = "%s"
password = "%s"
endpoint = "%s"
ssl_insecure = true
}

attributes = {
}
}
`,
testingInfo.Username,
testingInfo.Password,
testingInfo.Endpoint,
)
}

func testAccRedfishResourceLCAttributesTypeInvalid(testingInfo TestingServerCredentials) string {
return fmt.Sprintf(`
resource "redfish_dell_lc_attributes" "lc" {
redfish_server {
user = "%s"
password = "%s"
endpoint = "%s"
ssl_insecure = true
}

attributes = {
"invalid" = 9,
}
}
`,
testingInfo.Username,
testingInfo.Password,
testingInfo.Endpoint,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -343,10 +343,6 @@ func updateActiveDirectory(ctx context.Context, serviceURI string, service *gofi
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
Expand Down Expand Up @@ -395,10 +391,6 @@ func updateActiveDirectory(ctx context.Context, serviceURI string, service *gofi

// 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
Expand Down
Loading
Loading