Skip to content

Commit

Permalink
Add Supermicro OEM AccountService (#374)
Browse files Browse the repository at this point in the history
This adds an OEM version of the AccountService to expose a few
OEM-specific properties.

Signed-off-by: Sean McGinnis <[email protected]>
  • Loading branch information
stmcginnis authored Oct 16, 2024
1 parent 0cb0c9c commit 7257532
Show file tree
Hide file tree
Showing 3 changed files with 182 additions and 4 deletions.
64 changes: 64 additions & 0 deletions oem/smc/accountservice.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
//
// SPDX-License-Identifier: BSD-3-Clause
//

package smc

import (
"encoding/json"

"github.com/stmcginnis/gofish/redfish"
)

// AccountService is a Supermicro OEM instance of an AccountService.
type AccountService struct {
redfish.AccountService
SMCLDAP struct {
StartTLSEnabled bool
}
SMCActiveDirectory struct {
DNSLookupEnable bool
Prefix string
Port int
UserDomainNames []string
DynamicServerAddresses []string
}
}

// FromAccountService converts a standard AccountService object to the OEM implementation.
func FromAccountService(accountService *redfish.AccountService) (*AccountService, error) {
as := AccountService{
AccountService: *accountService,
}

var t struct {
Oem struct {
Supermicro struct {
LDAP struct {
StartTLSEnabled bool
} `json:"LDAP"`
ActiveDirectory struct {
DNSLookupEnable bool
Prefix string
Port int
UserDomainNames []string
DynamicServerAddresses []string
} `json:"ActiveDirectory"`
} `json:"Supermicro"`
} `json:"Oem"`
}

err := json.Unmarshal(accountService.RawData, &t)
if err != nil {
return nil, err
}

as.SMCLDAP.StartTLSEnabled = t.Oem.Supermicro.LDAP.StartTLSEnabled
as.SMCActiveDirectory.DNSLookupEnable = t.Oem.Supermicro.ActiveDirectory.DNSLookupEnable
as.SMCActiveDirectory.Prefix = t.Oem.Supermicro.ActiveDirectory.Prefix
as.SMCActiveDirectory.Port = t.Oem.Supermicro.ActiveDirectory.Port
as.SMCActiveDirectory.UserDomainNames = t.Oem.Supermicro.ActiveDirectory.UserDomainNames
as.SMCActiveDirectory.DynamicServerAddresses = t.Oem.Supermicro.ActiveDirectory.DynamicServerAddresses

return &as, nil
}
114 changes: 114 additions & 0 deletions oem/smc/accountservice_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
//
// SPDX-License-Identifier: BSD-3-Clause
//

package smc

import (
"encoding/json"
"testing"

"github.com/stmcginnis/gofish/redfish"
)

var accountServiceBody = `{
"@odata.type": "#AccountService.v1_7_2.AccountService",
"@odata.id": "/redfish/v1/AccountService",
"Id": "AccountService",
"Name": "Account Service",
"Description": "Account Service",
"Status": {
"State": "Enabled",
"Health": "OK"
},
"ServiceEnabled": true,
"MinPasswordLength": 8,
"MaxPasswordLength": 20,
"AuthFailureLoggingThreshold": 3,
"AccountLockoutThreshold": 3,
"AccountLockoutDuration": 30,
"AccountLockoutCounterResetAfter": 30,
"Accounts": {
"@odata.id": "/redfish/v1/AccountService/Accounts"
},
"Roles": {
"@odata.id": "/redfish/v1/AccountService/Roles"
},
"LDAP": {
"AccountProviderType": "LDAPService",
"ServiceEnabled": false,
"ServiceAddresses": [],
"Authentication": {
"AuthenticationType": "UsernameAndPassword",
"Username": "",
"Password": null,
"Oem": {}
},
"PasswordSet": false,
"RemoteRoleMapping": [],
"LDAPService": {
"SearchSettings": {
"BaseDistinguishedNames": []
},
"Oem": {}
}
},
"ActiveDirectory": {
"AccountProviderType": "ActiveDirectoryService",
"ServiceEnabled": false,
"ServiceAddresses": [],
"Authentication": {
"AuthenticationType": "UsernameAndPassword",
"Username": "",
"Password": null,
"Oem": {}
},
"PasswordSet": false,
"RemoteRoleMapping": []
},
"Oem": {
"Supermicro": {
"@odata.type": "#SmcAccountServiceExtensions.v1_0_1.AccountService",
"LDAP": {
"StartTLSEnabled": true
},
"ActiveDirectory": {
"DNSLookupEnable": true,
"Prefix": "ldap",
"Port": 389,
"UserDomainNames": ["example.com"],
"DynamicServerAddresses": []
}
}
},
"@odata.etag": "\"01dc844f1c2c3fae22b77263291f161b\""
}`

// TestSmcAccountServiceOem tests the parsing of the AccountService oem field
func TestSmcAccountServiceOem(t *testing.T) {
drive := &redfish.AccountService{}
if err := json.Unmarshal([]byte(accountServiceBody), drive); err != nil {
t.Fatalf("error decoding json: %v", err)
}

accountService, err := FromAccountService(drive)
if err != nil {
t.Fatalf("error getting oem info from drive: %v", err)
}

if accountService.ID != "AccountService" {
t.Errorf("unexpected ID: %s", accountService.ID)
}

if !accountService.SMCLDAP.StartTLSEnabled {
t.Errorf("unexpected StartTLSEnabled state: %t", accountService.SMCLDAP.StartTLSEnabled)
}

if !accountService.SMCActiveDirectory.DNSLookupEnable ||
accountService.SMCActiveDirectory.Prefix != "ldap" ||
accountService.SMCActiveDirectory.Port != 389 ||
len(accountService.SMCActiveDirectory.UserDomainNames) != 1 ||
accountService.SMCActiveDirectory.UserDomainNames[0] != "example.com" {
t.Errorf("unexpected ActiveDirectory settings: %+v", accountService.SMCActiveDirectory)
}
}
8 changes: 4 additions & 4 deletions redfish/accountservice.go
Original file line number Diff line number Diff line change
Expand Up @@ -388,8 +388,8 @@ type AccountService struct {
// populated by default. This entity shall not be present in the additional external account providers resource
// collection.
TACACSplus ExternalAccountProvider
// rawData holds the original serialized JSON so we can compare updates.
rawData []byte
// RawData holds the original serialized JSON so we can compare updates.
RawData []byte
}

// UnmarshalJSON unmarshals an AccountService object from the raw JSON.
Expand Down Expand Up @@ -427,7 +427,7 @@ func (accountservice *AccountService) UnmarshalJSON(b []byte) error {
accountservice.privilegeMap = t.PrivilegeMap.String()

// This is a read/write object, so we need to save the raw object data for later
accountservice.rawData = b
accountservice.RawData = b

return nil
}
Expand All @@ -450,7 +450,7 @@ func (accountservice *AccountService) Update() error {
// Get a representation of the object's original state so we can find what
// to update.
original := new(AccountService)
err := original.UnmarshalJSON(accountservice.rawData)
err := original.UnmarshalJSON(accountservice.RawData)
if err != nil {
return err
}
Expand Down

0 comments on commit 7257532

Please sign in to comment.