Skip to content

Commit

Permalink
Adds support for password rotation on databases
Browse files Browse the repository at this point in the history
  • Loading branch information
digiserg committed Dec 13, 2021
1 parent 550340a commit ae5f56c
Show file tree
Hide file tree
Showing 20 changed files with 836 additions and 410 deletions.
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ KUSTOMIZE = $(shell pwd)/bin/kustomize
kustomize: ## Download kustomize locally if necessary.
$(call go-get-tool,$(KUSTOMIZE),sigs.k8s.io/kustomize/kustomize/v3@v3.8.7)

release: docker-build ## Create a new release
cp config/crd/bases/digitalis.io_valssecrets.yaml charts/vals-operator/crds/valssecrets.yaml


# go-get-tool will 'go get' any package $2 and install it to $1.
PROJECT_DIR := $(shell dirname $(abspath $(lastword $(MAKEFILE_LIST))))
define go-get-tool
Expand Down
62 changes: 60 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,67 @@ The `TTL` is optional and used to decrease the number of times the operator call

The default encoding is `text` but you can change it to `base64` per secret reference. This way you can, for example, base64 encode large configuration files.

# Advance config: password rotation

If you're running a database you may want to keep the secrets in sync between your secrets store, Kubernetes and the database. This can be handy for password rotation to ensure the clients don't use the same password all the time. Please be aware your client *must* suppport re-reading the secret and reconnecting whenever it is updated.

We don't yet support TLS, we'll add it to future releases.

```yaml
---
apiVersion: digitalis.io/v1
kind: ValsSecret
metadata:
name: vals-secret-sample
labels:
owner: digitalis.io
spec:
name: my-secret # Optional, default is the resource name
ttl: 10 # Optional, default is 0. The secret will be checked at every "reconcile period". See below.
type: Opaque # Default type, others supported
data:
username:
ref: ref+gcpsecrets://databases/test#username
encoding: text
password:
ref: ref+gcpsecrets://databases/test#password
encoding: text
databases:
- driver: cassandra
loginCredentials:
secretName: cassandra-creds # secret containing the username and password to access the DB and run the below query
usernameKey: username # in the secret, which key contains the username (default `cassandra`)
passwordKey: password # in the secret, which key contains the password
port: 9042
query: "ALTER ROLE '{{.username}}' WITH PASSWORD = '{{.password}}';"
hosts: # list all your cassandra nodes here
- cassandra01
- cassandra02
- driver: postgres
loginCredentials:
secretName: postgres-creds
usernameKey: username
passwordKey: password
port: 5432
query: "ALTER USER {{.username}} WITH PASSWORD '{{.password}}';"
hosts:
- postgres
- driver: mysql
loginCredentials:
secretName: mysql-creds
namespace: mysql-server
passwordKey: mysql-root-password # if username is omitted it default to `mysql`
port: 3306
query: "ALTER USER '{{.username}}'@'localhost' IDENTIFIED BY '{{.password}}';"
hosts:
- mysql
```
# Options
The following options are available. See the [helm chart documentation](charts/vals-operator/README.md) for more information on adding them to your deployment configuration.
```sh
Usage of ./bin/vals-operator:
-exclude-namespaces string
Comma separated list of namespaces to ignore.
-health-probe-bind-address string
Expand All @@ -116,9 +172,11 @@ The following options are available. See the [helm chart documentation](charts/v
-metrics-bind-address string
The address the metric endpoint binds to. (default ":8080")
-reconcile-period duration
How often the controller will re-queue secretdefinition events (default 5s)
How often the controller will re-queue vals-operator events. (default 5s)
-record-changes
Records every time a secret has been updated. You can view them with kubectl describe (default true)
Records every time a secret has been updated. You can view them with kubectl describe. It may also be disabled globally and enabled per secret via the annotation 'vals-operator.digitalis.io/record: "true"' (default true)
-ttl duration
How often to check backend for updates. (default 5m0s)
-watch-namespaces string
Comma separated list of namespaces that vals-operator will watch.
-zap-devel
Expand Down
37 changes: 33 additions & 4 deletions api/v1/valssecret_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,41 @@ type DataSource struct {
Encoding string `json:"encoding,omitempty"`
}

type DatabaseLoginCredentials struct {
// Name of the secret containing the credentials to be able to log in to the database
SecretName string `json:"secretName"`
// Optional namespace of the secret, default current namespace
Namespace string `json:"namespace,omitempty"`
// Key in the secret containing the database username
UsernameKey string `json:"usernameKey,omitempty"`
// Key in the secret containing the database username
PasswordKey string `json:"passwordKey"`
}

type Database struct {
// Defines the database type
Driver string `json:"driver"`
// Credentials to access the database
LoginCredentials DatabaseLoginCredentials `json:"loginCredentials,omitempty"`
// Database port number
Port int `json:"port,omitempty"`
// Key in the secret containing the database username
UsernameKey string `json:"usernameKey,omitempty"`
// Key in the secret containing the database username
PasswordKey string `json:"passwordKey"`
// Used for MySQL only, the host part for the username
UserHost string `json:"userHost,omitempty"`
// List of hosts to connect to, they'll be tried in sequence until one succeeds
Hosts []string `json:"hosts"`
}

// ValsSecretSpec defines the desired state of ValsSecret
type ValsSecretSpec struct {
Name string `json:"name,omitempty"`
Data map[string]DataSource `json:"data"`
Ttl int64 `json:"ttl,omitempty"`
Type string `json:"type,omitempty"`
Name string `json:"name,omitempty"`
Data map[string]DataSource `json:"data"`
Ttl int64 `json:"ttl,omitempty"`
Type string `json:"type,omitempty"`
Databases []Database `json:"databases,omitempty"`
}

// ValsSecretStatus defines the observed state of ValsSecret
Expand Down
43 changes: 43 additions & 0 deletions api/v1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 8 additions & 18 deletions charts/vals-operator/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,14 @@ name: vals-operator
description: This helm chart installs the Digitalis Vals Operator to manage sync secrets from supported backends into Kubernetes
icon: https://digitalis.io/wp-content/uploads/2020/06/cropped-Digitalis-512x512-Blue_Digitalis-512x512-Blue-32x32.png
kubeVersion: ">= 1.19"

# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application

# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.2.0
# Chart version
version: 0.3.0
# Latest container tag
appVersion: "v0.4.0"

# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "v0.3.0"
kubeVersion: '>= 1.19'
maintainers:
- email: info@digitalis.io
name: Digitalis.IO
5 changes: 1 addition & 4 deletions charts/vals-operator/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@ vals-operator
=============
This helm chart installs the Digitalis Vals Operator to manage sync secrets from supported backends into Kubernetes

Current chart version is `0.1.0`



Current chart version is `0.4.0`


## Chart Values
Expand Down
51 changes: 51 additions & 0 deletions charts/vals-operator/crds/valssecrets.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,57 @@ spec:
- ref
type: object
type: object
databases:
items:
properties:
driver:
description: Defines the database type
type: string
hosts:
description: List of hosts to connect to, they'll be tried in
sequence until one succeeds
items:
type: string
type: array
loginCredentials:
description: Credentials to access the database
properties:
namespace:
description: Optional namespace of the secret, default current
namespace
type: string
passwordKey:
description: Key in the secret containing the database username
type: string
secretName:
description: Name of the secret containing the credentials
to be able to log in to the database
type: string
usernameKey:
description: Key in the secret containing the database username
type: string
required:
- passwordKey
- secretName
type: object
passwordKey:
description: Key in the secret containing the database username
type: string
port:
description: Database port number
type: integer
userHost:
description: Used for MySQL only, the host part for the username
type: string
usernameKey:
description: Key in the secret containing the database username
type: string
required:
- driver
- hosts
- passwordKey
type: object
type: array
name:
type: string
ttl:
Expand Down
50 changes: 26 additions & 24 deletions charts/vals-operator/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,30 +23,32 @@ manageCrds: true

# additional arguments to operator
args: []
# -exclude-namespaces string
# Comma separated list of namespaces to ignore.
# -health-probe-bind-address string
# The address the probe endpoint binds to. (default ":8081")
# -kubeconfig string
# Paths to a kubeconfig. Only required if out-of-cluster.
# -leader-elect
# Enable leader election for controller manager. Enabling this will ensure there is only one active controller manager.
# -metrics-bind-address string
# The address the metric endpoint binds to. (default ":8080")
# -reconcile-period duration
# How often the controller will re-queue secretdefinition events (default 5s)
# -record-changes
# Records every time a secret has been updated. You can view them with kubectl describe. It may also be disabled globally and enabled per secret via the annotation 'vals-operator.digitalis.io/record: "true"' (default true)
# -watch-namespaces string
# Comma separated list of namespaces that vals-operator will watch.
# -zap-devel
# Development Mode defaults(encoder=consoleEncoder,logLevel=Debug,stackTraceLevel=Warn). Production Mode defaults(encoder=jsonEncoder,logLevel=Info,stackTraceLevel=Error) (default true)
# -zap-encoder value
# Zap log encoding (one of 'json' or 'console')
# -zap-log-level value
# Zap Level to configure the verbosity of logging. Can be one of 'debug', 'info', 'error', or any integer value > 0 which corresponds to custom debug levels of increasing verbosity
# -zap-stacktrace-level value
# Zap Level at and above which stacktraces are captured (one of 'info', 'error', 'panic').
# -exclude-namespaces string
# Comma separated list of namespaces to ignore.
# -health-probe-bind-address string
# The address the probe endpoint binds to. (default ":8081")
# -kubeconfig string
# Paths to a kubeconfig. Only required if out-of-cluster.
# -leader-elect
# Enable leader election for controller manager. Enabling this will ensure there is only one active controller manager.
# -metrics-bind-address string
# The address the metric endpoint binds to. (default ":8080")
# -reconcile-period duration
# How often the controller will re-queue vals-operator events. (default 5s)
# -record-changes
# Records every time a secret has been updated. You can view them with kubectl describe. It may also be disabled globally and enabled per secret via the annotation 'vals-operator.digitalis.io/record: "true"' (default true)
# -ttl duration
# How often to check backend for updates. (default 5m0s)
# -watch-namespaces string
# Comma separated list of namespaces that vals-operator will watch.
# -zap-devel
# Development Mode defaults(encoder=consoleEncoder,logLevel=Debug,stackTraceLevel=Warn). Production Mode defaults(encoder=jsonEncoder,logLevel=Info,stackTraceLevel=Error) (default true)
# -zap-encoder value
# Zap log encoding (one of 'json' or 'console')
# -zap-log-level value
# Zap Level to configure the verbosity of logging. Can be one of 'debug', 'info', 'error', or any integer value > 0 which corresponds to custom debug levels of increasing verbosity
# -zap-stacktrace-level value
# Zap Level at and above which stacktraces are captured (one of 'info', 'error', 'panic').


environmentSecret: ""
Expand Down
Loading

0 comments on commit ae5f56c

Please sign in to comment.