mirror of
https://github.com/anchore/syft
synced 2024-11-10 06:14:16 +00:00
Add GitLab cataloger
Signed-off-by: Ryan <ryanhopk@protonmail.com>
This commit is contained in:
parent
21eaa5c82b
commit
094130a034
4 changed files with 156 additions and 0 deletions
15
syft/pkg/cataloger/gitlab/cataloger.go
Normal file
15
syft/pkg/cataloger/gitlab/cataloger.go
Normal file
|
@ -0,0 +1,15 @@
|
|||
package gitlab
|
||||
|
||||
import (
|
||||
"github.com/anchore/syft/syft/pkg/cataloger/generic"
|
||||
)
|
||||
|
||||
const (
|
||||
catalogerName = "gitlab-cataloger"
|
||||
versionManifestGlob = "**/opt/gitlab/version-manifest.json"
|
||||
)
|
||||
|
||||
func NewGitLabCataloger() *generic.Cataloger {
|
||||
return generic.NewCataloger(catalogerName).
|
||||
WithParserByGlobs(parseVersionManifest, versionManifestGlob)
|
||||
}
|
96
syft/pkg/cataloger/gitlab/parse_manifest.go
Normal file
96
syft/pkg/cataloger/gitlab/parse_manifest.go
Normal file
|
@ -0,0 +1,96 @@
|
|||
package gitlab
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"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 versionManifest struct {
|
||||
ManifestFormat int `json:"manifest_format"`
|
||||
Software map[string]manifestPackage `json:"software"`
|
||||
BuildVersion string `json:"build_version"`
|
||||
BuildGitRevision string `json:"build_git_revision"`
|
||||
License string `json:"license"`
|
||||
}
|
||||
|
||||
type manifestPackage struct {
|
||||
LockedVersion *string `json:"locked_version"`
|
||||
LockedSource *lockedSource `json:"locked_source"`
|
||||
SourceType *string `json:"url"`
|
||||
DescribedVersion *string `json:"described_version"`
|
||||
DisplayVersion *string `json:"display_version"`
|
||||
Vendor *string `json:"vendor"`
|
||||
License *string `json:"license"`
|
||||
}
|
||||
|
||||
type lockedSource struct {
|
||||
Git string `json:"git"`
|
||||
URL string `json:"url"`
|
||||
Sha256 string `json:"sha256"`
|
||||
}
|
||||
|
||||
func parseVersionManifest(_ context.Context, _ file.Resolver, _ *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) {
|
||||
bytes, err := io.ReadAll(reader)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("failed to load version-manifest.json file: %w", err)
|
||||
}
|
||||
|
||||
var pkgs []pkg.Package
|
||||
var manifest versionManifest
|
||||
err = json.Unmarshal(bytes, &manifest)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("failed to parse version-manifest.json file: %w", err)
|
||||
}
|
||||
|
||||
for pkgName, pkgData := range manifest.Software {
|
||||
p := pkg.Package{
|
||||
Name: pkgName,
|
||||
Locations: file.NewLocationSet(reader.Location),
|
||||
}
|
||||
|
||||
if pkgData.DisplayVersion != nil {
|
||||
p.Version = *pkgData.DisplayVersion
|
||||
}
|
||||
if pkgData.License != nil {
|
||||
p.Licenses = pkg.NewLicenseSet(pkg.NewLicense(*pkgData.License))
|
||||
}
|
||||
if pkgData.LockedSource != nil && (*pkgData.SourceType == "git" || *pkgData.SourceType == "url") {
|
||||
var purl packageurl.PackageURL
|
||||
if *pkgData.SourceType == "git" {
|
||||
purl.Type = "gitlab"
|
||||
gitUrlComponents := strings.Split(pkgData.LockedSource.Git, "/")
|
||||
// Namespace is the user or organization
|
||||
purl.Namespace = strings.Split(gitUrlComponents[0], ":")[1]
|
||||
// Name is the repository name (with .git sliced out)
|
||||
purl.Name = gitUrlComponents[1][:len(gitUrlComponents[1])-4]
|
||||
} else {
|
||||
purl.Type = "generic"
|
||||
purl.Qualifiers = append(
|
||||
purl.Qualifiers,
|
||||
packageurl.Qualifier{
|
||||
Key: "download_url",
|
||||
Value: pkgData.LockedSource.URL,
|
||||
},
|
||||
packageurl.Qualifier{
|
||||
Key: "checksum",
|
||||
Value: pkgData.LockedSource.Sha256,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pkgs = append(pkgs, p)
|
||||
}
|
||||
|
||||
pkg.Sort(pkgs)
|
||||
|
||||
return pkgs, nil, nil
|
||||
}
|
26
syft/pkg/cataloger/gitlab/parse_manifest_test.go
Normal file
26
syft/pkg/cataloger/gitlab/parse_manifest_test.go
Normal file
|
@ -0,0 +1,26 @@
|
|||
package gitlab
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/anchore/syft/syft/file"
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
"github.com/anchore/syft/syft/pkg/cataloger/internal/pkgtest"
|
||||
)
|
||||
|
||||
func TestParseVersionManifestFile(t *testing.T) {
|
||||
fixture := "test-fixtures/glob-paths/opt/gitlab/version-manifest.json"
|
||||
locations := file.NewLocationSet(file.NewLocation(fixture))
|
||||
|
||||
var expectedPkg = pkg.Package{
|
||||
Name: "openssl",
|
||||
Version: "1.1.1q",
|
||||
Locations: locations,
|
||||
Licenses: pkg.NewLicenseSet(
|
||||
pkg.NewLicenseFromLocations("OpenSSL"),
|
||||
),
|
||||
PURL: "pkg:gitlab/omnibus-mirror/openssl",
|
||||
}
|
||||
|
||||
pkgtest.TestFileParser(t, fixture, parseVersionManifest, []pkg.Package{expectedPkg}, nil)
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"manifest_format": 2,
|
||||
"software": {
|
||||
"openssl": {
|
||||
"locked_version": "29708a562a1887a91de0fa6ca668c71871accde9",
|
||||
"locked_source": {
|
||||
"git": "git@dev.gitlab.org:omnibus-mirror/openssl.git"
|
||||
},
|
||||
"source_type": "git",
|
||||
"described_version": "OpenSSL_1_1_1q",
|
||||
"display_version": "1.1.1q",
|
||||
"vendor": "openssl",
|
||||
"license": "OpenSSL"
|
||||
}
|
||||
},
|
||||
"build_version": "15.6.1",
|
||||
"build_git_revision": "e3d1cd74ef1abe2b9514d8aa64c065b434becd3a",
|
||||
"license": "MIT"
|
||||
}
|
Loading…
Reference in a new issue