Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion api/filters/replacement/replacement.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ type Filter struct {
// Filter replaces values of targets with values from sources
func (f Filter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
for i, r := range f.Replacements {
if r.Source == nil || r.Targets == nil {
if (r.SourceValue == nil && r.Source == nil) || r.Targets == nil {
return nil, fmt.Errorf("replacements must specify a source and at least one target")
}
value, err := getReplacement(nodes, &f.Replacements[i])
Expand All @@ -39,6 +39,13 @@ func (f Filter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
}

func getReplacement(nodes []*yaml.RNode, r *types.Replacement) (*yaml.RNode, error) {
if r.SourceValue != nil && r.Source != nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we already have check while reading yaml nodes to not allow nil while adding elements to Replacements list. But can we do an early return if r == nil to avoid nil pointers just in case?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually this can be done in Filter itself.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know if I'm understanding it.
In Filter function, replacements is an slice of type []types.Replacement, so their elements should not be nil.
Inside getReplacement function, as I can see, it's passed by reference so it can modify the field path to the default one in case it is not given.
As I see it, inside the for loop on Filter function, r cannot be nil, don't know if I'm missing something, sorry 😅

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe @varshaprasad96 care about getReplacement() is called other places and that is better to handle error instead of reference field in nil value.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But, This func is private and we have never checked that before.
I think acceptable this time and We can fix next PR.

return nil, fmt.Errorf("value and resource selectors are mutually exclusive")
}
if r.SourceValue != nil {
return yaml.NewScalarRNode(*r.SourceValue), nil
}

source, err := selectSourceNode(nodes, r.Source)
if err != nil {
return nil, err
Expand Down
64 changes: 64 additions & 0 deletions api/filters/replacement/replacement_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2829,6 +2829,70 @@ spec:
create: true
`,
expectedErr: "unable to find or create field \"spec.tls.5.hosts.5\" in replacement target: index 5 specified but only 0 elements found",
}, "replace with static value": {
input: `apiVersion: v1
kind: Deployment
metadata:
name: deploy
spec:
template:
spec:
containers:
- image: nginx:1.7.9
name: nginx-tagged
- image: postgres:1.8.0
name: postgresdb
`,
replacements: `replacements:
- sourceValue: custom/postgres:1.9.0
targets:
- select:
kind: Deployment
name: deploy
fieldPaths:
- spec.template.spec.containers.[name=postgresdb].image
`,
expected: `apiVersion: v1
kind: Deployment
metadata:
name: deploy
spec:
template:
spec:
containers:
- image: nginx:1.7.9
name: nginx-tagged
- image: custom/postgres:1.9.0
name: postgresdb
`,
}, "source value and selector error": {
input: `apiVersion: v1
kind: Deployment
metadata:
name: deploy
spec:
replicas: 1
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
sourceValue: 2
targets:
- select:
kind: Deployment
name: deploy
fieldPaths:
- spec.replicas
`,
expectedErr: "value and resource selectors are mutually exclusive",
},
}

Expand Down
3 changes: 3 additions & 0 deletions api/types/replacement.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ type Replacement struct {

// The N fields to write the value to.
Targets []*TargetSelector `json:"targets,omitempty" yaml:"targets,omitempty"`

// Used to define an static value
SourceValue *string `json:"sourceValue,omitempty" yaml:"sourceValue,omitempty"`
}

// SourceSelector is the source of the replacement transformer.
Expand Down