From 541ae915cd1a9157feeffba7793ba92e17d94a37 Mon Sep 17 00:00:00 2001 From: Jerome Brette Date: Fri, 12 Jul 2019 18:11:09 -0500 Subject: [PATCH] Prepare diamond import feature for upcoming high level merge feature. --- pkg/accumulator/resaccumulator.go | 61 +++++++++++++++++++++------ pkg/target/kusttarget.go | 26 +++++------- pkg/target/kusttarget_configplugin.go | 16 ++++++- 3 files changed, 71 insertions(+), 32 deletions(-) diff --git a/pkg/accumulator/resaccumulator.go b/pkg/accumulator/resaccumulator.go index 413ef95ad53..3633d3f2d3f 100644 --- a/pkg/accumulator/resaccumulator.go +++ b/pkg/accumulator/resaccumulator.go @@ -9,6 +9,7 @@ import ( "reflect" "strings" + "sigs.k8s.io/kustomize/v3/pkg/gvk" "sigs.k8s.io/kustomize/v3/pkg/resid" "sigs.k8s.io/kustomize/v3/pkg/resmap" "sigs.k8s.io/kustomize/v3/pkg/resource" @@ -21,11 +22,11 @@ import ( // used to customize those resources. It's a ResMap // plus stuff needed to modify the ResMap. type ResAccumulator struct { - resMap resmap.ResMap - tConfig *config.TransformerConfig - varSet types.VarSet - conflictingResources []*resource.Resource - unresolvedVars types.VarSet + resMap resmap.ResMap + tConfig *config.TransformerConfig + varSet types.VarSet + patchSet []types.Patch + unresolvedVars types.VarSet } func MakeEmptyAccumulator() *ResAccumulator { @@ -33,7 +34,7 @@ func MakeEmptyAccumulator() *ResAccumulator { ra.resMap = resmap.New() ra.tConfig = &config.TransformerConfig{} ra.varSet = types.NewVarSet() - ra.conflictingResources = []*resource.Resource{} + ra.patchSet = []types.Patch{} ra.unresolvedVars = types.NewVarSet() return ra } @@ -51,11 +52,40 @@ func (ra *ResAccumulator) Vars() []types.Var { return completeset.AsSlice() } +// accumlatePatch accumulates the information regarding conflicting +// resources as patches. +func (ra *ResAccumulator) accumlatePatch(id resid.ResId, conflicting ...*resource.Resource) error { + target := types.Selector{ + Gvk: gvk.Gvk{ + Group: id.Group, + Version: id.Version, + Kind: id.Kind, + }, + Namespace: id.Namespace, + Name: id.Name, + AnnotationSelector: "", + LabelSelector: "", + } + + for _, res := range conflicting { + out, err := res.AsYAML() + if err != nil { + return err + } + newPatch := types.Patch{ + Path: "", + Patch: string(out), + Target: target, + } + ra.patchSet = append(ra.patchSet, newPatch) + } + return nil +} + // HandoverConflictingResources removes conflicting resources from the local accumulator // and add the conflicting resources list in the other accumulator. // Conflicting is defined as have the same CurrentId but different Values. func (ra *ResAccumulator) HandoverConflictingResources(other *ResAccumulator) error { - conflicting := []*resource.Resource{} for _, rightResource := range other.ResMap().Resources() { rightId := rightResource.CurId() leftResources := ra.resMap.GetMatchingResourcesByCurrentId(rightId.Equals) @@ -68,10 +98,16 @@ func (ra *ResAccumulator) HandoverConflictingResources(other *ResAccumulator) er // TODO(jeb): Not sure we want to use DeepEqual here since there are some fields // which are artifacts (nameprefix, namesuffix, refvar, refby) added to the resources // by the algorithm here. + // Also we may be dropping here some of the artifacts (nameprefix, namesuffix,...) + // during the conversion from Resource/ResMap to Patch. if len(leftResources) != 1 || !reflect.DeepEqual(leftResources[0], rightResource) { // conflict detected. More than one resource or left and right are different. - conflicting = append(conflicting, rightResource) - conflicting = append(conflicting, leftResources...) + if err := other.accumlatePatch(rightId, rightResource); err != nil { + return err + } + if err := other.accumlatePatch(rightId, leftResources...); err != nil { + return err + } } // Remove the resource from that resMap @@ -81,17 +117,14 @@ func (ra *ResAccumulator) HandoverConflictingResources(other *ResAccumulator) er } } - // TODO(jeb): Should the conflictingResources be a ResMap ?. We are dropping here - // some of the artifacts (nameprefix, namesuffix,...) - other.conflictingResources = append(other.conflictingResources, conflicting...) return nil } // ConflictingResources return the list of resources that have been // put aside. It will let the PatchTransformer decide how to handle // the conflict, assuming the Transformer can. -func (ra *ResAccumulator) ConflictingResources() []*resource.Resource { - return ra.conflictingResources +func (ra *ResAccumulator) GetPatchSet() []types.Patch { + return ra.patchSet } func (ra *ResAccumulator) AppendAll( diff --git a/pkg/target/kusttarget.go b/pkg/target/kusttarget.go index 3c253b25a18..5d36562d5d4 100644 --- a/pkg/target/kusttarget.go +++ b/pkg/target/kusttarget.go @@ -31,6 +31,7 @@ type KustTarget struct { rFactory *resmap.Factory tFactory resmap.PatchFactory pLdr *plugins.Loader + dynamic *types.Kustomization } // NewKustTarget returns a new instance of KustTarget primed with a Loader. @@ -62,6 +63,7 @@ func NewKustTarget( rFactory: rFactory, tFactory: tFactory, pLdr: pLdr, + dynamic: &types.Kustomization{}, }, nil } @@ -300,24 +302,16 @@ func (kt *KustTarget) configureExternalGenerators() ([]transformers.Generator, e return kt.pLdr.LoadGenerators(kt.ldr, ra.ResMap()) } -func (kt *KustTarget) runTransformers(ra *accumulator.ResAccumulator) error { - var r []transformers.Transformer +func (kt *KustTarget) absorbDynamicKustomization(ra *accumulator.ResAccumulator) { + orig := ra.GetPatchSet() + kt.dynamic.Patches = make([]types.Patch, len(orig)) + copy(kt.dynamic.Patches, orig) +} - // Convertion to the buildin transformer is not compatible with this PR - // differed := ra.ConflictingResources() - // patches, err := kt.rFactory.RF().SliceFromPatches( - // kt.ldr, kt.kustomization.PatchesStrategicMerge) - // if err != nil { - // return errors.Wrapf( - // err, "reading strategic merge patches %v", - // kt.kustomization.PatchesStrategicMerge) - // } - // t, err := kt.tFactory.MakePatchTransformer(append(differed, patches...), kt.rFactory.RF()) - // if err != nil { - // return err - // } - // r = append(r, t) +func (kt *KustTarget) runTransformers(ra *accumulator.ResAccumulator) error { + kt.absorbDynamicKustomization(ra) + var r []transformers.Transformer tConfig := ra.GetTransformerConfig() lts, err := kt.configureBuiltinTransformers(tConfig) if err != nil { diff --git a/pkg/target/kusttarget_configplugin.go b/pkg/target/kusttarget_configplugin.go index e616f433488..2fde1edab35 100644 --- a/pkg/target/kusttarget_configplugin.go +++ b/pkg/target/kusttarget_configplugin.go @@ -4,6 +4,8 @@ package target import ( + "strings" + "github.com/pkg/errors" "sigs.k8s.io/kustomize/v3/pkg/image" "sigs.k8s.io/kustomize/v3/pkg/plugins" @@ -166,10 +168,20 @@ func (kt *KustTarget) configureBuiltinPatchJson6902Transformer( return } +// Until Issue 1292 is implemented, use PathStrategicMerge to address +// when possible diamond merge issues. +func (kt *KustTarget) asString(patchSet []types.Patch) string { + res := []string{} + for _, patch := range patchSet { + res = append(res, patch.Patch) + } + return strings.Join(res, "---\n") +} + func (kt *KustTarget) configureBuiltinPatchStrategicMergeTransformer( tConfig *config.TransformerConfig) ( result []transformers.Transformer, err error) { - if len(kt.kustomization.PatchesStrategicMerge) == 0 { + if len(kt.kustomization.PatchesStrategicMerge) == 0 && len(kt.dynamic.Patches) == 0 { result = append(result, transformers.NewNoOpTransformer()) return } @@ -178,7 +190,7 @@ func (kt *KustTarget) configureBuiltinPatchStrategicMergeTransformer( Patches string `json:"patches,omitempty" yaml:"patches,omitempty"` } c.Paths = kt.kustomization.PatchesStrategicMerge - c.Patches = "" // Not implemented for kustomization file yet + c.Patches = kt.asString(kt.dynamic.Patches) p := builtin.NewPatchStrategicMergeTransformerPlugin() err = kt.configureBuiltinPlugin(p, c, "patchStrategicMerge") if err != nil {