From e1e344d14170d797d5f81daea17959a9e463b7ee Mon Sep 17 00:00:00 2001 From: Sean McGinnis Date: Fri, 19 Apr 2024 12:27:38 -0500 Subject: [PATCH] Update TrustedComponent object This adds some things that were missed in the TrustedComponent object. Signed-off-by: Sean McGinnis --- redfish/trustedcomponent.go | 76 +++++++++++++++++++++++++++----- redfish/trustedcomponent_test.go | 53 ++++++++++++++++++++++ 2 files changed, 119 insertions(+), 10 deletions(-) create mode 100644 redfish/trustedcomponent_test.go diff --git a/redfish/trustedcomponent.go b/redfish/trustedcomponent.go index 833f159d..689380d5 100644 --- a/redfish/trustedcomponent.go +++ b/redfish/trustedcomponent.go @@ -81,15 +81,12 @@ type TrustedComponent struct { ODataType string `json:"@odata.type"` // Certificates shall contain a link to a resource collection of type CertificateCollection that contains device // identity certificates of the trusted component. - Certificates string + certificates string // Description provides a description of this resource. Description string // FirmwareVersion shall contain a version number associated with the active software image on the trusted // component. FirmwareVersion string - // Links shall contain links to resources that are related to but are not contained by, or subordinate to, this - // resource. - Links string // Manufacturer shall contain the name of the organization responsible for producing the trusted component. This // organization may be the entity from whom the trusted component is purchased, but this is not necessarily true. Manufacturer string @@ -111,7 +108,7 @@ type TrustedComponent struct { // TCG-defined TPM trusted components. TPM string // TrustedComponentType shall contain the type of trusted component. - TrustedComponentType string + TrustedComponentType TrustedComponentType // UUID shall contain a universally unique identifier number for the trusted component. UUID string @@ -136,8 +133,9 @@ func (trustedcomponent *TrustedComponent) UnmarshalJSON(b []byte) error { type temp TrustedComponent var t struct { temp - Links trustedComponentLinks - Actions struct { + Certificates common.Link + Links trustedComponentLinks + Actions struct { TPMGetEventLog struct { Target string } `json:"#TrustedComponent.TPMGetEventLog"` @@ -153,20 +151,78 @@ func (trustedcomponent *TrustedComponent) UnmarshalJSON(b []byte) error { *trustedcomponent = TrustedComponent(t.temp) trustedcomponent.tpmGetEventLogTarget = t.Actions.TPMGetEventLog.Target - // TODO: Implement accessors for linked objects + trustedcomponent.certificates = t.Certificates.String() + trustedcomponent.activeSoftwareImage = t.Links.ActiveSoftwareImage.String() trustedcomponent.componentIntegrity = t.Links.ComponentIntegrity.ToStrings() trustedcomponent.ComponentIntegrityCount = t.Links.ComponentIntegrityCount + trustedcomponent.softwareImages = t.Links.SoftwareImages.ToStrings() + trustedcomponent.SoftwareImagesCount = t.Links.SoftwareImagesCount + + // TODO: Implement accessors for linked objects trustedcomponent.componentsProtected = t.Links.ComponentsProtected.ToStrings() trustedcomponent.ComponentsProtectedCount = t.Links.ComponentsProtectedCount trustedcomponent.integratedInto = t.Links.IntegratedInto.String() trustedcomponent.owner = t.Links.Owner.String() - trustedcomponent.softwareImages = t.Links.SoftwareImages.ToStrings() - trustedcomponent.SoftwareImagesCount = t.Links.SoftwareImagesCount return nil } +// ActiveSoftwareImage gets the active firmware image for this trusted component. +func (trustedcomponent *TrustedComponent) ActiveSoftwareImage() (*SoftwareInventory, error) { + if trustedcomponent.activeSoftwareImage == "" { + return nil, nil + } + return GetSoftwareInventory(trustedcomponent.GetClient(), trustedcomponent.activeSoftwareImage) +} + +// ComponentIntegrity gets the resources for which the trusted component is responsible. +func (trustedcomponent *TrustedComponent) ComponentIntegrity() ([]*ComponentIntegrity, error) { + var result []*ComponentIntegrity + + collectionError := common.NewCollectionError() + for _, uri := range trustedcomponent.componentIntegrity { + cs, err := GetComponentIntegrity(trustedcomponent.GetClient(), uri) + if err != nil { + collectionError.Failures[uri] = err + } else { + result = append(result, cs) + } + } + + if collectionError.Empty() { + return result, nil + } + + return result, collectionError +} + +// SoftwareImages gets the firmware images that apply to this trusted component. +func (trustedcomponent *TrustedComponent) SoftwareImages() ([]*SoftwareInventory, error) { + var result []*SoftwareInventory + + collectionError := common.NewCollectionError() + for _, uri := range trustedcomponent.softwareImages { + cs, err := GetSoftwareInventory(trustedcomponent.GetClient(), uri) + if err != nil { + collectionError.Failures[uri] = err + } else { + result = append(result, cs) + } + } + + if collectionError.Empty() { + return result, nil + } + + return result, collectionError +} + +// Certificates gets the certificates associated with this trusted component. +func (trustedcomponent *TrustedComponent) Certificates() ([]*Certificate, error) { + return ListReferencedCertificates(trustedcomponent.GetClient(), trustedcomponent.certificates) +} + // TPMGetEventLog gets the event log for TPM 2.0 devices. func (trustedcomponent *TrustedComponent) TPMGetEventLog() (*TPMGetEventLogResponse, error) { resp, err := trustedcomponent.PostWithResponse(trustedcomponent.tpmGetEventLogTarget, nil) diff --git a/redfish/trustedcomponent_test.go b/redfish/trustedcomponent_test.go new file mode 100644 index 00000000..c369a85b --- /dev/null +++ b/redfish/trustedcomponent_test.go @@ -0,0 +1,53 @@ +// +// SPDX-License-Identifier: BSD-3-Clause +// + +package redfish + +import ( + "encoding/json" + "strings" + "testing" +) + +var tcBody = `{ + "@odata.type": "#TrustedComponent.v1_1_0.TrustedComponent", + "@odata.context": "/redfish/v1/$metadata#TrustedComponent.TrustedComponent", + "Id": "TPM", + "Name": "TrustedComponent for TPM", + "Description": "TrustedComponent for Trusted Platform Module", + "TrustedComponentType": "Discrete", + "Certificates": { + "@odata.id": "/redfish/v1/Chassis/System.Embedded.1/TrustedComponents/TPM/Certificates" + }, + "Links": { + "ComponentsProtected": [ + { + "@odata.id": "/redfish/v1/Systems/System.Embedded.1" + } + ] + }, + "@odata.id": "/redfish/v1/Chassis/System.Embedded.1/TrustedComponents/TPM" + }` + +// TestTrustedComponent tests the parsing of TrustedComponent objects. +func TestTrustedComponent(t *testing.T) { + var result TrustedComponent + err := json.NewDecoder(strings.NewReader(tcBody)).Decode(&result) + + if err != nil { + t.Errorf("Error decoding JSON: %s", err) + } + + if result.ID != "TPM" { + t.Errorf("Received invalid ID: %s", result.ID) + } + + if result.Name != "TrustedComponent for TPM" { + t.Errorf("Received invalid name: %s", result.Name) + } + + if result.certificates != "/redfish/v1/Chassis/System.Embedded.1/TrustedComponents/TPM/Certificates" { + t.Errorf("Invalid fan name: %s", result.certificates) + } +}