SecretMangler is a Kubernetes operator used to create secrets based on parts of other secrets or to mirror existing secrets.
An example for a secret constructed from parts of other secrets would look like the following:
---
apiVersion: secret-mangler.wreiner.at/v1alpha1
kind: SecretMangler
metadata:
name: mangler01
namespace: aha
spec:
secretTemplate:
apiVersion: v1
kind: Secret
namespace: aha
name: "mangler01-secret"
cascadeMode: [KeepNoAction|KeepLostSync|RemoveLostSync|CascadeDelete]
mappings:
fixedmapping: "some-value-which-will-used-as-is"
dynamicmapping: "[NAMESPACE/]OBJECT_NAME:LOOKUP_FIELD"
The dynamicmapping field explained:
<[NAMESPACE/]OBJECT_NAME:LOOKUP_FIELD>
[NAMESPACE/] .. namespace of the referenced secret
If omitted the namespace of the SecretMangler object is used.
OBJECT_NAME .. name of the referenced secret
LOOKUP_FIELD .. key value of the Data field of the referenced secret
Please note: The SecretMangler object needs to be added in the same namespace as the secret it should generate.
There are different edge cases which need to be taken care of or at least be discussed when working with objects accross multiple namespaces.
The SecretMangler operator handles those edge cases with an cascadeMode field:
cascadeMode: [KeepNoAction|KeepLostSync|RemoveLostSync|CascadeDelete]
On initial secret creation the secret is only created if all dynamic field mappings are found. If not, the secret will not be initially created.
cascadeMode | Function |
---|---|
KeepNoAction | Keeps the secret the way it was initially created or last changed and no sync of changes in referenced secrets is performed. |
KeepLostSync | Tries to sync data from referenced secrets. If one or more sources are lost their data is kept as it was synced last. |
RemoveLostSync | Tries to sync data from referenced secrets. If one or more sources are lost their data will be removed from the created secret. If no more sources are available and no fixed mappings are present the secret will be removed as a whole. |
CascadeDelete | Removes the secret entirely if only one source is lost no matter whether other sources are still present or not. |
For all modes if the data part of the secret would be empty the secret is being removed entirely.
- Initial secret creation
- If not all dynamic mappings are found do not create
- Create the new secret if all dynamic mappings are found
- If the new secret was created earlier and a reference gets changed handle it with:
- KeepNoAction = keep as is - keep the new secret the way it was initially created and do not sync changes of sources
- KeepLostSync = keep lost but sync present - if one source was deleted keep existing data but update all sources which can be found
- RemoveLostSync = remove lost and sync present - if one source was delted remove its data and sync all other sources
- if no more sources and no fixedmapping is present delete the secret
- CascadeDelete = cascade delete - if one source was deleted remove the complete generated secret
To install the secret-mangler-operator using Helm you can use the official helm chart:
helm repo add smo https://wreiner.github.io/secret-mangler-operator
helm repo update
helm install smo smo/secret-mangler-operator
- subscribe to created secret to handle
- subscribe to source secret
- define edge cases
- implement mirror function
An example for mirroring a secret:
---
apiVersion: secret-mangler.wreiner.at/v1alpha1
kind: SecretMangler
metadata:
name: mangler01
namespace: aha
spec:
secretTemplate:
apiVersion: v1
kind: Secret
namespace: aha
name: "mangler01-secret"
mirror: <[NAMESPACE/]OBJECT_NAME:LOOKUP_FIELD>
Please note that mirror and mappings will be mutually exclusive.
If mirror is defined the referenced secret data is mirrored as a whole and also the secret type is kept from the referenced secret. Labels and annotations from the referenced secret are not kept. Mappings are not possible in this situation.
If mappings is defined mirror can not be defined too.
To run the tests change into the controllers directory and either use
export USE_EXISTING_CLUSTER=true
go test ./...
or use Ginkgo:
export USE_EXISTING_CLUSTER=true
go install github.com/onsi/ginkgo/ginkgo@latest
export PATH=$PATH:~/go/bin
ginkgo -r
Using Ginkgo directly runs tests sequentially, using go test runs them in parallel.
- When using Helm use the lookup function
- Using Reflector to mirror secrets and configmaps
- Using Red Hat Service Binding Operator to project data into pods