From cc8ae98d134b0181976d7cff11f6b204ec51bcde Mon Sep 17 00:00:00 2001 From: davidvader Date: Wed, 23 Nov 2022 15:37:14 -0600 Subject: [PATCH 01/19] wip: move trusted check after assemblebuild --- executor/linux/build.go | 222 ++++++++++++++++++++++++++-------------- 1 file changed, 146 insertions(+), 76 deletions(-) diff --git a/executor/linux/build.go b/executor/linux/build.go index 8fa38f24..65f68ceb 100644 --- a/executor/linux/build.go +++ b/executor/linux/build.go @@ -44,74 +44,6 @@ func (c *client) CreateBuild(ctx context.Context) error { return fmt.Errorf("unable to upload build state: %w", c.err) } - // before setting up the build, enforce repo.trusted is set for pipelines containing privileged images - // this configuration is set as an executor flag - if c.enforceTrustedRepos { - // check if pipeline steps contain privileged images - // assume no privileged images are in use - containsPrivilegedImages := false - - // group steps services and stages together - containers := c.pipeline.Steps - - containers = append(containers, c.pipeline.Services...) - for _, stage := range c.pipeline.Stages { - containers = append(containers, stage.Steps...) - } - - for _, container := range containers { - // TODO: remove hardcoded reference - if container.Image == "#init" { - continue - } - - for _, pattern := range c.privilegedImages { - privileged, err := image.IsPrivilegedImage(container.Image, pattern) - if err != nil { - return fmt.Errorf("could not verify if image %s is privileged", container.Image) - } - - if privileged { - containsPrivilegedImages = true - } - } - } - - // check if this build should be denied - if (containsPrivilegedImages) && !(c.repo != nil && c.repo.GetTrusted()) { - // deny the build, clean build/steps, and return error - // populate the build error - e := "build denied, repo must be trusted in order to run privileged images" - c.build.SetError(e) - // set the build status to error - c.build.SetStatus(constants.StatusError) - - steps := c.pipeline.Steps - for _, stage := range c.pipeline.Stages { - steps = append(containers, stage.Steps...) - } - - // update all preconfigured steps to the correct status - for _, s := range steps { - // extract step - step := library.StepFromBuildContainer(c.build, s) - // status to use for preconfigured steps that are not ran - status := constants.StatusKilled - // set step status - step.SetStatus(status) - // send API call to update the step - //nolint:contextcheck // ignore passing context - _, _, err := c.Vela.Step.Update(c.repo.GetOrg(), c.repo.GetName(), c.build.GetNumber(), step) - if err != nil { - // only log any step update errors to allow the return err to run - c.Logger.Errorf("unable to update step %s to status %s: %s", s.Name, status, err.Error()) - } - } - - return fmt.Errorf("build containing privileged images %s/%d denied, repo is not trusted", c.repo.GetFullName(), c.build.GetNumber()) - } - } - // setup the runtime build c.err = c.Runtime.SetupBuild(ctx, c.pipeline) if c.err != nil { @@ -319,16 +251,62 @@ func (c *client) AssembleBuild(ctx context.Context) error { c.Logger.Infof("inspecting %s service", s.Name) // inspect the service image - image, err := c.Runtime.InspectImage(ctx, s) + _image, err := c.Runtime.InspectImage(ctx, s) if err != nil { c.err = err return fmt.Errorf("unable to inspect %s service: %w", s.Name, err) } - // update the init log with service image info + // update the init log with step image info // // https://pkg.go.dev/github.com/go-vela/types/library?tab=doc#Log.AppendData - _log.AppendData(image) + _log.AppendData(_image) + + // // before setting up the build, enforce repo.trusted is set for pipelines containing privileged images + // // this configuration is set as an executor flag + if c.enforceTrustedRepos { + c.Logger.Infof("checking %s service privilege", s.Name) + + _log.AppendData([]byte(fmt.Sprintf("> Checking privileges for service image %s...\n", s.Image))) + + privileged := false + var e error = nil + for _, pattern := range c.privilegedImages { + privileged, err = image.IsPrivilegedImage(s.Image, pattern) + if err != nil { + e = fmt.Errorf("could not verify if image %s is privileged: %s", s.Image, err.Error()) + _log.AppendData([]byte(fmt.Sprintf("> ERROR: Unable to verify if image %s is privileged.\n", s.Image))) + break + } + } + + if (privileged) && !(c.repo != nil && c.repo.GetTrusted()) { + e = fmt.Errorf("could not prepare %s service. image %s is privileged and repo is not trusted", s.Name, s.Image) + _log.AppendData([]byte(fmt.Sprintf("> ERROR: Unable to prepare privileged image %s, repo is not trusted.\n", s.Image))) + } + + // privileged check returned error + if e != nil { + c.build.SetStatus(constants.StatusError) + c.build.SetError(e.Error()) + for _, s := range c.pipeline.Steps { + // extract step + step := library.StepFromBuildContainer(c.build, s) + // status to use for preconfigured steps that are not ran + status := constants.StatusKilled + // set step status + step.SetStatus(status) + // send API call to update the step + //nolint:contextcheck // ignore passing context + _, _, err := c.Vela.Step.Update(c.repo.GetOrg(), c.repo.GetName(), c.build.GetNumber(), step) + if err != nil { + // only log any step update errors to allow the return err to run + c.Logger.Errorf("unable to update step %s to status %s: %s", s.Name, status, err.Error()) + } + } + return err + } + } } // update the init log with progress @@ -374,7 +352,7 @@ func (c *client) AssembleBuild(ctx context.Context) error { c.Logger.Infof("inspecting %s step", s.Name) // inspect the step image - image, err := c.Runtime.InspectImage(ctx, s) + _image, err := c.Runtime.InspectImage(ctx, s) if err != nil { c.err = err return fmt.Errorf("unable to inspect %s step: %w", s.Name, c.err) @@ -383,7 +361,53 @@ func (c *client) AssembleBuild(ctx context.Context) error { // update the init log with step image info // // https://pkg.go.dev/github.com/go-vela/types/library?tab=doc#Log.AppendData - _log.AppendData(image) + _log.AppendData(_image) + + // // before setting up the build, enforce repo.trusted is set for pipelines containing privileged images + // // this configuration is set as an executor flag + if c.enforceTrustedRepos { + c.Logger.Infof("checking %s step privilege", s.Name) + + _log.AppendData([]byte(fmt.Sprintf("> Checking privileges for step image %s...\n", s.Image))) + + privileged := false + var e error = nil + for _, pattern := range c.privilegedImages { + privileged, err = image.IsPrivilegedImage(s.Image, pattern) + if err != nil { + e = fmt.Errorf("could not verify if image %s is privileged: %s", s.Image, err.Error()) + _log.AppendData([]byte(fmt.Sprintf("> ERROR: Unable to verify if image %s is privileged.\n", s.Image))) + break + } + } + + if (privileged) && !(c.repo != nil && c.repo.GetTrusted()) { + e = fmt.Errorf("could not prepare %s step. image %s is privileged and repo is not trusted", s.Name, s.Image) + _log.AppendData([]byte(fmt.Sprintf("> ERROR: Unable to prepare privileged image %s, repo is not trusted.\n", s.Image))) + } + + // privileged check returned error + if e != nil { + c.build.SetStatus(constants.StatusError) + c.build.SetError(e.Error()) + for _, s := range c.pipeline.Steps { + // extract step + step := library.StepFromBuildContainer(c.build, s) + // status to use for preconfigured steps that are not ran + status := constants.StatusKilled + // set step status + step.SetStatus(status) + // send API call to update the step + //nolint:contextcheck // ignore passing context + _, _, err := c.Vela.Step.Update(c.repo.GetOrg(), c.repo.GetName(), c.build.GetNumber(), step) + if err != nil { + // only log any step update errors to allow the return err to run + c.Logger.Errorf("unable to update step %s to status %s: %s", s.Name, status, err.Error()) + } + } + return err + } + } } // update the init log with progress @@ -407,16 +431,62 @@ func (c *client) AssembleBuild(ctx context.Context) error { c.Logger.Infof("inspecting %s secret", s.Origin.Name) // inspect the service image - image, err := c.Runtime.InspectImage(ctx, s.Origin) + _image, err := c.Runtime.InspectImage(ctx, s.Origin) if err != nil { c.err = err return fmt.Errorf("unable to inspect %s secret: %w", s.Origin.Name, err) } - // update the init log with secret image info + // update the init log with step image info // // https://pkg.go.dev/github.com/go-vela/types/library?tab=doc#Log.AppendData - _log.AppendData(image) + _log.AppendData(_image) + + // // before setting up the build, enforce repo.trusted is set for pipelines containing privileged images + // // this configuration is set as an executor flag + if c.enforceTrustedRepos { + c.Logger.Infof("checking %s secret origin privilege", s.Name) + + _log.AppendData([]byte(fmt.Sprintf("> Checking privileges for secret origin image %s...\n", s.Origin.Image))) + + privileged := false + var e error = nil + for _, pattern := range c.privilegedImages { + privileged, err = image.IsPrivilegedImage(s.Origin.Image, pattern) + if err != nil { + e = fmt.Errorf("could not verify if image %s is privileged: %s", s.Origin.Image, err.Error()) + _log.AppendData([]byte(fmt.Sprintf("> ERROR: Unable to verify if image %s is privileged.\n", s.Origin.Image))) + break + } + } + + if (privileged) && !(c.repo != nil && c.repo.GetTrusted()) { + e = fmt.Errorf("could not prepare %s secret origin. image %s is privileged and repo is not trusted", s.Name, s.Origin.Image) + _log.AppendData([]byte(fmt.Sprintf("> ERROR: Unable to prepare privileged image %s, repo is not trusted.\n", s.Origin.Image))) + } + + // privileged check returned error + if e != nil { + c.build.SetStatus(constants.StatusError) + c.build.SetError(e.Error()) + for _, s := range c.pipeline.Steps { + // extract step + step := library.StepFromBuildContainer(c.build, s) + // status to use for preconfigured steps that are not ran + status := constants.StatusKilled + // set step status + step.SetStatus(status) + // send API call to update the step + //nolint:contextcheck // ignore passing context + _, _, err := c.Vela.Step.Update(c.repo.GetOrg(), c.repo.GetName(), c.build.GetNumber(), step) + if err != nil { + // only log any step update errors to allow the return err to run + c.Logger.Errorf("unable to update step %s to status %s: %s", s.Name, status, err.Error()) + } + } + return err + } + } } // inspect the runtime build (eg a kubernetes pod) for the pipeline From ee728e57d1f8512c9217c917362da4bd4f3ae909 Mon Sep 17 00:00:00 2001 From: davidvader Date: Wed, 23 Nov 2022 15:39:38 -0600 Subject: [PATCH 02/19] fix: comment tweaks --- executor/linux/build.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/executor/linux/build.go b/executor/linux/build.go index 65f68ceb..554194c7 100644 --- a/executor/linux/build.go +++ b/executor/linux/build.go @@ -257,7 +257,7 @@ func (c *client) AssembleBuild(ctx context.Context) error { return fmt.Errorf("unable to inspect %s service: %w", s.Name, err) } - // update the init log with step image info + // update the init log with service image info // // https://pkg.go.dev/github.com/go-vela/types/library?tab=doc#Log.AppendData _log.AppendData(_image) @@ -437,7 +437,7 @@ func (c *client) AssembleBuild(ctx context.Context) error { return fmt.Errorf("unable to inspect %s secret: %w", s.Origin.Name, err) } - // update the init log with step image info + // update the init log with secret origin image info // // https://pkg.go.dev/github.com/go-vela/types/library?tab=doc#Log.AppendData _log.AppendData(_image) From 3e72c3f3e2dd021cd9e52e9d09810f83656abf43 Mon Sep 17 00:00:00 2001 From: davidvader Date: Tue, 29 Nov 2022 09:27:06 -0600 Subject: [PATCH 03/19] wip: move trusted check after assemblebuild --- executor/linux/build.go | 229 +++++++++++++++-------------------- executor/linux/build_test.go | 63 ++++++---- executor/linux/service.go | 4 + executor/linux/stage.go | 14 ++- 4 files changed, 158 insertions(+), 152 deletions(-) diff --git a/executor/linux/build.go b/executor/linux/build.go index 554194c7..cd457325 100644 --- a/executor/linux/build.go +++ b/executor/linux/build.go @@ -14,7 +14,6 @@ import ( "golang.org/x/sync/errgroup" "github.com/go-vela/types/constants" - "github.com/go-vela/types/library" "github.com/go-vela/worker/internal/build" "github.com/go-vela/worker/internal/image" "github.com/go-vela/worker/internal/step" @@ -251,7 +250,7 @@ func (c *client) AssembleBuild(ctx context.Context) error { c.Logger.Infof("inspecting %s service", s.Name) // inspect the service image - _image, err := c.Runtime.InspectImage(ctx, s) + output, err := c.Runtime.InspectImage(ctx, s) if err != nil { c.err = err return fmt.Errorf("unable to inspect %s service: %w", s.Name, err) @@ -260,53 +259,27 @@ func (c *client) AssembleBuild(ctx context.Context) error { // update the init log with service image info // // https://pkg.go.dev/github.com/go-vela/types/library?tab=doc#Log.AppendData - _log.AppendData(_image) - - // // before setting up the build, enforce repo.trusted is set for pipelines containing privileged images - // // this configuration is set as an executor flag - if c.enforceTrustedRepos { - c.Logger.Infof("checking %s service privilege", s.Name) + _log.AppendData(output) - _log.AppendData([]byte(fmt.Sprintf("> Checking privileges for service image %s...\n", s.Image))) + c.Logger.Infof("verifying privilege for container %s", s.Name) - privileged := false - var e error = nil - for _, pattern := range c.privilegedImages { - privileged, err = image.IsPrivilegedImage(s.Image, pattern) - if err != nil { - e = fmt.Errorf("could not verify if image %s is privileged: %s", s.Image, err.Error()) - _log.AppendData([]byte(fmt.Sprintf("> ERROR: Unable to verify if image %s is privileged.\n", s.Image))) - break - } - } - - if (privileged) && !(c.repo != nil && c.repo.GetTrusted()) { - e = fmt.Errorf("could not prepare %s service. image %s is privileged and repo is not trusted", s.Name, s.Image) - _log.AppendData([]byte(fmt.Sprintf("> ERROR: Unable to prepare privileged image %s, repo is not trusted.\n", s.Image))) - } + // update the init log with service image info + // + // https://pkg.go.dev/github.com/go-vela/types/library?tab=doc#Log.AppendData + _log.AppendData([]byte(fmt.Sprintf("Verifying privileges for image %s...\n", s.Image))) - // privileged check returned error - if e != nil { - c.build.SetStatus(constants.StatusError) - c.build.SetError(e.Error()) - for _, s := range c.pipeline.Steps { - // extract step - step := library.StepFromBuildContainer(c.build, s) - // status to use for preconfigured steps that are not ran - status := constants.StatusKilled - // set step status - step.SetStatus(status) - // send API call to update the step - //nolint:contextcheck // ignore passing context - _, _, err := c.Vela.Step.Update(c.repo.GetOrg(), c.repo.GetName(), c.build.GetNumber(), step) - if err != nil { - // only log any step update errors to allow the return err to run - c.Logger.Errorf("unable to update step %s to status %s: %s", s.Name, status, err.Error()) - } - } - return err - } + // check image privileged permissions + err = c.verifyPrivileged(s.Image) + if err != nil { + c.err = err + _log.AppendData([]byte(fmt.Sprintf("ERROR: %s\n", err.Error()))) + return fmt.Errorf("unable to verify privilege for service image %s: %w", s.Name, err) } + + // update the init log with service image info + // + // https://pkg.go.dev/github.com/go-vela/types/library?tab=doc#Log.AppendData + _log.AppendData([]byte(fmt.Sprintf("Privileges verified for image %s...\n", s.Image))) } // update the init log with progress @@ -363,51 +336,25 @@ func (c *client) AssembleBuild(ctx context.Context) error { // https://pkg.go.dev/github.com/go-vela/types/library?tab=doc#Log.AppendData _log.AppendData(_image) - // // before setting up the build, enforce repo.trusted is set for pipelines containing privileged images - // // this configuration is set as an executor flag - if c.enforceTrustedRepos { - c.Logger.Infof("checking %s step privilege", s.Name) - - _log.AppendData([]byte(fmt.Sprintf("> Checking privileges for step image %s...\n", s.Image))) - - privileged := false - var e error = nil - for _, pattern := range c.privilegedImages { - privileged, err = image.IsPrivilegedImage(s.Image, pattern) - if err != nil { - e = fmt.Errorf("could not verify if image %s is privileged: %s", s.Image, err.Error()) - _log.AppendData([]byte(fmt.Sprintf("> ERROR: Unable to verify if image %s is privileged.\n", s.Image))) - break - } - } + c.Logger.Infof("verifying privilege for container %s", s.Name) - if (privileged) && !(c.repo != nil && c.repo.GetTrusted()) { - e = fmt.Errorf("could not prepare %s step. image %s is privileged and repo is not trusted", s.Name, s.Image) - _log.AppendData([]byte(fmt.Sprintf("> ERROR: Unable to prepare privileged image %s, repo is not trusted.\n", s.Image))) - } + // update the init log with step image info + // + // https://pkg.go.dev/github.com/go-vela/types/library?tab=doc#Log.AppendData + _log.AppendData([]byte(fmt.Sprintf("Verifying privileges for image %s...\n", s.Image))) - // privileged check returned error - if e != nil { - c.build.SetStatus(constants.StatusError) - c.build.SetError(e.Error()) - for _, s := range c.pipeline.Steps { - // extract step - step := library.StepFromBuildContainer(c.build, s) - // status to use for preconfigured steps that are not ran - status := constants.StatusKilled - // set step status - step.SetStatus(status) - // send API call to update the step - //nolint:contextcheck // ignore passing context - _, _, err := c.Vela.Step.Update(c.repo.GetOrg(), c.repo.GetName(), c.build.GetNumber(), step) - if err != nil { - // only log any step update errors to allow the return err to run - c.Logger.Errorf("unable to update step %s to status %s: %s", s.Name, status, err.Error()) - } - } - return err - } + // check image privileged permissions + err = c.verifyPrivileged(s.Image) + if err != nil { + c.err = err + _log.AppendData([]byte(fmt.Sprintf("ERROR: %s\n", err.Error()))) + return fmt.Errorf("unable to check privilege for step image %s: %w", s.Name, err) } + + // update the init log with service image info + // + // https://pkg.go.dev/github.com/go-vela/types/library?tab=doc#Log.AppendData + _log.AppendData([]byte(fmt.Sprintf("Privileges verified for image %s...\n", s.Image))) } // update the init log with progress @@ -442,51 +389,25 @@ func (c *client) AssembleBuild(ctx context.Context) error { // https://pkg.go.dev/github.com/go-vela/types/library?tab=doc#Log.AppendData _log.AppendData(_image) - // // before setting up the build, enforce repo.trusted is set for pipelines containing privileged images - // // this configuration is set as an executor flag - if c.enforceTrustedRepos { - c.Logger.Infof("checking %s secret origin privilege", s.Name) + c.Logger.Infof("verifying privilege for container %s", s.Origin.Name) - _log.AppendData([]byte(fmt.Sprintf("> Checking privileges for secret origin image %s...\n", s.Origin.Image))) - - privileged := false - var e error = nil - for _, pattern := range c.privilegedImages { - privileged, err = image.IsPrivilegedImage(s.Origin.Image, pattern) - if err != nil { - e = fmt.Errorf("could not verify if image %s is privileged: %s", s.Origin.Image, err.Error()) - _log.AppendData([]byte(fmt.Sprintf("> ERROR: Unable to verify if image %s is privileged.\n", s.Origin.Image))) - break - } - } - - if (privileged) && !(c.repo != nil && c.repo.GetTrusted()) { - e = fmt.Errorf("could not prepare %s secret origin. image %s is privileged and repo is not trusted", s.Name, s.Origin.Image) - _log.AppendData([]byte(fmt.Sprintf("> ERROR: Unable to prepare privileged image %s, repo is not trusted.\n", s.Origin.Image))) - } + // update the init log with secret origin image info + // + // https://pkg.go.dev/github.com/go-vela/types/library?tab=doc#Log.AppendData + _log.AppendData([]byte(fmt.Sprintf("Verifying privileges for image %s...\n", s.Origin.Image))) - // privileged check returned error - if e != nil { - c.build.SetStatus(constants.StatusError) - c.build.SetError(e.Error()) - for _, s := range c.pipeline.Steps { - // extract step - step := library.StepFromBuildContainer(c.build, s) - // status to use for preconfigured steps that are not ran - status := constants.StatusKilled - // set step status - step.SetStatus(status) - // send API call to update the step - //nolint:contextcheck // ignore passing context - _, _, err := c.Vela.Step.Update(c.repo.GetOrg(), c.repo.GetName(), c.build.GetNumber(), step) - if err != nil { - // only log any step update errors to allow the return err to run - c.Logger.Errorf("unable to update step %s to status %s: %s", s.Name, status, err.Error()) - } - } - return err - } + // check image privileged permissions + err = c.verifyPrivileged(s.Origin.Image) + if err != nil { + c.err = err + _log.AppendData([]byte(fmt.Sprintf("ERROR: %s\n", err.Error()))) + return fmt.Errorf("unable to check privilege for secret origin image %s: %w", s.Name, err) } + + // update the init log with service image info + // + // https://pkg.go.dev/github.com/go-vela/types/library?tab=doc#Log.AppendData + _log.AppendData([]byte(fmt.Sprintf("Privileges verified for image %s...\n", s.Origin.Image))) } // inspect the runtime build (eg a kubernetes pod) for the pipeline @@ -525,6 +446,56 @@ func (c *client) AssembleBuild(ctx context.Context) error { return c.err } +// enforce repo.trusted is set for pipelines containing privileged images +// this configuration is set as an executor flag +func (c *client) verifyPrivileged(img string) error { + // if not enforced, allow all + // this still does not impact the list of runtime privileged images + if !c.enforceTrustedRepos { + return nil + } + + // prevent ghosting + privileged := false + var err error = nil + for _, pattern := range c.privilegedImages { + privileged, err = image.IsPrivilegedImage(img, pattern) + if err != nil { + // wrap and return error + return fmt.Errorf("unable to verify if image is privileged: %s", err.Error()) + } + } + + if (privileged) && !(c.repo != nil && c.repo.GetTrusted()) { + return fmt.Errorf("unable to prepare %s. image is privileged and repo is not trusted", img) + } + + return nil +} + +func clean() { + // c.build.SetStatus(constants.StatusError) + // c.build.SetError(e.Error()) + + // // todo: vader: + // // also iterate over stages and services? + // for _, s := range c.pipeline.Steps { + // // extract step + // step := library.StepFromBuildContainer(c.build, s) + // // status to use for preconfigured steps that are not ran + // status := constants.StatusKilled + // // set step status + // step.SetStatus(status) + // // send API call to update the step + // //nolint:contextcheck // ignore passing context + // _, _, err := c.Vela.Step.Update(c.repo.GetOrg(), c.repo.GetName(), c.build.GetNumber(), step) + // if err != nil { + // // only log any step update errors to allow the return err to run + // c.Logger.Errorf("unable to update step %s to status %s: %s", s.Name, status, err.Error()) + // } + // } +} + // ExecBuild runs a pipeline for a build. func (c *client) ExecBuild(ctx context.Context) error { // defer an upload of the build diff --git a/executor/linux/build_test.go b/executor/linux/build_test.go index 6b7b2d9d..8db8b0f5 100644 --- a/executor/linux/build_test.go +++ b/executor/linux/build_test.go @@ -130,7 +130,7 @@ func TestLinux_CreateBuild(t *testing.T) { } } -func TestLinux_CreateBuild_EnforceTrustedRepos(t *testing.T) { +func TestLinux_AssembleBuild_EnforceTrustedRepos(t *testing.T) { // setup types compiler, _ := native.New(cli.NewContext(nil, flag.NewFlagSet("test", 0), nil)) @@ -399,15 +399,7 @@ func TestLinux_CreateBuild_EnforceTrustedRepos(t *testing.T) { privilegedImages: _privilegedImagesStepsPipeline, // this matches the image from test.pipeline enforceTrustedRepos: true, }, - { - name: "enforce trusted repos enabled: privileged steps pipeline with untrusted repo and init step name", - failure: true, - build: _build, - repo: _untrustedRepo, - pipeline: "testdata/build/steps/name_init.yml", - privilegedImages: _privilegedImagesStepsPipeline, // this matches the image from test.pipeline - enforceTrustedRepos: true, - }, + { name: "enforce trusted repos enabled: non-privileged steps pipeline with trusted repo and init step name", failure: false, @@ -417,15 +409,6 @@ func TestLinux_CreateBuild_EnforceTrustedRepos(t *testing.T) { privilegedImages: _privilegedImagesStepsPipeline, // this matches the image from test.pipeline enforceTrustedRepos: true, }, - { - name: "enforce trusted repos enabled: non-privileged steps pipeline with untrusted repo and init step name", - failure: true, - build: _build, - repo: _untrustedRepo, - pipeline: "testdata/build/steps/name_init.yml", - privilegedImages: _privilegedImagesStepsPipeline, // this matches the image from test.pipeline - enforceTrustedRepos: true, - }, { name: "enforce trusted repos disabled: privileged steps pipeline with trusted repo and init step name", failure: false, @@ -608,6 +591,34 @@ func TestLinux_CreateBuild_EnforceTrustedRepos(t *testing.T) { }, } + // focus these tests + tests = []struct { + name string + failure bool + build *library.Build + repo *library.Repo + pipeline string + privilegedImages []string + enforceTrustedRepos bool + }{{ + name: "enforce trusted repos enabled: privileged steps pipeline with untrusted repo and init step name", + failure: true, + build: _build, + repo: _untrustedRepo, + pipeline: "testdata/build/steps/name_init.yml", + privilegedImages: _privilegedImagesStepsPipeline, // this matches the image from test.pipeline + enforceTrustedRepos: true, + }, + { + name: "enforce trusted repos enabled: non-privileged steps pipeline with untrusted repo and init step name", + failure: true, + build: _build, + repo: _untrustedRepo, + pipeline: "testdata/build/steps/name_init.yml", + privilegedImages: _privilegedImagesStepsPipeline, // this matches the image from test.pipeline + enforceTrustedRepos: true, + }} + // run test for _, test := range tests { t.Run(test.name, func(t *testing.T) { @@ -637,17 +648,27 @@ func TestLinux_CreateBuild_EnforceTrustedRepos(t *testing.T) { } err = _engine.CreateBuild(context.Background()) + if err != nil { + t.Errorf("CreateBuild returned err: %v", err) + } + + err = _engine.PlanBuild(context.Background()) + if err != nil { + t.Errorf("PlanBuild returned err: %v", err) + } + + err = _engine.AssembleBuild(context.Background()) if test.failure { if err == nil { - t.Errorf("CreateBuild should have returned err") + t.Errorf("AssembleBuild should have returned err") } return // continue to next test } if err != nil { - t.Errorf("CreateBuild returned err: %v", err) + t.Errorf("AssembleBuild returned err: %v", err) } }) } diff --git a/executor/linux/service.go b/executor/linux/service.go index a79cd2ea..b3dc1ffb 100644 --- a/executor/linux/service.go +++ b/executor/linux/service.go @@ -33,6 +33,10 @@ func (c *client) CreateService(ctx context.Context, ctn *pipeline.Container) err return err } + // create a library step object to facilitate injecting environment as early as possible + // (PlanStep is too late to inject environment vars for the kubernetes runtime). + // _service := library.ServiceFromBuildContainer(c.build, ctn) + // update the service container environment // // https://pkg.go.dev/github.com/go-vela/worker/internal/service#Environment diff --git a/executor/linux/stage.go b/executor/linux/stage.go index ddab1b86..807d2b42 100644 --- a/executor/linux/stage.go +++ b/executor/linux/stage.go @@ -47,7 +47,7 @@ func (c *client) CreateStage(ctx context.Context, s *pipeline.Stage) error { logger.Infof("inspecting image for %s step", _step.Name) // inspect the step image - image, err := c.Runtime.InspectImage(ctx, _step) + _image, err := c.Runtime.InspectImage(ctx, _step) if err != nil { return err } @@ -55,7 +55,17 @@ func (c *client) CreateStage(ctx context.Context, s *pipeline.Stage) error { // update the init log with step image info // // https://pkg.go.dev/github.com/go-vela/types/library?tab=doc#Log.AppendData - _log.AppendData(image) + _log.AppendData(_image) + + c.Logger.Infof("checking privilege for container %s", _step.Name) + + // check image privileged permissions + err = c.verifyPrivileged(_step.Image) + if err != nil { + c.err = err + _log.AppendData([]byte(fmt.Sprintf("ERROR: %s\n", err.Error()))) + return fmt.Errorf("unable to verify privilege for stage image %s: %w", _step.Name, err) + } } return nil From 7981f221a6d0d8419bea34534f95f74c309aa61a Mon Sep 17 00:00:00 2001 From: davidvader Date: Tue, 29 Nov 2022 10:32:54 -0600 Subject: [PATCH 04/19] wip: group, move and clean container grouping --- executor/linux/build.go | 73 +++++++++++++++-------------------------- executor/linux/stage.go | 18 +++++----- 2 files changed, 35 insertions(+), 56 deletions(-) diff --git a/executor/linux/build.go b/executor/linux/build.go index cd457325..6a47d49a 100644 --- a/executor/linux/build.go +++ b/executor/linux/build.go @@ -260,26 +260,6 @@ func (c *client) AssembleBuild(ctx context.Context) error { // // https://pkg.go.dev/github.com/go-vela/types/library?tab=doc#Log.AppendData _log.AppendData(output) - - c.Logger.Infof("verifying privilege for container %s", s.Name) - - // update the init log with service image info - // - // https://pkg.go.dev/github.com/go-vela/types/library?tab=doc#Log.AppendData - _log.AppendData([]byte(fmt.Sprintf("Verifying privileges for image %s...\n", s.Image))) - - // check image privileged permissions - err = c.verifyPrivileged(s.Image) - if err != nil { - c.err = err - _log.AppendData([]byte(fmt.Sprintf("ERROR: %s\n", err.Error()))) - return fmt.Errorf("unable to verify privilege for service image %s: %w", s.Name, err) - } - - // update the init log with service image info - // - // https://pkg.go.dev/github.com/go-vela/types/library?tab=doc#Log.AppendData - _log.AppendData([]byte(fmt.Sprintf("Privileges verified for image %s...\n", s.Image))) } // update the init log with progress @@ -335,26 +315,6 @@ func (c *client) AssembleBuild(ctx context.Context) error { // // https://pkg.go.dev/github.com/go-vela/types/library?tab=doc#Log.AppendData _log.AppendData(_image) - - c.Logger.Infof("verifying privilege for container %s", s.Name) - - // update the init log with step image info - // - // https://pkg.go.dev/github.com/go-vela/types/library?tab=doc#Log.AppendData - _log.AppendData([]byte(fmt.Sprintf("Verifying privileges for image %s...\n", s.Image))) - - // check image privileged permissions - err = c.verifyPrivileged(s.Image) - if err != nil { - c.err = err - _log.AppendData([]byte(fmt.Sprintf("ERROR: %s\n", err.Error()))) - return fmt.Errorf("unable to check privilege for step image %s: %w", s.Name, err) - } - - // update the init log with service image info - // - // https://pkg.go.dev/github.com/go-vela/types/library?tab=doc#Log.AppendData - _log.AppendData([]byte(fmt.Sprintf("Privileges verified for image %s...\n", s.Image))) } // update the init log with progress @@ -388,26 +348,44 @@ func (c *client) AssembleBuild(ctx context.Context) error { // // https://pkg.go.dev/github.com/go-vela/types/library?tab=doc#Log.AppendData _log.AppendData(_image) + } - c.Logger.Infof("verifying privilege for container %s", s.Origin.Name) + // update the init log with progress + // + // https://pkg.go.dev/github.com/go-vela/types/library?tab=doc#Log.AppendData + _log.AppendData([]byte("> Verifying privileges for container images...\n")) - // update the init log with secret origin image info + // group steps services stages and secret origins together + containers := c.pipeline.Steps + containers = append(containers, c.pipeline.Services...) + for _, stage := range c.pipeline.Stages { + containers = append(containers, stage.Steps...) + } + for _, secret := range c.pipeline.Secrets { + containers = append(containers, secret.Origin) + } + + // verify the image privileges for all pipeline containers + for _, container := range containers { + c.Logger.Infof("verifying privileges for container %s", container.Name) + + // update the init log with image info // // https://pkg.go.dev/github.com/go-vela/types/library?tab=doc#Log.AppendData - _log.AppendData([]byte(fmt.Sprintf("Verifying privileges for image %s...\n", s.Origin.Image))) + _log.AppendData([]byte(fmt.Sprintf("Verifying privileges for image %s...\n", container.Image))) // check image privileged permissions - err = c.verifyPrivileged(s.Origin.Image) + err = c.verifyPrivileged(container.Image) if err != nil { c.err = err _log.AppendData([]byte(fmt.Sprintf("ERROR: %s\n", err.Error()))) - return fmt.Errorf("unable to check privilege for secret origin image %s: %w", s.Name, err) + return fmt.Errorf("unable to verify privilege for image %s: %w", container.Name, err) } - // update the init log with service image info + // update the init log with image info // // https://pkg.go.dev/github.com/go-vela/types/library?tab=doc#Log.AppendData - _log.AppendData([]byte(fmt.Sprintf("Privileges verified for image %s...\n", s.Origin.Image))) + _log.AppendData([]byte(fmt.Sprintf("Privileges verified for image %s\n", container.Image))) } // inspect the runtime build (eg a kubernetes pod) for the pipeline @@ -474,6 +452,7 @@ func (c *client) verifyPrivileged(img string) error { } func clean() { + // c.build.SetStatus(constants.StatusError) // c.build.SetError(e.Error()) diff --git a/executor/linux/stage.go b/executor/linux/stage.go index 807d2b42..0adf0c60 100644 --- a/executor/linux/stage.go +++ b/executor/linux/stage.go @@ -57,15 +57,15 @@ func (c *client) CreateStage(ctx context.Context, s *pipeline.Stage) error { // https://pkg.go.dev/github.com/go-vela/types/library?tab=doc#Log.AppendData _log.AppendData(_image) - c.Logger.Infof("checking privilege for container %s", _step.Name) - - // check image privileged permissions - err = c.verifyPrivileged(_step.Image) - if err != nil { - c.err = err - _log.AppendData([]byte(fmt.Sprintf("ERROR: %s\n", err.Error()))) - return fmt.Errorf("unable to verify privilege for stage image %s: %w", _step.Name, err) - } + // c.Logger.Infof("checking privilege for container %s", _step.Name) + + // // check image privileged permissions + // err = c.verifyPrivileged(_step.Image) + // if err != nil { + // c.err = err + // _log.AppendData([]byte(fmt.Sprintf("ERROR: %s\n", err.Error()))) + // return fmt.Errorf("unable to verify privilege for stage image %s: %w", _step.Name, err) + // } } return nil From b0679b90af3bb9f5128fce25e47d62de2ff1e462 Mon Sep 17 00:00:00 2001 From: davidvader Date: Tue, 29 Nov 2022 10:35:19 -0600 Subject: [PATCH 05/19] chore: remove unused code and variable changes --- executor/linux/build.go | 10 +++++----- executor/linux/stage.go | 14 ++------------ 2 files changed, 7 insertions(+), 17 deletions(-) diff --git a/executor/linux/build.go b/executor/linux/build.go index 6a47d49a..5643347b 100644 --- a/executor/linux/build.go +++ b/executor/linux/build.go @@ -305,7 +305,7 @@ func (c *client) AssembleBuild(ctx context.Context) error { c.Logger.Infof("inspecting %s step", s.Name) // inspect the step image - _image, err := c.Runtime.InspectImage(ctx, s) + image, err := c.Runtime.InspectImage(ctx, s) if err != nil { c.err = err return fmt.Errorf("unable to inspect %s step: %w", s.Name, c.err) @@ -314,7 +314,7 @@ func (c *client) AssembleBuild(ctx context.Context) error { // update the init log with step image info // // https://pkg.go.dev/github.com/go-vela/types/library?tab=doc#Log.AppendData - _log.AppendData(_image) + _log.AppendData(image) } // update the init log with progress @@ -338,16 +338,16 @@ func (c *client) AssembleBuild(ctx context.Context) error { c.Logger.Infof("inspecting %s secret", s.Origin.Name) // inspect the service image - _image, err := c.Runtime.InspectImage(ctx, s.Origin) + image, err := c.Runtime.InspectImage(ctx, s.Origin) if err != nil { c.err = err return fmt.Errorf("unable to inspect %s secret: %w", s.Origin.Name, err) } - // update the init log with secret origin image info + // update the init log with secret image info // // https://pkg.go.dev/github.com/go-vela/types/library?tab=doc#Log.AppendData - _log.AppendData(_image) + _log.AppendData(image) } // update the init log with progress diff --git a/executor/linux/stage.go b/executor/linux/stage.go index 0adf0c60..ddab1b86 100644 --- a/executor/linux/stage.go +++ b/executor/linux/stage.go @@ -47,7 +47,7 @@ func (c *client) CreateStage(ctx context.Context, s *pipeline.Stage) error { logger.Infof("inspecting image for %s step", _step.Name) // inspect the step image - _image, err := c.Runtime.InspectImage(ctx, _step) + image, err := c.Runtime.InspectImage(ctx, _step) if err != nil { return err } @@ -55,17 +55,7 @@ func (c *client) CreateStage(ctx context.Context, s *pipeline.Stage) error { // update the init log with step image info // // https://pkg.go.dev/github.com/go-vela/types/library?tab=doc#Log.AppendData - _log.AppendData(_image) - - // c.Logger.Infof("checking privilege for container %s", _step.Name) - - // // check image privileged permissions - // err = c.verifyPrivileged(_step.Image) - // if err != nil { - // c.err = err - // _log.AppendData([]byte(fmt.Sprintf("ERROR: %s\n", err.Error()))) - // return fmt.Errorf("unable to verify privilege for stage image %s: %w", _step.Name, err) - // } + _log.AppendData(image) } return nil From b1c09c6d184497bf753b3285cff49008cc165384 Mon Sep 17 00:00:00 2001 From: davidvader Date: Tue, 29 Nov 2022 10:37:32 -0600 Subject: [PATCH 06/19] chore: remove variable changes, commented code and useless log --- executor/linux/build.go | 9 ++------- executor/linux/service.go | 4 ---- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/executor/linux/build.go b/executor/linux/build.go index 5643347b..ac494cf7 100644 --- a/executor/linux/build.go +++ b/executor/linux/build.go @@ -250,7 +250,7 @@ func (c *client) AssembleBuild(ctx context.Context) error { c.Logger.Infof("inspecting %s service", s.Name) // inspect the service image - output, err := c.Runtime.InspectImage(ctx, s) + image, err := c.Runtime.InspectImage(ctx, s) if err != nil { c.err = err return fmt.Errorf("unable to inspect %s service: %w", s.Name, err) @@ -259,7 +259,7 @@ func (c *client) AssembleBuild(ctx context.Context) error { // update the init log with service image info // // https://pkg.go.dev/github.com/go-vela/types/library?tab=doc#Log.AppendData - _log.AppendData(output) + _log.AppendData(image) } // update the init log with progress @@ -350,11 +350,6 @@ func (c *client) AssembleBuild(ctx context.Context) error { _log.AppendData(image) } - // update the init log with progress - // - // https://pkg.go.dev/github.com/go-vela/types/library?tab=doc#Log.AppendData - _log.AppendData([]byte("> Verifying privileges for container images...\n")) - // group steps services stages and secret origins together containers := c.pipeline.Steps containers = append(containers, c.pipeline.Services...) diff --git a/executor/linux/service.go b/executor/linux/service.go index b3dc1ffb..a79cd2ea 100644 --- a/executor/linux/service.go +++ b/executor/linux/service.go @@ -33,10 +33,6 @@ func (c *client) CreateService(ctx context.Context, ctn *pipeline.Container) err return err } - // create a library step object to facilitate injecting environment as early as possible - // (PlanStep is too late to inject environment vars for the kubernetes runtime). - // _service := library.ServiceFromBuildContainer(c.build, ctn) - // update the service container environment // // https://pkg.go.dev/github.com/go-vela/worker/internal/service#Environment From 61b10dce9f61e5764539734c806a298badccf11d Mon Sep 17 00:00:00 2001 From: davidvader Date: Tue, 29 Nov 2022 10:56:12 -0600 Subject: [PATCH 07/19] fix: skip init+empty secrets --- executor/linux/build.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/executor/linux/build.go b/executor/linux/build.go index ac494cf7..27d4d95e 100644 --- a/executor/linux/build.go +++ b/executor/linux/build.go @@ -362,6 +362,16 @@ func (c *client) AssembleBuild(ctx context.Context) error { // verify the image privileges for all pipeline containers for _, container := range containers { + // TODO: remove hardcoded reference + if container.Image == "#init" { + continue + } + + // ignore secret origins coming from plugins + if container.Empty() { + continue + } + c.Logger.Infof("verifying privileges for container %s", container.Name) // update the init log with image info From c18947b07c2aa5f03c7bad325126afebe9c69711 Mon Sep 17 00:00:00 2001 From: davidvader Date: Tue, 29 Nov 2022 10:59:15 -0600 Subject: [PATCH 08/19] fix: remove specific tests, remove planBuild from test --- executor/linux/build.go | 2 +- executor/linux/build_test.go | 33 --------------------------------- 2 files changed, 1 insertion(+), 34 deletions(-) diff --git a/executor/linux/build.go b/executor/linux/build.go index 27d4d95e..2e3cf551 100644 --- a/executor/linux/build.go +++ b/executor/linux/build.go @@ -367,7 +367,7 @@ func (c *client) AssembleBuild(ctx context.Context) error { continue } - // ignore secret origins coming from plugins + // skip over non-plugin secrets origins if container.Empty() { continue } diff --git a/executor/linux/build_test.go b/executor/linux/build_test.go index 8db8b0f5..a2a289e3 100644 --- a/executor/linux/build_test.go +++ b/executor/linux/build_test.go @@ -591,34 +591,6 @@ func TestLinux_AssembleBuild_EnforceTrustedRepos(t *testing.T) { }, } - // focus these tests - tests = []struct { - name string - failure bool - build *library.Build - repo *library.Repo - pipeline string - privilegedImages []string - enforceTrustedRepos bool - }{{ - name: "enforce trusted repos enabled: privileged steps pipeline with untrusted repo and init step name", - failure: true, - build: _build, - repo: _untrustedRepo, - pipeline: "testdata/build/steps/name_init.yml", - privilegedImages: _privilegedImagesStepsPipeline, // this matches the image from test.pipeline - enforceTrustedRepos: true, - }, - { - name: "enforce trusted repos enabled: non-privileged steps pipeline with untrusted repo and init step name", - failure: true, - build: _build, - repo: _untrustedRepo, - pipeline: "testdata/build/steps/name_init.yml", - privilegedImages: _privilegedImagesStepsPipeline, // this matches the image from test.pipeline - enforceTrustedRepos: true, - }} - // run test for _, test := range tests { t.Run(test.name, func(t *testing.T) { @@ -652,11 +624,6 @@ func TestLinux_AssembleBuild_EnforceTrustedRepos(t *testing.T) { t.Errorf("CreateBuild returned err: %v", err) } - err = _engine.PlanBuild(context.Background()) - if err != nil { - t.Errorf("PlanBuild returned err: %v", err) - } - err = _engine.AssembleBuild(context.Background()) if test.failure { From e98a6736224da4fc40136e91be072eb89cb636ea Mon Sep 17 00:00:00 2001 From: davidvader Date: Wed, 30 Nov 2022 08:52:36 -0600 Subject: [PATCH 09/19] fix: move container checks to after create --- executor/linux/build.go | 108 +++----- executor/linux/build_test.go | 485 +++++++++++++++++------------------ 2 files changed, 283 insertions(+), 310 deletions(-) diff --git a/executor/linux/build.go b/executor/linux/build.go index 2e3cf551..67404302 100644 --- a/executor/linux/build.go +++ b/executor/linux/build.go @@ -350,47 +350,51 @@ func (c *client) AssembleBuild(ctx context.Context) error { _log.AppendData(image) } - // group steps services stages and secret origins together - containers := c.pipeline.Steps - containers = append(containers, c.pipeline.Services...) - for _, stage := range c.pipeline.Stages { - containers = append(containers, stage.Steps...) - } - for _, secret := range c.pipeline.Secrets { - containers = append(containers, secret.Origin) - } + // if not enforced, allow all + // this still does not impact the list of runtime privileged images + if c.enforceTrustedRepos { + // group steps services stages and secret origins together + containers := c.pipeline.Steps + containers = append(containers, c.pipeline.Services...) + for _, stage := range c.pipeline.Stages { + containers = append(containers, stage.Steps...) + } + for _, secret := range c.pipeline.Secrets { + containers = append(containers, secret.Origin) + } + + // verify the image privileges for all pipeline containers + for _, container := range containers { + // TODO: remove hardcoded reference + if container.Image == "#init" { + continue + } - // verify the image privileges for all pipeline containers - for _, container := range containers { - // TODO: remove hardcoded reference - if container.Image == "#init" { - continue - } + // skip over non-plugin secrets origins + if container.Empty() { + continue + } - // skip over non-plugin secrets origins - if container.Empty() { - continue - } + c.Logger.Infof("verifying privileges for container %s", container.Name) - c.Logger.Infof("verifying privileges for container %s", container.Name) + // update the init log with image info + // + // https://pkg.go.dev/github.com/go-vela/types/library?tab=doc#Log.AppendData + _log.AppendData([]byte(fmt.Sprintf("Verifying privileges for image %s...\n", container.Image))) - // update the init log with image info - // - // https://pkg.go.dev/github.com/go-vela/types/library?tab=doc#Log.AppendData - _log.AppendData([]byte(fmt.Sprintf("Verifying privileges for image %s...\n", container.Image))) + // check image privileged permissions + err = c.verifyPrivileged(container.Image) + if err != nil { + c.err = err + _log.AppendData([]byte(fmt.Sprintf("ERROR: %s\n", err.Error()))) + return fmt.Errorf("unable to verify privilege for image %s: %w", container.Name, err) + } - // check image privileged permissions - err = c.verifyPrivileged(container.Image) - if err != nil { - c.err = err - _log.AppendData([]byte(fmt.Sprintf("ERROR: %s\n", err.Error()))) - return fmt.Errorf("unable to verify privilege for image %s: %w", container.Name, err) + // update the init log with image info + // + // https://pkg.go.dev/github.com/go-vela/types/library?tab=doc#Log.AppendData + _log.AppendData([]byte(fmt.Sprintf("Privileges verified for image %s\n", container.Image))) } - - // update the init log with image info - // - // https://pkg.go.dev/github.com/go-vela/types/library?tab=doc#Log.AppendData - _log.AppendData([]byte(fmt.Sprintf("Privileges verified for image %s\n", container.Image))) } // inspect the runtime build (eg a kubernetes pod) for the pipeline @@ -432,12 +436,6 @@ func (c *client) AssembleBuild(ctx context.Context) error { // enforce repo.trusted is set for pipelines containing privileged images // this configuration is set as an executor flag func (c *client) verifyPrivileged(img string) error { - // if not enforced, allow all - // this still does not impact the list of runtime privileged images - if !c.enforceTrustedRepos { - return nil - } - // prevent ghosting privileged := false var err error = nil @@ -445,41 +443,17 @@ func (c *client) verifyPrivileged(img string) error { privileged, err = image.IsPrivilegedImage(img, pattern) if err != nil { // wrap and return error - return fmt.Errorf("unable to verify if image is privileged: %s", err.Error()) + return fmt.Errorf("unable to verify privileges for image %s", err.Error()) } } if (privileged) && !(c.repo != nil && c.repo.GetTrusted()) { - return fmt.Errorf("unable to prepare %s. image is privileged and repo is not trusted", img) + return fmt.Errorf("unable to verify image %s. image is privileged and repo is not trusted", img) } return nil } -func clean() { - - // c.build.SetStatus(constants.StatusError) - // c.build.SetError(e.Error()) - - // // todo: vader: - // // also iterate over stages and services? - // for _, s := range c.pipeline.Steps { - // // extract step - // step := library.StepFromBuildContainer(c.build, s) - // // status to use for preconfigured steps that are not ran - // status := constants.StatusKilled - // // set step status - // step.SetStatus(status) - // // send API call to update the step - // //nolint:contextcheck // ignore passing context - // _, _, err := c.Vela.Step.Update(c.repo.GetOrg(), c.repo.GetName(), c.build.GetNumber(), step) - // if err != nil { - // // only log any step update errors to allow the return err to run - // c.Logger.Errorf("unable to update step %s to status %s: %s", s.Name, status, err.Error()) - // } - // } -} - // ExecBuild runs a pipeline for a build. func (c *client) ExecBuild(ctx context.Context) error { // defer an upload of the build diff --git a/executor/linux/build_test.go b/executor/linux/build_test.go index a2a289e3..aac4bf47 100644 --- a/executor/linux/build_test.go +++ b/executor/linux/build_test.go @@ -130,6 +130,248 @@ func TestLinux_CreateBuild(t *testing.T) { } } +func TestLinux_PlanBuild(t *testing.T) { + // setup types + compiler, _ := native.New(cli.NewContext(nil, flag.NewFlagSet("test", 0), nil)) + + _build := testBuild() + _repo := testRepo() + _user := testUser() + _metadata := testMetadata() + + gin.SetMode(gin.TestMode) + + s := httptest.NewServer(server.FakeHandler()) + + _client, err := vela.NewClient(s.URL, "", nil) + if err != nil { + t.Errorf("unable to create Vela API client: %v", err) + } + + _runtime, err := docker.NewMock() + if err != nil { + t.Errorf("unable to create runtime engine: %v", err) + } + + tests := []struct { + name string + failure bool + pipeline string + }{ + { + name: "basic secrets pipeline", + failure: false, + pipeline: "testdata/build/secrets/basic.yml", + }, + { + name: "basic services pipeline", + failure: false, + pipeline: "testdata/build/services/basic.yml", + }, + { + name: "basic steps pipeline", + failure: false, + pipeline: "testdata/build/steps/basic.yml", + }, + { + name: "basic stages pipeline", + failure: false, + pipeline: "testdata/build/stages/basic.yml", + }, + } + + // run test + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + _pipeline, _, err := compiler. + Duplicate(). + WithBuild(_build). + WithRepo(_repo). + WithMetadata(_metadata). + WithUser(_user). + Compile(test.pipeline) + if err != nil { + t.Errorf("unable to compile pipeline %s: %v", test.pipeline, err) + } + + _engine, err := New( + WithBuild(_build), + WithPipeline(_pipeline), + WithRepo(_repo), + WithRuntime(_runtime), + WithUser(_user), + WithVelaClient(_client), + ) + if err != nil { + t.Errorf("unable to create executor engine: %v", err) + } + + // run create to init steps to be created properly + err = _engine.CreateBuild(context.Background()) + if err != nil { + t.Errorf("unable to create build: %v", err) + } + + err = _engine.PlanBuild(context.Background()) + + if test.failure { + if err == nil { + t.Errorf("PlanBuild should have returned err") + } + + return // continue to next test + } + + if err != nil { + t.Errorf("PlanBuild returned err: %v", err) + } + }) + } +} + +func TestLinux_AssembleBuild(t *testing.T) { + // setup types + compiler, _ := native.New(cli.NewContext(nil, flag.NewFlagSet("test", 0), nil)) + + _build := testBuild() + _repo := testRepo() + _user := testUser() + _metadata := testMetadata() + + gin.SetMode(gin.TestMode) + + s := httptest.NewServer(server.FakeHandler()) + + _client, err := vela.NewClient(s.URL, "", nil) + if err != nil { + t.Errorf("unable to create Vela API client: %v", err) + } + + _runtime, err := docker.NewMock() + if err != nil { + t.Errorf("unable to create runtime engine: %v", err) + } + + streamRequests, done := message.MockStreamRequestsWithCancel(context.Background()) + defer done() + + tests := []struct { + name string + failure bool + pipeline string + }{ + { + name: "basic secrets pipeline", + failure: false, + pipeline: "testdata/build/secrets/basic.yml", + }, + { + name: "secrets pipeline with image not found", + failure: true, + pipeline: "testdata/build/secrets/img_notfound.yml", + }, + { + name: "secrets pipeline with ignoring image not found", + failure: true, + pipeline: "testdata/build/secrets/img_ignorenotfound.yml", + }, + { + name: "basic services pipeline", + failure: false, + pipeline: "testdata/build/services/basic.yml", + }, + { + name: "services pipeline with image not found", + failure: true, + pipeline: "testdata/build/services/img_notfound.yml", + }, + { + name: "services pipeline with ignoring image not found", + failure: true, + pipeline: "testdata/build/services/img_ignorenotfound.yml", + }, + { + name: "basic steps pipeline", + failure: false, + pipeline: "testdata/build/steps/basic.yml", + }, + { + name: "steps pipeline with image not found", + failure: true, + pipeline: "testdata/build/steps/img_notfound.yml", + }, + { + name: "steps pipeline with ignoring image not found", + failure: true, + pipeline: "testdata/build/steps/img_ignorenotfound.yml", + }, + { + name: "basic stages pipeline", + failure: false, + pipeline: "testdata/build/stages/basic.yml", + }, + { + name: "stages pipeline with image not found", + failure: true, + pipeline: "testdata/build/stages/img_notfound.yml", + }, + { + name: "stages pipeline with ignoring image not found", + failure: true, + pipeline: "testdata/build/stages/img_ignorenotfound.yml", + }, + } + + // run test + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + _pipeline, _, err := compiler. + Duplicate(). + WithBuild(_build). + WithRepo(_repo). + WithMetadata(_metadata). + WithUser(_user). + Compile(test.pipeline) + if err != nil { + t.Errorf("unable to compile pipeline %s: %v", test.pipeline, err) + } + + _engine, err := New( + WithBuild(_build), + WithPipeline(_pipeline), + WithRepo(_repo), + WithRuntime(_runtime), + WithUser(_user), + WithVelaClient(_client), + withStreamRequests(streamRequests), + ) + if err != nil { + t.Errorf("unable to create executor engine: %v", err) + } + + // run create to init steps to be created properly + err = _engine.CreateBuild(context.Background()) + if err != nil { + t.Errorf("unable to create build: %v", err) + } + + err = _engine.AssembleBuild(context.Background()) + + if test.failure { + if err == nil { + t.Errorf("AssembleBuild should have returned err") + } + + return // continue to next test + } + + if err != nil { + t.Errorf("AssembleBuild returned err: %v", err) + } + }) + } +} + func TestLinux_AssembleBuild_EnforceTrustedRepos(t *testing.T) { // setup types compiler, _ := native.New(cli.NewContext(nil, flag.NewFlagSet("test", 0), nil)) @@ -399,7 +641,6 @@ func TestLinux_AssembleBuild_EnforceTrustedRepos(t *testing.T) { privilegedImages: _privilegedImagesStepsPipeline, // this matches the image from test.pipeline enforceTrustedRepos: true, }, - { name: "enforce trusted repos enabled: non-privileged steps pipeline with trusted repo and init step name", failure: false, @@ -641,248 +882,6 @@ func TestLinux_AssembleBuild_EnforceTrustedRepos(t *testing.T) { } } -func TestLinux_PlanBuild(t *testing.T) { - // setup types - compiler, _ := native.New(cli.NewContext(nil, flag.NewFlagSet("test", 0), nil)) - - _build := testBuild() - _repo := testRepo() - _user := testUser() - _metadata := testMetadata() - - gin.SetMode(gin.TestMode) - - s := httptest.NewServer(server.FakeHandler()) - - _client, err := vela.NewClient(s.URL, "", nil) - if err != nil { - t.Errorf("unable to create Vela API client: %v", err) - } - - _runtime, err := docker.NewMock() - if err != nil { - t.Errorf("unable to create runtime engine: %v", err) - } - - tests := []struct { - name string - failure bool - pipeline string - }{ - { - name: "basic secrets pipeline", - failure: false, - pipeline: "testdata/build/secrets/basic.yml", - }, - { - name: "basic services pipeline", - failure: false, - pipeline: "testdata/build/services/basic.yml", - }, - { - name: "basic steps pipeline", - failure: false, - pipeline: "testdata/build/steps/basic.yml", - }, - { - name: "basic stages pipeline", - failure: false, - pipeline: "testdata/build/stages/basic.yml", - }, - } - - // run test - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - _pipeline, _, err := compiler. - Duplicate(). - WithBuild(_build). - WithRepo(_repo). - WithMetadata(_metadata). - WithUser(_user). - Compile(test.pipeline) - if err != nil { - t.Errorf("unable to compile pipeline %s: %v", test.pipeline, err) - } - - _engine, err := New( - WithBuild(_build), - WithPipeline(_pipeline), - WithRepo(_repo), - WithRuntime(_runtime), - WithUser(_user), - WithVelaClient(_client), - ) - if err != nil { - t.Errorf("unable to create executor engine: %v", err) - } - - // run create to init steps to be created properly - err = _engine.CreateBuild(context.Background()) - if err != nil { - t.Errorf("unable to create build: %v", err) - } - - err = _engine.PlanBuild(context.Background()) - - if test.failure { - if err == nil { - t.Errorf("PlanBuild should have returned err") - } - - return // continue to next test - } - - if err != nil { - t.Errorf("PlanBuild returned err: %v", err) - } - }) - } -} - -func TestLinux_AssembleBuild(t *testing.T) { - // setup types - compiler, _ := native.New(cli.NewContext(nil, flag.NewFlagSet("test", 0), nil)) - - _build := testBuild() - _repo := testRepo() - _user := testUser() - _metadata := testMetadata() - - gin.SetMode(gin.TestMode) - - s := httptest.NewServer(server.FakeHandler()) - - _client, err := vela.NewClient(s.URL, "", nil) - if err != nil { - t.Errorf("unable to create Vela API client: %v", err) - } - - _runtime, err := docker.NewMock() - if err != nil { - t.Errorf("unable to create runtime engine: %v", err) - } - - streamRequests, done := message.MockStreamRequestsWithCancel(context.Background()) - defer done() - - tests := []struct { - name string - failure bool - pipeline string - }{ - { - name: "basic secrets pipeline", - failure: false, - pipeline: "testdata/build/secrets/basic.yml", - }, - { - name: "secrets pipeline with image not found", - failure: true, - pipeline: "testdata/build/secrets/img_notfound.yml", - }, - { - name: "secrets pipeline with ignoring image not found", - failure: true, - pipeline: "testdata/build/secrets/img_ignorenotfound.yml", - }, - { - name: "basic services pipeline", - failure: false, - pipeline: "testdata/build/services/basic.yml", - }, - { - name: "services pipeline with image not found", - failure: true, - pipeline: "testdata/build/services/img_notfound.yml", - }, - { - name: "services pipeline with ignoring image not found", - failure: true, - pipeline: "testdata/build/services/img_ignorenotfound.yml", - }, - { - name: "basic steps pipeline", - failure: false, - pipeline: "testdata/build/steps/basic.yml", - }, - { - name: "steps pipeline with image not found", - failure: true, - pipeline: "testdata/build/steps/img_notfound.yml", - }, - { - name: "steps pipeline with ignoring image not found", - failure: true, - pipeline: "testdata/build/steps/img_ignorenotfound.yml", - }, - { - name: "basic stages pipeline", - failure: false, - pipeline: "testdata/build/stages/basic.yml", - }, - { - name: "stages pipeline with image not found", - failure: true, - pipeline: "testdata/build/stages/img_notfound.yml", - }, - { - name: "stages pipeline with ignoring image not found", - failure: true, - pipeline: "testdata/build/stages/img_ignorenotfound.yml", - }, - } - - // run test - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - _pipeline, _, err := compiler. - Duplicate(). - WithBuild(_build). - WithRepo(_repo). - WithMetadata(_metadata). - WithUser(_user). - Compile(test.pipeline) - if err != nil { - t.Errorf("unable to compile pipeline %s: %v", test.pipeline, err) - } - - _engine, err := New( - WithBuild(_build), - WithPipeline(_pipeline), - WithRepo(_repo), - WithRuntime(_runtime), - WithUser(_user), - WithVelaClient(_client), - withStreamRequests(streamRequests), - ) - if err != nil { - t.Errorf("unable to create executor engine: %v", err) - } - - // run create to init steps to be created properly - err = _engine.CreateBuild(context.Background()) - if err != nil { - t.Errorf("unable to create build: %v", err) - } - - err = _engine.AssembleBuild(context.Background()) - - if test.failure { - if err == nil { - t.Errorf("AssembleBuild should have returned err") - } - - return // continue to next test - } - - if err != nil { - t.Errorf("AssembleBuild returned err: %v", err) - } - }) - } -} - func TestLinux_ExecBuild(t *testing.T) { // setup types compiler, _ := native.New(cli.NewContext(nil, flag.NewFlagSet("test", 0), nil)) From af8760fc3c4a8184c4cc7f700e620d79d40ea37d Mon Sep 17 00:00:00 2001 From: davidvader Date: Wed, 30 Nov 2022 08:55:10 -0600 Subject: [PATCH 10/19] fix: move test --- executor/linux/build_test.go | 484 +++++++++++++++++------------------ 1 file changed, 242 insertions(+), 242 deletions(-) diff --git a/executor/linux/build_test.go b/executor/linux/build_test.go index aac4bf47..4ff8964a 100644 --- a/executor/linux/build_test.go +++ b/executor/linux/build_test.go @@ -130,248 +130,6 @@ func TestLinux_CreateBuild(t *testing.T) { } } -func TestLinux_PlanBuild(t *testing.T) { - // setup types - compiler, _ := native.New(cli.NewContext(nil, flag.NewFlagSet("test", 0), nil)) - - _build := testBuild() - _repo := testRepo() - _user := testUser() - _metadata := testMetadata() - - gin.SetMode(gin.TestMode) - - s := httptest.NewServer(server.FakeHandler()) - - _client, err := vela.NewClient(s.URL, "", nil) - if err != nil { - t.Errorf("unable to create Vela API client: %v", err) - } - - _runtime, err := docker.NewMock() - if err != nil { - t.Errorf("unable to create runtime engine: %v", err) - } - - tests := []struct { - name string - failure bool - pipeline string - }{ - { - name: "basic secrets pipeline", - failure: false, - pipeline: "testdata/build/secrets/basic.yml", - }, - { - name: "basic services pipeline", - failure: false, - pipeline: "testdata/build/services/basic.yml", - }, - { - name: "basic steps pipeline", - failure: false, - pipeline: "testdata/build/steps/basic.yml", - }, - { - name: "basic stages pipeline", - failure: false, - pipeline: "testdata/build/stages/basic.yml", - }, - } - - // run test - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - _pipeline, _, err := compiler. - Duplicate(). - WithBuild(_build). - WithRepo(_repo). - WithMetadata(_metadata). - WithUser(_user). - Compile(test.pipeline) - if err != nil { - t.Errorf("unable to compile pipeline %s: %v", test.pipeline, err) - } - - _engine, err := New( - WithBuild(_build), - WithPipeline(_pipeline), - WithRepo(_repo), - WithRuntime(_runtime), - WithUser(_user), - WithVelaClient(_client), - ) - if err != nil { - t.Errorf("unable to create executor engine: %v", err) - } - - // run create to init steps to be created properly - err = _engine.CreateBuild(context.Background()) - if err != nil { - t.Errorf("unable to create build: %v", err) - } - - err = _engine.PlanBuild(context.Background()) - - if test.failure { - if err == nil { - t.Errorf("PlanBuild should have returned err") - } - - return // continue to next test - } - - if err != nil { - t.Errorf("PlanBuild returned err: %v", err) - } - }) - } -} - -func TestLinux_AssembleBuild(t *testing.T) { - // setup types - compiler, _ := native.New(cli.NewContext(nil, flag.NewFlagSet("test", 0), nil)) - - _build := testBuild() - _repo := testRepo() - _user := testUser() - _metadata := testMetadata() - - gin.SetMode(gin.TestMode) - - s := httptest.NewServer(server.FakeHandler()) - - _client, err := vela.NewClient(s.URL, "", nil) - if err != nil { - t.Errorf("unable to create Vela API client: %v", err) - } - - _runtime, err := docker.NewMock() - if err != nil { - t.Errorf("unable to create runtime engine: %v", err) - } - - streamRequests, done := message.MockStreamRequestsWithCancel(context.Background()) - defer done() - - tests := []struct { - name string - failure bool - pipeline string - }{ - { - name: "basic secrets pipeline", - failure: false, - pipeline: "testdata/build/secrets/basic.yml", - }, - { - name: "secrets pipeline with image not found", - failure: true, - pipeline: "testdata/build/secrets/img_notfound.yml", - }, - { - name: "secrets pipeline with ignoring image not found", - failure: true, - pipeline: "testdata/build/secrets/img_ignorenotfound.yml", - }, - { - name: "basic services pipeline", - failure: false, - pipeline: "testdata/build/services/basic.yml", - }, - { - name: "services pipeline with image not found", - failure: true, - pipeline: "testdata/build/services/img_notfound.yml", - }, - { - name: "services pipeline with ignoring image not found", - failure: true, - pipeline: "testdata/build/services/img_ignorenotfound.yml", - }, - { - name: "basic steps pipeline", - failure: false, - pipeline: "testdata/build/steps/basic.yml", - }, - { - name: "steps pipeline with image not found", - failure: true, - pipeline: "testdata/build/steps/img_notfound.yml", - }, - { - name: "steps pipeline with ignoring image not found", - failure: true, - pipeline: "testdata/build/steps/img_ignorenotfound.yml", - }, - { - name: "basic stages pipeline", - failure: false, - pipeline: "testdata/build/stages/basic.yml", - }, - { - name: "stages pipeline with image not found", - failure: true, - pipeline: "testdata/build/stages/img_notfound.yml", - }, - { - name: "stages pipeline with ignoring image not found", - failure: true, - pipeline: "testdata/build/stages/img_ignorenotfound.yml", - }, - } - - // run test - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - _pipeline, _, err := compiler. - Duplicate(). - WithBuild(_build). - WithRepo(_repo). - WithMetadata(_metadata). - WithUser(_user). - Compile(test.pipeline) - if err != nil { - t.Errorf("unable to compile pipeline %s: %v", test.pipeline, err) - } - - _engine, err := New( - WithBuild(_build), - WithPipeline(_pipeline), - WithRepo(_repo), - WithRuntime(_runtime), - WithUser(_user), - WithVelaClient(_client), - withStreamRequests(streamRequests), - ) - if err != nil { - t.Errorf("unable to create executor engine: %v", err) - } - - // run create to init steps to be created properly - err = _engine.CreateBuild(context.Background()) - if err != nil { - t.Errorf("unable to create build: %v", err) - } - - err = _engine.AssembleBuild(context.Background()) - - if test.failure { - if err == nil { - t.Errorf("AssembleBuild should have returned err") - } - - return // continue to next test - } - - if err != nil { - t.Errorf("AssembleBuild returned err: %v", err) - } - }) - } -} - func TestLinux_AssembleBuild_EnforceTrustedRepos(t *testing.T) { // setup types compiler, _ := native.New(cli.NewContext(nil, flag.NewFlagSet("test", 0), nil)) @@ -882,6 +640,248 @@ func TestLinux_AssembleBuild_EnforceTrustedRepos(t *testing.T) { } } +func TestLinux_PlanBuild(t *testing.T) { + // setup types + compiler, _ := native.New(cli.NewContext(nil, flag.NewFlagSet("test", 0), nil)) + + _build := testBuild() + _repo := testRepo() + _user := testUser() + _metadata := testMetadata() + + gin.SetMode(gin.TestMode) + + s := httptest.NewServer(server.FakeHandler()) + + _client, err := vela.NewClient(s.URL, "", nil) + if err != nil { + t.Errorf("unable to create Vela API client: %v", err) + } + + _runtime, err := docker.NewMock() + if err != nil { + t.Errorf("unable to create runtime engine: %v", err) + } + + tests := []struct { + name string + failure bool + pipeline string + }{ + { + name: "basic secrets pipeline", + failure: false, + pipeline: "testdata/build/secrets/basic.yml", + }, + { + name: "basic services pipeline", + failure: false, + pipeline: "testdata/build/services/basic.yml", + }, + { + name: "basic steps pipeline", + failure: false, + pipeline: "testdata/build/steps/basic.yml", + }, + { + name: "basic stages pipeline", + failure: false, + pipeline: "testdata/build/stages/basic.yml", + }, + } + + // run test + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + _pipeline, _, err := compiler. + Duplicate(). + WithBuild(_build). + WithRepo(_repo). + WithMetadata(_metadata). + WithUser(_user). + Compile(test.pipeline) + if err != nil { + t.Errorf("unable to compile pipeline %s: %v", test.pipeline, err) + } + + _engine, err := New( + WithBuild(_build), + WithPipeline(_pipeline), + WithRepo(_repo), + WithRuntime(_runtime), + WithUser(_user), + WithVelaClient(_client), + ) + if err != nil { + t.Errorf("unable to create executor engine: %v", err) + } + + // run create to init steps to be created properly + err = _engine.CreateBuild(context.Background()) + if err != nil { + t.Errorf("unable to create build: %v", err) + } + + err = _engine.PlanBuild(context.Background()) + + if test.failure { + if err == nil { + t.Errorf("PlanBuild should have returned err") + } + + return // continue to next test + } + + if err != nil { + t.Errorf("PlanBuild returned err: %v", err) + } + }) + } +} + +func TestLinux_AssembleBuild(t *testing.T) { + // setup types + compiler, _ := native.New(cli.NewContext(nil, flag.NewFlagSet("test", 0), nil)) + + _build := testBuild() + _repo := testRepo() + _user := testUser() + _metadata := testMetadata() + + gin.SetMode(gin.TestMode) + + s := httptest.NewServer(server.FakeHandler()) + + _client, err := vela.NewClient(s.URL, "", nil) + if err != nil { + t.Errorf("unable to create Vela API client: %v", err) + } + + _runtime, err := docker.NewMock() + if err != nil { + t.Errorf("unable to create runtime engine: %v", err) + } + + streamRequests, done := message.MockStreamRequestsWithCancel(context.Background()) + defer done() + + tests := []struct { + name string + failure bool + pipeline string + }{ + { + name: "basic secrets pipeline", + failure: false, + pipeline: "testdata/build/secrets/basic.yml", + }, + { + name: "secrets pipeline with image not found", + failure: true, + pipeline: "testdata/build/secrets/img_notfound.yml", + }, + { + name: "secrets pipeline with ignoring image not found", + failure: true, + pipeline: "testdata/build/secrets/img_ignorenotfound.yml", + }, + { + name: "basic services pipeline", + failure: false, + pipeline: "testdata/build/services/basic.yml", + }, + { + name: "services pipeline with image not found", + failure: true, + pipeline: "testdata/build/services/img_notfound.yml", + }, + { + name: "services pipeline with ignoring image not found", + failure: true, + pipeline: "testdata/build/services/img_ignorenotfound.yml", + }, + { + name: "basic steps pipeline", + failure: false, + pipeline: "testdata/build/steps/basic.yml", + }, + { + name: "steps pipeline with image not found", + failure: true, + pipeline: "testdata/build/steps/img_notfound.yml", + }, + { + name: "steps pipeline with ignoring image not found", + failure: true, + pipeline: "testdata/build/steps/img_ignorenotfound.yml", + }, + { + name: "basic stages pipeline", + failure: false, + pipeline: "testdata/build/stages/basic.yml", + }, + { + name: "stages pipeline with image not found", + failure: true, + pipeline: "testdata/build/stages/img_notfound.yml", + }, + { + name: "stages pipeline with ignoring image not found", + failure: true, + pipeline: "testdata/build/stages/img_ignorenotfound.yml", + }, + } + + // run test + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + _pipeline, _, err := compiler. + Duplicate(). + WithBuild(_build). + WithRepo(_repo). + WithMetadata(_metadata). + WithUser(_user). + Compile(test.pipeline) + if err != nil { + t.Errorf("unable to compile pipeline %s: %v", test.pipeline, err) + } + + _engine, err := New( + WithBuild(_build), + WithPipeline(_pipeline), + WithRepo(_repo), + WithRuntime(_runtime), + WithUser(_user), + WithVelaClient(_client), + withStreamRequests(streamRequests), + ) + if err != nil { + t.Errorf("unable to create executor engine: %v", err) + } + + // run create to init steps to be created properly + err = _engine.CreateBuild(context.Background()) + if err != nil { + t.Errorf("unable to create build: %v", err) + } + + err = _engine.AssembleBuild(context.Background()) + + if test.failure { + if err == nil { + t.Errorf("AssembleBuild should have returned err") + } + + return // continue to next test + } + + if err != nil { + t.Errorf("AssembleBuild returned err: %v", err) + } + }) + } +} + func TestLinux_ExecBuild(t *testing.T) { // setup types compiler, _ := native.New(cli.NewContext(nil, flag.NewFlagSet("test", 0), nil)) From be5839ba9b4e85980b012a75caaed156324b119b Mon Sep 17 00:00:00 2001 From: davidvader Date: Wed, 30 Nov 2022 08:56:33 -0600 Subject: [PATCH 11/19] fix: re-add test cases --- executor/linux/build_test.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/executor/linux/build_test.go b/executor/linux/build_test.go index 4ff8964a..c384fbba 100644 --- a/executor/linux/build_test.go +++ b/executor/linux/build_test.go @@ -399,6 +399,15 @@ func TestLinux_AssembleBuild_EnforceTrustedRepos(t *testing.T) { privilegedImages: _privilegedImagesStepsPipeline, // this matches the image from test.pipeline enforceTrustedRepos: true, }, + { + name: "enforce trusted repos enabled: privileged steps pipeline with untrusted repo and init step name", + failure: true, + build: _build, + repo: _untrustedRepo, + pipeline: "testdata/build/steps/name_init.yml", + privilegedImages: _privilegedImagesStepsPipeline, // this matches the image from test.pipeline + enforceTrustedRepos: true, + }, { name: "enforce trusted repos enabled: non-privileged steps pipeline with trusted repo and init step name", failure: false, @@ -408,6 +417,15 @@ func TestLinux_AssembleBuild_EnforceTrustedRepos(t *testing.T) { privilegedImages: _privilegedImagesStepsPipeline, // this matches the image from test.pipeline enforceTrustedRepos: true, }, + { + name: "enforce trusted repos enabled: non-privileged steps pipeline with untrusted repo and init step name", + failure: true, + build: _build, + repo: _untrustedRepo, + pipeline: "testdata/build/steps/name_init.yml", + privilegedImages: _privilegedImagesStepsPipeline, // this matches the image from test.pipeline + enforceTrustedRepos: true, + }, { name: "enforce trusted repos disabled: privileged steps pipeline with trusted repo and init step name", failure: false, From a62739260f2c2c69029fca8123becce6eb19d47d Mon Sep 17 00:00:00 2001 From: davidvader Date: Wed, 30 Nov 2022 09:05:28 -0600 Subject: [PATCH 12/19] chore: remove helper function --- executor/linux/build.go | 55 ++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/executor/linux/build.go b/executor/linux/build.go index 67404302..9ece725c 100644 --- a/executor/linux/build.go +++ b/executor/linux/build.go @@ -383,11 +383,35 @@ func (c *client) AssembleBuild(ctx context.Context) error { _log.AppendData([]byte(fmt.Sprintf("Verifying privileges for image %s...\n", container.Image))) // check image privileged permissions - err = c.verifyPrivileged(container.Image) - if err != nil { - c.err = err - _log.AppendData([]byte(fmt.Sprintf("ERROR: %s\n", err.Error()))) - return fmt.Errorf("unable to verify privilege for image %s: %w", container.Name, err) + privileged := false + var err error = nil + for _, pattern := range c.privilegedImages { + privileged, err = image.IsPrivilegedImage(container.Image, pattern) + if err != nil { + // wrap and return error + c.err = fmt.Errorf("unable to verify privileges for image %s", err.Error()) + + // update the init log with image info + // + // https://pkg.go.dev/github.com/go-vela/types/library?tab=doc#Log.AppendData + _log.AppendData([]byte(fmt.Sprintf("ERROR: %s\n", c.err.Error()))) + + // return error and destroy the build + return c.err + } + } + + // ensure privileged images are only permitted by trusted repos + if (privileged) && !(c.repo != nil && c.repo.GetTrusted()) { + c.err = fmt.Errorf("unable to verify image %s. image is privileged and repo is not trusted", container.Image) + + // update the init log with image info + // + // https://pkg.go.dev/github.com/go-vela/types/library?tab=doc#Log.AppendData + _log.AppendData([]byte(fmt.Sprintf("ERROR: %s\n", c.err.Error()))) + + // return error and destroy the build + return c.err } // update the init log with image info @@ -433,27 +457,6 @@ func (c *client) AssembleBuild(ctx context.Context) error { return c.err } -// enforce repo.trusted is set for pipelines containing privileged images -// this configuration is set as an executor flag -func (c *client) verifyPrivileged(img string) error { - // prevent ghosting - privileged := false - var err error = nil - for _, pattern := range c.privilegedImages { - privileged, err = image.IsPrivilegedImage(img, pattern) - if err != nil { - // wrap and return error - return fmt.Errorf("unable to verify privileges for image %s", err.Error()) - } - } - - if (privileged) && !(c.repo != nil && c.repo.GetTrusted()) { - return fmt.Errorf("unable to verify image %s. image is privileged and repo is not trusted", img) - } - - return nil -} - // ExecBuild runs a pipeline for a build. func (c *client) ExecBuild(ctx context.Context) error { // defer an upload of the build From 0aac9476ff696468bed3a8b67c176d05bfa94e32 Mon Sep 17 00:00:00 2001 From: davidvader Date: Wed, 30 Nov 2022 09:15:20 -0600 Subject: [PATCH 13/19] chore: clean up iteration --- executor/linux/build.go | 52 ++++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/executor/linux/build.go b/executor/linux/build.go index 9ece725c..5753ec3a 100644 --- a/executor/linux/build.go +++ b/executor/linux/build.go @@ -350,8 +350,8 @@ func (c *client) AssembleBuild(ctx context.Context) error { _log.AppendData(image) } - // if not enforced, allow all - // this still does not impact the list of runtime privileged images + // if not enforced, allow all that exist in the list of runtime privileged images + // this configuration is set as an executor flag if c.enforceTrustedRepos { // group steps services stages and secret origins together containers := c.pipeline.Steps @@ -363,7 +363,11 @@ func (c *client) AssembleBuild(ctx context.Context) error { containers = append(containers, secret.Origin) } - // verify the image privileges for all pipeline containers + // check if pipeline steps contain privileged images + // assume no privileged images are in use + containsPrivilegedImages := false + + // verify all pipeline containers for _, container := range containers { // TODO: remove hardcoded reference if container.Image == "#init" { @@ -382,14 +386,12 @@ func (c *client) AssembleBuild(ctx context.Context) error { // https://pkg.go.dev/github.com/go-vela/types/library?tab=doc#Log.AppendData _log.AppendData([]byte(fmt.Sprintf("Verifying privileges for image %s...\n", container.Image))) - // check image privileged permissions - privileged := false - var err error = nil for _, pattern := range c.privilegedImages { - privileged, err = image.IsPrivilegedImage(container.Image, pattern) + // check privilege + privileged, err := image.IsPrivilegedImage(container.Image, pattern) if err != nil { - // wrap and return error - c.err = fmt.Errorf("unable to verify privileges for image %s", err.Error()) + // wrap the error + c.err = fmt.Errorf("unable to verify privileges for image %s: %s", container.Image, err.Error()) // update the init log with image info // @@ -397,21 +399,14 @@ func (c *client) AssembleBuild(ctx context.Context) error { _log.AppendData([]byte(fmt.Sprintf("ERROR: %s\n", c.err.Error()))) // return error and destroy the build + // ignore checking more images return c.err } - } - // ensure privileged images are only permitted by trusted repos - if (privileged) && !(c.repo != nil && c.repo.GetTrusted()) { - c.err = fmt.Errorf("unable to verify image %s. image is privileged and repo is not trusted", container.Image) - - // update the init log with image info - // - // https://pkg.go.dev/github.com/go-vela/types/library?tab=doc#Log.AppendData - _log.AppendData([]byte(fmt.Sprintf("ERROR: %s\n", c.err.Error()))) - - // return error and destroy the build - return c.err + // we only care about privileged images + if privileged { + containsPrivilegedImages = privileged + } } // update the init log with image info @@ -419,6 +414,21 @@ func (c *client) AssembleBuild(ctx context.Context) error { // https://pkg.go.dev/github.com/go-vela/types/library?tab=doc#Log.AppendData _log.AppendData([]byte(fmt.Sprintf("Privileges verified for image %s\n", container.Image))) } + + // ensure privileged images are only permitted by trusted repos + if (containsPrivilegedImages) && !(c.repo != nil && c.repo.GetTrusted()) { + // update error + c.err = fmt.Errorf("unable to assemble build. pipeline contains privileged images and repo is not trusted") + + // update the init log with image info + // + // https://pkg.go.dev/github.com/go-vela/types/library?tab=doc#Log.AppendData + _log.AppendData([]byte(fmt.Sprintf("ERROR: %s\n", c.err.Error()))) + + // return error and destroy the build + // ignore checking more images + return c.err + } } // inspect the runtime build (eg a kubernetes pod) for the pipeline From 209fd1dd36d1a889973d547820b67865f85be272 Mon Sep 17 00:00:00 2001 From: davidvader Date: Wed, 30 Nov 2022 09:23:20 -0600 Subject: [PATCH 14/19] chore: clean up comments --- executor/linux/build.go | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/executor/linux/build.go b/executor/linux/build.go index 5753ec3a..38e47856 100644 --- a/executor/linux/build.go +++ b/executor/linux/build.go @@ -349,7 +349,7 @@ func (c *client) AssembleBuild(ctx context.Context) error { // https://pkg.go.dev/github.com/go-vela/types/library?tab=doc#Log.AppendData _log.AppendData(image) } - + // enforce repo.trusted is set for pipelines containing privileged images // if not enforced, allow all that exist in the list of runtime privileged images // this configuration is set as an executor flag if c.enforceTrustedRepos { @@ -363,7 +363,6 @@ func (c *client) AssembleBuild(ctx context.Context) error { containers = append(containers, secret.Origin) } - // check if pipeline steps contain privileged images // assume no privileged images are in use containsPrivilegedImages := false @@ -387,7 +386,7 @@ func (c *client) AssembleBuild(ctx context.Context) error { _log.AppendData([]byte(fmt.Sprintf("Verifying privileges for image %s...\n", container.Image))) for _, pattern := range c.privilegedImages { - // check privilege + // check if image matches privileged pattern privileged, err := image.IsPrivilegedImage(container.Image, pattern) if err != nil { // wrap the error @@ -403,8 +402,8 @@ func (c *client) AssembleBuild(ctx context.Context) error { return c.err } - // we only care about privileged images if privileged { + // pipeline contains at least one privileged image containsPrivilegedImages = privileged } } @@ -415,7 +414,7 @@ func (c *client) AssembleBuild(ctx context.Context) error { _log.AppendData([]byte(fmt.Sprintf("Privileges verified for image %s\n", container.Image))) } - // ensure privileged images are only permitted by trusted repos + // ensure pipelines containing privileged images are only permitted to run by trusted repos if (containsPrivilegedImages) && !(c.repo != nil && c.repo.GetTrusted()) { // update error c.err = fmt.Errorf("unable to assemble build. pipeline contains privileged images and repo is not trusted") @@ -426,7 +425,6 @@ func (c *client) AssembleBuild(ctx context.Context) error { _log.AppendData([]byte(fmt.Sprintf("ERROR: %s\n", c.err.Error()))) // return error and destroy the build - // ignore checking more images return c.err } } From 3ffd0607101935c01f49b32f849754fa828f087c Mon Sep 17 00:00:00 2001 From: davidvader Date: Wed, 30 Nov 2022 09:24:55 -0600 Subject: [PATCH 15/19] chore: lint --- executor/linux/build.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/executor/linux/build.go b/executor/linux/build.go index 38e47856..1648dc9e 100644 --- a/executor/linux/build.go +++ b/executor/linux/build.go @@ -355,10 +355,13 @@ func (c *client) AssembleBuild(ctx context.Context) error { if c.enforceTrustedRepos { // group steps services stages and secret origins together containers := c.pipeline.Steps + containers = append(containers, c.pipeline.Services...) + for _, stage := range c.pipeline.Stages { containers = append(containers, stage.Steps...) } + for _, secret := range c.pipeline.Secrets { containers = append(containers, secret.Origin) } @@ -390,7 +393,7 @@ func (c *client) AssembleBuild(ctx context.Context) error { privileged, err := image.IsPrivilegedImage(container.Image, pattern) if err != nil { // wrap the error - c.err = fmt.Errorf("unable to verify privileges for image %s: %s", container.Image, err.Error()) + c.err = fmt.Errorf("unable to verify privileges for image %s: %w", container.Image, err) // update the init log with image info // From 72eb2f4fce6c58e5f412e19aed5c446068240773 Mon Sep 17 00:00:00 2001 From: davidvader Date: Wed, 30 Nov 2022 09:26:07 -0600 Subject: [PATCH 16/19] chore: lint gocyclo --- executor/linux/build.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/executor/linux/build.go b/executor/linux/build.go index 1648dc9e..2758d193 100644 --- a/executor/linux/build.go +++ b/executor/linux/build.go @@ -192,7 +192,7 @@ func (c *client) PlanBuild(ctx context.Context) error { // AssembleBuild prepares the containers within a build for execution. // -//nolint:funlen // ignore function length due to comments and logging messages +//nolint:gocyclo,funlen // ignore cyclomatic complexity and function length due to comments and logging messages func (c *client) AssembleBuild(ctx context.Context) error { // defer taking a snapshot of the build // From 27483abeed76a78366258c4bbc59220d9f323c31 Mon Sep 17 00:00:00 2001 From: davidvader Date: Fri, 9 Dec 2022 15:53:56 -0600 Subject: [PATCH 17/19] fix: include dynamic image tag tests --- executor/linux/build_test.go | 234 +++++++++++++++++- .../build/services/img_environmentdynamic.yml | 22 ++ .../build/stages/img_environmentdynamic.yml | 17 ++ .../build/steps/img_environmentdynamic.yml | 15 ++ 4 files changed, 285 insertions(+), 3 deletions(-) create mode 100644 executor/linux/testdata/build/services/img_environmentdynamic.yml create mode 100644 executor/linux/testdata/build/stages/img_environmentdynamic.yml create mode 100644 executor/linux/testdata/build/steps/img_environmentdynamic.yml diff --git a/executor/linux/build_test.go b/executor/linux/build_test.go index c384fbba..3eaf5952 100644 --- a/executor/linux/build_test.go +++ b/executor/linux/build_test.go @@ -135,6 +135,11 @@ func TestLinux_AssembleBuild_EnforceTrustedRepos(t *testing.T) { compiler, _ := native.New(cli.NewContext(nil, flag.NewFlagSet("test", 0), nil)) _build := testBuild() + + // setting mock build for testing dynamic environment tags + _buildWithMessageAlpine := testBuild() + _buildWithMessageAlpine.SetMessage("alpine") + // test repo is not trusted by default _untrustedRepo := testRepo() _user := testUser() @@ -145,7 +150,6 @@ func TestLinux_AssembleBuild_EnforceTrustedRepos(t *testing.T) { _privilegedImagesServicesPipeline := []string{"postgres"} // to be matched with the image used by testdata/build/stages/basic.yml _privilegedImagesStagesPipeline := []string{"alpine"} - // create trusted repo _trustedRepo := testRepo() _trustedRepo.SetTrusted(true) @@ -163,7 +167,6 @@ func TestLinux_AssembleBuild_EnforceTrustedRepos(t *testing.T) { if err != nil { t.Errorf("unable to create runtime engine: %v", err) } - tests := []struct { name string failure bool @@ -245,7 +248,78 @@ func TestLinux_AssembleBuild_EnforceTrustedRepos(t *testing.T) { privilegedImages: []string{}, // this matches the image from test.pipeline enforceTrustedRepos: false, }, - + { + name: "enforce trusted repos enabled: privileged steps pipeline with trusted repo and dynamic image:tag", + failure: false, + build: _buildWithMessageAlpine, + repo: _trustedRepo, + pipeline: "testdata/build/steps/img_environmentdynamic.yml", + privilegedImages: _privilegedImagesStepsPipeline, // this matches the image from test.pipeline + enforceTrustedRepos: true, + }, + { + name: "enforce trusted repos enabled: privileged steps pipeline with untrusted repo and dynamic image:tag", + failure: true, + build: _buildWithMessageAlpine, + repo: _untrustedRepo, + pipeline: "testdata/build/steps/img_environmentdynamic.yml", + privilegedImages: _privilegedImagesStepsPipeline, // this matches the image from test.pipeline + enforceTrustedRepos: true, + }, + { + name: "enforce trusted repos enabled: non-privileged steps pipeline with trusted repo and dynamic image:tag", + failure: false, + build: _buildWithMessageAlpine, + repo: _trustedRepo, + pipeline: "testdata/build/steps/img_environmentdynamic.yml", + privilegedImages: []string{}, // this matches the image from test.pipeline + enforceTrustedRepos: true, + }, + { + name: "enforce trusted repos enabled: non-privileged steps pipeline with untrusted repo and dynamic image:tag", + failure: false, + build: _buildWithMessageAlpine, + repo: _untrustedRepo, + pipeline: "testdata/build/steps/img_environmentdynamic.yml", + privilegedImages: []string{}, // this matches the image from test.pipeline + enforceTrustedRepos: true, + }, + { + name: "enforce trusted repos disabled: privileged steps pipeline with trusted repo and dynamic image:tag", + failure: false, + build: _buildWithMessageAlpine, + repo: _trustedRepo, + pipeline: "testdata/build/steps/img_environmentdynamic.yml", + privilegedImages: _privilegedImagesStepsPipeline, // this matches the image from test.pipeline + enforceTrustedRepos: false, + }, + { + name: "enforce trusted repos disabled: privileged steps pipeline with untrusted repo and dynamic image:tag", + failure: false, + build: _buildWithMessageAlpine, + repo: _untrustedRepo, + pipeline: "testdata/build/steps/img_environmentdynamic.yml", + privilegedImages: _privilegedImagesStepsPipeline, // this matches the image from test.pipeline + enforceTrustedRepos: false, + }, + { + name: "enforce trusted repos disabled: non-privileged steps pipeline with trusted repo and dynamic image:tag", + failure: false, + build: _buildWithMessageAlpine, + repo: _trustedRepo, + pipeline: "testdata/build/steps/img_environmentdynamic.yml", + privilegedImages: []string{}, // this matches the image from test.pipeline + enforceTrustedRepos: false, + }, + { + name: "enforce trusted repos disabled: non-privileged steps pipeline with untrusted repo and dynamic image:tag", + failure: false, + build: _buildWithMessageAlpine, + repo: _untrustedRepo, + pipeline: "testdata/build/steps/img_environmentdynamic.yml", + privilegedImages: []string{}, // this matches the image from test.pipeline + enforceTrustedRepos: false, + }, { name: "enforce trusted repos enabled: privileged services pipeline with trusted repo", failure: false, @@ -318,6 +392,78 @@ func TestLinux_AssembleBuild_EnforceTrustedRepos(t *testing.T) { privilegedImages: []string{}, // this matches the image from test.pipeline enforceTrustedRepos: false, }, + { + name: "enforce trusted repos enabled: privileged services pipeline with trusted repo and dynamic image:tag", + failure: false, + build: _buildWithMessageAlpine, + repo: _trustedRepo, + pipeline: "testdata/build/services/img_environmentdynamic.yml", + privilegedImages: _privilegedImagesServicesPipeline, // this matches the image from test.pipeline + enforceTrustedRepos: true, + }, + { + name: "enforce trusted repos enabled: privileged services pipeline with untrusted repo and dynamic image:tag", + failure: true, + build: _buildWithMessageAlpine, + repo: _untrustedRepo, + pipeline: "testdata/build/services/img_environmentdynamic.yml", + privilegedImages: _privilegedImagesServicesPipeline, // this matches the image from test.pipeline + enforceTrustedRepos: true, + }, + { + name: "enforce trusted repos enabled: non-privileged services pipeline with trusted repo and dynamic image:tag", + failure: false, + build: _buildWithMessageAlpine, + repo: _trustedRepo, + pipeline: "testdata/build/services/img_environmentdynamic.yml", + privilegedImages: []string{}, // this matches the image from test.pipeline + enforceTrustedRepos: true, + }, + { + name: "enforce trusted repos enabled: non-privileged services pipeline with untrusted repo and dynamic image:tag", + failure: false, + build: _buildWithMessageAlpine, + repo: _untrustedRepo, + pipeline: "testdata/build/services/img_environmentdynamic.yml", + privilegedImages: []string{}, // this matches the image from test.pipeline + enforceTrustedRepos: true, + }, + { + name: "enforce trusted repos disabled: privileged services pipeline with trusted repo and dynamic image:tag", + failure: false, + build: _buildWithMessageAlpine, + repo: _trustedRepo, + pipeline: "testdata/build/services/img_environmentdynamic.yml", + privilegedImages: _privilegedImagesServicesPipeline, // this matches the image from test.pipeline + enforceTrustedRepos: false, + }, + { + name: "enforce trusted repos disabled: privileged services pipeline with untrusted repo and dynamic image:tag", + failure: false, + build: _buildWithMessageAlpine, + repo: _untrustedRepo, + pipeline: "testdata/build/services/img_environmentdynamic.yml", + privilegedImages: _privilegedImagesServicesPipeline, // this matches the image from test.pipeline + enforceTrustedRepos: false, + }, + { + name: "enforce trusted repos disabled: non-privileged services pipeline with trusted repo and dynamic image:tag", + failure: false, + build: _buildWithMessageAlpine, + repo: _trustedRepo, + pipeline: "testdata/build/services/img_environmentdynamic.yml", + privilegedImages: []string{}, // this matches the image from test.pipeline + enforceTrustedRepos: false, + }, + { + name: "enforce trusted repos disabled: non-privileged services pipeline with untrusted repo and dynamic image:tag", + failure: false, + build: _buildWithMessageAlpine, + repo: _untrustedRepo, + pipeline: "testdata/build/services/img_environmentdynamic.yml", + privilegedImages: []string{}, // this matches the image from test.pipeline + enforceTrustedRepos: false, + }, { name: "enforce trusted repos enabled: privileged stages pipeline with trusted repo", failure: false, @@ -390,6 +536,78 @@ func TestLinux_AssembleBuild_EnforceTrustedRepos(t *testing.T) { privilegedImages: []string{}, // this matches the image from test.pipeline enforceTrustedRepos: false, }, + { + name: "enforce trusted repos enabled: privileged stages pipeline with trusted repo and dynamic image:tag", + failure: false, + build: _buildWithMessageAlpine, + repo: _trustedRepo, + pipeline: "testdata/build/stages/img_environmentdynamic.yml", + privilegedImages: _privilegedImagesStagesPipeline, // this matches the image from test.pipeline + enforceTrustedRepos: true, + }, + { + name: "enforce trusted repos enabled: privileged stages pipeline with untrusted repo and dynamic image:tag", + failure: true, + build: _buildWithMessageAlpine, + repo: _untrustedRepo, + pipeline: "testdata/build/stages/img_environmentdynamic.yml", + privilegedImages: _privilegedImagesStagesPipeline, // this matches the image from test.pipeline + enforceTrustedRepos: true, + }, + { + name: "enforce trusted repos enabled: non-privileged stages pipeline with trusted repo and dynamic image:tag", + failure: false, + build: _buildWithMessageAlpine, + repo: _trustedRepo, + pipeline: "testdata/build/stages/img_environmentdynamic.yml", + privilegedImages: []string{}, // this matches the image from test.pipeline + enforceTrustedRepos: true, + }, + { + name: "enforce trusted repos enabled: non-privileged stages pipeline with untrusted repo and dynamic image:tag", + failure: false, + build: _buildWithMessageAlpine, + repo: _untrustedRepo, + pipeline: "testdata/build/stages/img_environmentdynamic.yml", + privilegedImages: []string{}, // this matches the image from test.pipeline + enforceTrustedRepos: true, + }, + { + name: "enforce trusted repos disabled: privileged stages pipeline with trusted repo and dynamic image:tag", + failure: false, + build: _buildWithMessageAlpine, + repo: _trustedRepo, + pipeline: "testdata/build/stages/img_environmentdynamic.yml", + privilegedImages: _privilegedImagesStagesPipeline, // this matches the image from test.pipeline + enforceTrustedRepos: false, + }, + { + name: "enforce trusted repos disabled: privileged stages pipeline with untrusted repo and dynamic image:tag", + failure: false, + build: _buildWithMessageAlpine, + repo: _untrustedRepo, + pipeline: "testdata/build/stages/img_environmentdynamic.yml", + privilegedImages: _privilegedImagesStagesPipeline, // this matches the image from test.pipeline + enforceTrustedRepos: false, + }, + { + name: "enforce trusted repos disabled: non-privileged stages pipeline with trusted repo and dynamic image:tag", + failure: false, + build: _buildWithMessageAlpine, + repo: _trustedRepo, + pipeline: "testdata/build/stages/img_environmentdynamic.yml", + privilegedImages: []string{}, // this matches the image from test.pipeline + enforceTrustedRepos: false, + }, + { + name: "enforce trusted repos disabled: non-privileged stages pipeline with untrusted repo and dynamic image:tag", + failure: false, + build: _buildWithMessageAlpine, + repo: _untrustedRepo, + pipeline: "testdata/build/stages/img_environmentdynamic.yml", + privilegedImages: []string{}, // this matches the image from test.pipeline + enforceTrustedRepos: false, + }, { name: "enforce trusted repos enabled: privileged steps pipeline with trusted repo and init step name", failure: false, @@ -641,6 +859,16 @@ func TestLinux_AssembleBuild_EnforceTrustedRepos(t *testing.T) { t.Errorf("CreateBuild returned err: %v", err) } + // run plan to init steps to be created properly + err = _engine.PlanBuild(context.Background()) + if err != nil { + t.Errorf("unable to create build: %v", err) + } + + // override mock handler PUT build update + // used for dynamic substitute testing + _engine.build.SetMessage(test.build.GetMessage()) + err = _engine.AssembleBuild(context.Background()) if test.failure { diff --git a/executor/linux/testdata/build/services/img_environmentdynamic.yml b/executor/linux/testdata/build/services/img_environmentdynamic.yml new file mode 100644 index 00000000..e9a4314a --- /dev/null +++ b/executor/linux/testdata/build/services/img_environmentdynamic.yml @@ -0,0 +1,22 @@ +--- +version: "1" + +environment: + DYNAMIC_IMAGE: "postgres" + DYNAMIC_TAG: "latest" + +services: + - name: test + environment: + FOO: bar + image: '${DYNAMIC_IMAGE}:${DYNAMIC_TAG}' + pull: on_start + +steps: + - name: test + commands: + - echo ${FOO} + environment: + FOO: bar + image: alpine:latest + pull: true \ No newline at end of file diff --git a/executor/linux/testdata/build/stages/img_environmentdynamic.yml b/executor/linux/testdata/build/stages/img_environmentdynamic.yml new file mode 100644 index 00000000..a6c0211d --- /dev/null +++ b/executor/linux/testdata/build/stages/img_environmentdynamic.yml @@ -0,0 +1,17 @@ +--- +version: "1" + +environment: + DYNAMIC_IMAGE: "${VELA_BUILD_MESSAGE}" + DYNAMIC_TAG: "${VELA_BUILD_NUMBER}" + +stages: + test: + steps: + - name: test + commands: + - echo ${FOO} + environment: + FOO: bar + image: '${DYNAMIC_IMAGE}:${DYNAMIC_TAG}' + pull: on_start diff --git a/executor/linux/testdata/build/steps/img_environmentdynamic.yml b/executor/linux/testdata/build/steps/img_environmentdynamic.yml new file mode 100644 index 00000000..250be02b --- /dev/null +++ b/executor/linux/testdata/build/steps/img_environmentdynamic.yml @@ -0,0 +1,15 @@ +--- +version: "1" + +environment: + DYNAMIC_IMAGE: "${VELA_BUILD_MESSAGE}" + DYNAMIC_TAG: "${VELA_BUILD_NUMBER}" + +steps: + - name: test + commands: + - echo ${FOO} + environment: + FOO: bar + image: '${DYNAMIC_IMAGE}:${DYNAMIC_TAG}' + pull: on_start From cdacfeae39ee402710b713950ef8e73dedce1922 Mon Sep 17 00:00:00 2001 From: davidvader Date: Fri, 9 Dec 2022 15:57:42 -0600 Subject: [PATCH 18/19] fix: test string format and remove planBuild --- executor/linux/build_test.go | 6 ------ .../testdata/build/services/img_environmentdynamic.yml | 2 +- .../linux/testdata/build/stages/img_environmentdynamic.yml | 2 +- .../linux/testdata/build/steps/img_environmentdynamic.yml | 2 +- 4 files changed, 3 insertions(+), 9 deletions(-) diff --git a/executor/linux/build_test.go b/executor/linux/build_test.go index 99623303..6b8501cf 100644 --- a/executor/linux/build_test.go +++ b/executor/linux/build_test.go @@ -859,12 +859,6 @@ func TestLinux_AssembleBuild_EnforceTrustedRepos(t *testing.T) { t.Errorf("CreateBuild returned err: %v", err) } - // run plan to init steps to be created properly - err = _engine.PlanBuild(context.Background()) - if err != nil { - t.Errorf("unable to create build: %v", err) - } - // override mock handler PUT build update // used for dynamic substitute testing _engine.build.SetMessage(test.build.GetMessage()) diff --git a/executor/linux/testdata/build/services/img_environmentdynamic.yml b/executor/linux/testdata/build/services/img_environmentdynamic.yml index e9a4314a..92cf36cb 100644 --- a/executor/linux/testdata/build/services/img_environmentdynamic.yml +++ b/executor/linux/testdata/build/services/img_environmentdynamic.yml @@ -9,7 +9,7 @@ services: - name: test environment: FOO: bar - image: '${DYNAMIC_IMAGE}:${DYNAMIC_TAG}' + image: "${DYNAMIC_IMAGE}:${DYNAMIC_TAG}" pull: on_start steps: diff --git a/executor/linux/testdata/build/stages/img_environmentdynamic.yml b/executor/linux/testdata/build/stages/img_environmentdynamic.yml index a6c0211d..6306a5f9 100644 --- a/executor/linux/testdata/build/stages/img_environmentdynamic.yml +++ b/executor/linux/testdata/build/stages/img_environmentdynamic.yml @@ -13,5 +13,5 @@ stages: - echo ${FOO} environment: FOO: bar - image: '${DYNAMIC_IMAGE}:${DYNAMIC_TAG}' + image: "${DYNAMIC_IMAGE}:${DYNAMIC_TAG}" pull: on_start diff --git a/executor/linux/testdata/build/steps/img_environmentdynamic.yml b/executor/linux/testdata/build/steps/img_environmentdynamic.yml index 250be02b..3d947ab5 100644 --- a/executor/linux/testdata/build/steps/img_environmentdynamic.yml +++ b/executor/linux/testdata/build/steps/img_environmentdynamic.yml @@ -11,5 +11,5 @@ steps: - echo ${FOO} environment: FOO: bar - image: '${DYNAMIC_IMAGE}:${DYNAMIC_TAG}' + image: "${DYNAMIC_IMAGE}:${DYNAMIC_TAG}" pull: on_start From 2f23a42a9e312fdae80e2d3627ae8851405ad3f1 Mon Sep 17 00:00:00 2001 From: davidvader Date: Tue, 13 Dec 2022 09:13:55 -0600 Subject: [PATCH 19/19] fix: lint error, cuddled statement --- executor/linux/build_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/executor/linux/build_test.go b/executor/linux/build_test.go index 6b8501cf..ade7766d 100644 --- a/executor/linux/build_test.go +++ b/executor/linux/build_test.go @@ -167,6 +167,7 @@ func TestLinux_AssembleBuild_EnforceTrustedRepos(t *testing.T) { if err != nil { t.Errorf("unable to create runtime engine: %v", err) } + tests := []struct { name string failure bool