From 4ecbf3251000c53483489b8aaf3a78f00dc1f5bb Mon Sep 17 00:00:00 2001 From: Andrey Trubachev <1354987+atrubachev@users.noreply.github.com> Date: Mon, 20 Apr 2020 12:32:39 +0200 Subject: [PATCH 1/2] Improve error handling --- providers/dell/idrac8/helpers.go | 34 +++++++++++++------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/providers/dell/idrac8/helpers.go b/providers/dell/idrac8/helpers.go index 5b4572d1..e5c3136a 100644 --- a/providers/dell/idrac8/helpers.go +++ b/providers/dell/idrac8/helpers.go @@ -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 { @@ -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'") } } @@ -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 } @@ -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 @@ -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 } From 3e3f5b8603c7a0ae21c561eb5667a9227258250b Mon Sep 17 00:00:00 2001 From: Andrey Trubachev <1354987+atrubachev@users.noreply.github.com> Date: Mon, 20 Apr 2020 12:34:11 +0200 Subject: [PATCH 2/2] PSM-2318 Add support for Dell PowerEdge R630 (idrac8) / R640 (idrac9) --- discover/probe.go | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/discover/probe.go b/discover/probe.go index df469ec2..cff6173d 100644 --- a/discover/probe.go +++ b/discover/probe.go @@ -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 @@ -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) } @@ -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) } @@ -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) } @@ -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 +}