github.com/redhat-appstudio/e2e-tests@v0.0.0-20240520140907-9709f6f59323/pkg/utils/build/sbom.go (about)

     1  package build
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"os"
     7  )
     8  
     9  func GetParsedSbomFilesContentFromImage(image string) (*SbomPurl, *SbomCyclonedx, error) {
    10  	tmpDir, err := ExtractImage(image)
    11  	defer os.RemoveAll(tmpDir)
    12  	if err != nil {
    13  		return nil, nil, err
    14  	}
    15  
    16  	purl, err := getSbomPurlContent(tmpDir)
    17  	if err != nil {
    18  		return nil, nil, fmt.Errorf("failed to get sbom purl content: %+v", err)
    19  	}
    20  
    21  	cyclonedx, err := getSbomCyclonedxContent(tmpDir)
    22  	if err != nil {
    23  		return nil, nil, fmt.Errorf("failed to get sbom cyclonedx content: %+v", err)
    24  	}
    25  	return purl, cyclonedx, nil
    26  }
    27  
    28  type SbomPurl struct {
    29  	ImageContents struct {
    30  		Dependencies []struct {
    31  			Purl string `json:"purl"`
    32  		} `json:"dependencies"`
    33  	} `json:"image_contents"`
    34  }
    35  
    36  type SbomCyclonedx struct {
    37  	BomFormat   string
    38  	SpecVersion string
    39  	Version     int
    40  	Components  []struct {
    41  		Name    string `json:"name"`
    42  		Purl    string `json:"purl"`
    43  		Type    string `json:"type"`
    44  		Version string `json:"version"`
    45  	} `json:"components"`
    46  }
    47  
    48  func getSbomPurlContent(rootDir string) (*SbomPurl, error) {
    49  	sbomPurlFilePath := rootDir + "/root/buildinfo/content_manifests/sbom-purl.json"
    50  	file, err := os.Stat(sbomPurlFilePath)
    51  	if err != nil {
    52  		return nil, fmt.Errorf("sbom file not found in path %s", sbomPurlFilePath)
    53  	}
    54  	if file.Size() == 0 {
    55  		return nil, fmt.Errorf("sbom file %s is empty", sbomPurlFilePath)
    56  	}
    57  
    58  	b, err := os.ReadFile(sbomPurlFilePath)
    59  	if err != nil {
    60  		return nil, fmt.Errorf("error when reading sbom file %s: %v", sbomPurlFilePath, err)
    61  	}
    62  	sbom := &SbomPurl{}
    63  	if err := json.Unmarshal(b, sbom); err != nil {
    64  		return nil, fmt.Errorf("error when parsing sbom PURL json: %v", err)
    65  	}
    66  
    67  	return sbom, nil
    68  }
    69  
    70  func getSbomCyclonedxContent(rootDir string) (*SbomCyclonedx, error) {
    71  	sbomCyclonedxFilePath := rootDir + "/root/buildinfo/content_manifests/sbom-cyclonedx.json"
    72  	file, err := os.Stat(sbomCyclonedxFilePath)
    73  	if err != nil {
    74  		return nil, fmt.Errorf("sbom file not found in path %s", sbomCyclonedxFilePath)
    75  	}
    76  	if file.Size() == 0 {
    77  		return nil, fmt.Errorf("sbom file %s is empty", sbomCyclonedxFilePath)
    78  	}
    79  
    80  	b, err := os.ReadFile(sbomCyclonedxFilePath)
    81  	if err != nil {
    82  		return nil, fmt.Errorf("error when reading sbom file %s: %v", sbomCyclonedxFilePath, err)
    83  	}
    84  	sbom := &SbomCyclonedx{}
    85  	if err := json.Unmarshal(b, sbom); err != nil {
    86  		return nil, fmt.Errorf("error when parsing sbom CycloneDX json: %v", err)
    87  	}
    88  
    89  	return sbom, nil
    90  }