Skip to content
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
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,26 @@ mappings:
secretName: k8s-secretname
vaultEngineType: # optionally "kv" or "kv-v2" to override the defaultEngineType specified above
secretType: Opaque # optionally - default "Opaque" e.g.: "kubernetes.io/tls"
additionalSecretLabels: # optionally add labels to the secret
environment: dev
team: core-services
# mappings from google secrets manager paths to kubernetes secret names
- sourceType: gsm
path: projects/my-project/secrets/my-secret/versions/latest
secretName: my-secret
- sourceType: gsm
path: projects/my-project/secrets/my-other-secret
secretName: defaults-to-latest-version
additionalSecretLabels:
environment: dev
team: core-services
```

### Labels and Reconciliation
By default, Pentagon will add a [metadata label](https://godoc.org/k8s.io/apimachinery/pkg/apis/meta/v1#ObjectMeta) with the key `pentagon` and the value `default`. At the least, this helps identify Pentagon as the creator and maintainer of the secret.

You can also specify custom labels for each secret mapping using the `additionalSecretLabels` filed. These labels will be added to the Kubernetes secret alongside the required `pentagon` label.

If you set the `label` configuration parameter, you can control the value of the label, allowing multiple Pentagon instances to exist without stepping on each other. Setting a non-default `label` also enables reconciliation which will cleanup any secrets that were created by Pentagon with a matching label, but are no longer present in the `mappings` configuration. This provides a simple way to ensure that old secret data does not remain present in your system after its time has passed.

### About Vault Engine Types
Expand Down
9 changes: 9 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,11 @@ func (c *Config) SetDefaults() {
if m.SourceType == GSMSourceType && !gsmVersionSuffix.MatchString(m.Path) {
c.Mappings[i].Path = path.Join(m.Path, gsmLatestSuffix)
}

if m.AdditionalSecretLabels == nil {
c.Mappings[i].AdditionalSecretLabels = make(map[string]string)
}

}
}

Expand Down Expand Up @@ -191,4 +196,8 @@ type Mapping struct {
// use for this secret's value in cases where gsmEncodingType is *not* json. If
// this is unset, the key name will default to the value of secretName.
GSMSecretKeyValue string `yaml:"gsmSecretKeyValue"`

// AdditionalSecretLabels allows you to specify the additional labels that will be
// added to the created Kubernetes secret.
AdditionalSecretLabels map[string]string `yaml:"additionalSecretLabels"`
}
6 changes: 5 additions & 1 deletion reflector.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"encoding/json"
"fmt"
"log"
"maps"

"cloud.google.com/go/secretmanager/apiv1/secretmanagerpb"
corev1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -186,11 +187,14 @@ func (r *Reflector) getGSMSecret(ctx context.Context, mapping Mapping) (map[stri
}

func (r *Reflector) createK8sSecret(ctx context.Context, mapping Mapping, data map[string][]byte) error {
labels := maps.Clone(mapping.AdditionalSecretLabels)
labels[LabelKey] = r.labelValue

secret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: mapping.SecretName,
Namespace: r.k8sNamespace,
Labels: map[string]string{LabelKey: r.labelValue},
Labels: labels,
},
Data: data,
Type: mapping.SecretType,
Expand Down
Loading