Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 30 additions & 18 deletions diff/diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,23 @@ func Manifests(oldIndex, newIndex map[string]*manifest.MappingResult, options *O
}

func ManifestsOwnership(oldIndex, newIndex map[string]*manifest.MappingResult, newOwnedReleases map[string]OwnershipDiff, options *Options, to io.Writer) bool {
seenAnyChanges, report, err := generateReport(oldIndex, newIndex, newOwnedReleases, options)
if err != nil {
panic(err)
}

report.print(to)
report.clean()
return seenAnyChanges
}

func ManifestReport(oldIndex, newIndex map[string]*manifest.MappingResult, options *Options) (*Report, error) {
_, report, err := generateReport(oldIndex, newIndex, nil, options)

return report, err
}

func generateReport(oldIndex, newIndex map[string]*manifest.MappingResult, newOwnedReleases map[string]OwnershipDiff, options *Options) (bool, *Report, error) {
report := Report{}
report.setupReportFormat(options.OutputFormat)
var possiblyRemoved []string
Expand Down Expand Up @@ -83,26 +100,21 @@ func ManifestsOwnership(oldIndex, newIndex map[string]*manifest.MappingResult, n
doDiff(&report, key, nil, newContent, options)
}

seenAnyChanges := len(report.entries) > 0
seenAnyChanges := len(report.Entries) > 0

report, err := doSuppress(report, options.SuppressedOutputLineRegex)
if err != nil {
panic(err)
}

report.print(to)
report.clean()
return seenAnyChanges
return seenAnyChanges, &report, err
}

func doSuppress(report Report, suppressedOutputLineRegex []string) (Report, error) {
if len(report.entries) == 0 || len(suppressedOutputLineRegex) == 0 {
if len(report.Entries) == 0 || len(suppressedOutputLineRegex) == 0 {
return report, nil
}

filteredReport := Report{}
filteredReport.format = report.format
filteredReport.entries = []ReportEntry{}
filteredReport.Entries = []ReportEntry{}

var suppressOutputRegexes []*regexp.Regexp

Expand All @@ -115,11 +127,11 @@ func doSuppress(report Report, suppressedOutputLineRegex []string) (Report, erro
suppressOutputRegexes = append(suppressOutputRegexes, regex)
}

for _, entry := range report.entries {
for _, entry := range report.Entries {
var diffs []difflib.DiffRecord

DIFFS:
for _, diff := range entry.diffs {
for _, diff := range entry.Diffs {
for _, suppressOutputRegex := range suppressOutputRegexes {
if suppressOutputRegex.MatchString(diff.Payload) {
continue DIFFS
Expand All @@ -143,11 +155,11 @@ func doSuppress(report Report, suppressedOutputLineRegex []string) (Report, erro
switch {
case containsDiff:
diffRecords = diffs
case entry.changeType == "MODIFY":
entry.changeType = "MODIFY_SUPPRESSED"
case entry.ChangeType == "MODIFY":
entry.ChangeType = "MODIFY_SUPPRESSED"
}

filteredReport.addEntry(entry.key, entry.suppressedKinds, entry.kind, entry.context, diffRecords, entry.changeType)
filteredReport.addEntry(entry.Key, entry.SuppressedKinds, entry.Kind, entry.Context, diffRecords, entry.ChangeType)
}

return filteredReport, nil
Expand Down Expand Up @@ -247,9 +259,9 @@ func preHandleSecrets(old, new *manifest.MappingResult) (v1.Secret, v1.Secret, e
if oldSecretDecodeErr != nil {
old.Content = fmt.Sprintf("Error parsing old secret: %s", oldSecretDecodeErr)
} else {
//if we have a Secret containing `stringData`, apply the same
//transformation that the apiserver would do with it (this protects
//stringData keys from being overwritten down below)
// if we have a Secret containing `stringData`, apply the same
// transformation that the apiserver would do with it (this protects
// stringData keys from being overwritten down below)
if len(oldSecret.StringData) > 0 && oldSecret.Data == nil {
oldSecret.Data = make(map[string][]byte, len(oldSecret.StringData))
}
Expand All @@ -263,7 +275,7 @@ func preHandleSecrets(old, new *manifest.MappingResult) (v1.Secret, v1.Secret, e
if newSecretDecodeErr != nil {
new.Content = fmt.Sprintf("Error parsing new secret: %s", newSecretDecodeErr)
} else {
//same as above
// same as above
if len(newSecret.StringData) > 0 && newSecret.Data == nil {
newSecret.Data = make(map[string][]byte, len(newSecret.StringData))
}
Expand Down
81 changes: 44 additions & 37 deletions diff/diff_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,6 @@ func TestManifests(t *testing.T) {

specBeta := map[string]*manifest.MappingResult{
"default, nginx, Deployment (apps)": {

Name: "default, nginx, Deployment (apps)",
Kind: "Deployment",
Content: `
Expand All @@ -181,11 +180,11 @@ kind: Deployment
metadata:
name: nginx
`,
}}
},
}

specRelease := map[string]*manifest.MappingResult{
"default, nginx, Deployment (apps)": {

Name: "default, nginx, Deployment (apps)",
Kind: "Deployment",
Content: `
Expand All @@ -194,11 +193,11 @@ kind: Deployment
metadata:
name: nginx
`,
}}
},
}

specReleaseSpec := map[string]*manifest.MappingResult{
"default, nginx, Deployment (apps)": {

Name: "default, nginx, Deployment (apps)",
Kind: "Deployment",
Content: `
Expand All @@ -209,11 +208,11 @@ metadata:
spec:
replicas: 3
`,
}}
},
}

specReleaseRenamed := map[string]*manifest.MappingResult{
"default, nginx-renamed, Deployment (apps)": {

Name: "default, nginx-renamed, Deployment (apps)",
Kind: "Deployment",
Content: `
Expand All @@ -224,11 +223,11 @@ metadata:
spec:
replicas: 3
`,
}}
},
}

specReleaseRenamedAndUpdated := map[string]*manifest.MappingResult{
"default, nginx-renamed, Deployment (apps)": {

Name: "default, nginx-renamed, Deployment (apps)",
Kind: "Deployment",
Content: `
Expand All @@ -239,11 +238,11 @@ metadata:
spec:
replicas: 1
`,
}}
},
}

specReleaseRenamedAndAdded := map[string]*manifest.MappingResult{
"default, nginx-renamed, Deployment (apps)": {

Name: "default, nginx-renamed, Deployment (apps)",
Kind: "Deployment",
Content: `
Expand All @@ -257,11 +256,11 @@ spec:
matchLabels:
app: nginx-renamed
`,
}}
},
}

specReleaseKeep := map[string]*manifest.MappingResult{
"default, nginx, Deployment (apps)": {

Name: "default, nginx, Deployment (apps)",
Kind: "Deployment",
Content: `
Expand All @@ -273,7 +272,8 @@ annotations:
helm.sh/resource-policy: keep
`,
ResourcePolicy: "keep",
}}
},
}

t.Run("OnChange", func(t *testing.T) {
var buf1 bytes.Buffer
Expand Down Expand Up @@ -603,7 +603,8 @@ data:
key2: dmFsdWUy
key3: dmFsdWUz
`,
}}
},
}

specSecretWithByteDataChanged := map[string]*manifest.MappingResult{
"default, foobar, Secret (v1)": {
Expand All @@ -620,7 +621,8 @@ data:
key2: dmFsdWUy
key4: dmFsdWU0
`,
}}
},
}

specSecretWithStringData := map[string]*manifest.MappingResult{
"default, foobar, Secret (v1)": {
Expand All @@ -637,7 +639,8 @@ stringData:
key2: value2
key3: value3
`,
}}
},
}

specSecretWithStringDataChanged := map[string]*manifest.MappingResult{
"default, foobar, Secret (v1)": {
Expand All @@ -654,17 +657,18 @@ stringData:
key2: value2
key4: value4
`,
}}
},
}

t.Run("OnChangeSecretWithByteData", func(t *testing.T) {
var buf1 bytes.Buffer
diffOptions := Options{"diff", 10, false, false, false, []string{}, 0.5, []string{}} //NOTE: ShowSecrets = false
diffOptions := Options{"diff", 10, false, false, false, []string{}, 0.5, []string{}} // NOTE: ShowSecrets = false

if changesSeen := Manifests(specSecretWithByteData, specSecretWithByteDataChanged, &diffOptions, &buf1); !changesSeen {
t.Error("Unexpected return value from Manifests: Expected the return value to be `true` to indicate that it has seen any change(s), but was `false`")
}

//TODO: Why is there no empty line between the header and the start of the diff, like in the other diffs?
// TODO: Why is there no empty line between the header and the start of the diff, like in the other diffs?
require.Equal(t, `default, foobar, Secret (v1) has changed:
apiVersion: v1
kind: Secret
Expand All @@ -683,7 +687,7 @@ stringData:

t.Run("OnChangeSecretWithStringData", func(t *testing.T) {
var buf1 bytes.Buffer
diffOptions := Options{"diff", 10, false, false, false, []string{}, 0.5, []string{}} //NOTE: ShowSecrets = false
diffOptions := Options{"diff", 10, false, false, false, []string{}, 0.5, []string{}} // NOTE: ShowSecrets = false

if changesSeen := Manifests(specSecretWithStringData, specSecretWithStringDataChanged, &diffOptions, &buf1); !changesSeen {
t.Error("Unexpected return value from Manifests: Expected the return value to be `true` to indicate that it has seen any change(s), but was `false`")
Expand Down Expand Up @@ -722,53 +726,53 @@ func TestDoSuppress(t *testing.T) {
{
name: "simple",
input: Report{
entries: []ReportEntry{
Entries: []ReportEntry{
{
diffs: diffStrings("hello: world", "hello: world2", false),
Diffs: diffStrings("hello: world", "hello: world2", false),
},
},
},
supressRegex: []string{},
expected: Report{
entries: []ReportEntry{
Entries: []ReportEntry{
{
diffs: diffStrings("hello: world", "hello: world2", false),
Diffs: diffStrings("hello: world", "hello: world2", false),
},
},
},
},
{
name: "ignore all",
input: Report{
entries: []ReportEntry{
Entries: []ReportEntry{
{
diffs: diffStrings("hello: world", "hello: world2", false),
Diffs: diffStrings("hello: world", "hello: world2", false),
},
},
},
supressRegex: []string{".*world2?"},
expected: Report{
entries: []ReportEntry{
Entries: []ReportEntry{
{
diffs: []difflib.DiffRecord{},
Diffs: []difflib.DiffRecord{},
},
},
},
},
{
name: "ignore partial",
input: Report{
entries: []ReportEntry{
Entries: []ReportEntry{
{
diffs: diffStrings("hello: world", "hello: world2", false),
Diffs: diffStrings("hello: world", "hello: world2", false),
},
},
},
supressRegex: []string{".*world2"},
expected: Report{
entries: []ReportEntry{
Entries: []ReportEntry{
{
diffs: []difflib.DiffRecord{
Diffs: []difflib.DiffRecord{
{
Payload: "hello: world",
Delta: difflib.LeftOnly,
Expand Down Expand Up @@ -803,11 +807,12 @@ metadata:
data:
key1: value1
`,
}}
},
}

t.Run("OnChangeOwnershipWithoutSpecChange", func(t *testing.T) {
var buf1 bytes.Buffer
diffOptions := Options{"diff", 10, false, true, false, []string{}, 0.5, []string{}} //NOTE: ShowSecrets = false
diffOptions := Options{"diff", 10, false, true, false, []string{}, 0.5, []string{}} // NOTE: ShowSecrets = false

newOwnedReleases := map[string]OwnershipDiff{
"default, foobar, ConfigMap (v1)": {
Expand All @@ -827,7 +832,7 @@ data:

t.Run("OnChangeOwnershipWithSpecChange", func(t *testing.T) {
var buf1 bytes.Buffer
diffOptions := Options{"diff", 10, false, true, false, []string{}, 0.5, []string{}} //NOTE: ShowSecrets = false
diffOptions := Options{"diff", 10, false, true, false, []string{}, 0.5, []string{}} // NOTE: ShowSecrets = false

specNew := map[string]*manifest.MappingResult{
"default, foobar, ConfigMap (v1)": {
Expand All @@ -841,7 +846,8 @@ metadata:
data:
key1: newValue1
`,
}}
},
}

newOwnedReleases := map[string]OwnershipDiff{
"default, foobar, ConfigMap (v1)": {
Expand Down Expand Up @@ -869,6 +875,7 @@ default, foobar, ConfigMap (v1) has changed:
`, buf1.String())
})
}

func TestDecodeSecrets(t *testing.T) {
ansi.DisableColors(true)

Expand Down
Loading
Loading