Skip to content

Commit

Permalink
Merge pull request #127 from bmc-toolbox/add-support-for-r630-r640
Browse files Browse the repository at this point in the history
PSM-2318 Add support for Dell PowerEdge R630 (idrac8) / R640 (idrac9)
  • Loading branch information
atrubachev authored Apr 20, 2020
2 parents 19cdfa7 + 3e3f5b8 commit 03a62f1
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 23 deletions.
21 changes: 18 additions & 3 deletions discover/probe.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ import (
log "github.com/sirupsen/logrus"
)

var (
idrac8SysDesc = []string{"PowerEdge M630", "PowerEdge R630"}
idrac9SysDesc = []string{"PowerEdge M640", "PowerEdge R640"}
m1000eSysDesc = []string{"PowerEdge M1000e"}
)

type Probe struct {
client *http.Client
host string
Expand Down Expand Up @@ -150,7 +156,7 @@ func (p *Probe) idrac8() (bmcConnection interface{}, err error) {
return bmcConnection, err
}

if resp.StatusCode == 200 && bytes.Contains(payload, []byte("PowerEdge M630")) {
if resp.StatusCode == 200 && containsAnySubStr(payload, idrac8SysDesc) {
log.WithFields(log.Fields{"step": "connection", "host": p.host, "vendor": devices.Dell}).Debug("it's a idrac8")
return idrac8.New(p.host, p.username, p.password)
}
Expand All @@ -173,7 +179,7 @@ func (p *Probe) idrac9() (bmcConnection interface{}, err error) {
return bmcConnection, err
}

if resp.StatusCode == 200 && bytes.Contains(payload, []byte("PowerEdge M640")) {
if resp.StatusCode == 200 && containsAnySubStr(payload, idrac9SysDesc) {
log.WithFields(log.Fields{"step": "connection", "host": p.host, "vendor": devices.Dell}).Debug("it's a idrac9")
return idrac9.New(p.host, p.username, p.password)
}
Expand All @@ -195,7 +201,7 @@ func (p *Probe) m1000e() (bmcConnection interface{}, err error) {
return bmcConnection, err
}

if resp.StatusCode == 200 && bytes.Contains(payload, []byte("PowerEdge M1000e")) {
if resp.StatusCode == 200 && containsAnySubStr(payload, m1000eSysDesc) {
log.WithFields(log.Fields{"step": "connection", "host": p.host, "vendor": devices.Dell}).Debug("it's a m1000e chassis")
return m1000e.New(p.host, p.username, p.password)
}
Expand Down Expand Up @@ -248,3 +254,12 @@ func (p *Probe) quanta() (bmcConnection interface{}, err error) {

return bmcConnection, errors.ErrDeviceNotMatched
}

func containsAnySubStr(data []byte, subStrs []string) bool {
for _, subStr := range subStrs {
if bytes.Contains(data, []byte(subStr)) {
return true
}
}
return false
}
34 changes: 14 additions & 20 deletions providers/dell/idrac8/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (

// Return bool value if the role is valid.
func isRoleValid(role string) bool {

validRoles := []string{"admin", "user"}
for _, v := range validRoles {
if role == v {
Expand All @@ -22,22 +21,18 @@ func isRoleValid(role string) bool {
}

// Return bool value if the role is valid.
func (i *IDrac8) validateUserCfg(cfgUsers []*cfgresources.User) (err error) {

func (i *IDrac8) validateUserCfg(cfgUsers []*cfgresources.User) error {
for _, cfgUser := range cfgUsers {
if cfgUser.Name == "" {
msg := "User resource expects parameter: Name."
return errors.New(msg)
return errors.New("user resource expects parameter: Name")
}

if cfgUser.Password == "" {
msg := "User resource expects parameter: Password."
return errors.New(msg)
return errors.New("user resource expects parameter: Password")
}

if !isRoleValid(cfgUser.Role) {
msg := "User resource expects parameter Role to be one of 'admin', 'user'"
return errors.New(msg)
return errors.New("user resource expects parameter Role to be one of 'admin', 'user'")
}
}

Expand All @@ -48,7 +43,6 @@ func (i *IDrac8) validateUserCfg(cfgUsers []*cfgresources.User) (err error) {
// this function returns an empty user slot that can be used for a new user account
func getEmptyUserSlot(idracUsers UserInfo) (userID int, user User, err error) {
for userID, user := range idracUsers {

if userID == 1 {
continue
}
Expand All @@ -58,12 +52,11 @@ func getEmptyUserSlot(idracUsers UserInfo) (userID int, user User, err error) {
}
}

return 0, user, errors.New("All user account slots in use, remove an account before adding a new one")
return 0, user, errors.New("all user account slots in use, remove an account before adding a new one")
}

// checks if a user is present in a given list
func userInIdrac(user string, usersInfo UserInfo) (userID int, userInfo User, exists bool) {

for userID, userInfo := range usersInfo {
if userInfo.UserName == user {
return userID, userInfo, true
Expand All @@ -74,23 +67,24 @@ func userInIdrac(user string, usersInfo UserInfo) (userID int, userInfo User, ex
}

// PUTs user config
func (i *IDrac8) putUser(userID int, user User) (err error) {

func (i *IDrac8) putUser(userID int, user User) error {
idracPayload := make(map[string]User)
idracPayload["iDRAC.Users"] = user

payload, err := json.Marshal(idracPayload)
if err != nil {
msg := fmt.Sprintf("Error unmarshalling User payload: %s", err)
return errors.New(msg)
return fmt.Errorf("error unmarshalling User payload: %w", err)
}

endpoint := fmt.Sprintf("sysmgmt/2012/server/configgroup/iDRAC.Users.%d", userID)
statusCode, _, err := i.put(endpoint, payload)
if err != nil || statusCode != 200 {
msg := fmt.Sprintf("PUT request to set User config returned error, return code: %d", statusCode)
return errors.New(msg)
if err != nil {
return fmt.Errorf("PUT request to set User config returned error: %w", err)
}

if statusCode != 200 {
return fmt.Errorf("PUT request to set User config returned status code: %d", statusCode)
}

return err
return nil
}

0 comments on commit 03a62f1

Please sign in to comment.