Skip to content

Commit

Permalink
Merge pull request #1864 from dgageot/fix-1851
Browse files Browse the repository at this point in the history
Verify patches and fail with a proper error message
  • Loading branch information
dgageot authored Mar 22, 2019
2 parents 29f1b8e + c7c1f10 commit 8e853c4
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 2 deletions.
24 changes: 22 additions & 2 deletions pkg/skaffold/schema/profiles.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,12 +156,18 @@ func applyProfile(config *latest.SkaffoldPipeline, profile latest.Profile) error
op = "replace"
}

patches = append(patches, yamlpatch.Operation{
patch := yamlpatch.Operation{
Op: yamlpatch.Op(op),
Path: yamlpatch.OpPath(patch.Path),
From: yamlpatch.OpPath(patch.From),
Value: patch.Value,
})
}

if !tryPatch(patch, buf) {
return fmt.Errorf("invalid path: %s", patch.Path)
}

patches = append(patches, patch)
}

buf, err = yamlpatch.Patch(patches).Apply(buf)
Expand All @@ -172,6 +178,20 @@ func applyProfile(config *latest.SkaffoldPipeline, profile latest.Profile) error
return yaml.Unmarshal(buf, config)
}

// tryPatch is here to verify patches one by one before we
// apply them because yamlpatch.Patch is known to panic when a path
// is not valid.
func tryPatch(patch yamlpatch.Operation, buf []byte) (valid bool) {
defer func() {
if errPanic := recover(); errPanic != nil {
valid = false
}
}()

_, err := yamlpatch.Patch([]yamlpatch.Operation{patch}).Apply(buf)
return err == nil
}

func profilesByName(profiles []latest.Profile) map[string]latest.Profile {
byName := make(map[string]latest.Profile)
for _, profile := range profiles {
Expand Down
28 changes: 28 additions & 0 deletions pkg/skaffold/schema/profiles_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,34 @@ profiles:
testutil.CheckDeepEqual(t, "Dockerfile.second", pipeline.Build.Artifacts[1].DockerArtifact.DockerfilePath)
}

func TestApplyInvalidPatch(t *testing.T) {
config := `build:
artifacts:
- image: example
profiles:
- name: patches
patches:
- path: /build/artifacts/0/image/
value: replacement
`

tmp, cleanup := testutil.NewTempDir(t)
defer cleanup()

yaml := fmt.Sprintf("apiVersion: %s\nkind: Config\n%s", latest.Version, config)
tmp.Write("skaffold.yaml", yaml)

parsed, err := ParseConfig(tmp.Path("skaffold.yaml"), false)
testutil.CheckError(t, false, err)

pipeline := parsed.(*latest.SkaffoldPipeline)
err = ApplyProfiles(pipeline, &cfg.SkaffoldOptions{
Profiles: []string{"patches"},
})

testutil.CheckErrorAndDeepEqual(t, true, err, "appying profile patches: invalid path: /build/artifacts/0/image/", err.Error())
}

func TestApplyProfiles(t *testing.T) {
tests := []struct {
description string
Expand Down

0 comments on commit 8e853c4

Please sign in to comment.