github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/pkg/configuration/core/config_patch.go (about) 1 /* 2 Copyright (C) 2022-2023 ApeCloud Co., Ltd 3 4 This file is part of KubeBlocks project 5 6 This program is free software: you can redistribute it and/or modify 7 it under the terms of the GNU Affero General Public License as published by 8 the Free Software Foundation, either version 3 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU Affero General Public License for more details. 15 16 You should have received a copy of the GNU Affero General Public License 17 along with this program. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 package core 21 22 import ( 23 appsv1alpha1 "github.com/1aal/kubeblocks/apis/apps/v1alpha1" 24 "github.com/1aal/kubeblocks/pkg/configuration/util" 25 ) 26 27 func CreateMergePatch(oldVersion, newVersion interface{}, option CfgOption) (*ConfigPatchInfo, error) { 28 29 ok, err := compareWithConfig(oldVersion, newVersion, option) 30 if err != nil { 31 return nil, err 32 } else if ok { 33 return &ConfigPatchInfo{IsModify: false}, err 34 } 35 36 old, err := NewConfigLoader(withOption(option, oldVersion)) 37 if err != nil { 38 return nil, WrapError(err, "failed to create config: [%s]", oldVersion) 39 } 40 41 new, err := NewConfigLoader(withOption(option, newVersion)) 42 if err != nil { 43 return nil, WrapError(err, "failed to create config: [%s]", oldVersion) 44 } 45 return difference(old.cfgWrapper, new.cfgWrapper) 46 } 47 48 func difference(base *cfgWrapper, target *cfgWrapper) (*ConfigPatchInfo, error) { 49 fromOMap := util.ToSet(base.indexer) 50 fromNMap := util.ToSet(target.indexer) 51 52 addSet := util.Difference(fromNMap, fromOMap) 53 deleteSet := util.Difference(fromOMap, fromNMap) 54 updateSet := util.Difference(fromOMap, deleteSet) 55 56 reconfigureInfo := &ConfigPatchInfo{ 57 IsModify: false, 58 AddConfig: make(map[string]interface{}, addSet.Length()), 59 DeleteConfig: make(map[string]interface{}, deleteSet.Length()), 60 UpdateConfig: make(map[string][]byte, updateSet.Length()), 61 62 Target: target, 63 LastVersion: base, 64 } 65 66 for elem := range addSet.Iter() { 67 reconfigureInfo.AddConfig[elem] = target.indexer[elem].GetAllParameters() 68 reconfigureInfo.IsModify = true 69 } 70 71 for elem := range deleteSet.Iter() { 72 reconfigureInfo.DeleteConfig[elem] = base.indexer[elem].GetAllParameters() 73 reconfigureInfo.IsModify = true 74 } 75 76 for elem := range updateSet.Iter() { 77 old := base.indexer[elem] 78 new := target.indexer[elem] 79 80 patch, err := util.JSONPatch(old.GetAllParameters(), new.GetAllParameters()) 81 if err != nil { 82 return nil, err 83 } 84 if len(patch) > len(emptyJSON) { 85 reconfigureInfo.UpdateConfig[elem] = patch 86 reconfigureInfo.IsModify = true 87 } 88 } 89 90 return reconfigureInfo, nil 91 } 92 93 func TransformConfigPatchFromData(data map[string]string, format appsv1alpha1.CfgFileFormat, keys []string) (*ConfigPatchInfo, error) { 94 emptyData := func(m map[string]string) map[string]string { 95 r := make(map[string]string, len(m)) 96 for key := range m { 97 r[key] = "" 98 } 99 return r 100 } 101 patch, _, err := CreateConfigPatch(emptyData(data), data, format, keys, false) 102 return patch, err 103 }