mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-07-17 01:39:06 +00:00
support label and annotation selection in replacement targets
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"sigs.k8s.io/kustomize/api/internal/utils"
|
"sigs.k8s.io/kustomize/api/internal/utils"
|
||||||
|
"sigs.k8s.io/kustomize/api/resource"
|
||||||
"sigs.k8s.io/kustomize/api/types"
|
"sigs.k8s.io/kustomize/api/types"
|
||||||
"sigs.k8s.io/kustomize/kyaml/resid"
|
"sigs.k8s.io/kustomize/kyaml/resid"
|
||||||
"sigs.k8s.io/kustomize/kyaml/yaml"
|
"sigs.k8s.io/kustomize/kyaml/yaml"
|
||||||
@@ -48,6 +49,17 @@ func applyReplacement(nodes []*yaml.RNode, value *yaml.RNode, targets []*types.T
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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 {
|
for _, id := range ids {
|
||||||
if id.IsSelectedBy(t.Select.ResId) && !rejectId(t.Reject, &id) {
|
if id.IsSelectedBy(t.Select.ResId) && !rejectId(t.Reject, &id) {
|
||||||
err := applyToNode(n, value, t)
|
err := applyToNode(n, value, t)
|
||||||
@@ -62,9 +74,37 @@ func applyReplacement(nodes []*yaml.RNode, value *yaml.RNode, targets []*types.T
|
|||||||
return nodes, nil
|
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 {
|
func rejectId(rejects []*types.Selector, id *resid.ResId) bool {
|
||||||
for _, r := range rejects {
|
for _, r := range rejects {
|
||||||
if id.IsSelectedBy(r.ResId) {
|
if !r.ResId.IsEmpty() && id.IsSelectedBy(r.ResId) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1658,7 +1658,157 @@ spec:
|
|||||||
containers:
|
containers:
|
||||||
- image: nginx:1.7.9
|
- image: nginx:1.7.9
|
||||||
name: nginx-tagged
|
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
|
- 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
|
name: postgresdb
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
package resid
|
package resid
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -129,3 +130,9 @@ func (id ResId) EffectiveNamespace() string {
|
|||||||
}
|
}
|
||||||
return id.Namespace
|
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