mirror of
https://github.com/anchore/syft.git
synced 2026-02-12 02:26:42 +01:00
feat: detect older bitnami img packages (#4532)
Signed-off-by: Rez Moss <hi@rezmoss.com>
This commit is contained in:
parent
ed339e4fed
commit
7f1d57d06f
@ -13,6 +13,35 @@ catalogers:
|
||||
- installed
|
||||
- package
|
||||
parsers: # AUTO-GENERATED structure
|
||||
- function: parseComponentsJSON
|
||||
detector: # AUTO-GENERATED
|
||||
method: glob # AUTO-GENERATED
|
||||
criteria: # AUTO-GENERATED
|
||||
- /opt/bitnami/.bitnami_components.json
|
||||
metadata_types: # AUTO-GENERATED
|
||||
- pkg.BitnamiSBOMEntry
|
||||
package_types: # AUTO-GENERATED
|
||||
- bitnami
|
||||
json_schema_types: # AUTO-GENERATED
|
||||
- BitnamiSbomEntry
|
||||
capabilities: # MANUAL - preserved across regeneration
|
||||
- name: license
|
||||
default: false
|
||||
comment: legacy components.json format does not include license information
|
||||
- name: dependency.depth
|
||||
default: []
|
||||
comment: legacy format has no dependency relationships
|
||||
- name: dependency.edges
|
||||
default: ""
|
||||
- name: dependency.kinds
|
||||
default: []
|
||||
- name: package_manager.files.listing
|
||||
default: false
|
||||
- name: package_manager.files.digests
|
||||
default: false
|
||||
- name: package_manager.package_integrity_hash
|
||||
default: false
|
||||
comment: digest field exists but is not captured in metadata
|
||||
- function: parseSBOM
|
||||
detector: # AUTO-GENERATED
|
||||
method: glob # AUTO-GENERATED
|
||||
|
||||
@ -23,6 +23,9 @@ func NewCataloger() pkg.Cataloger {
|
||||
return generic.NewCataloger(catalogerName).
|
||||
WithParserByGlobs(parseSBOM,
|
||||
"/opt/bitnami/**/.spdx-*.spdx",
|
||||
).
|
||||
WithParserByGlobs(parseComponentsJSON,
|
||||
"/opt/bitnami/.bitnami_components.json",
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -448,6 +448,109 @@ func TestBitnamiCataloger(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
mongodbComponentsPkgs := []pkg.Package{
|
||||
{
|
||||
Name: "gosu",
|
||||
Version: "1.14.0-1",
|
||||
Type: pkg.BitnamiPkg,
|
||||
Locations: file.NewLocationSet(file.NewLocation("opt/bitnami/.bitnami_components.json")),
|
||||
FoundBy: catalogerName,
|
||||
PURL: "pkg:bitnami/gosu@1.14.0-1?arch=amd64&distro=debian-10",
|
||||
Metadata: &pkg.BitnamiSBOMEntry{
|
||||
Name: "gosu",
|
||||
Version: "1.14.0",
|
||||
Revision: "1",
|
||||
Architecture: "amd64",
|
||||
Distro: "debian-10",
|
||||
Path: "opt/bitnami/gosu",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "mongodb",
|
||||
Version: "4.4.11-2",
|
||||
Type: pkg.BitnamiPkg,
|
||||
Locations: file.NewLocationSet(file.NewLocation("opt/bitnami/.bitnami_components.json")),
|
||||
FoundBy: catalogerName,
|
||||
PURL: "pkg:bitnami/mongodb@4.4.11-2?arch=amd64&distro=debian-10",
|
||||
Metadata: &pkg.BitnamiSBOMEntry{
|
||||
Name: "mongodb",
|
||||
Version: "4.4.11",
|
||||
Revision: "2",
|
||||
Architecture: "amd64",
|
||||
Distro: "debian-10",
|
||||
Path: "opt/bitnami/mongodb",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "render-template",
|
||||
Version: "1.0.1-5",
|
||||
Type: pkg.BitnamiPkg,
|
||||
Locations: file.NewLocationSet(file.NewLocation("opt/bitnami/.bitnami_components.json")),
|
||||
FoundBy: catalogerName,
|
||||
PURL: "pkg:bitnami/render-template@1.0.1-5?arch=amd64&distro=debian-10",
|
||||
Metadata: &pkg.BitnamiSBOMEntry{
|
||||
Name: "render-template",
|
||||
Version: "1.0.1",
|
||||
Revision: "5",
|
||||
Architecture: "amd64",
|
||||
Distro: "debian-10",
|
||||
Path: "opt/bitnami/render-template",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "wait-for-port",
|
||||
Version: "1.0.1-5",
|
||||
Type: pkg.BitnamiPkg,
|
||||
Locations: file.NewLocationSet(file.NewLocation("opt/bitnami/.bitnami_components.json")),
|
||||
FoundBy: catalogerName,
|
||||
PURL: "pkg:bitnami/wait-for-port@1.0.1-5?arch=amd64&distro=debian-10",
|
||||
Metadata: &pkg.BitnamiSBOMEntry{
|
||||
Name: "wait-for-port",
|
||||
Version: "1.0.1",
|
||||
Revision: "5",
|
||||
Architecture: "amd64",
|
||||
Distro: "debian-10",
|
||||
Path: "opt/bitnami/wait-for-port",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "yq",
|
||||
Version: "4.16.2-2",
|
||||
Type: pkg.BitnamiPkg,
|
||||
Locations: file.NewLocationSet(file.NewLocation("opt/bitnami/.bitnami_components.json")),
|
||||
FoundBy: catalogerName,
|
||||
PURL: "pkg:bitnami/yq@4.16.2-2?arch=amd64&distro=debian-10",
|
||||
Metadata: &pkg.BitnamiSBOMEntry{
|
||||
Name: "yq",
|
||||
Version: "4.16.2",
|
||||
Revision: "2",
|
||||
Architecture: "amd64",
|
||||
Distro: "debian-10",
|
||||
Path: "opt/bitnami/yq",
|
||||
},
|
||||
},
|
||||
}
|
||||
pkg.Sort(mongodbComponentsPkgs)
|
||||
|
||||
postgresqlComponentsPkgs := []pkg.Package{
|
||||
{
|
||||
Name: "postgresql",
|
||||
Version: "11.22.0-4",
|
||||
Type: pkg.BitnamiPkg,
|
||||
Locations: file.NewLocationSet(file.NewLocation("opt/bitnami/.bitnami_components.json")),
|
||||
FoundBy: catalogerName,
|
||||
PURL: "pkg:bitnami/postgresql@11.22.0-4?arch=amd64&distro=debian-11",
|
||||
Metadata: &pkg.BitnamiSBOMEntry{
|
||||
Name: "postgresql",
|
||||
Version: "11.22.0",
|
||||
Revision: "4",
|
||||
Architecture: "amd64",
|
||||
Distro: "debian-11",
|
||||
Path: "opt/bitnami/postgresql",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
fixture string
|
||||
@ -489,6 +592,20 @@ func TestBitnamiCataloger(t *testing.T) {
|
||||
wantPkgs: []pkg.Package{redisMainPkg},
|
||||
wantRelationships: nil,
|
||||
},
|
||||
{
|
||||
name: "parse legacy .bitnami_components.json (MongoDB with multiple components)",
|
||||
fixture: "test-fixtures/components-json-mongodb",
|
||||
wantPkgs: mongodbComponentsPkgs,
|
||||
wantRelationships: nil,
|
||||
wantErr: require.NoError,
|
||||
},
|
||||
{
|
||||
name: "parse legacy .bitnami_components.json (PostgreSQL single component, no digest)",
|
||||
fixture: "test-fixtures/components-json-postgresql",
|
||||
wantPkgs: postgresqlComponentsPkgs,
|
||||
wantRelationships: nil,
|
||||
wantErr: require.NoError,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
|
||||
100
syft/pkg/cataloger/bitnami/parse_components.go
Normal file
100
syft/pkg/cataloger/bitnami/parse_components.go
Normal file
@ -0,0 +1,100 @@
|
||||
package bitnami
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/anchore/packageurl-go"
|
||||
"github.com/anchore/syft/syft/artifact"
|
||||
"github.com/anchore/syft/syft/file"
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
"github.com/anchore/syft/syft/pkg/cataloger/generic"
|
||||
)
|
||||
|
||||
type componentEntry struct {
|
||||
Arch string `json:"arch"`
|
||||
Digest string `json:"digest,omitempty"`
|
||||
Distro string `json:"distro"`
|
||||
Type string `json:"type"`
|
||||
Version string `json:"version"`
|
||||
}
|
||||
|
||||
func parseComponentsJSON(_ context.Context, _ file.Resolver, _ *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) {
|
||||
var components map[string]componentEntry
|
||||
|
||||
decoder := json.NewDecoder(reader)
|
||||
if err := decoder.Decode(&components); err != nil {
|
||||
return nil, nil, fmt.Errorf("unable to parse .bitnami_components.json: %w", err)
|
||||
}
|
||||
|
||||
var pkgs []pkg.Package
|
||||
|
||||
names := make([]string, 0, len(components))
|
||||
for name := range components {
|
||||
names = append(names, name)
|
||||
}
|
||||
sort.Strings(names)
|
||||
|
||||
for _, name := range names {
|
||||
entry := components[name]
|
||||
|
||||
version, revision := parseVersionRevision(entry.Version)
|
||||
|
||||
var qualifiers []packageurl.Qualifier
|
||||
if entry.Arch != "" {
|
||||
qualifiers = append(qualifiers, packageurl.Qualifier{Key: "arch", Value: entry.Arch})
|
||||
}
|
||||
if entry.Distro != "" {
|
||||
qualifiers = append(qualifiers, packageurl.Qualifier{Key: "distro", Value: entry.Distro})
|
||||
}
|
||||
|
||||
purl := packageurl.NewPackageURL(
|
||||
"bitnami",
|
||||
"",
|
||||
name,
|
||||
entry.Version,
|
||||
qualifiers,
|
||||
"",
|
||||
).String()
|
||||
|
||||
metadata := &pkg.BitnamiSBOMEntry{
|
||||
Name: name,
|
||||
Version: version,
|
||||
Revision: revision,
|
||||
Architecture: entry.Arch,
|
||||
Distro: entry.Distro,
|
||||
Path: filepath.Join(filepath.Dir(reader.RealPath), name),
|
||||
}
|
||||
|
||||
p := pkg.Package{
|
||||
Name: name,
|
||||
Version: entry.Version,
|
||||
Type: pkg.BitnamiPkg,
|
||||
FoundBy: catalogerName,
|
||||
PURL: purl,
|
||||
Locations: file.NewLocationSet(
|
||||
reader.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||
),
|
||||
Metadata: metadata,
|
||||
}
|
||||
|
||||
p.SetID()
|
||||
pkgs = append(pkgs, p)
|
||||
}
|
||||
|
||||
// seems legacy format doesnt have relation between pkgs
|
||||
return pkgs, nil, nil
|
||||
}
|
||||
|
||||
func parseVersionRevision(fullVersion string) (version, revision string) {
|
||||
lastHyphen := strings.LastIndex(fullVersion, "-")
|
||||
if lastHyphen == -1 {
|
||||
return fullVersion, ""
|
||||
}
|
||||
|
||||
return fullVersion[:lastHyphen], fullVersion[lastHyphen+1:]
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
{
|
||||
"gosu": {
|
||||
"arch": "amd64",
|
||||
"digest": "16f1a317859b06ae82e816b30f98f28b4707d18fe6cc3881bff535192a7715dc",
|
||||
"distro": "debian-10",
|
||||
"type": "NAMI",
|
||||
"version": "1.14.0-1"
|
||||
},
|
||||
"mongodb": {
|
||||
"arch": "amd64",
|
||||
"digest": "d21fc890385eae0aaa394ce6491ef304d28a5cc43f860def6badee401fe55bc5",
|
||||
"distro": "debian-10",
|
||||
"type": "NAMI",
|
||||
"version": "4.4.11-2"
|
||||
},
|
||||
"render-template": {
|
||||
"arch": "amd64",
|
||||
"digest": "9e312b4a7e16a55d08e67c4fd69c91000e4dcc4af149d59915c49375b83852af",
|
||||
"distro": "debian-10",
|
||||
"type": "NAMI",
|
||||
"version": "1.0.1-5"
|
||||
},
|
||||
"wait-for-port": {
|
||||
"arch": "amd64",
|
||||
"digest": "1e34030c18f0ec2467fa5f1b1fbad24add217f671c3a61628f7b8671391f9676",
|
||||
"distro": "debian-10",
|
||||
"type": "NAMI",
|
||||
"version": "1.0.1-5"
|
||||
},
|
||||
"yq": {
|
||||
"arch": "amd64",
|
||||
"digest": "1c135708aaa8cb69936471de63563de08e97b7d0bfb4126d41b54a149557c5c0",
|
||||
"distro": "debian-10",
|
||||
"type": "NAMI",
|
||||
"version": "4.16.2-2"
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
{
|
||||
"postgresql": {
|
||||
"arch": "amd64",
|
||||
"distro": "debian-11",
|
||||
"type": "NAMI",
|
||||
"version": "11.22.0-4"
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user