feat: kubesphere 4.0 (#6115)

* feat: kubesphere 4.0

Signed-off-by: ci-bot <ci-bot@kubesphere.io>

* feat: kubesphere 4.0

Signed-off-by: ci-bot <ci-bot@kubesphere.io>

---------

Signed-off-by: ci-bot <ci-bot@kubesphere.io>
Co-authored-by: ks-ci-bot <ks-ci-bot@example.com>
Co-authored-by: joyceliu <joyceliu@yunify.com>
This commit is contained in:
KubeSphere CI Bot
2024-09-06 11:05:52 +08:00
committed by GitHub
parent b5015ec7b9
commit 447a51f08b
8557 changed files with 546695 additions and 1146174 deletions

View File

@@ -4,9 +4,13 @@
package yaml
import (
"fmt"
"regexp"
"strconv"
"strings"
"sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/internal/forked/github.com/go-yaml/yaml"
)
// PathMatcher returns all RNodes matching the path wrapped in a SequenceNode.
@@ -21,7 +25,7 @@ type PathMatcher struct {
// Each path part may be one of:
// * FieldMatcher -- e.g. "spec"
// * Map Key -- e.g. "app.k8s.io/version"
// * List Entry -- e.g. "[name=nginx]" or "[=-jar]"
// * List Entry -- e.g. "[name=nginx]" or "[=-jar]" or "0"
//
// Map Keys and Fields are equivalent.
// See FieldMatcher for more on Fields and Map Keys.
@@ -43,10 +47,18 @@ type PathMatcher struct {
// This is useful for if the nodes are to be printed in FlowStyle.
StripComments bool
val *RNode
field string
matchRegex string
indexNumber int
// Create will cause missing path parts to be created as they are walked.
//
// * The leaf Node (final path) will be created with a Kind matching Create
// * Intermediary Nodes will be created as either a MappingNodes or
// SequenceNodes as appropriate for each's Path location.
// * Nodes identified by an index will only be created if the index indicates
// an append operation (i.e. index=len(list))
Create yaml.Kind `yaml:"create,omitempty"`
val *RNode
field string
matchRegex string
}
func (p *PathMatcher) stripComments(n *Node) {
@@ -109,7 +121,7 @@ func (p *PathMatcher) doMatchEvery(rn *RNode) (*RNode, error) {
func (p *PathMatcher) visitEveryElem(elem *RNode) error {
fieldName := p.Path[0]
// recurse on the matching element
pm := &PathMatcher{Path: p.Path[1:]}
pm := &PathMatcher{Path: p.Path[1:], Create: p.Create}
add, err := pm.filter(elem)
for k, v := range pm.Matches {
p.Matches[k] = v
@@ -125,13 +137,25 @@ func (p *PathMatcher) visitEveryElem(elem *RNode) error {
func (p *PathMatcher) doField(rn *RNode) (*RNode, error) {
// lookup the field
field, err := rn.Pipe(Get(p.Path[0]))
if err != nil || field == nil {
// if the field doesn't exist, return nil
if err != nil || (!IsCreate(p.Create) && field == nil) {
return nil, err
}
if IsCreate(p.Create) && field == nil {
var nextPart string
if len(p.Path) > 1 {
nextPart = p.Path[1]
}
nextPartKind := getPathPartKind(nextPart, p.Create)
field = &RNode{value: &yaml.Node{Kind: nextPartKind}}
err := rn.PipeE(SetField(p.Path[0], field))
if err != nil {
return nil, err
}
}
// recurse on the field, removing the first element of the path
pm := &PathMatcher{Path: p.Path[1:]}
pm := &PathMatcher{Path: p.Path[1:], Create: p.Create}
p.val, err = pm.filter(field)
p.Matches = pm.Matches
return p.val, err
@@ -144,18 +168,33 @@ func (p *PathMatcher) doIndexSeq(rn *RNode) (*RNode, error) {
if err != nil {
return nil, err
}
p.indexNumber = idx
elements, err := rn.Elements()
if err != nil {
return nil, err
}
if len(elements) == idx && IsCreate(p.Create) {
var nextPart string
if len(p.Path) > 1 {
nextPart = p.Path[1]
}
elem := &yaml.Node{Kind: getPathPartKind(nextPart, p.Create)}
err = rn.PipeE(Append(elem))
if err != nil {
return nil, errors.WrapPrefixf(err, "failed to append element for %q", p.Path[0])
}
elements = append(elements, NewRNode(elem))
}
if len(elements) < idx+1 {
return nil, fmt.Errorf("index %d specified but only %d elements found", idx, len(elements))
}
// get target element
element := elements[idx]
// recurse on the matching element
pm := &PathMatcher{Path: p.Path[1:]}
pm := &PathMatcher{Path: p.Path[1:], Create: p.Create}
add, err := pm.filter(element)
for k, v := range pm.Matches {
p.Matches[k] = v
@@ -176,16 +215,39 @@ func (p *PathMatcher) doSeq(rn *RNode) (*RNode, error) {
return nil, err
}
if p.field == "" {
primitiveElement := len(p.field) == 0
if primitiveElement {
err = rn.VisitElements(p.visitPrimitiveElem)
} else {
err = rn.VisitElements(p.visitElem)
}
if err != nil || p.val == nil || len(p.val.YNode().Content) == 0 {
if err != nil {
return nil, err
}
if !p.val.IsNil() && len(p.val.YNode().Content) == 0 {
p.val = nil
}
return p.val, nil
if !IsCreate(p.Create) || p.val != nil {
return p.val, nil
}
var elem *yaml.Node
valueNode := NewScalarRNode(p.matchRegex).YNode()
if primitiveElement {
elem = valueNode
} else {
elem = &yaml.Node{
Kind: yaml.MappingNode,
Content: []*yaml.Node{{Kind: yaml.ScalarNode, Value: p.field}, valueNode},
}
}
err = rn.PipeE(Append(elem))
if err != nil {
return nil, errors.WrapPrefixf(err, "failed to create element for %q", p.Path[0])
}
// re-do the sequence search; this time we'll find the element we just created
return p.doSeq(rn)
}
func (p *PathMatcher) visitPrimitiveElem(elem *RNode) error {
@@ -228,7 +290,7 @@ func (p *PathMatcher) visitElem(elem *RNode) error {
}
// recurse on the matching element
pm := &PathMatcher{Path: p.Path[1:]}
pm := &PathMatcher{Path: p.Path[1:], Create: p.Create}
add, err := pm.filter(elem)
for k, v := range pm.Matches {
p.Matches[k] = v