Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(replacements): add IgnoreMissingField option #5778

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
10 changes: 7 additions & 3 deletions api/filters/replacement/replacement.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,20 +185,24 @@ func containsRejectId(rejects []*types.Selector, ids []resid.ResId) bool {
func copyValueToTarget(target *yaml.RNode, value *yaml.RNode, selector *types.TargetSelector) error {
for _, fp := range selector.FieldPaths {
createKind := yaml.Kind(0) // do not create
ignoreMissingField := false
if selector.Options != nil {
ignoreMissingField = selector.Options.IgnoreMissingField
}
if selector.Options != nil && selector.Options.Create {
createKind = value.YNode().Kind
}
targetFieldList, err := target.Pipe(&yaml.PathMatcher{
Path: kyaml_utils.SmarterPathSplitter(fp, "."),
Create: createKind})
if err != nil {
if err != nil && !ignoreMissingField {
return errors.WrapPrefixf(err, fieldRetrievalError(fp, createKind != 0)) //nolint:govet
}
targetFields, err := targetFieldList.Elements()
if err != nil {
if err != nil && !ignoreMissingField {
return errors.WrapPrefixf(err, fieldRetrievalError(fp, createKind != 0)) //nolint:govet
}
if len(targetFields) == 0 {
if len(targetFields) == 0 && !ignoreMissingField {
return errors.Errorf(fieldRetrievalError(fp, createKind != 0)) //nolint:govet
}

Expand Down
139 changes: 139 additions & 0 deletions api/filters/replacement/replacement_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2830,6 +2830,145 @@ spec:
`,
expectedErr: "unable to find or create field \"spec.tls.5.hosts.5\" in replacement target: index 5 specified but only 0 elements found",
},
"replace target path and ignore missing fields": {
input: `apiVersion: v1
kind: ConfigMap
metadata:
name: clusterConfig
data:
accountId: "123456789101"
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: service-account-with-field
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::REPLACEME:role/super-admin
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: service-account-without-field
`,
replacements: `replacements:
- source:
kind: ConfigMap
name: clusterConfig
fieldPath: data.accountId
targets:
- select:
kind: ServiceAccount
fieldPaths:
- metadata.annotations.[eks.amazonaws.com/role-arn]
options:
# not all Service Accounts have irsa annotations
ignoreMissingField: true
delimiter: ":"
index: 4
`,
expected: `apiVersion: v1
kind: ConfigMap
metadata:
name: clusterConfig
data:
accountId: "123456789101"
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: service-account-with-field
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::123456789101:role/super-admin
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: service-account-without-field`,
},
"no replacement or error with ignore missing fields when there is no matching field": {
input: `apiVersion: v1
kind: ConfigMap
metadata:
name: clusterConfig
data:
accountId: "123456789101"
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: service-account-without-field
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: service-account-without-field-again
`,
replacements: `replacements:
- source:
kind: ConfigMap
name: clusterConfig
fieldPath: data.accountId
targets:
- select:
kind: ServiceAccount
fieldPaths:
- metadata.annotations.[eks.amazonaws.com/role-arn]
options:
# not all Service Accounts have irsa annotations
ignoreMissingField: true
delimiter: ":"
index: 4
`,
expected: `apiVersion: v1
kind: ConfigMap
metadata:
name: clusterConfig
data:
accountId: "123456789101"
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: service-account-without-field
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: service-account-without-field-again`,
},
"non matching field with no options": {
input: `apiVersion: v1
kind: ConfigMap
metadata:
name: clusterConfig
data:
accountId: "123456789101"
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: service-account-with-field
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::REPLACEME:role/super-admin
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: service-account-without-field-again
`,
replacements: `replacements:
- source:
kind: ConfigMap
name: clusterConfig
fieldPath: data.accountId
targets:
- select:
kind: ServiceAccount
fieldPaths:
- metadata.annotations.[eks.amazonaws.com/role-arn]
`,
expectedErr: `unable to find field "metadata.annotations.[eks.amazonaws.com/role-arn]" in replacement target`,
},
}

for tn, tc := range testCases {
Expand Down
7 changes: 5 additions & 2 deletions api/types/replacement.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,14 @@ type FieldOptions struct {

// If field missing, add it.
Create bool `json:"create,omitempty" yaml:"create,omitempty"`

// If field missing, ignore it.
IgnoreMissingField bool `json:"ignoreMissingField,omitempty" yaml:"ignoreMissingField,omitempty"`
}

func (fo *FieldOptions) String() string {
if fo == nil || (fo.Delimiter == "" && !fo.Create) {
if fo == nil || (fo.Delimiter == "" && !fo.Create && !fo.IgnoreMissingField) {
return ""
}
return fmt.Sprintf("%s(%d), create=%t", fo.Delimiter, fo.Index, fo.Create)
return fmt.Sprintf("%s(%d), create=%t, ignoreMissingField=%t", fo.Delimiter, fo.Index, fo.Create, fo.IgnoreMissingField)
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ replacements:
delimiter: string
index: int
create: bool
ignoreMissingField: bool
targets:
- select:
group: string
Expand Down Expand Up @@ -103,6 +104,7 @@ replacements:
|`delimiter`| | Used to split/join the field
|`index`| | Which position in the split to consider | `0`
|`create`| | If target field is missing, add it | `false`
|`ignoreMissingField`| | If target field is missing, ignore it | `false`

#### Source
The source field is a selector that determines the source of the value by finding a
Expand Down