Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce DiffResources struct #665

Open
wants to merge 6 commits into
base: develop
Choose a base branch
from
Open
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
6 changes: 4 additions & 2 deletions pkg/kapp/cmd/app/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -411,13 +411,15 @@ func (o *DeployOptions) calculateAndPresentChanges(existingResources,
changeFactory := ctldiff.NewChangeFactory(conf.RebaseMods(), conf.DiffAgainstLastAppliedFieldExclusionMods())
changeSetFactory := ctldiff.NewChangeSetFactory(o.DiffFlags.ChangeSetOpts, changeFactory)

err := ctldiff.NewRenewableResources(existingResources, newResources).Prepare()
diffRs := ctldiff.NewDiffResources(existingResources, newResources, conf.TemplateRules())

err := ctldiff.NewRenewableResources(diffRs).Prepare()
if err != nil {
return clusterChangeSet, nil, false, "", err
}

changes, err := ctldiff.NewChangeSetWithVersionedRs(
existingResources, newResources, conf.TemplateRules(),
diffRs,
o.DiffFlags.ChangeSetOpts, changeFactory).Calculate()
if err != nil {
return clusterChangeSet, nil, false, "", err
Expand Down
2 changes: 1 addition & 1 deletion pkg/kapp/config/default_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ spec:
}

// Calculate changes with default template rules
changes, err := ctldiff.NewChangeSetWithVersionedRs([]ctlres.Resource{}, newResources, defaultConfig.TemplateRules(), ctldiff.ChangeSetOpts{}, changeFactory).Calculate()
changes, err := ctldiff.NewChangeSetWithVersionedRs(ctldiff.NewDiffResources([]ctlres.Resource{}, newResources, defaultConfig.TemplateRules()), ctldiff.ChangeSetOpts{}, changeFactory).Calculate()
require.NoError(t, err)

// Compare against expected diff
Expand Down
102 changes: 9 additions & 93 deletions pkg/kapp/diff/change_set_with_versioned_rs.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@ package diff

import (
"fmt"
"sort"
"strconv"

ctlconf "github.com/vmware-tanzu/carvel-kapp/pkg/kapp/config"
ctlres "github.com/vmware-tanzu/carvel-kapp/pkg/kapp/resources"
)

Expand All @@ -19,23 +17,21 @@ const (
)

type ChangeSetWithVersionedRs struct {
existingRs, newRs []ctlres.Resource
rules []ctlconf.TemplateRule
opts ChangeSetOpts
changeFactory ChangeFactory
diffRs DiffResources
opts ChangeSetOpts
changeFactory ChangeFactory
}

func NewChangeSetWithVersionedRs(existingRs, newRs []ctlres.Resource,
rules []ctlconf.TemplateRule, opts ChangeSetOpts, changeFactory ChangeFactory) *ChangeSetWithVersionedRs {
func NewChangeSetWithVersionedRs(diffRs DiffResources, opts ChangeSetOpts, changeFactory ChangeFactory) *ChangeSetWithVersionedRs {

return &ChangeSetWithVersionedRs{existingRs, newRs, rules, opts, changeFactory}
return &ChangeSetWithVersionedRs{diffRs, opts, changeFactory}
}

func (d ChangeSetWithVersionedRs) Calculate() ([]Change, error) {
existingRs := existingVersionedResources(d.existingRs)
existingRsGrouped := newGroupedVersionedResources(existingRs.Versioned)
existingRs := d.diffRs.ExistingResources
existingRsGrouped := d.diffRs.ExistingResourcesGrouped

newRs := newVersionedResources(d.newRs)
newRs := d.diffRs.NewResources
allChanges := []Change{}

d.assignNewNames(newRs, existingRsGrouped)
Expand Down Expand Up @@ -133,7 +129,7 @@ func (d ChangeSetWithVersionedRs) addAndKeepChanges(
}

// Update both versioned and non-versioned
verRes := VersionedResource{usedRes, d.rules}
verRes := VersionedResource{usedRes, d.diffRs.rules}

err := verRes.UpdateAffected(newRs.NonVersioned)
if err != nil {
Expand Down Expand Up @@ -232,83 +228,3 @@ func (d ChangeSetWithVersionedRs) newChange(existingRes, newRes ctlres.Resource)
}
return changeFactoryFunc(existingRes, newRes)
}

type versionedResources struct {
Versioned []ctlres.Resource
NonVersioned []ctlres.Resource
}

func newVersionedResources(rs []ctlres.Resource) versionedResources {
var result versionedResources
for _, res := range rs {
_, hasVersionedAnn := res.Annotations()[versionedResAnnKey]
_, hasVersionedOrigAnn := res.Annotations()[versionedResOrigAnnKey]

if hasVersionedAnn {
result.Versioned = append(result.Versioned, res)
if hasVersionedOrigAnn {
result.NonVersioned = append(result.NonVersioned, res.DeepCopy())
}
} else {
result.NonVersioned = append(result.NonVersioned, res)
}
}
return result
}

func existingVersionedResources(rs []ctlres.Resource) versionedResources {
var result versionedResources
for _, res := range rs {
// Expect that versioned resources should not be transient
// (Annotations may have been copied from versioned resources
// onto transient resources for non-versioning related purposes).
_, hasVersionedAnn := res.Annotations()[versionedResAnnKey]

versionedRs := VersionedResource{res: res}
_, version := versionedRs.BaseNameAndVersion()

if hasVersionedAnn && !res.Transient() && version != "" {
result.Versioned = append(result.Versioned, res)
} else {
result.NonVersioned = append(result.NonVersioned, res)
}
}
return result
}

func newGroupedVersionedResources(rs []ctlres.Resource) map[string][]ctlres.Resource {
result := map[string][]ctlres.Resource{}

groupByFunc := func(res ctlres.Resource) string {
_, found := res.Annotations()[versionedResAnnKey]
if found {
return VersionedResource{res, nil}.UniqVersionedKey().String()
}
panic("Expected to find versioned annotation on resource")
}

for resKey, subRs := range (GroupResources{rs, groupByFunc}).Resources() {
sort.Slice(subRs, func(i, j int) bool {
return VersionedResource{subRs[i], nil}.Version() < VersionedResource{subRs[j], nil}.Version()
})
result[resKey] = subRs
}
return result
}

func existingResourcesMap(res []ctlres.Resource) map[string]ctlres.Resource {
result := map[string]ctlres.Resource{}

existingRs := existingVersionedResources(res)
existingVersionRsGrouped := newGroupedVersionedResources(existingRs.Versioned)

for _, res := range existingRs.NonVersioned {
resKey := ctlres.NewUniqueResourceKey(res).String()
result[resKey] = res
}

for resKey, res := range existingVersionRsGrouped {
result[resKey] = res[len(res)-1]
}
return result
}
6 changes: 3 additions & 3 deletions pkg/kapp/diff/change_set_with_versioned_rs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ metadata:
kapp.k14s.io/versioned: ""
`))

changeSetWithVerRes := NewChangeSetWithVersionedRs([]ctlres.Resource{existingRes}, []ctlres.Resource{newRs}, nil,
changeSetWithVerRes := NewChangeSetWithVersionedRs(NewDiffResources([]ctlres.Resource{existingRes}, []ctlres.Resource{newRs}, nil),
ChangeSetOpts{}, ChangeFactory{})

changes, err := changeSetWithVerRes.Calculate()
Expand Down Expand Up @@ -75,7 +75,7 @@ metadata:
name: secret
`))

changeSetWithVerRes := NewChangeSetWithVersionedRs([]ctlres.Resource{existingRes}, []ctlres.Resource{newRs}, nil,
changeSetWithVerRes := NewChangeSetWithVersionedRs(NewDiffResources([]ctlres.Resource{existingRes}, []ctlres.Resource{newRs}, nil),
ChangeSetOpts{}, ChangeFactory{})

changes, err := changeSetWithVerRes.Calculate()
Expand Down Expand Up @@ -124,7 +124,7 @@ metadata:
name: secret
`))

changeSetWithVerRes := NewChangeSetWithVersionedRs([]ctlres.Resource{existingRes}, []ctlres.Resource{newRs}, nil,
changeSetWithVerRes := NewChangeSetWithVersionedRs(NewDiffResources([]ctlres.Resource{existingRes}, []ctlres.Resource{newRs}, nil),
ChangeSetOpts{}, ChangeFactory{})

changes, err := changeSetWithVerRes.Calculate()
Expand Down
105 changes: 105 additions & 0 deletions pkg/kapp/diff/diff_resources.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
// Copyright 2020 VMware, Inc.
// SPDX-License-Identifier: Apache-2.0

package diff

import (
"sort"

ctlconf "github.com/vmware-tanzu/carvel-kapp/pkg/kapp/config"
ctlres "github.com/vmware-tanzu/carvel-kapp/pkg/kapp/resources"
)

type DiffResources struct {
ExistingResources, NewResources versionedResources
ExistingResourcesGrouped map[string][]ctlres.Resource

newRs []ctlres.Resource
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saving newRs is only a workaround for RenewableResources, I would prefer a different approach, but did not want to spend to much time here for the moment :)

rules []ctlconf.TemplateRule
}

func NewDiffResources(existingRs, newRs []ctlres.Resource, rules []ctlconf.TemplateRule) DiffResources {
existingVRs := existingVersionedResources(existingRs)
newVRs := newVersionedResources(newRs)

existingRsGrouped := newGroupedVersionedResources(existingVRs.Versioned)

return DiffResources{existingVRs, newVRs, existingRsGrouped, newRs, rules}
}

type versionedResources struct {
Versioned []ctlres.Resource
NonVersioned []ctlres.Resource
}

func newVersionedResources(rs []ctlres.Resource) versionedResources {
var result versionedResources
for _, res := range rs {
_, hasVersionedAnn := res.Annotations()[versionedResAnnKey]
_, hasVersionedOrigAnn := res.Annotations()[versionedResOrigAnnKey]

if hasVersionedAnn {
result.Versioned = append(result.Versioned, res)
if hasVersionedOrigAnn {
result.NonVersioned = append(result.NonVersioned, res.DeepCopy())
}
} else {
result.NonVersioned = append(result.NonVersioned, res)
}
}
return result
}

func existingVersionedResources(rs []ctlres.Resource) versionedResources {
var result versionedResources
for _, res := range rs {
// Expect that versioned resources should not be transient
// (Annotations may have been copied from versioned resources
// onto transient resources for non-versioning related purposes).
_, hasVersionedAnn := res.Annotations()[versionedResAnnKey]

versionedRs := VersionedResource{res: res}
_, version := versionedRs.BaseNameAndVersion()

if hasVersionedAnn && !res.Transient() && version != "" {
result.Versioned = append(result.Versioned, res)
} else {
result.NonVersioned = append(result.NonVersioned, res)
}
}
return result
}

func newGroupedVersionedResources(rs []ctlres.Resource) map[string][]ctlres.Resource {
result := map[string][]ctlres.Resource{}

groupByFunc := func(res ctlres.Resource) string {
_, found := res.Annotations()[versionedResAnnKey]
if found {
return VersionedResource{res, nil}.UniqVersionedKey().String()
}
panic("Expected to find versioned annotation on resource")
}

for resKey, subRs := range (GroupResources{rs, groupByFunc}).Resources() {
sort.Slice(subRs, func(i, j int) bool {
return VersionedResource{subRs[i], nil}.Version() < VersionedResource{subRs[j], nil}.Version()
})
result[resKey] = subRs
}
return result
}

func (d DiffResources) existingResourcesMap() map[string]ctlres.Resource {
result := map[string]ctlres.Resource{}

for _, res := range d.ExistingResources.NonVersioned {
resKey := ctlres.NewUniqueResourceKey(res).String()
result[resKey] = res
}

for resKey, res := range d.ExistingResourcesGrouped {
result[resKey] = res[len(res)-1]
}
return result
}
10 changes: 5 additions & 5 deletions pkg/kapp/diff/renewable_resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,17 @@ const (
)

type RenewableResources struct {
existingRs, newRs []ctlres.Resource
diffRs DiffResources
}

func NewRenewableResources(existingRs, newRs []ctlres.Resource) *RenewableResources {
return &RenewableResources{existingRs: existingRs, newRs: newRs}
func NewRenewableResources(diffRs DiffResources) *RenewableResources {
return &RenewableResources{diffRs}
}

func (d RenewableResources) Prepare() error {
exResourcesMap := existingResourcesMap(d.existingRs)
exResourcesMap := d.diffRs.existingResourcesMap()

for _, res := range d.newRs {
for _, res := range d.diffRs.newRs {
val, found := res.Annotations()[renewDurationAnnKey]
if found {
duration, err := time.ParseDuration(val)
Expand Down