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

Example, README and output for search and replace #194

Merged
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
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
runCount: 2
11 changes: 11 additions & 0 deletions examples/mutators/search-replace/simple/.expected/diff.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
diff --git a/resources.yaml b/resources.yaml
index 7481208..1055c0f 100644
--- a/resources.yaml
+++ b/resources.yaml
@@ -1,5 +1,5 @@
apiVersion: apps/v1
kind: Deployment
metadata:
- name: the-deployment
+ name: my-deployment
namespace: my-space
1 change: 1 addition & 0 deletions examples/mutators/search-replace/simple/.krmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.expected
58 changes: 58 additions & 0 deletions examples/mutators/search-replace/simple/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# search-replace: Simple Example

The `search-replace` function performs search and optionally replace fields
across all resources.

This is a simple example depicting search and replace operation on KRM resource config.

Let's start with the input resource

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: the-deployment
namespace: my-space
```

Search matchers are provided with `by-` prefix. When multiple matchers are
provided they are AND’ed together. `put-` matchers are mutually exclusive.

We use the following ConfigMap to provide input matchers to the function.

```yaml
apiVersion: v1
kind: ConfigMap
metadata: ...
data:
by-path: metadata.name
by-value: the-deployment
put-value: my-deployment
```

Invoking `search-replace` function would apply the changes to resource configs

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-deployment
namespace: my-space
```

## Function invocation

Get the config example and try it out by running the following commands:

```sh
kpt pkg get https://github.com/GoogleContainerTools/kpt-functions-catalog.git/examples/mutators/search/simple .
kpt fn run simple
```

## Expected result

Check the value of deployment `the-deloyment` is changed to `my-deloyment`.

```sh
kpt cfg cat simple
```
12 changes: 12 additions & 0 deletions examples/mutators/search-replace/simple/fn-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: my-func-config
annotations:
config.k8s.io/function: |
container:
image: gcr.io/kpt-fn/search-replace:unstable
data:
by-path: metadata.name
by-value: the-deployment
put-value: my-deployment
5 changes: 5 additions & 0 deletions examples/mutators/search-replace/simple/resources.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: the-deployment
namespace: my-space
3 changes: 2 additions & 1 deletion functions/go/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ FUNCTIONS := \
set-annotation \
set-namespace \
starlark \
apply-setters
apply-setters \
search-replace

# Targets for running all function tests
FUNCTION_TESTS := $(patsubst %,%-TEST,$(FUNCTIONS))
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module github.com/GoogleContainerTools/kpt-functions-catalog/functions/go/search
module github.com/GoogleContainerTools/kpt-functions-catalog/functions/go/search-replace

go 1.15

Expand Down
File renamed without changes.
118 changes: 118 additions & 0 deletions functions/go/search-replace/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package main

import (
"fmt"
"os"

"sigs.k8s.io/kustomize/kyaml/fn/framework"
kyaml "sigs.k8s.io/kustomize/kyaml/yaml"
)

//nolint
func main() {
resourceList := &framework.ResourceList{}
resourceList.FunctionConfig = map[string]interface{}{}
cmd := framework.Command(resourceList, func() error {
resourceList.Result = &framework.Result{
Name: "search-replace",
}
items, err := run(resourceList)
if err != nil {
resourceList.Result.Items = getErrorItem(err.Error())
return resourceList.Result
}
resourceList.Result.Items = items
return nil
})

cmd.Long = usage()
if err := cmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}

// run resolves the function params and runs the function on resources
func run(resourceList *framework.ResourceList) ([]framework.Item, error) {
sr, err := getSearchReplaceParams(resourceList.FunctionConfig)
if err != nil {
return nil, err
}

_, err = sr.Filter(resourceList.Items)
if err != nil {
return nil, err
}

return searchResultsToItems(sr), nil
}
func usage() string {
return `` // TODO: pmarupaka add usage docs
}

// getSearchReplaceParams retrieve the search parameters from input config
func getSearchReplaceParams(fc interface{}) (SearchReplace, error) {
var fcd SearchReplace
f, ok := fc.(map[string]interface{})
if !ok {
return fcd, fmt.Errorf("function config %#v is not valid", fc)
}
rn, err := kyaml.FromMap(f)
if err != nil {
return fcd, fmt.Errorf("failed to parse input from function config: %w", err)
}

decode(rn, &fcd)
return fcd, nil
}

// decode decodes the input yaml node into SearchReplace struct
func decode(rn *kyaml.RNode, fcd *SearchReplace) {
dm := rn.GetDataMap()
fcd.ByPath = getValue(dm, "by-path")
fcd.ByValue = getValue(dm, "by-value")
fcd.ByValueRegex = getValue(dm, "by-value-regex")
fcd.PutValue = getValue(dm, "put-value")
fcd.PutComment = getValue(dm, "put-comment")
}

// getValue returns the value for 'key' in map 'm'
// returns empty string if 'key' doesn't exist in 'm'
func getValue(m map[string]string, key string) string {
if val, ok := m[key]; ok {
return val
}
return ""
}

// searchResultsToItems converts the Search and Replace results to
// equivalent items([]framework.Item)
func searchResultsToItems(sr SearchReplace) []framework.Item {
var items []framework.Item
for _, res := range sr.Results {

var message string
if sr.PutComment != "" || sr.PutValue != "" {
message = fmt.Sprintf("Mutated field value to %q", res.Value)
} else {
message = fmt.Sprintf("Matched field value %q", res.Value)
}

items = append(items, framework.Item{
Message: message,
Field: framework.Field{Path: res.FieldPath},
File: framework.File{Path: res.FilePath},
})
}
return items
}

// getErrorItem returns the item for input error message
func getErrorItem(errMsg string) []framework.Item {
return []framework.Item{
{
Message: fmt.Sprintf("failed to perform search-replace operation: %q", errMsg),
Severity: framework.Error,
},
}
}
File renamed without changes.
72 changes: 0 additions & 72 deletions functions/go/search/main.go

This file was deleted.