mirror of
https://github.com/SAP/jenkins-library.git
synced 2025-03-05 15:15:44 +02:00
cnbBuild: create CycloneDX SBOM file (#3959)
Co-authored-by: Johannes Dillmann <j.dillmann@sap.com> Co-authored-by: Ralf Pannemans <ralf.pannemans@sap.com>
This commit is contained in:
parent
85b277c7c6
commit
14ce92b4fb
@ -7,6 +7,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/SAP/jenkins-library/pkg/buildsettings"
|
"github.com/SAP/jenkins-library/pkg/buildsettings"
|
||||||
"github.com/SAP/jenkins-library/pkg/certutils"
|
"github.com/SAP/jenkins-library/pkg/certutils"
|
||||||
@ -368,6 +369,7 @@ func callCnbBuild(config *cnbBuildOptions, telemetryData *telemetry.CustomData,
|
|||||||
cnbTelemetry.dockerImage = dockerImage
|
cnbTelemetry.dockerImage = dockerImage
|
||||||
|
|
||||||
cnbBuildConfig := buildsettings.BuildOptions{
|
cnbBuildConfig := buildsettings.BuildOptions{
|
||||||
|
CreateBOM: config.CreateBOM,
|
||||||
DockerImage: dockerImage,
|
DockerImage: dockerImage,
|
||||||
BuildSettingsInfo: config.BuildSettingsInfo,
|
BuildSettingsInfo: config.BuildSettingsInfo,
|
||||||
}
|
}
|
||||||
@ -619,6 +621,16 @@ func runCnbBuild(config *cnbBuildOptions, cnbTelemetry *cnbBuildTelemetry, utils
|
|||||||
commonPipelineEnvironment.container.imageDigest = digest
|
commonPipelineEnvironment.container.imageDigest = digest
|
||||||
commonPipelineEnvironment.container.imageDigests = append(commonPipelineEnvironment.container.imageDigests, digest)
|
commonPipelineEnvironment.container.imageDigests = append(commonPipelineEnvironment.container.imageDigests, digest)
|
||||||
|
|
||||||
|
if config.CreateBOM {
|
||||||
|
bomFilename := fmt.Sprintf("bom-%s-%s.xml", targetImage.ContainerImageName, strings.TrimLeft(digest, "sha256:"))
|
||||||
|
imageName := fmt.Sprintf("%s:%s", containerImage, targetImage.ContainerImageTag)
|
||||||
|
err = cnbutils.MergeSBOMFiles("/layers/sbom/launch/**/sbom.syft.json", bomFilename, imageName, dockerConfigFile, utils)
|
||||||
|
if err != nil {
|
||||||
|
log.SetErrorCategory(log.ErrorBuild)
|
||||||
|
return errors.Wrap(err, "failed to create SBoM file")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if len(config.PreserveFiles) > 0 {
|
if len(config.PreserveFiles) > 0 {
|
||||||
if pathType != pathEnumArchive {
|
if pathType != pathEnumArchive {
|
||||||
err = cnbutils.CopyProject(target, source, ignore.CompileIgnoreLines(config.PreserveFiles...), nil, utils)
|
err = cnbutils.CopyProject(target, source, ignore.CompileIgnoreLines(config.PreserveFiles...), nil, utils)
|
||||||
|
@ -6,14 +6,18 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/SAP/jenkins-library/pkg/config"
|
"github.com/SAP/jenkins-library/pkg/config"
|
||||||
|
"github.com/SAP/jenkins-library/pkg/gcs"
|
||||||
"github.com/SAP/jenkins-library/pkg/log"
|
"github.com/SAP/jenkins-library/pkg/log"
|
||||||
"github.com/SAP/jenkins-library/pkg/piperenv"
|
"github.com/SAP/jenkins-library/pkg/piperenv"
|
||||||
"github.com/SAP/jenkins-library/pkg/splunk"
|
"github.com/SAP/jenkins-library/pkg/splunk"
|
||||||
"github.com/SAP/jenkins-library/pkg/telemetry"
|
"github.com/SAP/jenkins-library/pkg/telemetry"
|
||||||
"github.com/SAP/jenkins-library/pkg/validation"
|
"github.com/SAP/jenkins-library/pkg/validation"
|
||||||
|
"github.com/bmatcuk/doublestar"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -33,6 +37,7 @@ type cnbBuildOptions struct {
|
|||||||
MultipleImages []map[string]interface{} `json:"multipleImages,omitempty"`
|
MultipleImages []map[string]interface{} `json:"multipleImages,omitempty"`
|
||||||
PreserveFiles []string `json:"preserveFiles,omitempty"`
|
PreserveFiles []string `json:"preserveFiles,omitempty"`
|
||||||
BuildSettingsInfo string `json:"buildSettingsInfo,omitempty"`
|
BuildSettingsInfo string `json:"buildSettingsInfo,omitempty"`
|
||||||
|
CreateBOM bool `json:"createBOM,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type cnbBuildCommonPipelineEnvironment struct {
|
type cnbBuildCommonPipelineEnvironment struct {
|
||||||
@ -77,6 +82,42 @@ func (p *cnbBuildCommonPipelineEnvironment) persist(path, resourceName string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type cnbBuildReports struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *cnbBuildReports) persist(stepConfig cnbBuildOptions, gcpJsonKeyFilePath string, gcsBucketId string, gcsFolderPath string, gcsSubFolder string) {
|
||||||
|
if gcsBucketId == "" {
|
||||||
|
log.Entry().Info("persisting reports to GCS is disabled, because gcsBucketId is empty")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Entry().Info("Uploading reports to Google Cloud Storage...")
|
||||||
|
content := []gcs.ReportOutputParam{
|
||||||
|
{FilePattern: "**/bom-*.xml", ParamRef: "", StepResultType: "sbom"},
|
||||||
|
}
|
||||||
|
envVars := []gcs.EnvVar{
|
||||||
|
{Name: "GOOGLE_APPLICATION_CREDENTIALS", Value: gcpJsonKeyFilePath, Modified: false},
|
||||||
|
}
|
||||||
|
gcsClient, err := gcs.NewClient(gcs.WithEnvVars(envVars))
|
||||||
|
if err != nil {
|
||||||
|
log.Entry().Errorf("creation of GCS client failed: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer gcsClient.Close()
|
||||||
|
structVal := reflect.ValueOf(&stepConfig).Elem()
|
||||||
|
inputParameters := map[string]string{}
|
||||||
|
for i := 0; i < structVal.NumField(); i++ {
|
||||||
|
field := structVal.Type().Field(i)
|
||||||
|
if field.Type.String() == "string" {
|
||||||
|
paramName := strings.Split(field.Tag.Get("json"), ",")
|
||||||
|
paramValue, _ := structVal.Field(i).Interface().(string)
|
||||||
|
inputParameters[paramName[0]] = paramValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err := gcs.PersistReportsToGCS(gcsClient, content, inputParameters, gcsFolderPath, gcsBucketId, gcsSubFolder, doublestar.Glob, os.Stat); err != nil {
|
||||||
|
log.Entry().Errorf("failed to persist reports: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// CnbBuildCommand Executes Cloud Native Buildpacks.
|
// CnbBuildCommand Executes Cloud Native Buildpacks.
|
||||||
func CnbBuildCommand() *cobra.Command {
|
func CnbBuildCommand() *cobra.Command {
|
||||||
const STEP_NAME = "cnbBuild"
|
const STEP_NAME = "cnbBuild"
|
||||||
@ -85,6 +126,7 @@ func CnbBuildCommand() *cobra.Command {
|
|||||||
var stepConfig cnbBuildOptions
|
var stepConfig cnbBuildOptions
|
||||||
var startTime time.Time
|
var startTime time.Time
|
||||||
var commonPipelineEnvironment cnbBuildCommonPipelineEnvironment
|
var commonPipelineEnvironment cnbBuildCommonPipelineEnvironment
|
||||||
|
var reports cnbBuildReports
|
||||||
var logCollector *log.CollectorHook
|
var logCollector *log.CollectorHook
|
||||||
var splunkClient *splunk.Splunk
|
var splunkClient *splunk.Splunk
|
||||||
telemetryClient := &telemetry.Telemetry{}
|
telemetryClient := &telemetry.Telemetry{}
|
||||||
@ -143,6 +185,7 @@ func CnbBuildCommand() *cobra.Command {
|
|||||||
stepTelemetryData.ErrorCode = "1"
|
stepTelemetryData.ErrorCode = "1"
|
||||||
handler := func() {
|
handler := func() {
|
||||||
commonPipelineEnvironment.persist(GeneralConfig.EnvRootPath, "commonPipelineEnvironment")
|
commonPipelineEnvironment.persist(GeneralConfig.EnvRootPath, "commonPipelineEnvironment")
|
||||||
|
reports.persist(stepConfig, GeneralConfig.GCPJsonKeyFilePath, GeneralConfig.GCSBucketId, GeneralConfig.GCSFolderPath, GeneralConfig.GCSSubFolder)
|
||||||
config.RemoveVaultSecretFiles()
|
config.RemoveVaultSecretFiles()
|
||||||
stepTelemetryData.Duration = fmt.Sprintf("%v", time.Since(startTime).Milliseconds())
|
stepTelemetryData.Duration = fmt.Sprintf("%v", time.Since(startTime).Milliseconds())
|
||||||
stepTelemetryData.ErrorCategory = log.GetErrorCategory().String()
|
stepTelemetryData.ErrorCategory = log.GetErrorCategory().String()
|
||||||
@ -188,6 +231,7 @@ func addCnbBuildFlags(cmd *cobra.Command, stepConfig *cnbBuildOptions) {
|
|||||||
|
|
||||||
cmd.Flags().StringSliceVar(&stepConfig.PreserveFiles, "preserveFiles", []string{}, "List of globs, for keeping build results in the Jenkins workspace.\n\n*Note*: globs will be calculated relative to the [path](#path) property.\n")
|
cmd.Flags().StringSliceVar(&stepConfig.PreserveFiles, "preserveFiles", []string{}, "List of globs, for keeping build results in the Jenkins workspace.\n\n*Note*: globs will be calculated relative to the [path](#path) property.\n")
|
||||||
cmd.Flags().StringVar(&stepConfig.BuildSettingsInfo, "buildSettingsInfo", os.Getenv("PIPER_buildSettingsInfo"), "Build settings info is typically filled by the step automatically to create information about the build settings that were used during the mta build. This information is typically used for compliance related processes.")
|
cmd.Flags().StringVar(&stepConfig.BuildSettingsInfo, "buildSettingsInfo", os.Getenv("PIPER_buildSettingsInfo"), "Build settings info is typically filled by the step automatically to create information about the build settings that were used during the mta build. This information is typically used for compliance related processes.")
|
||||||
|
cmd.Flags().BoolVar(&stepConfig.CreateBOM, "createBOM", false, "**EXPERIMENTAL:** Creates the bill of materials (BOM) using CycloneDX plugin.")
|
||||||
|
|
||||||
cmd.MarkFlagRequired("containerImageTag")
|
cmd.MarkFlagRequired("containerImageTag")
|
||||||
cmd.MarkFlagRequired("containerRegistryUrl")
|
cmd.MarkFlagRequired("containerRegistryUrl")
|
||||||
@ -380,6 +424,15 @@ func cnbBuildMetadata() config.StepData {
|
|||||||
Aliases: []config.Alias{},
|
Aliases: []config.Alias{},
|
||||||
Default: os.Getenv("PIPER_buildSettingsInfo"),
|
Default: os.Getenv("PIPER_buildSettingsInfo"),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "createBOM",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
|
Scope: []string{"GENERAL", "STEPS", "STAGES", "PARAMETERS"},
|
||||||
|
Type: "bool",
|
||||||
|
Mandatory: false,
|
||||||
|
Aliases: []config.Alias{},
|
||||||
|
Default: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Containers: []config.Container{
|
Containers: []config.Container{
|
||||||
@ -400,6 +453,13 @@ func cnbBuildMetadata() config.StepData {
|
|||||||
{"name": "custom/buildSettingsInfo"},
|
{"name": "custom/buildSettingsInfo"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "reports",
|
||||||
|
Type: "reports",
|
||||||
|
Parameters: []map[string]interface{}{
|
||||||
|
{"filePattern": "**/bom-*.xml", "type": "sbom"},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -11,6 +11,8 @@ import (
|
|||||||
piperhttp "github.com/SAP/jenkins-library/pkg/http"
|
piperhttp "github.com/SAP/jenkins-library/pkg/http"
|
||||||
"github.com/SAP/jenkins-library/pkg/mock"
|
"github.com/SAP/jenkins-library/pkg/mock"
|
||||||
"github.com/SAP/jenkins-library/pkg/telemetry"
|
"github.com/SAP/jenkins-library/pkg/telemetry"
|
||||||
|
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||||
|
"github.com/google/go-containerregistry/pkg/v1/fake"
|
||||||
"github.com/jarcoal/httpmock"
|
"github.com/jarcoal/httpmock"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
@ -22,7 +24,20 @@ func newCnbBuildTestsUtils() cnbutils.MockUtils {
|
|||||||
utils := cnbutils.MockUtils{
|
utils := cnbutils.MockUtils{
|
||||||
ExecMockRunner: &mock.ExecMockRunner{},
|
ExecMockRunner: &mock.ExecMockRunner{},
|
||||||
FilesMock: &mock.FilesMock{},
|
FilesMock: &mock.FilesMock{},
|
||||||
|
DownloadMock: &mock.DownloadMock{},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fakeImage := &fake.FakeImage{}
|
||||||
|
fakeImage.ConfigFileReturns(&v1.ConfigFile{
|
||||||
|
Config: v1.Config{
|
||||||
|
Labels: map[string]string{
|
||||||
|
"io.buildpacks.buildpackage.metadata": "{\"id\": \"testbuildpack\", \"version\": \"0.0.1\"}",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, nil)
|
||||||
|
|
||||||
|
utils.RemoteImageInfo = fakeImage
|
||||||
|
utils.ReturnImage = fakeImage
|
||||||
utils.AddFile("/layers/report.toml", []byte(`[build]
|
utils.AddFile("/layers/report.toml", []byte(`[build]
|
||||||
[image]
|
[image]
|
||||||
tags = ["localhost:5000/not-found:0.0.1"]
|
tags = ["localhost:5000/not-found:0.0.1"]
|
||||||
|
227
go.mod
227
go.mod
@ -3,79 +3,80 @@ module github.com/SAP/jenkins-library
|
|||||||
go 1.18
|
go 1.18
|
||||||
|
|
||||||
require (
|
require (
|
||||||
cloud.google.com/go/storage v1.10.0
|
cloud.google.com/go/storage v1.22.1
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.4.0
|
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.4.0
|
||||||
github.com/Jeffail/gabs/v2 v2.6.1
|
github.com/Jeffail/gabs/v2 v2.6.1
|
||||||
github.com/Masterminds/sprig v2.22.0+incompatible
|
github.com/Masterminds/sprig v2.22.0+incompatible
|
||||||
|
github.com/anchore/syft v0.53.4
|
||||||
github.com/antchfx/htmlquery v1.2.4
|
github.com/antchfx/htmlquery v1.2.4
|
||||||
github.com/aws/aws-sdk-go-v2/config v1.15.3
|
github.com/aws/aws-sdk-go-v2/config v1.15.10
|
||||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.26.3
|
github.com/aws/aws-sdk-go-v2/service/s3 v1.26.3
|
||||||
github.com/bmatcuk/doublestar v1.3.4
|
github.com/bmatcuk/doublestar v1.3.4
|
||||||
github.com/bndr/gojenkins v1.1.1-0.20210520222939-90ed82bfdff6
|
github.com/bndr/gojenkins v1.1.1-0.20210520222939-90ed82bfdff6
|
||||||
github.com/buildpacks/lifecycle v0.13.0
|
github.com/buildpacks/lifecycle v0.13.0
|
||||||
github.com/docker/cli v20.10.11+incompatible
|
github.com/docker/cli v20.10.17+incompatible
|
||||||
github.com/elliotchance/orderedmap v1.4.0
|
github.com/elliotchance/orderedmap v1.4.0
|
||||||
github.com/evanphx/json-patch v4.12.0+incompatible
|
github.com/evanphx/json-patch v4.12.0+incompatible
|
||||||
github.com/getsentry/sentry-go v0.11.0
|
github.com/getsentry/sentry-go v0.11.0
|
||||||
github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32
|
github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32
|
||||||
github.com/go-git/go-billy/v5 v5.3.1
|
github.com/go-git/go-billy/v5 v5.3.1
|
||||||
github.com/go-git/go-git/v5 v5.4.2
|
github.com/go-git/go-git/v5 v5.4.2
|
||||||
github.com/go-openapi/runtime v0.20.0
|
github.com/go-openapi/runtime v0.24.1
|
||||||
github.com/go-openapi/strfmt v0.20.3
|
github.com/go-openapi/strfmt v0.21.3
|
||||||
github.com/go-playground/locales v0.14.0
|
github.com/go-playground/locales v0.14.0
|
||||||
github.com/go-playground/universal-translator v0.18.0
|
github.com/go-playground/universal-translator v0.18.0
|
||||||
github.com/go-playground/validator/v10 v10.9.0
|
github.com/go-playground/validator/v10 v10.11.0
|
||||||
github.com/google/go-cmp v0.5.8
|
github.com/google/go-cmp v0.5.8
|
||||||
github.com/google/go-containerregistry v0.6.0
|
github.com/google/go-containerregistry v0.10.0
|
||||||
github.com/google/go-github/v45 v45.2.0
|
github.com/google/go-github/v45 v45.2.0
|
||||||
github.com/google/uuid v1.3.0
|
github.com/google/uuid v1.3.0
|
||||||
github.com/hashicorp/go-retryablehttp v0.7.0
|
github.com/hashicorp/go-retryablehttp v0.7.1
|
||||||
github.com/hashicorp/vault v1.9.3
|
github.com/hashicorp/vault v1.9.3
|
||||||
github.com/hashicorp/vault/api v1.3.0
|
github.com/hashicorp/vault/api v1.3.0
|
||||||
github.com/imdario/mergo v0.3.12
|
github.com/imdario/mergo v0.3.12
|
||||||
github.com/influxdata/influxdb-client-go/v2 v2.5.1
|
github.com/influxdata/influxdb-client-go/v2 v2.5.1
|
||||||
github.com/jarcoal/httpmock v1.0.8
|
github.com/jarcoal/httpmock v1.0.8
|
||||||
github.com/magiconair/properties v1.8.5
|
github.com/magiconair/properties v1.8.6
|
||||||
github.com/magicsong/sonargo v0.0.1
|
github.com/magicsong/sonargo v0.0.1
|
||||||
github.com/microsoft/azure-devops-go-api/azuredevops v1.0.0-b5
|
github.com/microsoft/azure-devops-go-api/azuredevops v1.0.0-b5
|
||||||
github.com/mitchellh/mapstructure v1.4.3
|
github.com/mitchellh/mapstructure v1.5.0
|
||||||
github.com/motemen/go-nuts v0.0.0-20210915132349-615a782f2c69
|
github.com/motemen/go-nuts v0.0.0-20210915132349-615a782f2c69
|
||||||
github.com/package-url/packageurl-go v0.1.0
|
github.com/package-url/packageurl-go v0.1.0
|
||||||
github.com/pelletier/go-toml v1.9.4
|
github.com/pelletier/go-toml v1.9.5
|
||||||
github.com/piper-validation/fortify-client-go v0.0.0-20220126145513-7b3e9a72af01
|
github.com/piper-validation/fortify-client-go v0.0.0-20220126145513-7b3e9a72af01
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06
|
github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06
|
||||||
github.com/sirupsen/logrus v1.8.1
|
github.com/sirupsen/logrus v1.8.1
|
||||||
github.com/spf13/cobra v1.3.0
|
github.com/spf13/cobra v1.5.0
|
||||||
github.com/spf13/pflag v1.0.5
|
github.com/spf13/pflag v1.0.5
|
||||||
github.com/stretchr/testify v1.7.1
|
github.com/stretchr/testify v1.8.0
|
||||||
github.com/testcontainers/testcontainers-go v0.10.0
|
github.com/testcontainers/testcontainers-go v0.10.0
|
||||||
github.com/xuri/excelize/v2 v2.4.1
|
github.com/xuri/excelize/v2 v2.4.1
|
||||||
golang.org/x/mod v0.5.1
|
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3
|
||||||
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8
|
golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2
|
||||||
golang.org/x/text v0.3.7
|
golang.org/x/text v0.3.7
|
||||||
google.golang.org/api v0.67.0
|
google.golang.org/api v0.88.0
|
||||||
gopkg.in/ini.v1 v1.66.2
|
gopkg.in/ini.v1 v1.66.6
|
||||||
gopkg.in/yaml.v2 v2.4.0
|
gopkg.in/yaml.v2 v2.4.0
|
||||||
helm.sh/helm/v3 v3.8.0
|
helm.sh/helm/v3 v3.8.0
|
||||||
mvdan.cc/xurls/v2 v2.4.0
|
mvdan.cc/xurls/v2 v2.4.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
cloud.google.com/go v0.100.2 // indirect
|
cloud.google.com/go v0.102.0 // indirect
|
||||||
cloud.google.com/go/compute v0.1.0 // indirect
|
cloud.google.com/go/compute v1.7.0 // indirect
|
||||||
cloud.google.com/go/iam v0.1.0 // indirect
|
cloud.google.com/go/iam v0.3.0 // indirect
|
||||||
cloud.google.com/go/kms v1.3.0 // indirect
|
cloud.google.com/go/kms v1.3.0 // indirect
|
||||||
cloud.google.com/go/monitoring v1.3.0 // indirect
|
cloud.google.com/go/monitoring v1.3.0 // indirect
|
||||||
github.com/Azure/azure-sdk-for-go v58.3.0+incompatible // indirect
|
github.com/Azure/azure-sdk-for-go v65.0.0+incompatible // indirect
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v0.23.0 // indirect
|
github.com/Azure/azure-sdk-for-go/sdk/azcore v0.23.0 // indirect
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/internal v0.9.2 // indirect
|
github.com/Azure/azure-sdk-for-go/sdk/internal v0.9.2 // indirect
|
||||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
|
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
|
||||||
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
|
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
|
||||||
github.com/Azure/go-autorest/autorest v0.11.21 // indirect
|
github.com/Azure/go-autorest/autorest v0.11.27 // indirect
|
||||||
github.com/Azure/go-autorest/autorest/adal v0.9.15 // indirect
|
github.com/Azure/go-autorest/autorest/adal v0.9.18 // indirect
|
||||||
github.com/Azure/go-autorest/autorest/azure/auth v0.5.8 // indirect
|
github.com/Azure/go-autorest/autorest/azure/auth v0.5.11 // indirect
|
||||||
github.com/Azure/go-autorest/autorest/azure/cli v0.4.2 // indirect
|
github.com/Azure/go-autorest/autorest/azure/cli v0.4.5 // indirect
|
||||||
github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect
|
github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect
|
||||||
github.com/Azure/go-autorest/autorest/to v0.4.0 // indirect
|
github.com/Azure/go-autorest/autorest/to v0.4.0 // indirect
|
||||||
github.com/Azure/go-autorest/autorest/validation v0.3.1 // indirect
|
github.com/Azure/go-autorest/autorest/validation v0.3.1 // indirect
|
||||||
@ -88,90 +89,101 @@ require (
|
|||||||
github.com/Masterminds/goutils v1.1.1 // indirect
|
github.com/Masterminds/goutils v1.1.1 // indirect
|
||||||
github.com/Masterminds/semver v1.5.0 // indirect
|
github.com/Masterminds/semver v1.5.0 // indirect
|
||||||
github.com/Masterminds/semver/v3 v3.1.1 // indirect
|
github.com/Masterminds/semver/v3 v3.1.1 // indirect
|
||||||
github.com/Microsoft/go-winio v0.5.1 // indirect
|
github.com/Masterminds/sprig/v3 v3.2.2 // indirect
|
||||||
|
github.com/Microsoft/go-winio v0.5.2 // indirect
|
||||||
github.com/Microsoft/hcsshim v0.9.1 // indirect
|
github.com/Microsoft/hcsshim v0.9.1 // indirect
|
||||||
github.com/NYTimes/gziphandler v1.1.1 // indirect
|
github.com/NYTimes/gziphandler v1.1.1 // indirect
|
||||||
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 // indirect
|
github.com/ProtonMail/go-crypto v0.0.0-20220407094043-a94812496cf5 // indirect
|
||||||
github.com/PuerkitoBio/purell v1.1.1 // indirect
|
|
||||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
|
|
||||||
github.com/StackExchange/wmi v1.2.1 // indirect
|
github.com/StackExchange/wmi v1.2.1 // indirect
|
||||||
|
github.com/acobaugh/osrelease v0.1.0 // indirect
|
||||||
github.com/acomagu/bufpipe v1.0.3 // indirect
|
github.com/acomagu/bufpipe v1.0.3 // indirect
|
||||||
github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190620160927-9418d7b0cd0f // indirect
|
github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190620160927-9418d7b0cd0f // indirect
|
||||||
|
github.com/anchore/go-macholibre v0.0.0-20220308212642-53e6d0aaf6fb // indirect
|
||||||
|
github.com/anchore/packageurl-go v0.1.1-0.20220428202044-a072fa3cb6d7 // indirect
|
||||||
|
github.com/anchore/stereoscope v0.0.0-20220803153229-c55b13fee7e4 // indirect
|
||||||
|
github.com/andybalholm/brotli v1.0.4 // indirect
|
||||||
github.com/antchfx/xpath v1.2.0 // indirect
|
github.com/antchfx/xpath v1.2.0 // indirect
|
||||||
github.com/armon/go-metrics v0.3.10 // indirect
|
github.com/armon/go-metrics v0.3.10 // indirect
|
||||||
github.com/armon/go-proxyproto v0.0.0-20210323213023-7e956b284f0a // indirect
|
github.com/armon/go-proxyproto v0.0.0-20210323213023-7e956b284f0a // indirect
|
||||||
github.com/armon/go-radix v1.0.0 // indirect
|
github.com/armon/go-radix v1.0.0 // indirect
|
||||||
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef // indirect
|
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect
|
||||||
github.com/aws/aws-sdk-go v1.37.19 // indirect
|
github.com/aws/aws-sdk-go v1.37.19 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2 v1.16.2 // indirect
|
github.com/aws/aws-sdk-go-v2 v1.16.5 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.1 // indirect
|
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.1 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/credentials v1.11.2 // indirect
|
github.com/aws/aws-sdk-go-v2/credentials v1.12.5 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.3 // indirect
|
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.6 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.9 // indirect
|
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.12 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.3 // indirect
|
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.6 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.10 // indirect
|
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.13 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.1 // indirect
|
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.1 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.3 // indirect
|
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.3 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.3 // indirect
|
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.6 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.3 // indirect
|
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.3 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/sso v1.11.3 // indirect
|
github.com/aws/aws-sdk-go-v2/service/sso v1.11.8 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/sts v1.16.3 // indirect
|
github.com/aws/aws-sdk-go-v2/service/sts v1.16.7 // indirect
|
||||||
github.com/aws/smithy-go v1.11.2 // indirect
|
github.com/aws/smithy-go v1.11.3 // indirect
|
||||||
github.com/beorn7/perks v1.0.1 // indirect
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
github.com/bgentry/speakeasy v0.1.0 // indirect
|
github.com/bgentry/speakeasy v0.1.0 // indirect
|
||||||
|
github.com/bmatcuk/doublestar/v4 v4.0.2 // indirect
|
||||||
github.com/buildpacks/imgutil v0.0.0-20211001201950-cf7ae41c3771 // indirect
|
github.com/buildpacks/imgutil v0.0.0-20211001201950-cf7ae41c3771 // indirect
|
||||||
github.com/cenkalti/backoff v2.2.1+incompatible // indirect
|
github.com/cenkalti/backoff v2.2.1+incompatible // indirect
|
||||||
github.com/cenkalti/backoff/v3 v3.0.0 // indirect
|
github.com/cenkalti/backoff/v3 v3.0.0 // indirect
|
||||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||||
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible // indirect
|
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible // indirect
|
||||||
github.com/circonus-labs/circonusllhist v0.1.3 // indirect
|
github.com/circonus-labs/circonusllhist v0.1.3 // indirect
|
||||||
github.com/containerd/cgroups v1.0.2 // indirect
|
github.com/containerd/cgroups v1.0.3 // indirect
|
||||||
github.com/containerd/containerd v1.5.9 // indirect
|
github.com/containerd/containerd v1.5.13 // indirect
|
||||||
github.com/containerd/stargz-snapshotter/estargz v0.7.0 // indirect
|
github.com/containerd/stargz-snapshotter/estargz v0.11.4 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
github.com/deepmap/oapi-codegen v1.8.2 // indirect
|
github.com/deepmap/oapi-codegen v1.8.2 // indirect
|
||||||
github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba // indirect
|
github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba // indirect
|
||||||
github.com/digitalocean/godo v1.7.5 // indirect
|
github.com/digitalocean/godo v1.7.5 // indirect
|
||||||
github.com/dimchansky/utfbom v1.1.1 // indirect
|
github.com/dimchansky/utfbom v1.1.1 // indirect
|
||||||
github.com/docker/distribution v2.7.1+incompatible // indirect
|
github.com/docker/distribution v2.8.1+incompatible // indirect
|
||||||
github.com/docker/docker v20.10.12+incompatible // indirect
|
github.com/docker/docker v20.10.17+incompatible // indirect
|
||||||
github.com/docker/docker-credential-helpers v0.6.4 // indirect
|
github.com/docker/docker-credential-helpers v0.6.4 // indirect
|
||||||
github.com/docker/go-connections v0.4.0 // indirect
|
github.com/docker/go-connections v0.4.0 // indirect
|
||||||
github.com/docker/go-metrics v0.0.1 // indirect
|
github.com/docker/go-metrics v0.0.1 // indirect
|
||||||
github.com/docker/go-units v0.4.0 // indirect
|
github.com/docker/go-units v0.4.0 // indirect
|
||||||
|
github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect
|
||||||
|
github.com/dustin/go-humanize v1.0.0 // indirect
|
||||||
github.com/emirpasic/gods v1.12.0 // indirect
|
github.com/emirpasic/gods v1.12.0 // indirect
|
||||||
github.com/evanphx/json-patch/v5 v5.5.0 // indirect
|
github.com/evanphx/json-patch/v5 v5.5.0 // indirect
|
||||||
|
github.com/facebookincubator/nvdtools v0.1.4 // indirect
|
||||||
github.com/fatih/color v1.13.0 // indirect
|
github.com/fatih/color v1.13.0 // indirect
|
||||||
|
github.com/gabriel-vasile/mimetype v1.4.0 // indirect
|
||||||
github.com/go-errors/errors v1.4.1 // indirect
|
github.com/go-errors/errors v1.4.1 // indirect
|
||||||
github.com/go-git/gcfg v1.5.0 // indirect
|
github.com/go-git/gcfg v1.5.0 // indirect
|
||||||
github.com/go-logr/logr v1.2.0 // indirect
|
github.com/go-logr/logr v1.2.3 // indirect
|
||||||
github.com/go-ole/go-ole v1.2.5 // indirect
|
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||||
github.com/go-openapi/analysis v0.19.10 // indirect
|
github.com/go-openapi/analysis v0.21.2 // indirect
|
||||||
github.com/go-openapi/errors v0.19.8 // indirect
|
github.com/go-openapi/errors v0.20.2 // indirect
|
||||||
github.com/go-openapi/jsonpointer v0.19.5 // indirect
|
github.com/go-openapi/jsonpointer v0.19.5 // indirect
|
||||||
github.com/go-openapi/jsonreference v0.19.5 // indirect
|
github.com/go-openapi/jsonreference v0.20.0 // indirect
|
||||||
github.com/go-openapi/loads v0.19.5 // indirect
|
github.com/go-openapi/loads v0.21.1 // indirect
|
||||||
github.com/go-openapi/spec v0.19.8 // indirect
|
github.com/go-openapi/spec v0.20.6 // indirect
|
||||||
github.com/go-openapi/swag v0.19.14 // indirect
|
github.com/go-openapi/swag v0.21.1 // indirect
|
||||||
github.com/go-openapi/validate v0.19.10 // indirect
|
github.com/go-openapi/validate v0.22.0 // indirect
|
||||||
|
github.com/go-restruct/restruct v1.2.0-alpha // indirect
|
||||||
github.com/go-sql-driver/mysql v1.5.0 // indirect
|
github.com/go-sql-driver/mysql v1.5.0 // indirect
|
||||||
github.com/go-stack/stack v1.8.0 // indirect
|
|
||||||
github.com/go-test/deep v1.0.8 // indirect
|
github.com/go-test/deep v1.0.8 // indirect
|
||||||
github.com/gogo/protobuf v1.3.2 // indirect
|
github.com/gogo/protobuf v1.3.2 // indirect
|
||||||
github.com/golang-jwt/jwt/v4 v4.2.0 // indirect
|
github.com/golang-jwt/jwt/v4 v4.3.0 // indirect
|
||||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||||
github.com/golang/protobuf v1.5.2 // indirect
|
github.com/golang/protobuf v1.5.2 // indirect
|
||||||
github.com/golang/snappy v0.0.4 // indirect
|
github.com/golang/snappy v0.0.4 // indirect
|
||||||
github.com/google/btree v1.0.1 // indirect
|
github.com/google/btree v1.0.1 // indirect
|
||||||
github.com/google/go-metrics-stackdriver v0.2.0 // indirect
|
github.com/google/go-metrics-stackdriver v0.2.0 // indirect
|
||||||
github.com/google/go-querystring v1.1.0 // indirect
|
github.com/google/go-querystring v1.1.0 // indirect
|
||||||
github.com/google/gofuzz v1.1.0 // indirect
|
github.com/google/gofuzz v1.2.0 // indirect
|
||||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
|
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
|
||||||
github.com/googleapis/gax-go/v2 v2.1.1 // indirect
|
github.com/googleapis/enterprise-certificate-proxy v0.1.0 // indirect
|
||||||
|
github.com/googleapis/gax-go/v2 v2.4.0 // indirect
|
||||||
github.com/googleapis/gnostic v0.5.5 // indirect
|
github.com/googleapis/gnostic v0.5.5 // indirect
|
||||||
|
github.com/googleapis/go-type-adapters v1.0.0 // indirect
|
||||||
github.com/gophercloud/gophercloud v0.1.0 // indirect
|
github.com/gophercloud/gophercloud v0.1.0 // indirect
|
||||||
github.com/gorilla/mux v1.8.0 // indirect
|
github.com/gorilla/mux v1.8.0 // indirect
|
||||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect
|
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
|
||||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||||
github.com/hashicorp/go-discover v0.0.0-20210818145131-c573d69da192 // indirect
|
github.com/hashicorp/go-discover v0.0.0-20210818145131-c573d69da192 // indirect
|
||||||
@ -211,27 +223,35 @@ require (
|
|||||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
|
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
|
||||||
github.com/jefferai/isbadcipher v0.0.0-20190226160619-51d2077c035f // indirect
|
github.com/jefferai/isbadcipher v0.0.0-20190226160619-51d2077c035f // indirect
|
||||||
github.com/jefferai/jsonx v1.0.0 // indirect
|
github.com/jefferai/jsonx v1.0.0 // indirect
|
||||||
|
github.com/jinzhu/copier v0.3.2 // indirect
|
||||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||||
github.com/josharian/intern v1.0.0 // indirect
|
github.com/josharian/intern v1.0.0 // indirect
|
||||||
github.com/joyent/triton-go v1.7.1-0.20200416154420-6801d15b779f // indirect
|
github.com/joyent/triton-go v1.7.1-0.20200416154420-6801d15b779f // indirect
|
||||||
github.com/json-iterator/go v1.1.12 // indirect
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
|
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||||
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 // indirect
|
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 // indirect
|
||||||
github.com/keybase/go-crypto v0.0.0-20190403132359-d65b6b94177f // indirect
|
github.com/keybase/go-crypto v0.0.0-20190403132359-d65b6b94177f // indirect
|
||||||
github.com/klauspost/compress v1.13.6 // indirect
|
github.com/klauspost/compress v1.15.4 // indirect
|
||||||
|
github.com/klauspost/pgzip v1.2.5 // indirect
|
||||||
|
github.com/knqyf263/go-rpmdb v0.0.0-20220629110411-9a3bd2ebb923 // indirect
|
||||||
github.com/leodido/go-urn v1.2.1 // indirect
|
github.com/leodido/go-urn v1.2.1 // indirect
|
||||||
github.com/lib/pq v1.10.4 // indirect
|
github.com/lib/pq v1.10.4 // indirect
|
||||||
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
|
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
|
||||||
github.com/linode/linodego v0.7.1 // indirect
|
github.com/linode/linodego v0.7.1 // indirect
|
||||||
github.com/magicsong/color-glog v0.0.1 // indirect
|
github.com/magicsong/color-glog v0.0.1 // indirect
|
||||||
github.com/mailru/easyjson v0.7.6 // indirect
|
github.com/mailru/easyjson v0.7.7 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.12 // indirect
|
github.com/mattn/go-colorable v0.1.12 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.14 // indirect
|
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||||
|
github.com/mattn/go-runewidth v0.0.13 // indirect
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
|
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
|
||||||
|
github.com/mholt/archiver/v3 v3.5.1 // indirect
|
||||||
|
github.com/microsoft/go-rustaudit v0.0.0-20220730194248-4b17361d90a5 // indirect
|
||||||
github.com/miekg/dns v1.1.41 // indirect
|
github.com/miekg/dns v1.1.41 // indirect
|
||||||
github.com/mitchellh/cli v1.1.2 // indirect
|
github.com/mitchellh/cli v1.1.2 // indirect
|
||||||
github.com/mitchellh/copystructure v1.2.0 // indirect
|
github.com/mitchellh/copystructure v1.2.0 // indirect
|
||||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||||
github.com/mitchellh/go-testing-interface v1.14.0 // indirect
|
github.com/mitchellh/go-testing-interface v1.14.0 // indirect
|
||||||
|
github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect
|
||||||
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
||||||
github.com/moby/locker v1.0.1 // indirect
|
github.com/moby/locker v1.0.1 // indirect
|
||||||
github.com/moby/sys/mount v0.2.0 // indirect
|
github.com/moby/sys/mount v0.2.0 // indirect
|
||||||
@ -243,12 +263,12 @@ require (
|
|||||||
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
|
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
|
||||||
github.com/morikuni/aec v1.0.0 // indirect
|
github.com/morikuni/aec v1.0.0 // indirect
|
||||||
github.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2 // indirect
|
github.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2 // indirect
|
||||||
|
github.com/nwaples/rardecode v1.1.2 // indirect
|
||||||
github.com/oklog/run v1.0.0 // indirect
|
github.com/oklog/run v1.0.0 // indirect
|
||||||
github.com/oklog/ulid v1.3.1 // indirect
|
github.com/oklog/ulid v1.3.1 // indirect
|
||||||
github.com/onsi/ginkgo v1.16.4 // indirect
|
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
||||||
github.com/onsi/gomega v1.16.0 // indirect
|
|
||||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||||
github.com/opencontainers/image-spec v1.0.2 // indirect
|
github.com/opencontainers/image-spec v1.0.3-0.20220114050600-8b9d41f48198 // indirect
|
||||||
github.com/opencontainers/runc v1.0.2 // indirect
|
github.com/opencontainers/runc v1.0.2 // indirect
|
||||||
github.com/opentracing/opentracing-go v1.2.0 // indirect
|
github.com/opentracing/opentracing-go v1.2.0 // indirect
|
||||||
github.com/oracle/oci-go-sdk v13.1.0+incompatible // indirect
|
github.com/oracle/oci-go-sdk v13.1.0+incompatible // indirect
|
||||||
@ -258,63 +278,92 @@ require (
|
|||||||
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
|
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
|
||||||
github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect
|
github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect
|
||||||
github.com/pierrec/lz4 v2.5.2+incompatible // indirect
|
github.com/pierrec/lz4 v2.5.2+incompatible // indirect
|
||||||
|
github.com/pierrec/lz4/v4 v4.1.8 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
github.com/posener/complete v1.2.3 // indirect
|
github.com/posener/complete v1.2.3 // indirect
|
||||||
github.com/prometheus/client_golang v1.11.0 // indirect
|
github.com/prometheus/client_golang v1.12.2 // indirect
|
||||||
github.com/prometheus/client_model v0.2.0 // indirect
|
github.com/prometheus/client_model v0.2.0 // indirect
|
||||||
github.com/prometheus/common v0.28.0 // indirect
|
github.com/prometheus/common v0.34.0 // indirect
|
||||||
github.com/prometheus/procfs v0.6.0 // indirect
|
github.com/prometheus/procfs v0.7.3 // indirect
|
||||||
github.com/rboyer/safeio v0.2.1 // indirect
|
github.com/rboyer/safeio v0.2.1 // indirect
|
||||||
|
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect
|
||||||
github.com/renier/xmlrpc v0.0.0-20170708154548-ce4a1a486c03 // indirect
|
github.com/renier/xmlrpc v0.0.0-20170708154548-ce4a1a486c03 // indirect
|
||||||
github.com/richardlehane/mscfb v1.0.3 // indirect
|
github.com/richardlehane/mscfb v1.0.3 // indirect
|
||||||
github.com/richardlehane/msoleps v1.0.1 // indirect
|
github.com/richardlehane/msoleps v1.0.1 // indirect
|
||||||
|
github.com/rivo/uniseg v0.2.0 // indirect
|
||||||
github.com/ryanuber/go-glob v1.0.0 // indirect
|
github.com/ryanuber/go-glob v1.0.0 // indirect
|
||||||
github.com/sasha-s/go-deadlock v0.2.0 // indirect
|
github.com/sasha-s/go-deadlock v0.2.0 // indirect
|
||||||
github.com/sergi/go-diff v1.1.0 // indirect
|
github.com/scylladb/go-set v1.0.3-0.20200225121959-cc7b2070d91e // indirect
|
||||||
|
github.com/sergi/go-diff v1.2.0 // indirect
|
||||||
github.com/sethvargo/go-limiter v0.7.1 // indirect
|
github.com/sethvargo/go-limiter v0.7.1 // indirect
|
||||||
github.com/shirou/gopsutil v3.21.5+incompatible // indirect
|
github.com/shirou/gopsutil v3.21.5+incompatible // indirect
|
||||||
|
github.com/shopspring/decimal v1.2.0 // indirect
|
||||||
github.com/softlayer/softlayer-go v0.0.0-20180806151055-260589d94c7d // indirect
|
github.com/softlayer/softlayer-go v0.0.0-20180806151055-260589d94c7d // indirect
|
||||||
github.com/stretchr/objx v0.2.0 // indirect
|
github.com/spdx/tools-golang v0.2.0 // indirect
|
||||||
|
github.com/spf13/afero v1.8.2 // indirect
|
||||||
|
github.com/spf13/cast v1.5.0 // indirect
|
||||||
|
github.com/stretchr/objx v0.4.0 // indirect
|
||||||
|
github.com/sylabs/sif/v2 v2.7.0 // indirect
|
||||||
|
github.com/sylabs/squashfs v0.5.5-0.20220803150326-9393a0b4cef5 // indirect
|
||||||
github.com/tencentcloud/tencentcloud-sdk-go v3.0.83+incompatible // indirect
|
github.com/tencentcloud/tencentcloud-sdk-go v3.0.83+incompatible // indirect
|
||||||
|
github.com/therootcompany/xz v1.0.1 // indirect
|
||||||
github.com/tklauser/go-sysconf v0.3.9 // indirect
|
github.com/tklauser/go-sysconf v0.3.9 // indirect
|
||||||
github.com/tklauser/numcpus v0.3.0 // indirect
|
github.com/tklauser/numcpus v0.3.0 // indirect
|
||||||
github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c // indirect
|
github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c // indirect
|
||||||
|
github.com/ulikunitz/xz v0.5.10 // indirect
|
||||||
|
github.com/vbatts/go-mtree v0.5.0 // indirect
|
||||||
|
github.com/vbatts/tar-split v0.11.2 // indirect
|
||||||
|
github.com/vifraa/gopom v0.1.0 // indirect
|
||||||
github.com/vmware/govmomi v0.18.0 // indirect
|
github.com/vmware/govmomi v0.18.0 // indirect
|
||||||
|
github.com/wagoodman/go-partybus v0.0.0-20210627031916-db1f5573bbc5 // indirect
|
||||||
|
github.com/wagoodman/go-progress v0.0.0-20200731105512-1020f39e6240 // indirect
|
||||||
github.com/xanzy/ssh-agent v0.3.0 // indirect
|
github.com/xanzy/ssh-agent v0.3.0 // indirect
|
||||||
|
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
|
||||||
github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca // indirect
|
github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca // indirect
|
||||||
github.com/xuri/efp v0.0.0-20210322160811-ab561f5b45e3 // indirect
|
github.com/xuri/efp v0.0.0-20210322160811-ab561f5b45e3 // indirect
|
||||||
go.etcd.io/bbolt v1.3.6 // indirect
|
go.etcd.io/bbolt v1.3.6 // indirect
|
||||||
go.mongodb.org/mongo-driver v1.7.3 // indirect
|
go.mongodb.org/mongo-driver v1.10.0 // indirect
|
||||||
go.opencensus.io v0.23.0 // indirect
|
go.opencensus.io v0.23.0 // indirect
|
||||||
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect
|
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect
|
||||||
go.uber.org/atomic v1.9.0 // indirect
|
go.uber.org/atomic v1.9.0 // indirect
|
||||||
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871 // indirect
|
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d // indirect
|
||||||
golang.org/x/net v0.0.0-20220107192237-5cfca573fb4d // indirect
|
golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e // indirect
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
|
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f // indirect
|
||||||
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27 // indirect
|
golang.org/x/sys v0.0.0-20220624220833-87e55d714810 // indirect
|
||||||
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b // indirect
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
|
||||||
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect
|
golang.org/x/time v0.0.0-20220411224347-583f2d630306 // indirect
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
golang.org/x/tools v0.1.10 // indirect
|
||||||
|
golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f // indirect
|
||||||
google.golang.org/appengine v1.6.7 // indirect
|
google.golang.org/appengine v1.6.7 // indirect
|
||||||
google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00 // indirect
|
google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f // indirect
|
||||||
google.golang.org/grpc v1.44.0 // indirect
|
google.golang.org/grpc v1.48.0 // indirect
|
||||||
google.golang.org/protobuf v1.27.1 // indirect
|
google.golang.org/protobuf v1.28.0 // indirect
|
||||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||||
gopkg.in/resty.v1 v1.12.0 // indirect
|
gopkg.in/resty.v1 v1.12.0 // indirect
|
||||||
gopkg.in/square/go-jose.v2 v2.6.0 // indirect
|
gopkg.in/square/go-jose.v2 v2.6.0 // indirect
|
||||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
k8s.io/api v0.23.1 // indirect
|
k8s.io/api v0.23.5 // indirect
|
||||||
k8s.io/apimachinery v0.23.1 // indirect
|
k8s.io/apimachinery v0.23.5 // indirect
|
||||||
k8s.io/cli-runtime v0.23.1 // indirect
|
k8s.io/cli-runtime v0.23.1 // indirect
|
||||||
k8s.io/client-go v0.23.1 // indirect
|
k8s.io/client-go v0.23.5 // indirect
|
||||||
k8s.io/klog/v2 v2.30.0 // indirect
|
k8s.io/klog/v2 v2.60.1-0.20220317184644-43cc75f9ae89 // indirect
|
||||||
k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 // indirect
|
k8s.io/kube-openapi v0.0.0-20220124234850-424119656bbf // indirect
|
||||||
k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b // indirect
|
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 // indirect
|
||||||
|
lukechampine.com/uint128 v1.1.1 // indirect
|
||||||
|
modernc.org/cc/v3 v3.36.0 // indirect
|
||||||
|
modernc.org/ccgo/v3 v3.16.6 // indirect
|
||||||
|
modernc.org/libc v1.16.7 // indirect
|
||||||
|
modernc.org/mathutil v1.4.1 // indirect
|
||||||
|
modernc.org/memory v1.1.1 // indirect
|
||||||
|
modernc.org/opt v0.1.1 // indirect
|
||||||
|
modernc.org/sqlite v1.17.3 // indirect
|
||||||
|
modernc.org/strutil v1.1.1 // indirect
|
||||||
|
modernc.org/token v1.0.0 // indirect
|
||||||
oras.land/oras-go v1.1.0 // indirect
|
oras.land/oras-go v1.1.0 // indirect
|
||||||
sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 // indirect
|
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect
|
||||||
sigs.k8s.io/kustomize/api v0.10.1 // indirect
|
sigs.k8s.io/kustomize/api v0.10.1 // indirect
|
||||||
sigs.k8s.io/kustomize/kyaml v0.13.0 // indirect
|
sigs.k8s.io/kustomize/kyaml v0.13.0 // indirect
|
||||||
sigs.k8s.io/structured-merge-diff/v4 v4.1.2 // indirect
|
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect
|
||||||
sigs.k8s.io/yaml v1.3.0 // indirect
|
sigs.k8s.io/yaml v1.3.0 // indirect
|
||||||
)
|
)
|
||||||
|
@ -14,16 +14,16 @@ value = "16"
|
|||||||
|
|
||||||
[[build.buildpacks]]
|
[[build.buildpacks]]
|
||||||
id = "paketo-buildpacks/ca-certificates"
|
id = "paketo-buildpacks/ca-certificates"
|
||||||
version = "3.2.4"
|
version = "3.2.5"
|
||||||
|
|
||||||
[[build.buildpacks]]
|
[[build.buildpacks]]
|
||||||
uri = "gcr.io/paketo-buildpacks/node-engine:0.14.0"
|
uri = "gcr.io/paketo-buildpacks/node-engine:0.15.0"
|
||||||
|
|
||||||
[[build.buildpacks]]
|
[[build.buildpacks]]
|
||||||
uri = "gcr.io/paketo-buildpacks/npm-install:0.10.2"
|
uri = "gcr.io/paketo-buildpacks/npm-install:0.10.3"
|
||||||
|
|
||||||
[[build.buildpacks]]
|
[[build.buildpacks]]
|
||||||
uri = "gcr.io/paketo-buildpacks/node-module-bom:0.3.0"
|
uri = "gcr.io/paketo-buildpacks/node-module-bom:0.4.0"
|
||||||
|
|
||||||
[[build.buildpacks]]
|
[[build.buildpacks]]
|
||||||
uri = "gcr.io/paketo-buildpacks/npm-start:0.9.1"
|
uri = "gcr.io/paketo-buildpacks/npm-start:0.9.2"
|
||||||
|
@ -13,16 +13,16 @@ name = "BP_NODE_VERSION"
|
|||||||
value = "16"
|
value = "16"
|
||||||
|
|
||||||
[[build.buildpacks]]
|
[[build.buildpacks]]
|
||||||
uri = "gcr.io/paketo-buildpacks/ca-certificates:3.2.4"
|
uri = "gcr.io/paketo-buildpacks/ca-certificates:3.2.5"
|
||||||
|
|
||||||
[[build.buildpacks]]
|
[[build.buildpacks]]
|
||||||
uri = "gcr.io/paketo-buildpacks/node-engine:0.14.0"
|
uri = "gcr.io/paketo-buildpacks/node-engine:0.15.0"
|
||||||
|
|
||||||
[[build.buildpacks]]
|
[[build.buildpacks]]
|
||||||
uri = "gcr.io/paketo-buildpacks/npm-install:0.10.2"
|
uri = "gcr.io/paketo-buildpacks/npm-install:0.10.3"
|
||||||
|
|
||||||
[[build.buildpacks]]
|
[[build.buildpacks]]
|
||||||
uri = "gcr.io/paketo-buildpacks/node-module-bom:0.3.0"
|
uri = "gcr.io/paketo-buildpacks/node-module-bom:0.4.0"
|
||||||
|
|
||||||
[[build.buildpacks]]
|
[[build.buildpacks]]
|
||||||
uri = "gcr.io/paketo-buildpacks/npm-start:0.9.1"
|
uri = "gcr.io/paketo-buildpacks/npm-start:0.9.2"
|
||||||
|
@ -5,6 +5,8 @@ import (
|
|||||||
|
|
||||||
"github.com/SAP/jenkins-library/pkg/cnbutils"
|
"github.com/SAP/jenkins-library/pkg/cnbutils"
|
||||||
"github.com/SAP/jenkins-library/pkg/mock"
|
"github.com/SAP/jenkins-library/pkg/mock"
|
||||||
|
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||||
|
fakeImage "github.com/google/go-containerregistry/pkg/v1/fake"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -12,10 +14,23 @@ func TestBuildpackDownload(t *testing.T) {
|
|||||||
var mockUtils = &cnbutils.MockUtils{
|
var mockUtils = &cnbutils.MockUtils{
|
||||||
ExecMockRunner: &mock.ExecMockRunner{},
|
ExecMockRunner: &mock.ExecMockRunner{},
|
||||||
FilesMock: &mock.FilesMock{},
|
FilesMock: &mock.FilesMock{},
|
||||||
|
DownloadMock: &mock.DownloadMock{},
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Run("it creates an order object", func(t *testing.T) {
|
t.Run("it creates an order object", func(t *testing.T) {
|
||||||
|
fakeImg := &fakeImage.FakeImage{}
|
||||||
|
fakeImg.ConfigFileReturns(&v1.ConfigFile{
|
||||||
|
Config: v1.Config{
|
||||||
|
Labels: map[string]string{
|
||||||
|
"io.buildpacks.buildpackage.metadata": "{\"id\": \"testbuildpack\", \"version\": \"0.0.1\"}",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, nil)
|
||||||
|
mockUtils.ReturnImage = fakeImg
|
||||||
|
mockUtils.RemoteImageInfo = fakeImg
|
||||||
|
|
||||||
order, err := cnbutils.DownloadBuildpacks("/destination", []string{"buildpack"}, "/tmp/config.json", mockUtils)
|
order, err := cnbutils.DownloadBuildpacks("/destination", []string{"buildpack"}, "/tmp/config.json", mockUtils)
|
||||||
|
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, 1, len(order.Order))
|
assert.Equal(t, 1, len(order.Order))
|
||||||
})
|
})
|
||||||
|
@ -4,57 +4,16 @@
|
|||||||
package cnbutils
|
package cnbutils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"path/filepath"
|
|
||||||
|
|
||||||
"github.com/SAP/jenkins-library/pkg/mock"
|
"github.com/SAP/jenkins-library/pkg/mock"
|
||||||
"github.com/SAP/jenkins-library/pkg/piperutils"
|
"github.com/SAP/jenkins-library/pkg/piperutils"
|
||||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
|
||||||
fakeImage "github.com/google/go-containerregistry/pkg/v1/fake"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type MockUtils struct {
|
type MockUtils struct {
|
||||||
*mock.ExecMockRunner
|
*mock.ExecMockRunner
|
||||||
*mock.FilesMock
|
*mock.FilesMock
|
||||||
|
*mock.DownloadMock
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *MockUtils) GetFileUtils() piperutils.FileUtils {
|
func (c *MockUtils) GetFileUtils() piperutils.FileUtils {
|
||||||
return c.FilesMock
|
return c.FilesMock
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *MockUtils) DownloadImageContent(bpack, targetDir string) (v1.Image, error) {
|
|
||||||
fakeImage := fakeImage.FakeImage{}
|
|
||||||
fakeImage.ConfigFileReturns(&v1.ConfigFile{
|
|
||||||
Config: v1.Config{
|
|
||||||
Labels: map[string]string{
|
|
||||||
"io.buildpacks.buildpackage.metadata": "{\"id\": \"testbuildpack\", \"version\": \"0.0.1\"}",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}, nil)
|
|
||||||
|
|
||||||
c.AddDir(filepath.Join(targetDir, "cnb/buildpacks", bpack))
|
|
||||||
c.AddDir(filepath.Join(targetDir, "cnb/buildpacks", bpack, "0.0.1"))
|
|
||||||
return &fakeImage, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *MockUtils) DownloadImage(src, dst string) (v1.Image, error) {
|
|
||||||
return nil, fmt.Errorf("not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *MockUtils) GetImageSource() (string, error) {
|
|
||||||
return "imageSource", nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *MockUtils) GetRemoteImageInfo(imageSource string) (v1.Image, error) {
|
|
||||||
fakeImage := fakeImage.FakeImage{}
|
|
||||||
fakeImage.ConfigFileReturns(&v1.ConfigFile{
|
|
||||||
Config: v1.Config{
|
|
||||||
Labels: map[string]string{
|
|
||||||
"io.buildpacks.buildpackage.metadata": "{\"id\": \"testbuildpack\", \"version\": \"0.0.1\"}",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}, nil)
|
|
||||||
fakeImage.DigestReturns(v1.Hash{}, nil)
|
|
||||||
|
|
||||||
return &fakeImage, nil
|
|
||||||
}
|
|
||||||
|
185
pkg/cnbutils/sbom.go
Normal file
185
pkg/cnbutils/sbom.go
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
package cnbutils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"archive/tar"
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
|
"github.com/SAP/jenkins-library/pkg/log"
|
||||||
|
"github.com/anchore/syft/syft"
|
||||||
|
"github.com/anchore/syft/syft/sbom"
|
||||||
|
"github.com/anchore/syft/syft/source"
|
||||||
|
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
var cycloneDxXML = syft.FormatByID(syft.CycloneDxXMLFormatID)
|
||||||
|
|
||||||
|
func MergeSBOMFiles(pattern, output, img, dockerConfigFile string, utils BuildUtils) error {
|
||||||
|
if dockerConfigFile != "" {
|
||||||
|
os.Setenv("DOCKER_CONFIG", filepath.Dir(dockerConfigFile))
|
||||||
|
defer os.Unsetenv("DOCKER_CONFIG")
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Entry().Debugf("reading remote image %s", img)
|
||||||
|
remoteImage, err := utils.GetRemoteImageInfo(img)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
imgConfig, err := remoteImage.ConfigFile()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
layerSHA, exists := imgConfig.Config.Labels["io.buildpacks.base.sbom"]
|
||||||
|
if !exists {
|
||||||
|
return fmt.Errorf("image %q does not contain label \"io.buildpacks.base.sbom\"", img)
|
||||||
|
}
|
||||||
|
|
||||||
|
var bom *sbom.SBOM
|
||||||
|
log.Entry().Debug("found SBOM layer")
|
||||||
|
bom, err = readBOMFromLayer(remoteImage, layerSHA)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
log.Entry().Debugf("initial source.ImageMetadata: %#v", bom.Source.ImageMetadata)
|
||||||
|
|
||||||
|
imageMetaData, err := extractImageMetaData(remoteImage)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
bom.Source.ImageMetadata = *imageMetaData
|
||||||
|
bom.Source.ImageMetadata.UserInput = img
|
||||||
|
log.Entry().Debugf("updated source.ImageMetadata: %#v", bom.Source.ImageMetadata)
|
||||||
|
|
||||||
|
log.Entry().Debugf("search for sbom file using the pattern %s", pattern)
|
||||||
|
syftFiles, err := utils.Glob(pattern)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, syftFile := range syftFiles {
|
||||||
|
log.Entry().Debugf("reading Syft SBOM file %q", syftFile)
|
||||||
|
f, err := utils.Open(syftFile)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
bill, _, err := syft.Decode(f)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for p := range bill.Artifacts.PackageCatalog.Enumerate() {
|
||||||
|
bom.Artifacts.PackageCatalog.Add(p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
outFile, err := utils.Abs(output)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
out, err := utils.Create(outFile)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer out.Close()
|
||||||
|
|
||||||
|
fmt.Printf("*** saving %q ***", outFile)
|
||||||
|
log.Entry().Debugf("saving CycloneDX SBOM file to %q", outFile)
|
||||||
|
err = cycloneDxXML.Encode(out, *bom)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func readBOMFromLayer(img v1.Image, layerDiffSHA string) (*sbom.SBOM, error) {
|
||||||
|
layerDiffDigest, err := v1.NewHash(layerDiffSHA)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "failed to parse layer sha %q", layerDiffSHA)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Entry().Debugf("looking for the layer %q", layerDiffDigest.String())
|
||||||
|
|
||||||
|
sbomLayer, err := img.LayerByDiffID(layerDiffDigest)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "failed get layer %q", layerDiffDigest)
|
||||||
|
}
|
||||||
|
|
||||||
|
rc, err := sbomLayer.Uncompressed()
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "failed to get uncompressed reader")
|
||||||
|
}
|
||||||
|
|
||||||
|
tr := tar.NewReader(rc)
|
||||||
|
sbomRegex := regexp.MustCompile(`cnb/sbom/[a-z0-9]+\.syft\.json`)
|
||||||
|
for {
|
||||||
|
hdr, err := tr.Next()
|
||||||
|
if err == io.EOF {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "failed to read tar content")
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Entry().Debugf("checking SBOM layer file %q", hdr.Name)
|
||||||
|
if sbomRegex.Match([]byte(hdr.Name)) {
|
||||||
|
log.Entry().Debugf("file %q matches the regex", hdr.Name)
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
_, err = io.Copy(buf, tr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "failed to read SBOM file from the layer")
|
||||||
|
}
|
||||||
|
|
||||||
|
bom, _, err := syft.Decode(buf)
|
||||||
|
return bom, errors.Wrap(err, "failed to decode SBOM file")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, errors.New("no sbom file found")
|
||||||
|
}
|
||||||
|
|
||||||
|
func extractImageMetaData(img v1.Image) (*source.ImageMetadata, error) {
|
||||||
|
imageDigest, err := img.Digest()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
imageMediaType, err := img.MediaType()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
imageSize, err := img.Size()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
imageRawManifest, err := img.RawManifest()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
imageRawConfig, err := img.RawConfigFile()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &source.ImageMetadata{
|
||||||
|
ID: imageDigest.String(),
|
||||||
|
Size: imageSize,
|
||||||
|
MediaType: string(imageMediaType),
|
||||||
|
RawConfig: imageRawConfig,
|
||||||
|
RawManifest: imageRawManifest,
|
||||||
|
}, nil
|
||||||
|
}
|
118
pkg/cnbutils/sbom_test.go
Normal file
118
pkg/cnbutils/sbom_test.go
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
package cnbutils_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"archive/tar"
|
||||||
|
"bytes"
|
||||||
|
"crypto/sha256"
|
||||||
|
"encoding/hex"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/SAP/jenkins-library/pkg/cnbutils"
|
||||||
|
"github.com/SAP/jenkins-library/pkg/mock"
|
||||||
|
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||||
|
"github.com/google/go-containerregistry/pkg/v1/fake"
|
||||||
|
"github.com/google/go-containerregistry/pkg/v1/partial"
|
||||||
|
"github.com/google/go-containerregistry/pkg/v1/types"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
type uncompressedLayer struct {
|
||||||
|
diffID v1.Hash
|
||||||
|
mediaType types.MediaType
|
||||||
|
content []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// DiffID implements partial.UncompressedLayer
|
||||||
|
func (ul *uncompressedLayer) DiffID() (v1.Hash, error) {
|
||||||
|
return ul.diffID, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uncompressed implements partial.UncompressedLayer
|
||||||
|
func (ul *uncompressedLayer) Uncompressed() (io.ReadCloser, error) {
|
||||||
|
return io.NopCloser(bytes.NewBuffer(ul.content)), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MediaType returns the media type of the layer
|
||||||
|
func (ul *uncompressedLayer) MediaType() (types.MediaType, error) {
|
||||||
|
return ul.mediaType, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func fakeLayer(path string, content []byte) (v1.Layer, error) {
|
||||||
|
var b bytes.Buffer
|
||||||
|
hasher := sha256.New()
|
||||||
|
mw := io.MultiWriter(&b, hasher)
|
||||||
|
|
||||||
|
// Write a single file with a random name and random contents.
|
||||||
|
tw := tar.NewWriter(mw)
|
||||||
|
if err := tw.WriteHeader(&tar.Header{
|
||||||
|
Name: path,
|
||||||
|
Size: int64(len(content)),
|
||||||
|
Typeflag: tar.TypeRegA,
|
||||||
|
}); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := io.WriteString(tw, string(content)); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := tw.Close(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
h := v1.Hash{
|
||||||
|
Algorithm: "sha256",
|
||||||
|
Hex: hex.EncodeToString(hasher.Sum(make([]byte, 0, hasher.Size()))),
|
||||||
|
}
|
||||||
|
|
||||||
|
return partial.UncompressedToLayer(&uncompressedLayer{
|
||||||
|
mediaType: types.DockerLayer,
|
||||||
|
diffID: h,
|
||||||
|
content: b.Bytes(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMergeSBOMFiles(t *testing.T) {
|
||||||
|
var mockUtils = &cnbutils.MockUtils{
|
||||||
|
ExecMockRunner: &mock.ExecMockRunner{},
|
||||||
|
FilesMock: &mock.FilesMock{},
|
||||||
|
DownloadMock: &mock.DownloadMock{},
|
||||||
|
}
|
||||||
|
|
||||||
|
fakeImg := &fake.FakeImage{}
|
||||||
|
fakeImg.ConfigFileReturns(&v1.ConfigFile{
|
||||||
|
Config: v1.Config{Labels: map[string]string{"io.buildpacks.base.sbom": "sha256:9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"}},
|
||||||
|
}, nil)
|
||||||
|
|
||||||
|
baseSBOM, err := os.ReadFile("testdata/base.syft.json")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
fLayer, err := fakeLayer("cnb/sbom/test.syft.json", baseSBOM)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
fakeImg.LayerByDiffIDReturns(fLayer, nil)
|
||||||
|
|
||||||
|
mockUtils.ReturnImage = fakeImg
|
||||||
|
mockUtils.RemoteImageInfo = fakeImg
|
||||||
|
|
||||||
|
sbom1, err := os.ReadFile("testdata/sbom1.syft.json")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
mockUtils.FilesMock.AddFile("/layer/1/sbom.syft.json", sbom1)
|
||||||
|
sbom2, err := os.ReadFile("testdata/sbom2.syft.json")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
mockUtils.FilesMock.AddFile("/layer/2/sbom.syft.json", sbom2)
|
||||||
|
|
||||||
|
err = cnbutils.MergeSBOMFiles("layer/**/sbom.syft.json", "sbom.xml", "imageName", "", mockUtils)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
exists, err := mockUtils.FileExists("/sbom.xml")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.True(t, exists)
|
||||||
|
|
||||||
|
content, err := mockUtils.ReadFile("/sbom.xml")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Contains(t, string(content), "base-files")
|
||||||
|
assert.Contains(t, string(content), "operating-system")
|
||||||
|
assert.Contains(t, string(content), "component1")
|
||||||
|
assert.Contains(t, string(content), "component2")
|
||||||
|
}
|
@ -1,7 +1,6 @@
|
|||||||
package cnbutils_test
|
package cnbutils_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
@ -61,7 +60,7 @@ func TestGetImageName(t *testing.T) {
|
|||||||
err := os.MkdirAll(filepath.Join(tmpdir, "commonPipelineEnvironment", "git"), os.ModePerm)
|
err := os.MkdirAll(filepath.Join(tmpdir, "commonPipelineEnvironment", "git"), os.ModePerm)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
err = ioutil.WriteFile(filepath.Join(tmpdir, "commonPipelineEnvironment", "git", "repository"), []byte("repo-name"), os.ModePerm)
|
err = os.WriteFile(filepath.Join(tmpdir, "commonPipelineEnvironment", "git", "repository"), []byte("repo-name"), os.ModePerm)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
targetImage, err := cnbutils.GetTargetImage("http://registry", "", "tag", "", tmpdir)
|
targetImage, err := cnbutils.GetTargetImage("http://registry", "", "tag", "", tmpdir)
|
||||||
@ -78,7 +77,7 @@ func TestGetImageName(t *testing.T) {
|
|||||||
err := os.MkdirAll(filepath.Join(tmpdir, "commonPipelineEnvironment", "github"), os.ModePerm)
|
err := os.MkdirAll(filepath.Join(tmpdir, "commonPipelineEnvironment", "github"), os.ModePerm)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
err = ioutil.WriteFile(filepath.Join(tmpdir, "commonPipelineEnvironment", "github", "repository"), []byte("repo-name"), os.ModePerm)
|
err = os.WriteFile(filepath.Join(tmpdir, "commonPipelineEnvironment", "github", "repository"), []byte("repo-name"), os.ModePerm)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
targetImage, err := cnbutils.GetTargetImage("http://registry", "", "tag", "", tmpdir)
|
targetImage, err := cnbutils.GetTargetImage("http://registry", "", "tag", "", tmpdir)
|
||||||
|
79
pkg/cnbutils/testdata/base.syft.json
vendored
Normal file
79
pkg/cnbutils/testdata/base.syft.json
vendored
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
{
|
||||||
|
"artifacts": [
|
||||||
|
{
|
||||||
|
"id": "7b5b9b5141083199",
|
||||||
|
"name": "base-files",
|
||||||
|
"version": "12ubuntu4.2",
|
||||||
|
"type": "deb",
|
||||||
|
"foundBy": "dpkgdb-cataloger",
|
||||||
|
"locations": [{
|
||||||
|
"path": "/usr/share/doc/base-files/copyright",
|
||||||
|
"layerID": "sha256:44f1d51522f4298504cb24fa13058e91fee57de4b2f64e5d383d8ed9f082e180"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "/var/lib/dpkg/status.d/base-files",
|
||||||
|
"layerID": "sha256:44f1d51522f4298504cb24fa13058e91fee57de4b2f64e5d383d8ed9f082e180"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"licenses": [
|
||||||
|
"GPL"
|
||||||
|
],
|
||||||
|
"language": "",
|
||||||
|
"cpes": [
|
||||||
|
"cpe:2.3:a:base-files:base-files:12ubuntu4.2:*:*:*:*:*:*:*",
|
||||||
|
"cpe:2.3:a:base-files:base_files:12ubuntu4.2:*:*:*:*:*:*:*",
|
||||||
|
"cpe:2.3:a:base_files:base-files:12ubuntu4.2:*:*:*:*:*:*:*",
|
||||||
|
"cpe:2.3:a:base_files:base_files:12ubuntu4.2:*:*:*:*:*:*:*",
|
||||||
|
"cpe:2.3:a:base:base-files:12ubuntu4.2:*:*:*:*:*:*:*",
|
||||||
|
"cpe:2.3:a:base:base_files:12ubuntu4.2:*:*:*:*:*:*:*"
|
||||||
|
],
|
||||||
|
"purl": "pkg:deb/ubuntu/base-files@12ubuntu4.2?arch=amd64&distro=ubuntu-22.04",
|
||||||
|
"metadataType": "DpkgMetadata",
|
||||||
|
"metadata": {
|
||||||
|
"package": "base-files",
|
||||||
|
"source": "",
|
||||||
|
"version": "12ubuntu4.2",
|
||||||
|
"sourceVersion": "",
|
||||||
|
"architecture": "amd64",
|
||||||
|
"maintainer": "Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>",
|
||||||
|
"installedSize": 394,
|
||||||
|
"files": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"artifactRelationships": [],
|
||||||
|
"source": {
|
||||||
|
"type": "image",
|
||||||
|
"target": {
|
||||||
|
"userInput": "paketo.io/stack/oz20quaydr",
|
||||||
|
"imageID": "sha256:a8cbcad35fa3386ce790e400957594e3af0051f809fee1410f64fe4b99abcbdd",
|
||||||
|
"manifestDigest": "sha256:4110cccbd5a97ed7d9a759ef18af644c035d212f5d3cec4266b3f0349dddea0f",
|
||||||
|
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
|
||||||
|
"tags": [
|
||||||
|
"paketo.io/stack/oz20quaydr:latest"
|
||||||
|
],
|
||||||
|
"imageSize": 26397332,
|
||||||
|
"layers": [{
|
||||||
|
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
|
||||||
|
"digest": "sha256:44f1d51522f4298504cb24fa13058e91fee57de4b2f64e5d383d8ed9f082e180",
|
||||||
|
"size": 26397332
|
||||||
|
}],
|
||||||
|
"manifest": "eyJzY2hlbWFWZXJzaW9uIjoyLCJtZWRpYVR5cGUiOiJhcHBsaWNhdGlvbi92bmQuZG9ja2VyLmRpc3RyaWJ1dGlvbi5tYW5pZmVzdC52Mitqc29uIiwiY29uZmlnIjp7Im1lZGlhVHlwZSI6ImFwcGxpY2F0aW9uL3ZuZC5kb2NrZXIuY29udGFpbmVyLmltYWdlLnYxK2pzb24iLCJzaXplIjo0NDUsImRpZ2VzdCI6InNoYTI1NjphOGNiY2FkMzVmYTMzODZjZTc5MGU0MDA5NTc1OTRlM2FmMDA1MWY4MDlmZWUxNDEwZjY0ZmU0Yjk5YWJjYmRkIn0sImxheWVycyI6W3sibWVkaWFUeXBlIjoiYXBwbGljYXRpb24vdm5kLmRvY2tlci5pbWFnZS5yb290ZnMuZGlmZi50YXIuZ3ppcCIsInNpemUiOjI3OTk4NzIwLCJkaWdlc3QiOiJzaGEyNTY6NDRmMWQ1MTUyMmY0Mjk4NTA0Y2IyNGZhMTMwNThlOTFmZWU1N2RlNGIyZjY0ZTVkMzgzZDhlZDlmMDgyZTE4MCJ9XX0=",
|
||||||
|
"config": "eyJhcmNoaXRlY3R1cmUiOiJhbWQ2NCIsImNvbmZpZyI6eyJFbnYiOlsiUEFUSD0vdXNyL2xvY2FsL3NiaW46L3Vzci9sb2NhbC9iaW46L3Vzci9zYmluOi91c3IvYmluOi9zYmluOi9iaW4iXSwiV29ya2luZ0RpciI6Ii8iLCJPbkJ1aWxkIjpudWxsfSwiY3JlYXRlZCI6IjIwMjItMDgtMTJUMDk6NTE6MzMuMjM3NDkyMDUyWiIsImhpc3RvcnkiOlt7ImNyZWF0ZWQiOiIyMDIyLTA4LTEyVDA5OjUxOjMzLjIzNzQ5MjA1MloiLCJjcmVhdGVkX2J5IjoiQ09QWSAvdGlueS8gLyAjIGJ1aWxka2l0IiwiY29tbWVudCI6ImJ1aWxka2l0LmRvY2tlcmZpbGUudjAifV0sIm9zIjoibGludXgiLCJyb290ZnMiOnsidHlwZSI6ImxheWVycyIsImRpZmZfaWRzIjpbInNoYTI1Njo0NGYxZDUxNTIyZjQyOTg1MDRjYjI0ZmExMzA1OGU5MWZlZTU3ZGU0YjJmNjRlNWQzODNkOGVkOWYwODJlMTgwIl19fQ==",
|
||||||
|
"repoDigests": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"distro": {
|
||||||
|
"name": "ubuntu",
|
||||||
|
"version": "22.04.1 LTS (Jammy Jellyfish)",
|
||||||
|
"idLike": "debian"
|
||||||
|
},
|
||||||
|
"descriptor": {
|
||||||
|
"name": "",
|
||||||
|
"version": ""
|
||||||
|
},
|
||||||
|
"schema": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"url": "https://raw.githubusercontent.com/anchore/syft/main/schema/json/schema-2.0.2.json"
|
||||||
|
}
|
||||||
|
}
|
79
pkg/cnbutils/testdata/sbom1.syft.json
vendored
Normal file
79
pkg/cnbutils/testdata/sbom1.syft.json
vendored
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
{
|
||||||
|
"artifacts": [
|
||||||
|
{
|
||||||
|
"id": "8c5b9b5141133199",
|
||||||
|
"name": "component1",
|
||||||
|
"version": "1",
|
||||||
|
"type": "unknown",
|
||||||
|
"foundBy": "dpkgdb-cataloger",
|
||||||
|
"locations": [{
|
||||||
|
"path": "/usr/share/doc/base-files/copyright",
|
||||||
|
"layerID": "sha256:44f1d51522f4298504cb24fa13058e91fee57de4b2f64e5d383d8ed9f082e180"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "/var/lib/dpkg/status.d/base-files",
|
||||||
|
"layerID": "sha256:44f1d51522f4298504cb24fa13058e91fee57de4b2f64e5d383d8ed9f082e180"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"licenses": [
|
||||||
|
"GPL"
|
||||||
|
],
|
||||||
|
"language": "",
|
||||||
|
"cpes": [
|
||||||
|
"cpe:2.3:a:base-files:base-files:12ubuntu4.2:*:*:*:*:*:*:*",
|
||||||
|
"cpe:2.3:a:base-files:base_files:12ubuntu4.2:*:*:*:*:*:*:*",
|
||||||
|
"cpe:2.3:a:base_files:base-files:12ubuntu4.2:*:*:*:*:*:*:*",
|
||||||
|
"cpe:2.3:a:base_files:base_files:12ubuntu4.2:*:*:*:*:*:*:*",
|
||||||
|
"cpe:2.3:a:base:base-files:12ubuntu4.2:*:*:*:*:*:*:*",
|
||||||
|
"cpe:2.3:a:base:base_files:12ubuntu4.2:*:*:*:*:*:*:*"
|
||||||
|
],
|
||||||
|
"purl": "pkg:deb/ubuntu/base-files@12ubuntu4.2?arch=amd64&distro=ubuntu-22.04",
|
||||||
|
"metadataType": "DpkgMetadata",
|
||||||
|
"metadata": {
|
||||||
|
"package": "component1",
|
||||||
|
"source": "",
|
||||||
|
"version": "1",
|
||||||
|
"sourceVersion": "",
|
||||||
|
"architecture": "amd64",
|
||||||
|
"maintainer": "Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>",
|
||||||
|
"installedSize": 394,
|
||||||
|
"files": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"artifactRelationships": [],
|
||||||
|
"source": {
|
||||||
|
"type": "image",
|
||||||
|
"target": {
|
||||||
|
"userInput": "paketo.io/stack/oz20quaydr",
|
||||||
|
"imageID": "sha256:a8cbcad35fa3386ce790e400957594e3af0051f809fee1410f64fe4b99abcbdd",
|
||||||
|
"manifestDigest": "sha256:4110cccbd5a97ed7d9a759ef18af644c035d212f5d3cec4266b3f0349dddea0f",
|
||||||
|
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
|
||||||
|
"tags": [
|
||||||
|
"paketo.io/stack/oz20quaydr:latest"
|
||||||
|
],
|
||||||
|
"imageSize": 26397332,
|
||||||
|
"layers": [{
|
||||||
|
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
|
||||||
|
"digest": "sha256:44f1d51522f4298504cb24fa13058e91fee57de4b2f64e5d383d8ed9f082e180",
|
||||||
|
"size": 26397332
|
||||||
|
}],
|
||||||
|
"manifest": "eyJzY2hlbWFWZXJzaW9uIjoyLCJtZWRpYVR5cGUiOiJhcHBsaWNhdGlvbi92bmQuZG9ja2VyLmRpc3RyaWJ1dGlvbi5tYW5pZmVzdC52Mitqc29uIiwiY29uZmlnIjp7Im1lZGlhVHlwZSI6ImFwcGxpY2F0aW9uL3ZuZC5kb2NrZXIuY29udGFpbmVyLmltYWdlLnYxK2pzb24iLCJzaXplIjo0NDUsImRpZ2VzdCI6InNoYTI1NjphOGNiY2FkMzVmYTMzODZjZTc5MGU0MDA5NTc1OTRlM2FmMDA1MWY4MDlmZWUxNDEwZjY0ZmU0Yjk5YWJjYmRkIn0sImxheWVycyI6W3sibWVkaWFUeXBlIjoiYXBwbGljYXRpb24vdm5kLmRvY2tlci5pbWFnZS5yb290ZnMuZGlmZi50YXIuZ3ppcCIsInNpemUiOjI3OTk4NzIwLCJkaWdlc3QiOiJzaGEyNTY6NDRmMWQ1MTUyMmY0Mjk4NTA0Y2IyNGZhMTMwNThlOTFmZWU1N2RlNGIyZjY0ZTVkMzgzZDhlZDlmMDgyZTE4MCJ9XX0=",
|
||||||
|
"config": "eyJhcmNoaXRlY3R1cmUiOiJhbWQ2NCIsImNvbmZpZyI6eyJFbnYiOlsiUEFUSD0vdXNyL2xvY2FsL3NiaW46L3Vzci9sb2NhbC9iaW46L3Vzci9zYmluOi91c3IvYmluOi9zYmluOi9iaW4iXSwiV29ya2luZ0RpciI6Ii8iLCJPbkJ1aWxkIjpudWxsfSwiY3JlYXRlZCI6IjIwMjItMDgtMTJUMDk6NTE6MzMuMjM3NDkyMDUyWiIsImhpc3RvcnkiOlt7ImNyZWF0ZWQiOiIyMDIyLTA4LTEyVDA5OjUxOjMzLjIzNzQ5MjA1MloiLCJjcmVhdGVkX2J5IjoiQ09QWSAvdGlueS8gLyAjIGJ1aWxka2l0IiwiY29tbWVudCI6ImJ1aWxka2l0LmRvY2tlcmZpbGUudjAifV0sIm9zIjoibGludXgiLCJyb290ZnMiOnsidHlwZSI6ImxheWVycyIsImRpZmZfaWRzIjpbInNoYTI1Njo0NGYxZDUxNTIyZjQyOTg1MDRjYjI0ZmExMzA1OGU5MWZlZTU3ZGU0YjJmNjRlNWQzODNkOGVkOWYwODJlMTgwIl19fQ==",
|
||||||
|
"repoDigests": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"distro": {
|
||||||
|
"name": "ubuntu",
|
||||||
|
"version": "22.04.1 LTS (Jammy Jellyfish)",
|
||||||
|
"idLike": "debian"
|
||||||
|
},
|
||||||
|
"descriptor": {
|
||||||
|
"name": "",
|
||||||
|
"version": ""
|
||||||
|
},
|
||||||
|
"schema": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"url": "https://raw.githubusercontent.com/anchore/syft/main/schema/json/schema-2.0.2.json"
|
||||||
|
}
|
||||||
|
}
|
79
pkg/cnbutils/testdata/sbom2.syft.json
vendored
Normal file
79
pkg/cnbutils/testdata/sbom2.syft.json
vendored
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
{
|
||||||
|
"artifacts": [
|
||||||
|
{
|
||||||
|
"id": "8c5b9b5141083199",
|
||||||
|
"name": "component2",
|
||||||
|
"version": "2",
|
||||||
|
"type": "unknown",
|
||||||
|
"foundBy": "dpkgdb-cataloger",
|
||||||
|
"locations": [{
|
||||||
|
"path": "/usr/share/doc/base-files/copyright",
|
||||||
|
"layerID": "sha256:44f1d51522f4298504cb24fa13058e91fee57de4b2f64e5d383d8ed9f082e180"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "/var/lib/dpkg/status.d/base-files",
|
||||||
|
"layerID": "sha256:44f1d51522f4298504cb24fa13058e91fee57de4b2f64e5d383d8ed9f082e180"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"licenses": [
|
||||||
|
"GPL"
|
||||||
|
],
|
||||||
|
"language": "",
|
||||||
|
"cpes": [
|
||||||
|
"cpe:2.3:a:base-files:base-files:12ubuntu4.2:*:*:*:*:*:*:*",
|
||||||
|
"cpe:2.3:a:base-files:base_files:12ubuntu4.2:*:*:*:*:*:*:*",
|
||||||
|
"cpe:2.3:a:base_files:base-files:12ubuntu4.2:*:*:*:*:*:*:*",
|
||||||
|
"cpe:2.3:a:base_files:base_files:12ubuntu4.2:*:*:*:*:*:*:*",
|
||||||
|
"cpe:2.3:a:base:base-files:12ubuntu4.2:*:*:*:*:*:*:*",
|
||||||
|
"cpe:2.3:a:base:base_files:12ubuntu4.2:*:*:*:*:*:*:*"
|
||||||
|
],
|
||||||
|
"purl": "pkg:deb/ubuntu/base-files@12ubuntu4.2?arch=amd64&distro=ubuntu-22.04",
|
||||||
|
"metadataType": "DpkgMetadata",
|
||||||
|
"metadata": {
|
||||||
|
"package": "component2",
|
||||||
|
"source": "",
|
||||||
|
"version": "2",
|
||||||
|
"sourceVersion": "",
|
||||||
|
"architecture": "amd64",
|
||||||
|
"maintainer": "Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>",
|
||||||
|
"installedSize": 394,
|
||||||
|
"files": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"artifactRelationships": [],
|
||||||
|
"source": {
|
||||||
|
"type": "image",
|
||||||
|
"target": {
|
||||||
|
"userInput": "paketo.io/stack/oz20quaydr",
|
||||||
|
"imageID": "sha256:a8cbcad35fa3386ce790e400957594e3af0051f809fee1410f64fe4b99abcbdd",
|
||||||
|
"manifestDigest": "sha256:4110cccbd5a97ed7d9a759ef18af644c035d212f5d3cec4266b3f0349dddea0f",
|
||||||
|
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
|
||||||
|
"tags": [
|
||||||
|
"paketo.io/stack/oz20quaydr:latest"
|
||||||
|
],
|
||||||
|
"imageSize": 26397332,
|
||||||
|
"layers": [{
|
||||||
|
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
|
||||||
|
"digest": "sha256:44f1d51522f4298504cb24fa13058e91fee57de4b2f64e5d383d8ed9f082e180",
|
||||||
|
"size": 26397332
|
||||||
|
}],
|
||||||
|
"manifest": "eyJzY2hlbWFWZXJzaW9uIjoyLCJtZWRpYVR5cGUiOiJhcHBsaWNhdGlvbi92bmQuZG9ja2VyLmRpc3RyaWJ1dGlvbi5tYW5pZmVzdC52Mitqc29uIiwiY29uZmlnIjp7Im1lZGlhVHlwZSI6ImFwcGxpY2F0aW9uL3ZuZC5kb2NrZXIuY29udGFpbmVyLmltYWdlLnYxK2pzb24iLCJzaXplIjo0NDUsImRpZ2VzdCI6InNoYTI1NjphOGNiY2FkMzVmYTMzODZjZTc5MGU0MDA5NTc1OTRlM2FmMDA1MWY4MDlmZWUxNDEwZjY0ZmU0Yjk5YWJjYmRkIn0sImxheWVycyI6W3sibWVkaWFUeXBlIjoiYXBwbGljYXRpb24vdm5kLmRvY2tlci5pbWFnZS5yb290ZnMuZGlmZi50YXIuZ3ppcCIsInNpemUiOjI3OTk4NzIwLCJkaWdlc3QiOiJzaGEyNTY6NDRmMWQ1MTUyMmY0Mjk4NTA0Y2IyNGZhMTMwNThlOTFmZWU1N2RlNGIyZjY0ZTVkMzgzZDhlZDlmMDgyZTE4MCJ9XX0=",
|
||||||
|
"config": "eyJhcmNoaXRlY3R1cmUiOiJhbWQ2NCIsImNvbmZpZyI6eyJFbnYiOlsiUEFUSD0vdXNyL2xvY2FsL3NiaW46L3Vzci9sb2NhbC9iaW46L3Vzci9zYmluOi91c3IvYmluOi9zYmluOi9iaW4iXSwiV29ya2luZ0RpciI6Ii8iLCJPbkJ1aWxkIjpudWxsfSwiY3JlYXRlZCI6IjIwMjItMDgtMTJUMDk6NTE6MzMuMjM3NDkyMDUyWiIsImhpc3RvcnkiOlt7ImNyZWF0ZWQiOiIyMDIyLTA4LTEyVDA5OjUxOjMzLjIzNzQ5MjA1MloiLCJjcmVhdGVkX2J5IjoiQ09QWSAvdGlueS8gLyAjIGJ1aWxka2l0IiwiY29tbWVudCI6ImJ1aWxka2l0LmRvY2tlcmZpbGUudjAifV0sIm9zIjoibGludXgiLCJyb290ZnMiOnsidHlwZSI6ImxheWVycyIsImRpZmZfaWRzIjpbInNoYTI1Njo0NGYxZDUxNTIyZjQyOTg1MDRjYjI0ZmExMzA1OGU5MWZlZTU3ZGU0YjJmNjRlNWQzODNkOGVkOWYwODJlMTgwIl19fQ==",
|
||||||
|
"repoDigests": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"distro": {
|
||||||
|
"name": "ubuntu",
|
||||||
|
"version": "22.04.1 LTS (Jammy Jellyfish)",
|
||||||
|
"idLike": "debian"
|
||||||
|
},
|
||||||
|
"descriptor": {
|
||||||
|
"name": "",
|
||||||
|
"version": ""
|
||||||
|
},
|
||||||
|
"schema": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"url": "https://raw.githubusercontent.com/anchore/syft/main/schema/json/schema-2.0.2.json"
|
||||||
|
}
|
||||||
|
}
|
@ -4,6 +4,7 @@
|
|||||||
package mock
|
package mock
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
@ -545,19 +546,12 @@ type FileMock struct {
|
|||||||
absPath string
|
absPath string
|
||||||
files *FilesMock
|
files *FilesMock
|
||||||
content []byte
|
content []byte
|
||||||
|
buf io.Reader
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reads the content of the mock
|
// Reads the content of the mock
|
||||||
func (f *FileMock) Read(b []byte) (n int, err error) {
|
func (f *FileMock) Read(b []byte) (n int, err error) {
|
||||||
if len(b) == 0 {
|
return f.buf.Read(b)
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, p := range f.content {
|
|
||||||
b[i] = p
|
|
||||||
}
|
|
||||||
|
|
||||||
return len(f.content), io.EOF
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close mocks freeing the associated OS resources.
|
// Close mocks freeing the associated OS resources.
|
||||||
@ -608,21 +602,22 @@ func (f *FilesMock) OpenFile(path string, flag int, perm os.FileMode) (*FileMock
|
|||||||
}
|
}
|
||||||
if !exists && flag&os.O_CREATE != 0 {
|
if !exists && flag&os.O_CREATE != 0 {
|
||||||
f.associateContentAbs(absPath, &[]byte{}, perm)
|
f.associateContentAbs(absPath, &[]byte{}, perm)
|
||||||
properties, _ = f.files[absPath]
|
properties = f.files[absPath]
|
||||||
}
|
}
|
||||||
|
|
||||||
file := FileMock{
|
file := FileMock{
|
||||||
absPath: absPath,
|
absPath: absPath,
|
||||||
files: f,
|
files: f,
|
||||||
content: []byte{},
|
content: *properties.content,
|
||||||
}
|
}
|
||||||
|
|
||||||
if flag&os.O_APPEND != 0 {
|
if flag&os.O_TRUNC != 0 || flag&os.O_CREATE != 0 {
|
||||||
file.content = *properties.content
|
file.content = []byte{}
|
||||||
} else if flag&os.O_TRUNC != 0 {
|
|
||||||
properties.content = &file.content
|
properties.content = &file.content
|
||||||
}
|
}
|
||||||
|
|
||||||
|
file.buf = bytes.NewBuffer(file.content)
|
||||||
|
|
||||||
return &file, nil
|
return &file, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,6 +256,14 @@ spec:
|
|||||||
resourceRef:
|
resourceRef:
|
||||||
- name: commonPipelineEnvironment
|
- name: commonPipelineEnvironment
|
||||||
param: custom/buildSettingsInfo
|
param: custom/buildSettingsInfo
|
||||||
|
- name: createBOM
|
||||||
|
type: bool
|
||||||
|
description: "**EXPERIMENTAL:** Creates the bill of materials (BOM) using CycloneDX plugin."
|
||||||
|
scope:
|
||||||
|
- GENERAL
|
||||||
|
- STEPS
|
||||||
|
- STAGES
|
||||||
|
- PARAMETERS
|
||||||
outputs:
|
outputs:
|
||||||
resources:
|
resources:
|
||||||
- name: commonPipelineEnvironment
|
- name: commonPipelineEnvironment
|
||||||
@ -271,5 +279,10 @@ spec:
|
|||||||
- name: container/imageDigests
|
- name: container/imageDigests
|
||||||
type: "[]string"
|
type: "[]string"
|
||||||
- name: custom/buildSettingsInfo
|
- name: custom/buildSettingsInfo
|
||||||
|
- name: reports
|
||||||
|
type: reports
|
||||||
|
params:
|
||||||
|
- filePattern: "**/bom-*.xml"
|
||||||
|
type: sbom
|
||||||
containers:
|
containers:
|
||||||
- image: "paketobuildpacks/builder:base"
|
- image: "paketobuildpacks/builder:base"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user