Skip to content

Commit

Permalink
fix: handle path indicies, docs updates
Browse files Browse the repository at this point in the history
  • Loading branch information
meganwolf0 committed Nov 4, 2024
1 parent 4ab6611 commit b2dba9c
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 10 deletions.
2 changes: 2 additions & 0 deletions docs/cli-commands/lula_dev_validate.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ To hang for timeout of 5 seconds:
-h, --help help for validate
-f, --input-file string the path to a validation manifest file (default "0")
-o, --output-file string the path to write the validation with results
--print-test-resources whether to print resources used for tests; prints <test-name>.json to the validation directory
-r, --resources-file string the path to an optional resources file
--run-tests run tests specified in the validation
-t, --timeout int the timeout for stdin (in seconds, -1 for no timeout) (default 1)
```

Expand Down
24 changes: 22 additions & 2 deletions docs/reference/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ The path should be a "." delimited string that specifies the keys along the path
pods.[metadata.namespace=grafana].spec.containers.[name=istio-proxy]
```

Will start at the pods key, then since the next item is a [*] it assumes pods is a list, and will iterate over each item in the list to find where the key metadata.namespace is equal to grafana It will then find the item where the key spec.containers is a list, and iterate over each item in the list to find where the key name is equal to istio-proxy
Will start at the pods key, then since the next item is a [*=*] it assumes pods is a list, and will iterate over each item in the list to find where the key `metadata.namespace` is equal to `grafana`. It will then find the `containers` list item in `spec`, and iterate over each item in the list to find where the key `name` is equal to `istio-proxy`.

Multiple filters can be added for a list, for example the above example could be modified to filter both by namespace and pod name:

Expand All @@ -88,7 +88,13 @@ To support map keys containing ".", [] syntax will also be used, e.g.,
namespaces.[metadata.namespace=grafana].metadata.labels.["some.key/label"]
```
Do not use the "[]" syntax for anything other than a key containing a ".", else the path will not be parsed correctly.
Additionally, individual list items can be found via their index, e.g.,
```
namespaces.[0].metadata.labels
```
Which will point to the labels key of the first namespace. Additionally, a `[-]` can be used to specify the last item in the list.
>[!IMPORTANT]
> The path will return only one item, the first item that matches the filters along the path. If no items match the filters, the path will return an empty map.
Expand All @@ -106,6 +112,20 @@ Do not use the "[]" syntax for anything other than a key containing a ".", else
* Currently only supports deleting a key, error will be returned if the last item in the path resolves to a sequence.
* No values should be specified for delete.
A note about replacing a key with an empty map - due to the way the `kyaml` library works, simply trying to overwrite an existing key with an empty map will not yield a removal of all the existing data of the map, it will just try and merge the differences, which is possibly not the desired outcome. To replace a map with an empty map, you must combine `delete` a change type and `add` a change type, e.g.,
```yaml
changes:
- path: pods.[metadata.namespace=grafana].metadata.labels
type: delete
- path: pods.[metadata.namespace=grafana].metadata
type: add
value-map:
labels: {}
```

Which will delete the existing labels map and then add an empty map, such that the "labels" key will still exist but will be an empty map.

## Executing Tests

Tests can be executed by specifying the `--run-tests` flag when running `lula dev validate`. E.g.,
Expand Down
8 changes: 8 additions & 0 deletions src/internal/transform/filters.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ type filterParts struct {

// BuildFilters builds kyaml filters from a pathSlice
func BuildFilters(targetNode *yaml.RNode, pathSlice []string) ([]yaml.Filter, error) {
if targetNode == nil {
return nil, fmt.Errorf("root node is nil")
}

filters := make([]yaml.Filter, 0)
for _, segment := range pathSlice {
if isFilter, filterParts, err := extractFilter(segment); err != nil {
Expand Down Expand Up @@ -106,6 +110,10 @@ func returnIndexFromComplexFilters(targetNode *yaml.RNode, parentFilters []yaml.
return index, err
}

if parentNode == nil {
return index, fmt.Errorf("parent node is not found for filters: %v", parentFilters)
}

if parentNode.YNode().Kind == yaml.SequenceNode {
nodes, err := parentNode.Elements()
if err != nil {
Expand Down
13 changes: 11 additions & 2 deletions src/internal/transform/transform.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,9 @@ func (t *TransformTarget) ExecuteTransform(path string, cType ChangeType, value

// Set the node back into the target
if len(pathSlice) == 0 {
t.RootNode = node
rootNodeCopy = node
} else {
if err := SetNodeAtPath(t.RootNode, node, filters, pathSlice); err != nil {
if err := SetNodeAtPath(rootNodeCopy, node, filters, pathSlice); err != nil {
return nil, fmt.Errorf("error setting merged node back into target: %v", err)
}
}
Expand Down Expand Up @@ -205,10 +205,19 @@ func CalcPath(path string, cType ChangeType) ([]string, string, error) {
return pathSlice, lastSegment, nil
}

// cleanPath cleans the path slice
func cleanPath(pathSlice []string) []string {
for i, p := range pathSlice {
// Remove escaped double quotes
p = strings.ReplaceAll(p, "\"", "")
pathSlice[i] = p

if isFilter(p) {
// If there's no equal, assume item is a key, NOT a filter
if !strings.Contains(p, "=") {
pathSlice[i] = strings.TrimPrefix(strings.TrimSuffix(p, "]"), "[")
}
}
}
return pathSlice
}
Expand Down
10 changes: 4 additions & 6 deletions src/internal/transform/transform_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -594,11 +594,10 @@ foo:
},
{
name: "update-list-at-root",
path: "foo",
path: ".",
changeType: transform.ChangeTypeUpdate,
target: []byte(`
foo:
subset:
- uuid: abc
subsubset:
- uuid: 321
Expand All @@ -613,15 +612,14 @@ foo:
test: some data to be replaced
`),
valueByte: []byte(`
subset:
foo:
- uuid: hi
test: hi
`),
expected: []byte(`
foo:
subset:
- uuid: hi
test: hi
- uuid: hi
test: hi
`),
},
{
Expand Down

0 comments on commit b2dba9c

Please sign in to comment.