mirror of
https://github.com/anchore/syft.git
synced 2025-11-18 08:53:15 +01:00
Identify Jenkins plugin upstream of CPE generation
Signed-off-by: Dan Luhring <dan.luhring@anchore.com>
This commit is contained in:
parent
fa7fd718cb
commit
33e6be0b74
@ -54,9 +54,6 @@ func (s candidateStore) getCandidates(t pkg.Type, key string) []string {
|
||||
return value
|
||||
}
|
||||
|
||||
const pomPropertiesGroupIDJenkinsPlugins = "com.cloudbees.jenkins.plugins"
|
||||
const pomPropertiesGroupIDJiraPlugins = "com.atlassian.jira.plugins"
|
||||
|
||||
func newCPE(product, vendor, version, targetSW string) wfn.Attributes {
|
||||
cpe := *(wfn.NewAttributesWithAny())
|
||||
cpe.Part = "a"
|
||||
@ -115,22 +112,9 @@ func candidateTargetSoftwareAttrs(p pkg.Package) []string {
|
||||
return targetSw
|
||||
}
|
||||
|
||||
func isJenkinsPlugin(p pkg.Package) bool {
|
||||
if p.Type == pkg.JenkinsPluginPkg {
|
||||
return true
|
||||
}
|
||||
|
||||
if groupID := groupIDFromPomProperties(p); groupID == pomPropertiesGroupIDJenkinsPlugins {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func candidateTargetSoftwareAttrsForJava(p pkg.Package) []string {
|
||||
// Use the more specific indicator if available
|
||||
|
||||
if isJenkinsPlugin(p) {
|
||||
if p.Type == pkg.JenkinsPluginPkg {
|
||||
return []string{"jenkins", "cloudbees_jenkins"}
|
||||
}
|
||||
|
||||
@ -217,8 +201,8 @@ func shouldConsiderGroupID(groupID string) bool {
|
||||
}
|
||||
|
||||
excludedGroupIDs := []string{
|
||||
pomPropertiesGroupIDJiraPlugins,
|
||||
pomPropertiesGroupIDJenkinsPlugins,
|
||||
pkg.PomPropertiesGroupIDJiraPlugins,
|
||||
pkg.PomPropertiesGroupIDJenkinsPlugins,
|
||||
}
|
||||
|
||||
for _, excludedGroupID := range excludedGroupIDs {
|
||||
|
||||
@ -156,7 +156,7 @@ func TestGeneratePackageCPEs(t *testing.T) {
|
||||
Version: "3.2",
|
||||
FoundBy: "some-analyzer",
|
||||
Language: pkg.Java,
|
||||
Type: pkg.JavaPkg,
|
||||
Type: pkg.JenkinsPluginPkg,
|
||||
Metadata: pkg.JavaMetadata{
|
||||
PomProperties: &pkg.PomProperties{
|
||||
GroupID: "com.cloudbees.jenkins.plugins",
|
||||
|
||||
@ -186,14 +186,14 @@ func (j *archiveParser) discoverPkgsFromAllPomProperties(parentPkg *pkg.Package)
|
||||
continue
|
||||
}
|
||||
|
||||
pkgs = append(pkgs, j.packagesFromPomProperties(pomProperties, parentPkg)...)
|
||||
pkgs = append(pkgs, j.packagesFromPomProperties(*pomProperties, parentPkg)...)
|
||||
}
|
||||
return pkgs, nil
|
||||
}
|
||||
|
||||
// packagesFromPomProperties processes a single Maven POM properties for a given parent package, returning all listed Java packages found and
|
||||
// associating each discovered package to the given parent package.
|
||||
func (j *archiveParser) packagesFromPomProperties(pomProperties *pkg.PomProperties, parentPkg *pkg.Package) []pkg.Package {
|
||||
func (j *archiveParser) packagesFromPomProperties(pomProperties pkg.PomProperties, parentPkg *pkg.Package) []pkg.Package {
|
||||
// keep the artifact name within the virtual path if this package does not match the parent package
|
||||
vPathSuffix := ""
|
||||
if !strings.HasPrefix(pomProperties.ArtifactID, parentPkg.Name) {
|
||||
@ -206,11 +206,11 @@ func (j *archiveParser) packagesFromPomProperties(pomProperties *pkg.PomProperti
|
||||
Name: pomProperties.ArtifactID,
|
||||
Version: pomProperties.Version,
|
||||
Language: pkg.Java,
|
||||
Type: pkg.JavaPkg,
|
||||
Type: pomProperties.PkgTypeIndicated(),
|
||||
MetadataType: pkg.JavaMetadataType,
|
||||
Metadata: pkg.JavaMetadata{
|
||||
VirtualPath: virtualPath,
|
||||
PomProperties: pomProperties,
|
||||
PomProperties: &pomProperties,
|
||||
Parent: parentPkg,
|
||||
},
|
||||
}
|
||||
@ -243,10 +243,13 @@ func (j *archiveParser) packagesFromPomProperties(pomProperties *pkg.PomProperti
|
||||
parentPkg.Version = p.Version
|
||||
}
|
||||
|
||||
// We may have learned more about the type via data in the pom properties
|
||||
parentPkg.Type = p.Type
|
||||
|
||||
// keep the pom properties, but don't overwrite existing pom properties
|
||||
parentMetadata, ok := parentPkg.Metadata.(pkg.JavaMetadata)
|
||||
if ok && parentMetadata.PomProperties == nil {
|
||||
parentMetadata.PomProperties = pomProperties
|
||||
parentMetadata.PomProperties = &pomProperties
|
||||
parentPkg.Metadata = parentMetadata
|
||||
}
|
||||
|
||||
|
||||
@ -629,12 +629,12 @@ func TestPackagesFromPomProperties(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "child matches parent by key",
|
||||
name: "single package from pom properties that's a Jenkins plugin",
|
||||
props: &pkg.PomProperties{
|
||||
Name: "some-name",
|
||||
GroupID: "some-group-id",
|
||||
ArtifactID: "some-parent-name", // note: matches parent package
|
||||
Version: "2.0", // note: matches parent package
|
||||
GroupID: "com.cloudbees.jenkins.plugins",
|
||||
ArtifactID: "some-artifact-id",
|
||||
Version: "1.0",
|
||||
},
|
||||
parent: &pkg.Package{
|
||||
Name: "some-parent-name",
|
||||
@ -650,6 +650,66 @@ func TestPackagesFromPomProperties(t *testing.T) {
|
||||
expectedParent: pkg.Package{
|
||||
Name: "some-parent-name",
|
||||
Version: "2.0",
|
||||
Metadata: pkg.JavaMetadata{
|
||||
VirtualPath: "some-parent-virtual-path",
|
||||
Manifest: nil,
|
||||
PomProperties: nil,
|
||||
Parent: nil,
|
||||
},
|
||||
},
|
||||
expectedPackages: []pkg.Package{
|
||||
{
|
||||
Name: "some-artifact-id",
|
||||
Version: "1.0",
|
||||
Language: pkg.Java,
|
||||
Type: pkg.JenkinsPluginPkg,
|
||||
MetadataType: pkg.JavaMetadataType,
|
||||
Metadata: pkg.JavaMetadata{
|
||||
VirtualPath: virtualPath + ":" + "some-artifact-id",
|
||||
PomProperties: &pkg.PomProperties{
|
||||
Name: "some-name",
|
||||
GroupID: "com.cloudbees.jenkins.plugins",
|
||||
ArtifactID: "some-artifact-id",
|
||||
Version: "1.0",
|
||||
},
|
||||
Parent: &pkg.Package{
|
||||
Name: "some-parent-name",
|
||||
Version: "2.0",
|
||||
Metadata: pkg.JavaMetadata{
|
||||
VirtualPath: "some-parent-virtual-path",
|
||||
Manifest: nil,
|
||||
PomProperties: nil,
|
||||
Parent: nil,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "child matches parent by key",
|
||||
props: &pkg.PomProperties{
|
||||
Name: "some-name",
|
||||
GroupID: "some-group-id",
|
||||
ArtifactID: "some-parent-name", // note: matches parent package
|
||||
Version: "2.0", // note: matches parent package
|
||||
},
|
||||
parent: &pkg.Package{
|
||||
Name: "some-parent-name",
|
||||
Version: "2.0",
|
||||
Type: pkg.JavaPkg,
|
||||
Metadata: pkg.JavaMetadata{
|
||||
VirtualPath: "some-parent-virtual-path",
|
||||
Manifest: nil,
|
||||
PomProperties: nil,
|
||||
Parent: nil,
|
||||
},
|
||||
},
|
||||
// note: the SAME as the original parent values
|
||||
expectedParent: pkg.Package{
|
||||
Name: "some-parent-name",
|
||||
Version: "2.0",
|
||||
Type: pkg.JavaPkg,
|
||||
Metadata: pkg.JavaMetadata{
|
||||
VirtualPath: "some-parent-virtual-path",
|
||||
Manifest: nil,
|
||||
@ -665,6 +725,44 @@ func TestPackagesFromPomProperties(t *testing.T) {
|
||||
},
|
||||
expectedPackages: nil,
|
||||
},
|
||||
{
|
||||
name: "child matches parent by key and is Jenkins plugin",
|
||||
props: &pkg.PomProperties{
|
||||
Name: "some-name",
|
||||
GroupID: "com.cloudbees.jenkins.plugins",
|
||||
ArtifactID: "some-parent-name", // note: matches parent package
|
||||
Version: "2.0", // note: matches parent package
|
||||
},
|
||||
parent: &pkg.Package{
|
||||
Name: "some-parent-name",
|
||||
Version: "2.0",
|
||||
Type: pkg.JavaPkg,
|
||||
Metadata: pkg.JavaMetadata{
|
||||
VirtualPath: "some-parent-virtual-path",
|
||||
Manifest: nil,
|
||||
PomProperties: nil,
|
||||
Parent: nil,
|
||||
},
|
||||
},
|
||||
expectedParent: pkg.Package{
|
||||
Name: "some-parent-name",
|
||||
Version: "2.0",
|
||||
Type: pkg.JenkinsPluginPkg,
|
||||
Metadata: pkg.JavaMetadata{
|
||||
VirtualPath: "some-parent-virtual-path",
|
||||
Manifest: nil,
|
||||
// note: we attach the discovered pom properties data
|
||||
PomProperties: &pkg.PomProperties{
|
||||
Name: "some-name",
|
||||
GroupID: "com.cloudbees.jenkins.plugins",
|
||||
ArtifactID: "some-parent-name", // note: matches parent package
|
||||
Version: "2.0", // note: matches parent package
|
||||
},
|
||||
Parent: nil,
|
||||
},
|
||||
},
|
||||
expectedPackages: nil,
|
||||
},
|
||||
{
|
||||
name: "child matches parent by virtual path",
|
||||
props: &pkg.PomProperties{
|
||||
@ -676,6 +774,7 @@ func TestPackagesFromPomProperties(t *testing.T) {
|
||||
parent: &pkg.Package{
|
||||
Name: "some-parent-name",
|
||||
Version: "2.0",
|
||||
Type: pkg.JavaPkg,
|
||||
Metadata: pkg.JavaMetadata{
|
||||
VirtualPath: virtualPath + ":some-parent-name", // note: matching virtual path
|
||||
Manifest: nil,
|
||||
@ -686,6 +785,7 @@ func TestPackagesFromPomProperties(t *testing.T) {
|
||||
expectedParent: pkg.Package{
|
||||
Name: "some-parent-name",
|
||||
Version: "2.0",
|
||||
Type: pkg.JavaPkg,
|
||||
Metadata: pkg.JavaMetadata{
|
||||
VirtualPath: virtualPath + ":some-parent-name", // note: matching virtual path
|
||||
Manifest: nil,
|
||||
@ -712,6 +812,7 @@ func TestPackagesFromPomProperties(t *testing.T) {
|
||||
parent: &pkg.Package{
|
||||
Name: "", // note: empty
|
||||
Version: "", // note: empty
|
||||
Type: pkg.JavaPkg,
|
||||
Metadata: pkg.JavaMetadata{
|
||||
VirtualPath: virtualPath + ":some-parent-name", // note: matching virtual path
|
||||
Manifest: nil,
|
||||
@ -722,6 +823,7 @@ func TestPackagesFromPomProperties(t *testing.T) {
|
||||
expectedParent: pkg.Package{
|
||||
Name: "some-parent-name",
|
||||
Version: "3.0",
|
||||
Type: pkg.JavaPkg,
|
||||
Metadata: pkg.JavaMetadata{
|
||||
VirtualPath: virtualPath + ":some-parent-name", // note: matching virtual path
|
||||
Manifest: nil,
|
||||
@ -748,11 +850,12 @@ func TestPackagesFromPomProperties(t *testing.T) {
|
||||
parent: &pkg.Package{
|
||||
Name: "some-parent-name",
|
||||
Version: "2.0",
|
||||
Type: pkg.JavaPkg,
|
||||
Metadata: pkg.JavaMetadata{
|
||||
VirtualPath: virtualPath + ":some-parent-name", // note: matching virtual path
|
||||
Manifest: nil,
|
||||
PomProperties: &pkg.PomProperties{
|
||||
Name: "EXISTS", //note: this already exists and should not be overridden
|
||||
Name: "EXISTS", // note: this already exists and should not be overridden
|
||||
},
|
||||
Parent: nil,
|
||||
},
|
||||
@ -760,12 +863,13 @@ func TestPackagesFromPomProperties(t *testing.T) {
|
||||
expectedParent: pkg.Package{
|
||||
Name: "some-parent-name",
|
||||
Version: "2.0",
|
||||
Type: pkg.JavaPkg,
|
||||
Metadata: pkg.JavaMetadata{
|
||||
VirtualPath: virtualPath + ":some-parent-name", // note: matching virtual path
|
||||
Manifest: nil,
|
||||
// note: we attach the discovered pom properties data
|
||||
PomProperties: &pkg.PomProperties{
|
||||
Name: "EXISTS", //note: this already exists and should not be overridden
|
||||
Name: "EXISTS", // note: this already exists and should not be overridden
|
||||
},
|
||||
Parent: nil,
|
||||
},
|
||||
@ -783,6 +887,7 @@ func TestPackagesFromPomProperties(t *testing.T) {
|
||||
parent: &pkg.Package{
|
||||
Name: "some-parent-name",
|
||||
Version: "2.0",
|
||||
Type: pkg.JavaPkg,
|
||||
Metadata: pkg.JavaMetadata{
|
||||
VirtualPath: virtualPath + ":NEW_VIRTUAL_PATH", // note: DOES NOT match the existing virtual path
|
||||
Manifest: nil,
|
||||
@ -794,6 +899,7 @@ func TestPackagesFromPomProperties(t *testing.T) {
|
||||
expectedParent: pkg.Package{
|
||||
Name: "some-parent-name",
|
||||
Version: "2.0",
|
||||
Type: pkg.JavaPkg,
|
||||
Metadata: pkg.JavaMetadata{
|
||||
VirtualPath: virtualPath + ":NEW_VIRTUAL_PATH",
|
||||
Manifest: nil,
|
||||
@ -823,7 +929,7 @@ func TestPackagesFromPomProperties(t *testing.T) {
|
||||
t.Cleanup(cleanup)
|
||||
|
||||
// get the test data
|
||||
actualPackages := parser.packagesFromPomProperties(test.props, test.parent)
|
||||
actualPackages := parser.packagesFromPomProperties(*test.props, test.parent)
|
||||
assert.Equal(t, test.expectedPackages, actualPackages)
|
||||
assert.Equal(t, test.expectedParent, *test.parent)
|
||||
})
|
||||
|
||||
@ -20,6 +20,15 @@ type PomProperties struct {
|
||||
Extra map[string]string `mapstructure:",remain" json:"extraFields"`
|
||||
}
|
||||
|
||||
// PkgTypeIndicated returns the package Type indicated by the data contained in the PomProperties.
|
||||
func (p PomProperties) PkgTypeIndicated() Type {
|
||||
if p.GroupID == PomPropertiesGroupIDJenkinsPlugins {
|
||||
return JenkinsPluginPkg
|
||||
}
|
||||
|
||||
return JavaPkg
|
||||
}
|
||||
|
||||
// JavaManifest represents the fields of interest extracted from a Java archive's META-INF/MANIFEST.MF file.
|
||||
type JavaManifest struct {
|
||||
Main map[string]string `json:"main,omitempty"`
|
||||
@ -43,3 +52,6 @@ func (m JavaMetadata) PackageURL() string {
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
const PomPropertiesGroupIDJenkinsPlugins = "com.cloudbees.jenkins.plugins"
|
||||
const PomPropertiesGroupIDJiraPlugins = "com.atlassian.jira.plugins"
|
||||
|
||||
@ -2,9 +2,48 @@ package pkg
|
||||
|
||||
import (
|
||||
"github.com/sergi/go-diff/diffmatchpatch"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestPomProperties_PkgTypeIndicated(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
pomProperties PomProperties
|
||||
expectedType Type
|
||||
}{
|
||||
{
|
||||
name: "regular Java package",
|
||||
pomProperties: PomProperties{
|
||||
Path: "some path",
|
||||
Name: "some name",
|
||||
GroupID: "some group ID",
|
||||
ArtifactID: "some artifact ID",
|
||||
Version: "1",
|
||||
},
|
||||
expectedType: JavaPkg,
|
||||
},
|
||||
{
|
||||
name: "jenkins plugin",
|
||||
pomProperties: PomProperties{
|
||||
Path: "some path",
|
||||
Name: "some name",
|
||||
GroupID: "com.cloudbees.jenkins.plugins",
|
||||
ArtifactID: "some artifact ID",
|
||||
Version: "1",
|
||||
},
|
||||
expectedType: JenkinsPluginPkg,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
actual := tc.pomProperties.PkgTypeIndicated()
|
||||
assert.Equal(t, tc.expectedType, actual)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestJavaMetadata_pURL(t *testing.T) {
|
||||
tests := []struct {
|
||||
metadata JavaMetadata
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user