mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-05-18 05:05:14 +00:00
support label and annotation selection in replacement targets
This commit is contained in:
@@ -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"
|
||||
@@ -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)
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
`,
|
||||
},
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
package resid
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@@ -129,3 +130,9 @@ 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 reflect.DeepEqual(id, ResId{})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user