Skip to content

Commit

Permalink
support label and annotation selection in replacement targets
Browse files Browse the repository at this point in the history
  • Loading branch information
natasha41575 committed Oct 7, 2021
1 parent 605239a commit cdfa337
Show file tree
Hide file tree
Showing 3 changed files with 201 additions and 1 deletion.
42 changes: 41 additions & 1 deletion api/filters/replacement/replacement.go
Expand Up @@ -8,6 +8,7 @@ import (
"strings"

"sigs.k8s.io/kustomize/api/internal/utils"
"sigs.k8s.io/kustomize/api/resource"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/resid"
"sigs.k8s.io/kustomize/kyaml/yaml"
Expand Down Expand Up @@ -48,6 +49,17 @@ func applyReplacement(nodes []*yaml.RNode, value *yaml.RNode, targets []*types.T
if err != nil {
return nil, err
}

// filter targets by label and annotation selectors
selectByAnnoAndLabel, err := selectByAnnoAndLabel(n, t)
if err != nil {
return nil, err
}
if !selectByAnnoAndLabel {
continue
}

// filter targets by matching resource IDs
for _, id := range ids {
if id.IsSelectedBy(t.Select.ResId) && !rejectId(t.Reject, &id) {
err := applyToNode(n, value, t)
Expand All @@ -62,9 +74,37 @@ func applyReplacement(nodes []*yaml.RNode, value *yaml.RNode, targets []*types.T
return nodes, nil
}

func selectByAnnoAndLabel(n *yaml.RNode, t *types.TargetSelector) (bool, error) {
if matchesSelect, err := matchesAnnoAndLabelSelector(n, t.Select); !matchesSelect || err != nil {
return false, err
}
for _, reject := range t.Reject {
if reject.AnnotationSelector == "" && reject.LabelSelector == "" {
continue
}
if m, err := matchesAnnoAndLabelSelector(n, reject); m || err != nil {
return false, err
}
}
return true, nil
}

func matchesAnnoAndLabelSelector(n *yaml.RNode, selector *types.Selector) (bool, error) {
r := resource.Resource{RNode: *n}
annoMatch, err := r.MatchesAnnotationSelector(selector.AnnotationSelector)
if err != nil {
return false, err
}
labelMatch, err := r.MatchesLabelSelector(selector.LabelSelector)
if err != nil {
return false, err
}
return annoMatch && labelMatch, nil
}

func rejectId(rejects []*types.Selector, id *resid.ResId) bool {
for _, r := range rejects {
if id.IsSelectedBy(r.ResId) {
if !r.ResId.IsEmpty() && id.IsSelectedBy(r.ResId) {
return true
}
}
Expand Down
150 changes: 150 additions & 0 deletions api/filters/replacement/replacement_test.go
Expand Up @@ -1658,7 +1658,157 @@ spec:
containers:
- image: nginx:1.7.9
name: nginx-tagged
- image: postgres:1.8.0
name: postgresdb
`,
},
"labelSelector": {
input: `apiVersion: v1
kind: Deployment
metadata:
name: deploy-1
labels:
foo: bar-1
spec:
template:
spec:
containers:
- image: nginx:1.7.9
name: nginx-tagged
- image: postgres:1.8.0
name: postgresdb
---
apiVersion: v1
kind: Deployment
metadata:
name: deploy-2
labels:
foo: bar-2
spec:
template:
spec:
containers:
- image: nginx:1.7.9
name: nginx-tagged
- image: postgres:1.8.0
name: postgresdb
`,
replacements: `replacements:
- source:
kind: Deployment
name: deploy-1
fieldPath: spec.template.spec.containers.0.image
targets:
- select:
labelSelector: foo=bar-1
fieldPaths:
- spec.template.spec.containers.1.image
`,
expected: `apiVersion: v1
kind: Deployment
metadata:
name: deploy-1
labels:
foo: bar-1
spec:
template:
spec:
containers:
- image: nginx:1.7.9
name: nginx-tagged
- image: nginx:1.7.9
name: postgresdb
---
apiVersion: v1
kind: Deployment
metadata:
name: deploy-2
labels:
foo: bar-2
spec:
template:
spec:
containers:
- image: nginx:1.7.9
name: nginx-tagged
- image: postgres:1.8.0
name: postgresdb
`,
},
"reject via labelSelector": {
input: `apiVersion: v1
kind: Deployment
metadata:
name: deploy-1
labels:
foo: bar-1
spec:
template:
spec:
containers:
- image: nginx:1.7.9
name: nginx-tagged
- image: postgres:1.8.0
name: postgresdb
---
apiVersion: v1
kind: Deployment
metadata:
name: deploy-2
labels:
foo: bar-2
spec:
template:
spec:
containers:
- image: nginx:1.7.9
name: nginx-tagged
- image: postgres:1.8.0
name: postgresdb
`,
replacements: `replacements:
- source:
kind: Deployment
name: deploy-1
fieldPath: spec.template.spec.containers.0.image
targets:
- select:
kind: Deployment
reject:
- labelSelector: foo=bar-2
fieldPaths:
- spec.template.spec.containers.1.image
`,
expected: `apiVersion: v1
kind: Deployment
metadata:
name: deploy-1
labels:
foo: bar-1
spec:
template:
spec:
containers:
- image: nginx:1.7.9
name: nginx-tagged
- image: nginx:1.7.9
name: postgresdb
---
apiVersion: v1
kind: Deployment
metadata:
name: deploy-2
labels:
foo: bar-2
spec:
template:
spec:
containers:
- image: nginx:1.7.9
name: nginx-tagged
- image: postgres:1.8.0
name: postgresdb
`,
},
Expand Down
10 changes: 10 additions & 0 deletions kyaml/resid/resid.go
Expand Up @@ -129,3 +129,13 @@ func (id ResId) EffectiveNamespace() string {
}
return id.Namespace
}

// IsEmpty returns true of all of the id's fields are
// empty strings
func (id ResId) IsEmpty() bool {
return id.Name == "" &&
id.Namespace == "" &&
id.Group == "" &&
id.Version == "" &&
id.Kind == ""
}

0 comments on commit cdfa337

Please sign in to comment.