mirror of
https://github.com/kubevela/kubevela.git
synced 2026-02-14 18:10:21 +00:00
Feat: support multi keys in patchKey (#3826)
Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>
This commit is contained in:
@@ -17,6 +17,7 @@ limitations under the License.
|
||||
package sets
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"cuelang.org/go/cue"
|
||||
@@ -95,50 +96,57 @@ type interceptor func(baseNode ast.Node, patchNode ast.Node) error
|
||||
func listMergeProcess(field *ast.Field, key string, baseList, patchList *ast.ListLit) {
|
||||
kmaps := map[string]ast.Expr{}
|
||||
nElts := []ast.Expr{}
|
||||
|
||||
for i, elt := range patchList.Elts {
|
||||
if _, ok := elt.(*ast.Ellipsis); ok {
|
||||
continue
|
||||
}
|
||||
nodev, err := lookUp(elt, strings.Split(key, ".")...)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
blit, ok := nodev.(*ast.BasicLit)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
kmaps[blit.Value] = patchList.Elts[i]
|
||||
}
|
||||
|
||||
hasStrategyRetainKeys := isStrategyRetainKeys(field)
|
||||
|
||||
for i, elt := range baseList.Elts {
|
||||
if _, ok := elt.(*ast.Ellipsis); ok {
|
||||
continue
|
||||
}
|
||||
|
||||
nodev, err := lookUp(elt, strings.Split(key, ".")...)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
blit, ok := nodev.(*ast.BasicLit)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
if v, ok := kmaps[blit.Value]; ok {
|
||||
if hasStrategyRetainKeys {
|
||||
baseList.Elts[i] = ast.NewStruct()
|
||||
keys := strings.Split(key, ",")
|
||||
for _, key := range keys {
|
||||
foundPatch := false
|
||||
for i, elt := range patchList.Elts {
|
||||
if _, ok := elt.(*ast.Ellipsis); ok {
|
||||
continue
|
||||
}
|
||||
nElts = append(nElts, v)
|
||||
delete(kmaps, blit.Value)
|
||||
} else {
|
||||
nElts = append(nElts, ast.NewStruct())
|
||||
nodev, err := lookUp(elt, strings.Split(key, ".")...)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
foundPatch = true
|
||||
blit, ok := nodev.(*ast.BasicLit)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
kmaps[fmt.Sprintf(key, blit.Value)] = patchList.Elts[i]
|
||||
}
|
||||
if !foundPatch {
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
hasStrategyRetainKeys := isStrategyRetainKeys(field)
|
||||
|
||||
for i, elt := range baseList.Elts {
|
||||
if _, ok := elt.(*ast.Ellipsis); ok {
|
||||
continue
|
||||
}
|
||||
|
||||
nodev, err := lookUp(elt, strings.Split(key, ".")...)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
blit, ok := nodev.(*ast.BasicLit)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
k := fmt.Sprintf(key, blit.Value)
|
||||
if v, ok := kmaps[k]; ok {
|
||||
if hasStrategyRetainKeys {
|
||||
baseList.Elts[i] = ast.NewStruct()
|
||||
}
|
||||
nElts = append(nElts, v)
|
||||
delete(kmaps, k)
|
||||
} else {
|
||||
nElts = append(nElts, ast.NewStruct())
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
for _, elt := range patchList.Elts {
|
||||
for _, v := range kmaps {
|
||||
if elt == v {
|
||||
|
||||
@@ -74,7 +74,11 @@ containers: [{
|
||||
patch: `
|
||||
// +patchKey=name
|
||||
containers: [{name: "x2"},{name: "x1"}]`,
|
||||
result: "_|_\n",
|
||||
result: ` // +patchKey=name
|
||||
containers: [_|_, // field "name" not allowed in closed struct{
|
||||
name: "x1"
|
||||
}, ...]
|
||||
`,
|
||||
},
|
||||
|
||||
{
|
||||
@@ -99,9 +103,22 @@ containers: [{
|
||||
base: `containers: [{name: "x1"},{name: "x2"},...]`,
|
||||
patch: `
|
||||
// +patchKey=name
|
||||
containers: [{noname: "x3"},{name: "x1"}]`,
|
||||
containers: [{noname: "x3"}]`,
|
||||
result: "_|_\n",
|
||||
},
|
||||
{
|
||||
base: `containers: [{name: "x1"},{name: "x2"},...]`,
|
||||
patch: `
|
||||
// +patchKey=name
|
||||
containers: [{noname: "x3"},{name: "x1"}]`,
|
||||
result: `// +patchKey=name
|
||||
containers: [{
|
||||
name: "x1"
|
||||
}, {
|
||||
name: "x2"
|
||||
}, ...]
|
||||
`,
|
||||
},
|
||||
{
|
||||
base: `containers: [{name: "x1"},{name: "x2", envs:[ {name: "OPS",value: string},...]},...]`,
|
||||
patch: `
|
||||
@@ -281,6 +298,63 @@ volumes: [{
|
||||
name: "x3"
|
||||
value: "x2"
|
||||
}, ...]
|
||||
`},
|
||||
|
||||
{
|
||||
base: `
|
||||
containers: [{
|
||||
name: "c1"
|
||||
},{
|
||||
name: "c2"
|
||||
envFrom: [{
|
||||
secretRef: {
|
||||
name: "nginx-rds"
|
||||
},
|
||||
}, {
|
||||
configMapRef: {
|
||||
name: "nginx-rds"
|
||||
},
|
||||
},...]
|
||||
},...]`,
|
||||
patch: `
|
||||
// +patchKey=name
|
||||
containers: [{
|
||||
name: "c2"
|
||||
// +patchKey=secretRef.name,configMapRef.name
|
||||
envFrom: [{
|
||||
secretRef: {
|
||||
name: "nginx-redis"
|
||||
},
|
||||
}, {
|
||||
configMapRef: {
|
||||
name: "nginx-redis"
|
||||
},
|
||||
},...]
|
||||
}]`,
|
||||
result: `// +patchKey=name
|
||||
containers: [{
|
||||
name: "c1"
|
||||
}, {
|
||||
name: "c2"
|
||||
// +patchKey=secretRef.name,configMapRef.name
|
||||
envFrom: [{
|
||||
secretRef: {
|
||||
name: "nginx-rds"
|
||||
}
|
||||
}, {
|
||||
configMapRef: {
|
||||
name: "nginx-rds"
|
||||
}
|
||||
}, {
|
||||
secretRef: {
|
||||
name: "nginx-redis"
|
||||
}
|
||||
}, {
|
||||
configMapRef: {
|
||||
name: "nginx-redis"
|
||||
}
|
||||
}, ...]
|
||||
}, ...]
|
||||
`},
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user