# Rewriting Keys in DataFrom When calling out an ExternalSecret with `dataFrom.extract` or `dataFrom.find`, it is possible that you end up with a kubernetes secret that has conflicts in the key names, or that you simply want to remove a common path from the secret keys. In order to do so, it is possible to define a set of rewrite operations using `dataFrom.rewrite`. These operations can be stacked, hence allowing complex manipulations of the secret keys. Rewrite operations are all applied before `ConversionStrategy` is applied. ## Methods ### Regexp This method implements rewriting through the use of regular expressions. It needs a `source` and a `target` field. The source field is where the definition of the matching regular expression goes, where the `target` field is where the replacing expression goes. ### Transform This method uses Go templating to rewrite the keys of each secret. The `template` field is used to specify the template. You can reference the key of each secret by the `.value` string. You can also use [helper functions](templating.md#helper-functions) in the template. ### Merge This method implements rewriting keys by merging operation and solving key collisions. It supports two merging strategies: `Extract` and `JSON`. The `Extract` strategy interprets all secret values in the secret map as JSON and merges all contained key/value pairs hoisting them to the top level, substituting the original secret map. The `JSON` strategy interprets all secret values in the secret map as JSON and merges all contained key/value pairs in the key specified by the _required_ parameter `into`. If the key specified by `into` already exists in the original secrets map it will be overwritten. Key collisions can be ignored or cause an error according to `conflictPolicy` which can be either `Ignore` or `Error`. To guarantee deterministic results of the merge operation, secret keys are processed in alphabetical order. Key priority can also be made explicit by providing a list of secret keys in the `priority` parameter. These keys will be processed last in the order they appear while all other keys will still be processed in alphabetical order. Specifying a key in the `priority` list which is not found in the source secret will cause an error. You can override this behavior setting `priorityPolicy` to `IgnoreNotFound` instead of the default `Strict`. ## Considerations about Rewrite implementation 1. The input of a subsequent rewrite operation are the outputs of the previous rewrite. 2. If a given set of keys do not match any Rewrite operation, there will be no error. Rather, the original keys will be used. 3. In Regexp operations, if a `source` is not a compilable `regexp` expression, an error will be produced and the external secret will go into a error state. 4. In Merge operations, if secrets are not valid JSON, an error will be produced and the external secret will go into an error state. ## Examples ### Removing a common path from find operations The following ExternalSecret: ```yaml {% include 'datafrom-rewrite-remove-path.yaml' %} ``` Will get all the secrets matching `path/to/my/secrets/*` and then rewrite them by removing the common path away. In this example, if we had the following secrets available in the provider: ``` path/to/my/secrets/username path/to/my/secrets/password ``` the output kubernetes secret would be: ```yaml apiVersion: v1 kind: Secret type: Opaque data: username: ... password: ... ``` ### Avoiding key collisions The following ExternalSecret: ```yaml {% include 'datafrom-rewrite-conflict.yaml' %} ``` Will allow two secrets with the same JSON keys to be imported into a Kubernetes Secret without any conflict. In this example, if we had the following secrets available in the provider: ```json { "my-secrets-dev": { "password": "bar", }, "my-secrets-prod": { "password": "safebar", } } ``` the output kubernetes secret would be: ```yaml apiVersion: v1 kind: Secret type: Opaque data: dev_password: YmFy #bar prod_password: c2FmZWJhcg== #safebar ``` ### Remove invalid characters The following ExternalSecret: ```yaml {% include 'datafrom-rewrite-invalid-characters.yaml' %} ``` Will remove invalid characters from the secret key. In this example, if we had the following secrets available in the provider: ```json { "development": { "foo/bar": "1111", "foo$baz": "2222" } } ``` the output kubernetes secret would be: ```yaml apiVersion: v1 kind: Secret type: Opaque data: foo_bar: MTExMQ== #1111 foo_baz: MjIyMg== #2222 ``` ### Merging all secrets The following ExternalSecret: ```yaml {% include 'datafrom-rewrite-merge-empty.yaml' %} ``` Will merge all keys found in all secrets at top level. In this example, if we had the following secrets available in the provider: ```json { "path/to/secrets/object-storage-credentials": { "ACCESS_KEY": "XXXX", "SECRET_KEY": "YYYY" }, "path/to/secrets/mongo-credentials": { "USERNAME": "XXXX", "PASSWORD": "YYYY" } } ``` the output kubernetes secret would be: ```yaml apiVersion: v1 kind: Secret type: Opaque data: ACCESS_KEY: WFhYWA== #XXXX SECRET_KEY: WVlZWQ== #YYYY USERNAME: WFhYWA== #XXXX PASSWORD: WVlZWQ== #YYYY ``` ### Transform secret keys The following ExternalSecret: ```yaml {% include 'datafrom-rewrite-transform.yaml' %} ``` Uses a template to transform all secret keys into an "environment variable" format by capitalizing, replacing `-` with `_` and prefixing them with `ENV_`. In this example, if we had the following secrets available in the provider: ```json { "foo-nut-bar": "HELLO1" "foo-naz-bar": "HELLO2" "foo-bar-baz": '{"john": "doe"}' } ``` the output kubernetes secret would be: ```yaml apiVersion: v1 kind: Secret type: Opaque data: ENV_FOO_BAR_BAZ: eyJqb2huIjogImRvZSJ9 ENV_FOO_NAZ_BAR: SEVMTE8y ENV_FOO_NUT_BAR: SEVMTE8x ``` ## Limitations Regexp Rewrite is based on golang `regexp`, which in turns implements `RE2` regexp language. There a a series of known limitations to this implementation, such as: * Lack of ability to do lookaheads or lookbehinds; * Lack of negation expressions; * Lack of support for conditional branches; * Lack of support for possessive repetitions. A list of compatibility and known limitations considering other commonly used regexp frameworks (such as PCRE and PERL) are listed [here](https://github.com/google/re2/wiki/Syntax).