Skip to content

Commit

Permalink
Changed to return status codes of 404 when the vault entry is missing (
Browse files Browse the repository at this point in the history
…#59)

CASMHMS-6125
CASMTRIAGE-6464
  • Loading branch information
shunr-hpe authored Jan 19, 2024
1 parent f9712f4 commit c4d8f70
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 70 deletions.
2 changes: 1 addition & 1 deletion .version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.18.0
1.19.0
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\

## [1.19.0] - 2023-01-10

### Changed

- Changed to return bmc creds with no vault entry with 404 status code

## [1.18.0] - 2023-01-26

### Fixed
Expand Down
150 changes: 81 additions & 69 deletions cmd/scsd/creds.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// MIT License
//
// (C) Copyright [2020-2022] Hewlett Packard Enterprise Development LP
// (C) Copyright [2020-2022,2024] Hewlett Packard Enterprise Development LP
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
Expand Down Expand Up @@ -67,7 +67,6 @@ type credsPostSingle struct {
Creds credsData `jtag:"Creds"`
}


type bmcCredsData struct {
Xname string `json:"Xname"`
Username string `json:"Username,omitempty"`
Expand Down Expand Up @@ -134,6 +133,10 @@ type discoverPayload struct {
Force bool `json:"force"`
}

const (
EMPTY = "<empty>"
)

// Fix an Etag so we discard any decorations.

func fixEtag(etag string) string {
Expand Down Expand Up @@ -329,7 +332,7 @@ func fetchTargAccount(taskList []trsapi.HttpTask, username []string, retEtags *[
acctMaxURL := ""
for jj := 0; jj < len(acctMembers.Members); jj++ {
//iLO bug: URIs can have trailing '/' sometimes, must trim.
uri := strings.TrimRight(acctMembers.Members[jj].ID,"/")
uri := strings.TrimRight(acctMembers.Members[jj].ID, "/")
toks := strings.Split(uri, "/")
ord, err := strconv.Atoi(toks[len(toks)-1])
if err != nil {
Expand Down Expand Up @@ -963,69 +966,69 @@ func doCredsPostOne(w http.ResponseWriter, r *http.Request) {
}

func doCredsGet(w http.ResponseWriter, r *http.Request) {
var xnames,retXnames []string
var xnames, retXnames []string
var compType string
var retData bmcCredsReturn

if (appParams.VaultEnable == nil) || !(*appParams.VaultEnable) {
logger.Tracef("doCredsGet(), Vault is disabled, no creds available.")
sendErrorRsp(w,"Vault not available",
sendErrorRsp(w, "Vault not available",
"ERROR: Vault access is disabled.",
r.URL.Path,http.StatusGone)
r.URL.Path, http.StatusGone)
return
}

//Get the params. If none, we get all BMC creds.

qvals := r.URL.Query()
targlist,ok := qvals["targets"]
typelist,tlok := qvals["type"]
targlist, ok := qvals["targets"]
typelist, tlok := qvals["type"]

if (ok && ((len(targlist) == 0) || (targlist[0] == ""))) {
sendErrorRsp(w,"Invalid query parameter",
if ok && ((len(targlist) == 0) || (targlist[0] == "")) {
sendErrorRsp(w, "Invalid query parameter",
"ERROR: URL query parameter is empty.",
r.URL.Path,http.StatusBadRequest)
r.URL.Path, http.StatusBadRequest)
return
}

if (ok) {
xlist := strings.Split(targlist[0],",")
if ok {
xlist := strings.Split(targlist[0], ",")
elist := []string{}

//Verify the name formats
for ii := 0; ii < len(xlist); ii++ {
xn := base.VerifyNormalizeCompID(xlist[ii])
if (xn == "") {
logger.Errorf("Invalid XName: '%s'",xlist[ii])
elist = append(elist,xlist[ii])
if xn == "" {
logger.Errorf("Invalid XName: '%s'", xlist[ii])
elist = append(elist, xlist[ii])
} else {
xnames = append(xnames,xn)
xnames = append(xnames, xn)
}
}

if (len(elist) != 0) {
bxn := strings.Join(elist,",")
sendErrorRsp(w,"Bad XName(s) entered",
fmt.Sprintf("ERROR: Invalid Xnames: %s.",bxn),
r.URL.Path,http.StatusInternalServerError)
if len(elist) != 0 {
bxn := strings.Join(elist, ",")
sendErrorRsp(w, "Bad XName(s) entered",
fmt.Sprintf("ERROR: Invalid Xnames: %s.", bxn),
r.URL.Path, http.StatusInternalServerError)
return
}
}

if (tlok) {
if tlok {
//We'll only allow one type
toks := strings.Split(typelist[0],",")
if (len(toks) > 1) {
sendErrorRsp(w,"Invalid query parameter 'type'",
toks := strings.Split(typelist[0], ",")
if len(toks) > 1 {
sendErrorRsp(w, "Invalid query parameter 'type'",
"ERROR: URL query parameter 'type' can only be a single value.",
r.URL.Path,http.StatusBadRequest)
r.URL.Path, http.StatusBadRequest)
return
}
compType = base.VerifyNormalizeType(toks[0])
if (compType == "") {
sendErrorRsp(w,"Invalid query parameter 'type'",
if compType == "" {
sendErrorRsp(w, "Invalid query parameter 'type'",
"ERROR: URL query parameter 'type' is invalid component type.",
r.URL.Path,http.StatusBadRequest)
r.URL.Path, http.StatusBadRequest)
return
}
}
Expand All @@ -1036,93 +1039,102 @@ func doCredsGet(w http.ResponseWriter, r *http.Request) {
var rsp []byte
var rerr error

if (len(xnames) == 0) {
if len(xnames) == 0 {
urlTail = "/State/Components"
if (compType == "") {
if compType == "" {
urlTail = urlTail + "?type=NodeBMC&type=ChassisBMC&type=RouterBMC&type=CabinetBMC&stateonly=true"
} else {
urlTail = urlTail + "?type=" + compType + "&stateonly=true"
}
rsp, rerr = doHSMGet(appParams.SmdURL + urlTail)
} else {
urlTail = "/State/Components/Query"
jdata := hsmComponentQuery{ComponentIDs: xnames, StateOnly: true,}
if (compType != "") {
jdata.Type = []string{compType,}
jdata := hsmComponentQuery{ComponentIDs: xnames, StateOnly: true}
if compType != "" {
jdata.Type = []string{compType}
}
ba,baerr := json.Marshal(&jdata)
if (baerr != nil) {
sendErrorRsp(w,"Error marshalling HSM query data",
ba, baerr := json.Marshal(&jdata)
if baerr != nil {
sendErrorRsp(w, "Error marshalling HSM query data",
"ERROR: problem marshalling HSM query data.",
r.URL.Path,http.StatusInternalServerError)
r.URL.Path, http.StatusInternalServerError)
return
}
rsp, rerr = doHSMPutPostPatchDel(appParams.SmdURL + urlTail, http.MethodPost, ba)
rsp, rerr = doHSMPutPostPatchDel(appParams.SmdURL+urlTail, http.MethodPost, ba)
}
if (rerr != nil) {
sendErrorRsp(w,"Can't get HSM component data",
if rerr != nil {
sendErrorRsp(w, "Can't get HSM component data",
"ERROR: problem getting component info from HSM.",
r.URL.Path,http.StatusInternalServerError)
r.URL.Path, http.StatusInternalServerError)
return
}
if (rsp == nil) {
sendErrorRsp(w,"No HSM component data",
if rsp == nil {
sendErrorRsp(w, "No HSM component data",
"ERROR: Nil response data from HSM.",
r.URL.Path,http.StatusInternalServerError)
r.URL.Path, http.StatusInternalServerError)
return
}

var compData hsmComponentList
rerr = json.Unmarshal(rsp, &compData)
if (rerr != nil) {
sendErrorRsp(w,"Can't unmarshall HSM component data",
if rerr != nil {
sendErrorRsp(w, "Can't unmarshall HSM component data",
"ERROR: Problem unmarshaling HSM data.",
r.URL.Path,http.StatusInternalServerError)
r.URL.Path, http.StatusInternalServerError)
return
}

for ii := 0; ii < len(compData.Components); ii++ {
if (base.IsHMSTypeController(base.GetHMSType(compData.Components[ii].ID))) {
if (goodHSMState(compData.Components[ii].State)) {
retXnames = append(retXnames,compData.Components[ii].ID)
if base.IsHMSTypeController(base.GetHMSType(compData.Components[ii].ID)) {
if goodHSMState(compData.Components[ii].State) {
retXnames = append(retXnames, compData.Components[ii].ID)
}
}
}

//For each XName, get the BMC creds from vault. NOTE: this is SLOW
//on larger systems. Nothing we can really do about that.

for ii := 0; ii < len(retXnames); ii ++ {
for ii := 0; ii < len(retXnames); ii++ {
creds, err := compCredStore.GetCompCred(retXnames[ii])
if (err != nil) {
if err != nil {
logger.Errorf("Error getting credentials for '%s': %v",
retXnames[ii],err)
retData.Targets = append(retData.Targets,bmcCredsData{Xname: retXnames[ii],
retXnames[ii], err)
retData.Targets = append(retData.Targets, bmcCredsData{Xname: retXnames[ii],
StatusCode: http.StatusInternalServerError,
StatusMsg: "No credentials found.",
StatusMsg: "No credentials found.",
})
} else {
un := "<empty>"
pw := "<empty>"
if (creds.Username != "") {
statusCode := http.StatusOK
statusMsg := "OK"
un := EMPTY
pw := EMPTY
if creds.Username != "" {
un = creds.Username
}
if (creds.Password != "") {
if creds.Password != "" {
pw = creds.Password
}

retData.Targets = append(retData.Targets,bmcCredsData{Xname: retXnames[ii],
Username: un, Password: pw, StatusCode: http.StatusOK,
StatusMsg: "OK",
if (un == EMPTY || pw == EMPTY) && creds.Xname == "" {
statusCode = http.StatusNotFound
statusMsg = "Not Found"
}

retData.Targets = append(retData.Targets, bmcCredsData{
Xname: retXnames[ii],
Username: un,
Password: pw,
StatusCode: statusCode,
StatusMsg: statusMsg,
})
}
}

ba, berr := json.Marshal(&retData)
if (berr != nil) {
sendErrorRsp(w,"Return data marshal error", "ERROR: problem marshaling return data.",
r.URL.Path,http.StatusInternalServerError)
return
if berr != nil {
sendErrorRsp(w, "Return data marshal error", "ERROR: problem marshaling return data.",
r.URL.Path, http.StatusInternalServerError)
return
}

w.Header().Set(CT_TYPE, CT_APPJSON)
Expand Down

0 comments on commit c4d8f70

Please sign in to comment.