syft
syft copied to clipboard
Support accessing individual CPE fields from templates
What would you like to be added:
I'd like to be able to use individual fields from the CPE when providing a custom template.
Why is this needed: I am investigating syft to assess whether we can migrate to using it. One of the requirements is to be able to generate a SBOM in a proprietary json format. This format requires the CPE information (vendor, product and version) to be in separate fields.
Additional context:
The following patch allows me to get what I want, but it breaks other parts. I think we can do it this way, but have pkg.CPEString
be the default formatting function for a pkg.CPE
diff --git a/syft/formats/syftjson/model/package.go b/syft/formats/syftjson/model/package.go
index 12ef3c3..f3a8294 100644
--- a/syft/formats/syftjson/model/package.go
+++ b/syft/formats/syftjson/model/package.go
@@ -29,7 +29,7 @@ type PackageBasicData struct {
Locations []source.Coordinates `json:"locations"`
Licenses []string `json:"licenses"`
Language pkg.Language `json:"language"`
- CPEs []string `json:"cpes"`
+ CPEs []pkg.CPE `json:"cpes"`
PURL string `json:"purl"`
}
diff --git a/syft/formats/syftjson/to_format_model.go b/syft/formats/syftjson/to_format_model.go
index 58e4dbb..e72f09c 100644
--- a/syft/formats/syftjson/to_format_model.go
+++ b/syft/formats/syftjson/to_format_model.go
@@ -169,11 +169,6 @@ func toPackageModels(catalog *pkg.Catalog) []model.Package {
// toPackageModel crates a new Package from the given pkg.Package.
func toPackageModel(p pkg.Package) model.Package {
- var cpes = make([]string, len(p.CPEs))
- for i, c := range p.CPEs {
- cpes[i] = pkg.CPEString(c)
- }
-
var licenses = make([]string, 0)
if p.Licenses != nil {
licenses = p.Licenses
@@ -195,7 +190,7 @@ func toPackageModel(p pkg.Package) model.Package {
Locations: coordinates,
Licenses: licenses,
Language: p.Language,
- CPEs: cpes,
+ CPEs: p.CPEs,
PURL: p.PURL,
},
PackageCustomData: model.PackageCustomData{
diff --git a/syft/formats/syftjson/to_syft_model.go b/syft/formats/syftjson/to_syft_model.go
index 9c27604..f5f6600 100644
--- a/syft/formats/syftjson/to_syft_model.go
+++ b/syft/formats/syftjson/to_syft_model.go
@@ -153,13 +153,7 @@ func toSyftCatalog(pkgs []model.Package, idAliases map[string]string) *pkg.Catal
func toSyftPackage(p model.Package, idAliases map[string]string) pkg.Package {
var cpes []pkg.CPE
for _, c := range p.CPEs {
- value, err := pkg.NewCPE(c)
- if err != nil {
- log.Warnf("excluding invalid CPE %q: %v", c, err)
- continue
- }
-
- cpes = append(cpes, value)
+ cpes = append(cpes, c)
}
var locations = make([]source.Location, len(p.Locations))
I wonder if we could surface some helper functions in the template instead for this, what do you think?
That would be possible indeed. I just feel that it would be cleaner to allow direct access as they are already stored with separated fields internally.