mirror of
https://github.com/SAP/jenkins-library.git
synced 2025-01-18 05:18:24 +02:00
Feat(cnbBuild): collecting the telemetry data for cnbBuild (#3368)
Co-authored-by: Sumit Kulhadia <sumit.kulhadia@sap.com> Co-authored-by: Ralf Pannemans <ralf.pannemans@sap.com> Co-authored-by: Philipp Stehle <philipp.stehle@sap.com> Co-authored-by: Pavel Busko <pavel.busko@sap.com>
This commit is contained in:
parent
880be73a4c
commit
6feb1217aa
@ -2,6 +2,7 @@ package cmd
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
@ -11,6 +12,7 @@ import (
|
||||
"github.com/SAP/jenkins-library/pkg/certutils"
|
||||
"github.com/SAP/jenkins-library/pkg/cnbutils"
|
||||
"github.com/SAP/jenkins-library/pkg/cnbutils/bindings"
|
||||
"github.com/SAP/jenkins-library/pkg/cnbutils/privacy"
|
||||
"github.com/SAP/jenkins-library/pkg/cnbutils/project"
|
||||
"github.com/SAP/jenkins-library/pkg/cnbutils/project/metadata"
|
||||
"github.com/SAP/jenkins-library/pkg/command"
|
||||
@ -34,6 +36,37 @@ type cnbBuildUtilsBundle struct {
|
||||
*docker.Client
|
||||
}
|
||||
|
||||
type cnbBuildTelemetryData struct {
|
||||
Version int `json:"version"`
|
||||
ImageTag string `json:"imageTag"`
|
||||
AdditionalTags []string `json:"additionalTags"`
|
||||
BindingKeys []string `json:"bindingKeys"`
|
||||
Path string `json:"path"`
|
||||
BuildEnv cnbBuildTelemetryDataBuildEnv `json:"buildEnv"`
|
||||
Buildpacks cnbBuildTelemetryDataBuildpacks `json:"buildpacks"`
|
||||
ProjectDescriptor cnbBuildTelemetryDataProjectDescriptor `json:"projectDescriptor"`
|
||||
}
|
||||
|
||||
type cnbBuildTelemetryDataBuildEnv struct {
|
||||
KeysFromConfig []string `json:"keysFromConfig"`
|
||||
KeysFromProjectDescriptor []string `json:"keysFromProjectDescriptor"`
|
||||
KeysOverall []string `json:"keysOverall"`
|
||||
JVMVersion string `json:"jvmVersion"`
|
||||
KeyValues map[string]interface{} `json:"keyValues"`
|
||||
}
|
||||
|
||||
type cnbBuildTelemetryDataBuildpacks struct {
|
||||
FromConfig []string `json:"FromConfig"`
|
||||
FromProjectDescriptor []string `json:"FromProjectDescriptor"`
|
||||
Overall []string `json:"overall"`
|
||||
}
|
||||
|
||||
type cnbBuildTelemetryDataProjectDescriptor struct {
|
||||
Used bool `json:"used"`
|
||||
IncludeUsed bool `json:"includeUsed"`
|
||||
ExcludeUsed bool `json:"excludeUsed"`
|
||||
}
|
||||
|
||||
func setCustomBuildpacks(bpacks []string, dockerCreds string, utils cnbutils.BuildUtils) (string, string, error) {
|
||||
buildpacksPath := "/tmp/buildpacks"
|
||||
orderPath := "/tmp/buildpacks/order.toml"
|
||||
@ -249,9 +282,51 @@ func (c *cnbBuildOptions) mergeEnvVars(vars map[string]interface{}) {
|
||||
}
|
||||
}
|
||||
|
||||
func addConfigTelemetryData(data *cnbBuildTelemetryData, config *cnbBuildOptions) {
|
||||
bindingKeys := []string{}
|
||||
for k := range config.Bindings {
|
||||
bindingKeys = append(bindingKeys, k)
|
||||
}
|
||||
data.ImageTag = config.ContainerImageTag
|
||||
data.AdditionalTags = config.AdditionalTags
|
||||
data.BindingKeys = bindingKeys
|
||||
data.Path = config.Path
|
||||
|
||||
configKeys := data.BuildEnv.KeysFromConfig
|
||||
overallKeys := data.BuildEnv.KeysOverall
|
||||
for key := range config.BuildEnvVars {
|
||||
configKeys = append(configKeys, key)
|
||||
overallKeys = append(overallKeys, key)
|
||||
}
|
||||
data.BuildEnv.KeysFromConfig = configKeys
|
||||
data.BuildEnv.KeysOverall = overallKeys
|
||||
|
||||
data.Buildpacks.FromConfig = privacy.FilterBuildpacks(config.Buildpacks)
|
||||
}
|
||||
|
||||
func addProjectDescriptorTelemetryData(data *cnbBuildTelemetryData, descriptor project.Descriptor) {
|
||||
descriptorKeys := data.BuildEnv.KeysFromProjectDescriptor
|
||||
overallKeys := data.BuildEnv.KeysOverall
|
||||
for key := range descriptor.EnvVars {
|
||||
descriptorKeys = append(descriptorKeys, key)
|
||||
overallKeys = append(overallKeys, key)
|
||||
}
|
||||
data.BuildEnv.KeysFromProjectDescriptor = descriptorKeys
|
||||
data.BuildEnv.KeysOverall = overallKeys
|
||||
|
||||
data.Buildpacks.FromProjectDescriptor = privacy.FilterBuildpacks(descriptor.Buildpacks)
|
||||
|
||||
data.ProjectDescriptor.Used = true
|
||||
data.ProjectDescriptor.IncludeUsed = descriptor.Include != nil
|
||||
data.ProjectDescriptor.ExcludeUsed = descriptor.Exclude != nil
|
||||
}
|
||||
|
||||
func runCnbBuild(config *cnbBuildOptions, telemetryData *telemetry.CustomData, utils cnbutils.BuildUtils, commonPipelineEnvironment *cnbBuildCommonPipelineEnvironment, httpClient piperhttp.Sender) error {
|
||||
var err error
|
||||
|
||||
customTelemetryData := cnbBuildTelemetryData{Version: 1}
|
||||
addConfigTelemetryData(&customTelemetryData, config)
|
||||
|
||||
err = isBuilder(utils)
|
||||
if err != nil {
|
||||
log.SetErrorCategory(log.ErrorConfiguration)
|
||||
@ -274,6 +349,7 @@ func runCnbBuild(config *cnbBuildOptions, telemetryData *telemetry.CustomData, u
|
||||
log.SetErrorCategory(log.ErrorConfiguration)
|
||||
return errors.Wrapf(err, "failed to parse %s", config.ProjectDescriptor)
|
||||
}
|
||||
addProjectDescriptorTelemetryData(&customTelemetryData, *descriptor)
|
||||
|
||||
config.mergeEnvVars(descriptor.EnvVars)
|
||||
|
||||
@ -297,6 +373,16 @@ func runCnbBuild(config *cnbBuildOptions, telemetryData *telemetry.CustomData, u
|
||||
log.SetErrorCategory(log.ErrorConfiguration)
|
||||
return errors.Wrap(err, "failed to retrieve target image configuration")
|
||||
}
|
||||
customTelemetryData.Buildpacks.Overall = config.Buildpacks
|
||||
customTelemetryData.BuildEnv.KeyValues = privacy.FilterEnv(config.BuildEnvVars)
|
||||
|
||||
telemetryData.Custom1Label = "cnbBuildStepData"
|
||||
customData, err := json.Marshal(customTelemetryData)
|
||||
if err != nil {
|
||||
log.SetErrorCategory(log.ErrorCustom)
|
||||
return errors.Wrap(err, "failed to marshal custom telemetry data")
|
||||
}
|
||||
telemetryData.Custom1 = string(customData)
|
||||
|
||||
commonPipelineEnvironment.container.registryURL = fmt.Sprintf("%s://%s", targetImage.ContainerRegistry.Scheme, targetImage.ContainerRegistry.Host)
|
||||
commonPipelineEnvironment.container.imageNameTag = fmt.Sprintf("%v:%v", targetImage.ContainerImageName, targetImage.ContainerImageTag)
|
||||
|
@ -1,6 +1,7 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"testing"
|
||||
@ -313,7 +314,7 @@ func TestRunCnbBuild(t *testing.T) {
|
||||
utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"my-registry":"dXNlcjpwYXNz"}}`))
|
||||
addBuilderFiles(&utils)
|
||||
|
||||
err := runCnbBuild(&config, nil, &utils, &commonPipelineEnvironment, &piperhttp.Client{})
|
||||
err := runCnbBuild(&config, &telemetry.CustomData{}, &utils, &commonPipelineEnvironment, &piperhttp.Client{})
|
||||
assert.EqualError(t, err, "failed to generate CNB_REGISTRY_AUTH: json: cannot unmarshal string into Go struct field ConfigFile.auths of type types.AuthConfig")
|
||||
})
|
||||
|
||||
@ -330,7 +331,7 @@ func TestRunCnbBuild(t *testing.T) {
|
||||
utils := newCnbBuildTestsUtils()
|
||||
addBuilderFiles(&utils)
|
||||
|
||||
err := runCnbBuild(&config, nil, &utils, &commonPipelineEnvironment, &piperhttp.Client{})
|
||||
err := runCnbBuild(&config, &telemetry.CustomData{}, &utils, &commonPipelineEnvironment, &piperhttp.Client{})
|
||||
assert.EqualError(t, err, "failed to generate CNB_REGISTRY_AUTH: could not read 'not-there/config.json'")
|
||||
})
|
||||
|
||||
@ -347,7 +348,7 @@ func TestRunCnbBuild(t *testing.T) {
|
||||
utils := newCnbBuildTestsUtils()
|
||||
addBuilderFiles(&utils)
|
||||
|
||||
err := runCnbBuild(&config, nil, &utils, &commonPipelineEnvironment, &piperhttp.Client{})
|
||||
err := runCnbBuild(&config, &telemetry.CustomData{}, &utils, &commonPipelineEnvironment, &piperhttp.Client{})
|
||||
assert.EqualError(t, err, "failed to rename DockerConfigJSON file 'not-there': renaming file 'not-there' is not supported, since it does not exist, or is not a leaf-entry")
|
||||
})
|
||||
|
||||
@ -358,7 +359,7 @@ func TestRunCnbBuild(t *testing.T) {
|
||||
|
||||
utils := newCnbBuildTestsUtils()
|
||||
|
||||
err := runCnbBuild(&config, nil, &utils, &commonPipelineEnvironment, &piperhttp.Client{})
|
||||
err := runCnbBuild(&config, &telemetry.CustomData{}, &utils, &commonPipelineEnvironment, &piperhttp.Client{})
|
||||
assert.EqualError(t, err, "the provided dockerImage is not a valid builder: binary '/cnb/lifecycle/creator' not found")
|
||||
})
|
||||
|
||||
@ -378,7 +379,126 @@ func TestRunCnbBuild(t *testing.T) {
|
||||
utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"my-registry":{"auth":"dXNlcjpwYXNz"}}}`))
|
||||
addBuilderFiles(&utils)
|
||||
|
||||
err := runCnbBuild(&config, nil, &utils, &commonPipelineEnvironment, &piperhttp.Client{})
|
||||
err := runCnbBuild(&config, &telemetry.CustomData{}, &utils, &commonPipelineEnvironment, &piperhttp.Client{})
|
||||
assert.EqualError(t, err, "failed to copy certificates: cannot copy '/etc/ssl/certs/ca-certificates.crt': file does not exist")
|
||||
})
|
||||
|
||||
t.Run("success case (telemetry was added)", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
commonPipelineEnvironment := cnbBuildCommonPipelineEnvironment{}
|
||||
registry := "some-registry"
|
||||
config := cnbBuildOptions{
|
||||
ContainerImageName: "my-image",
|
||||
ContainerImageTag: "3.1.5",
|
||||
ContainerRegistryURL: registry,
|
||||
DockerConfigJSON: "/path/to/config.json",
|
||||
ProjectDescriptor: "project.toml",
|
||||
AdditionalTags: []string{"latest"},
|
||||
Buildpacks: []string{"paketobuildpacks/java", "gcr.io/paketo-buildpacks/node"},
|
||||
Bindings: map[string]interface{}{"SECRET": map[string]string{"key": "KEY", "file": "a_file"}},
|
||||
Path: "target",
|
||||
}
|
||||
|
||||
utils := newCnbBuildTestsUtils()
|
||||
utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"my-registry":{"auth":"dXNlcjpwYXNz"}}}`))
|
||||
utils.FilesMock.AddFile("project.toml", []byte(`[project]
|
||||
id = "test"
|
||||
name = "test"
|
||||
version = "1.0.0"
|
||||
|
||||
[build]
|
||||
include = []
|
||||
exclude = ["*.tar"]
|
||||
|
||||
[[build.buildpacks]]
|
||||
uri = "some-buildpack"`))
|
||||
utils.FilesMock.AddFile("a_file", []byte(`{}`))
|
||||
utils.FilesMock.AddDir("target")
|
||||
utils.FilesMock.AddFile("target/somelib.jar", []byte(`FFFFFF`))
|
||||
|
||||
addBuilderFiles(&utils)
|
||||
|
||||
telemetryData := telemetry.CustomData{}
|
||||
err := runCnbBuild(&config, &telemetryData, &utils, &commonPipelineEnvironment, &piperhttp.Client{})
|
||||
assert.NoError(t, err)
|
||||
|
||||
customDataAsString := telemetryData.Custom1
|
||||
customData := cnbBuildTelemetryData{}
|
||||
err = json.Unmarshal([]byte(customDataAsString), &customData)
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 1, customData.Version)
|
||||
assert.Equal(t, "3.1.5", customData.ImageTag)
|
||||
assert.Equal(t, "target", customData.Path)
|
||||
assert.Contains(t, customData.AdditionalTags, "latest")
|
||||
assert.Contains(t, customData.BindingKeys, "SECRET")
|
||||
|
||||
assert.Contains(t, customData.Buildpacks.FromConfig, "paketobuildpacks/java")
|
||||
assert.NotContains(t, customData.Buildpacks.FromProjectDescriptor, "paketobuildpacks/java")
|
||||
assert.Contains(t, customData.Buildpacks.FromProjectDescriptor, "<redacted>")
|
||||
assert.NotContains(t, customData.Buildpacks.Overall, "<redacted>")
|
||||
assert.Contains(t, customData.Buildpacks.Overall, "paketobuildpacks/java")
|
||||
|
||||
assert.True(t, customData.ProjectDescriptor.Used)
|
||||
assert.False(t, customData.ProjectDescriptor.IncludeUsed)
|
||||
assert.True(t, customData.ProjectDescriptor.ExcludeUsed)
|
||||
})
|
||||
|
||||
t.Run("success case (build env telemetry was added)", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
commonPipelineEnvironment := cnbBuildCommonPipelineEnvironment{}
|
||||
registry := "some-registry"
|
||||
config := cnbBuildOptions{
|
||||
ContainerImageName: "my-image",
|
||||
ContainerImageTag: "3.1.5",
|
||||
ContainerRegistryURL: registry,
|
||||
ProjectDescriptor: "project.toml",
|
||||
BuildEnvVars: map[string]interface{}{"CONFIG_KEY": "var", "BP_JVM_VERSION": "8"},
|
||||
}
|
||||
|
||||
utils := newCnbBuildTestsUtils()
|
||||
utils.FilesMock.AddFile("project.toml", []byte(`[project]
|
||||
id = "test"
|
||||
|
||||
[build]
|
||||
include = []
|
||||
|
||||
[[build.env]]
|
||||
name='PROJECT_KEY'
|
||||
value='var'
|
||||
|
||||
[[build.env]]
|
||||
name='BP_NODE_VERSION'
|
||||
value='11'
|
||||
|
||||
[[build.buildpacks]]
|
||||
uri = "some-buildpack"
|
||||
`))
|
||||
|
||||
addBuilderFiles(&utils)
|
||||
|
||||
telemetryData := telemetry.CustomData{}
|
||||
err := runCnbBuild(&config, &telemetryData, &utils, &commonPipelineEnvironment, &piperhttp.Client{})
|
||||
assert.NoError(t, err)
|
||||
|
||||
customDataAsString := telemetryData.Custom1
|
||||
customData := cnbBuildTelemetryData{}
|
||||
err = json.Unmarshal([]byte(customDataAsString), &customData)
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, customData.BuildEnv.KeysFromConfig, "CONFIG_KEY")
|
||||
assert.NotContains(t, customData.BuildEnv.KeysFromProjectDescriptor, "CONFIG_KEY")
|
||||
assert.Contains(t, customData.BuildEnv.KeysOverall, "CONFIG_KEY")
|
||||
|
||||
assert.NotContains(t, customData.BuildEnv.KeysFromConfig, "PROJECT_KEY")
|
||||
assert.Contains(t, customData.BuildEnv.KeysFromProjectDescriptor, "PROJECT_KEY")
|
||||
assert.Contains(t, customData.BuildEnv.KeysOverall, "PROJECT_KEY")
|
||||
|
||||
assert.Equal(t, "8", customData.BuildEnv.KeyValues["BP_JVM_VERSION"])
|
||||
assert.Equal(t, "11", customData.BuildEnv.KeyValues["BP_NODE_VERSION"])
|
||||
assert.NotContains(t, customData.BuildEnv.KeyValues, "PROJECT_KEY")
|
||||
|
||||
assert.Contains(t, customData.Buildpacks.Overall, "some-buildpack")
|
||||
})
|
||||
|
||||
}
|
||||
|
85
pkg/cnbutils/privacy/privacy.go
Normal file
85
pkg/cnbutils/privacy/privacy.go
Normal file
@ -0,0 +1,85 @@
|
||||
package privacy
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
containerName "github.com/google/go-containerregistry/pkg/name"
|
||||
)
|
||||
|
||||
var allowedBuildpackSources = []struct {
|
||||
registry, repositoryPrefix string
|
||||
}{
|
||||
// Paketo
|
||||
{
|
||||
registry: "gcr.io",
|
||||
repositoryPrefix: "paketo-buildpacks/",
|
||||
}, {
|
||||
registry: "index.docker.io",
|
||||
repositoryPrefix: "paketobuildpacks/",
|
||||
},
|
||||
// Google Buildpacks
|
||||
{
|
||||
registry: "gcr.io",
|
||||
repositoryPrefix: "buildpacks/",
|
||||
},
|
||||
// Heroku
|
||||
{
|
||||
registry: "public.ecr.aws",
|
||||
repositoryPrefix: "heroku-buildpacks/",
|
||||
},
|
||||
}
|
||||
|
||||
// FilterBuildpacks filters a list of buildpacks to redact Personally Identifiable Information (PII) like the hostname of a personal registry
|
||||
func FilterBuildpacks(buildpacks []string) []string {
|
||||
result := make([]string, 0, len(buildpacks))
|
||||
for _, buildpack := range buildpacks {
|
||||
ref, err := containerName.ParseReference(strings.ToLower(buildpack))
|
||||
if err != nil {
|
||||
result = append(result, "<error>")
|
||||
continue
|
||||
}
|
||||
|
||||
registry := ref.Context().Registry.Name()
|
||||
repository := ref.Context().RepositoryStr()
|
||||
|
||||
allowed := false
|
||||
for _, allowedBuildpackSource := range allowedBuildpackSources {
|
||||
if registry == allowedBuildpackSource.registry && strings.HasPrefix(repository, allowedBuildpackSource.repositoryPrefix) {
|
||||
allowed = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if allowed {
|
||||
result = append(result, buildpack)
|
||||
} else {
|
||||
result = append(result, "<redacted>")
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
var allowedEnvKeys = map[string]interface{}{
|
||||
// Java
|
||||
// https://github.com/paketo-buildpacks/sap-machine and https://github.com/paketo-buildpacks/bellsoft-liberica
|
||||
"BP_JVM_VERSION": nil,
|
||||
"BP_JVM_TYPE": nil,
|
||||
// https://github.com/paketo-buildpacks/apache-tomcat
|
||||
"BP_TOMCAT_VERSION": nil,
|
||||
|
||||
// Node
|
||||
// https://github.com/paketo-buildpacks/node-engine
|
||||
"BP_NODE_VERSION": nil,
|
||||
}
|
||||
|
||||
// FilterEnv filters a map of environment variables to redact Personally Identifiable Information (PII)
|
||||
func FilterEnv(in map[string]interface{}) map[string]interface{} {
|
||||
out := map[string]interface{}{}
|
||||
for key, value := range in {
|
||||
_, allowed := allowedEnvKeys[key]
|
||||
if allowed {
|
||||
out[key] = value
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
112
pkg/cnbutils/privacy/privacy_test.go
Normal file
112
pkg/cnbutils/privacy/privacy_test.go
Normal file
@ -0,0 +1,112 @@
|
||||
package privacy_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/SAP/jenkins-library/pkg/cnbutils/privacy"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestCnbPrivacy_FilterBuildpacks(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
t.Run("allows paketo", func(t *testing.T) {
|
||||
aliases := []string{
|
||||
"paketobuildpacks/nodejs:v1",
|
||||
"docker.io/paketobuildpacks/nodejs:v1",
|
||||
"index.docker.io/paketobuildpacks/nodejs:v1",
|
||||
"gcr.io/paketo-buildpacks/nodejs:v1",
|
||||
}
|
||||
|
||||
filtered := privacy.FilterBuildpacks(aliases)
|
||||
|
||||
require.Len(t, filtered, len(aliases))
|
||||
for i := range filtered {
|
||||
assert.Equal(t, aliases[i], filtered[i])
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("allows heroku", func(t *testing.T) {
|
||||
aliases := []string{
|
||||
"public.ecr.aws/heroku-buildpacks/heroku-jvm-buildpack@sha256:3a8ee9ebf88e47c5e30bc5712fb2794380aed75552499f92bd6773ec446421ef",
|
||||
}
|
||||
|
||||
filtered := privacy.FilterBuildpacks(aliases)
|
||||
|
||||
require.Len(t, filtered, len(aliases))
|
||||
for i := range filtered {
|
||||
assert.Equal(t, aliases[i], filtered[i])
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("allows google buildpacks", func(t *testing.T) {
|
||||
aliases := []string{
|
||||
"gcr.io/buildpacks/java:latest",
|
||||
"gcr.io/buildpacks/java",
|
||||
}
|
||||
|
||||
filtered := privacy.FilterBuildpacks(aliases)
|
||||
|
||||
require.Len(t, filtered, len(aliases))
|
||||
for i := range filtered {
|
||||
assert.Equal(t, aliases[i], filtered[i])
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("filters others", func(t *testing.T) {
|
||||
images := []string{
|
||||
"test/nodejs:v1",
|
||||
"my-mirror.de/paketobuildpacks/nodejs:v1",
|
||||
"gcr.io/my-project/paketo-buildpacks/nodejs:v1",
|
||||
}
|
||||
|
||||
filtered := privacy.FilterBuildpacks(images)
|
||||
|
||||
require.Len(t, filtered, len(images))
|
||||
for _, image := range filtered {
|
||||
assert.Equal(t, "<redacted>", image)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("fails gracefully on parse error", func(t *testing.T) {
|
||||
images := []string{
|
||||
"test/nodejs v1 spaces are not allowed",
|
||||
}
|
||||
|
||||
filtered := privacy.FilterBuildpacks(images)
|
||||
|
||||
require.Len(t, filtered, len(images))
|
||||
for _, image := range filtered {
|
||||
assert.Equal(t, "<error>", image)
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func TestCnbPrivacy_FilterEnv(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
t.Run("copies only allow listed keys", func(t *testing.T) {
|
||||
env := map[string]interface{}{
|
||||
"PRIVATE": "paketobuildpacks/nodejs:v1",
|
||||
"BP_NODE_VERSION": "8",
|
||||
"BP_JVM_VERSION": "11",
|
||||
}
|
||||
|
||||
filteredEnv := privacy.FilterEnv(env)
|
||||
|
||||
assert.Equal(t, map[string]interface{}{
|
||||
"BP_NODE_VERSION": "8",
|
||||
"BP_JVM_VERSION": "11",
|
||||
}, filteredEnv)
|
||||
})
|
||||
|
||||
t.Run("works on nil map", func(t *testing.T) {
|
||||
var env map[string]interface{} = nil
|
||||
|
||||
filteredEnv := privacy.FilterEnv(env)
|
||||
|
||||
assert.Empty(t, filteredEnv)
|
||||
})
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user