fix(redfish): narrow MSI PCIeFunctions crawl

This commit is contained in:
Mikhail Chusavitin
2026-04-01 16:50:51 +03:00
parent 475f6ac472
commit bb82387d48
4 changed files with 180 additions and 1 deletions

View File

@@ -1288,12 +1288,17 @@ func (c *RedfishConnector) collectNICs(ctx context.Context, client *http.Client,
}
for _, doc := range adapterDocs {
nic := parseNIC(doc)
adapterFunctionDocs := c.getNetworkAdapterFunctionDocs(ctx, client, req, baseURL, doc)
for _, pciePath := range networkAdapterPCIeDevicePaths(doc) {
pcieDoc, err := c.getJSON(ctx, client, req, baseURL, pciePath)
if err != nil {
continue
}
functionDocs := c.getLinkedPCIeFunctions(ctx, client, req, baseURL, pcieDoc)
for _, adapterFnDoc := range adapterFunctionDocs {
functionDocs = append(functionDocs, c.getLinkedPCIeFunctions(ctx, client, req, baseURL, adapterFnDoc)...)
}
functionDocs = dedupeJSONDocsByPath(functionDocs)
supplementalDocs := c.getLinkedSupplementalDocs(ctx, client, req, baseURL, pcieDoc, "EnvironmentMetrics", "Metrics")
for _, fn := range functionDocs {
supplementalDocs = append(supplementalDocs, c.getLinkedSupplementalDocs(ctx, client, req, baseURL, fn, "EnvironmentMetrics", "Metrics")...)
@@ -2810,6 +2815,14 @@ func shouldCrawlPath(path string) bool {
if isAllowedNVSwitchFabricPath(normalized) {
return true
}
if strings.Contains(normalized, "/Chassis/") &&
strings.Contains(normalized, "/PCIeDevices/") &&
strings.HasSuffix(normalized, "/PCIeFunctions") {
// Avoid crawling entire chassis PCIeFunctions collections. Concrete member
// docs can still be reached through direct links such as
// NetworkDeviceFunction Links.PCIeFunction.
return false
}
if strings.Contains(normalized, "/Memory/") {
after := strings.SplitN(normalized, "/Memory/", 2)
if len(after) == 2 && strings.Count(after[1], "/") >= 1 {
@@ -2982,6 +2995,15 @@ func (c *RedfishConnector) getLinkedPCIeFunctions(ctx context.Context, client *h
}
return out
}
if ref, ok := links["PCIeFunction"].(map[string]interface{}); ok {
memberPath := asString(ref["@odata.id"])
if memberPath != "" {
memberDoc, err := c.getJSON(ctx, client, req, baseURL, memberPath)
if err == nil {
return []map[string]interface{}{memberDoc}
}
}
}
}
// Some implementations expose a collection object in PCIeFunctions.@odata.id.
@@ -2997,6 +3019,22 @@ func (c *RedfishConnector) getLinkedPCIeFunctions(ctx context.Context, client *h
return nil
}
func (c *RedfishConnector) getNetworkAdapterFunctionDocs(ctx context.Context, client *http.Client, req Request, baseURL string, adapterDoc map[string]interface{}) []map[string]interface{} {
ndfCol, ok := adapterDoc["NetworkDeviceFunctions"].(map[string]interface{})
if !ok {
return nil
}
colPath := asString(ndfCol["@odata.id"])
if colPath == "" {
return nil
}
funcDocs, err := c.getCollectionMembers(ctx, client, req, baseURL, colPath)
if err != nil {
return nil
}
return funcDocs
}
func (c *RedfishConnector) getCollectionMembers(ctx context.Context, client *http.Client, req Request, baseURL, collectionPath string) ([]map[string]interface{}, error) {
collection, err := c.getJSON(ctx, client, req, baseURL, collectionPath)
if err != nil {