fix(inspur): detect standard Inspur servers via SystemManufacturer
NF-series storage servers (e.g. NF5280M6) have no GPU/outboard-PCIe topology, so the previous score gate (topologyScore==0 || boardScore==0 → return 0) always produced score=0 despite SystemManufacturer="Inspur" being available. These servers fell into mode=fallback, activating the AMI profile and probing /Oem/Ami paths that don't exist on the BMC. Add manufacturer-based detection: SystemManufacturer or ChassisManufacturer containing "inspur" contributes 60 points — enough to enter matched mode on its own. GPU servers with full topology+board signals still score higher as before. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -29,6 +29,7 @@ func inspurGroupOEMPlatformsProfile() Profile {
|
|||||||
matchFn: func(s MatchSignals) int {
|
matchFn: func(s MatchSignals) int {
|
||||||
topologyScore := 0
|
topologyScore := 0
|
||||||
boardScore := 0
|
boardScore := 0
|
||||||
|
manufacturerScore := 0
|
||||||
chassisOutboard := matchedPathTokens(s.ResourceHints, "/redfish/v1/Chassis/", outboardCardHintRe)
|
chassisOutboard := matchedPathTokens(s.ResourceHints, "/redfish/v1/Chassis/", outboardCardHintRe)
|
||||||
systemOutboard := matchedPathTokens(s.ResourceHints, "/redfish/v1/Systems/", outboardCardHintRe)
|
systemOutboard := matchedPathTokens(s.ResourceHints, "/redfish/v1/Systems/", outboardCardHintRe)
|
||||||
obDrives := matchedPathTokens(s.ResourceHints, "", obDriveHintRe)
|
obDrives := matchedPathTokens(s.ResourceHints, "", obDriveHintRe)
|
||||||
@@ -62,10 +63,17 @@ func inspurGroupOEMPlatformsProfile() Profile {
|
|||||||
if anySignalContains(s, "GetServerAllUSBStatus") {
|
if anySignalContains(s, "GetServerAllUSBStatus") {
|
||||||
boardScore += 8
|
boardScore += 8
|
||||||
}
|
}
|
||||||
if topologyScore == 0 || boardScore == 0 {
|
// Manufacturer alone is sufficient for standard Inspur servers (e.g. NF-series
|
||||||
|
// storage servers) that lack GPU/outboard-PCIe topology signals. Score 60 is
|
||||||
|
// the minimum to enter matched mode; topology+board can push it higher.
|
||||||
|
if containsFold(s.SystemManufacturer, "inspur") || containsFold(s.ChassisManufacturer, "inspur") {
|
||||||
|
manufacturerScore = 60
|
||||||
|
}
|
||||||
|
total := manufacturerScore + topologyScore + boardScore
|
||||||
|
if total < 60 {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
return min(topologyScore+boardScore, 100)
|
return min(total, 100)
|
||||||
},
|
},
|
||||||
extendAcquisition: func(plan *AcquisitionPlan, _ MatchSignals) {
|
extendAcquisition: func(plan *AcquisitionPlan, _ MatchSignals) {
|
||||||
addPlanNote(plan, "Inspur Group OEM platform fingerprint matched")
|
addPlanNote(plan, "Inspur Group OEM platform fingerprint matched")
|
||||||
|
|||||||
@@ -118,6 +118,52 @@ func TestCollectSignalsFromTree_InspurGroupOEMPlatformsSelectsMatchedMode(t *tes
|
|||||||
assertProfileSelected(t, match, "inspur-group-oem-platforms")
|
assertProfileSelected(t, match, "inspur-group-oem-platforms")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestCollectSignalsFromTree_InspurGroupOEMPlatformsMatchesViaManufacturer covers standard
|
||||||
|
// Inspur storage servers (e.g. NF5280M6) that have no outboard PCIe / GPU topology but
|
||||||
|
// do expose Manufacturer="Inspur" in their System document.
|
||||||
|
func TestCollectSignalsFromTree_InspurGroupOEMPlatformsMatchesViaManufacturer(t *testing.T) {
|
||||||
|
// Minimal tree: no GPU cards, no OEM firmware hints — only System Manufacturer.
|
||||||
|
tree := map[string]interface{}{
|
||||||
|
"/redfish/v1": map[string]interface{}{
|
||||||
|
"@odata.id": "/redfish/v1",
|
||||||
|
},
|
||||||
|
"/redfish/v1/Systems": map[string]interface{}{
|
||||||
|
"Members": []interface{}{
|
||||||
|
map[string]interface{}{"@odata.id": "/redfish/v1/Systems/1"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"/redfish/v1/Systems/1": map[string]interface{}{
|
||||||
|
"@odata.id": "/redfish/v1/Systems/1",
|
||||||
|
"Manufacturer": "Inspur",
|
||||||
|
"Model": "NF5280M6",
|
||||||
|
},
|
||||||
|
"/redfish/v1/Chassis": map[string]interface{}{
|
||||||
|
"Members": []interface{}{
|
||||||
|
map[string]interface{}{"@odata.id": "/redfish/v1/Chassis/1"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"/redfish/v1/Chassis/1": map[string]interface{}{
|
||||||
|
"@odata.id": "/redfish/v1/Chassis/1",
|
||||||
|
},
|
||||||
|
"/redfish/v1/Managers": map[string]interface{}{
|
||||||
|
"Members": []interface{}{
|
||||||
|
map[string]interface{}{"@odata.id": "/redfish/v1/Managers/1"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"/redfish/v1/Managers/1": map[string]interface{}{
|
||||||
|
"@odata.id": "/redfish/v1/Managers/1",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
signals := CollectSignalsFromTree(tree)
|
||||||
|
match := MatchProfiles(signals)
|
||||||
|
|
||||||
|
if match.Mode != ModeMatched {
|
||||||
|
t.Fatalf("expected matched mode for Inspur NF-series, got %q (scores: %v)", match.Mode, match.Scores)
|
||||||
|
}
|
||||||
|
assertProfileSelected(t, match, "inspur-group-oem-platforms")
|
||||||
|
}
|
||||||
|
|
||||||
func TestCollectSignalsFromTree_InspurGroupOEMPlatformsDoesNotFalsePositiveOnExampleRawExports(t *testing.T) {
|
func TestCollectSignalsFromTree_InspurGroupOEMPlatformsDoesNotFalsePositiveOnExampleRawExports(t *testing.T) {
|
||||||
examples := []string{
|
examples := []string{
|
||||||
"2026-03-18 (G5500 V7) - 210619KUGGXGS2000015.zip",
|
"2026-03-18 (G5500 V7) - 210619KUGGXGS2000015.zip",
|
||||||
|
|||||||
Reference in New Issue
Block a user