Skip to content
This repository has been archived by the owner on Nov 28, 2022. It is now read-only.

Commit

Permalink
Static secrets (#20)
Browse files Browse the repository at this point in the history
  • Loading branch information
asaintsever authored Mar 4, 2020
1 parent 3ab5813 commit f708f20
Show file tree
Hide file tree
Showing 91 changed files with 3,167 additions and 869 deletions.
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
# Changelog for Vault Sidecar Injector

## Release v6.0.0 - 2020-03-04

This is a major release introducing new features and complete code refactoring for clear isolation of modes.

Highlights:

- New Static Secrets feature, part of `secrets` mode (now supporting both **dynamic** and **static** secrets)
- Kubernetes Jobs are now handled as a *Vault Sidecar Injector mode*. Annotation `sidecar.vault.talend.org/workload` is **still supported but deprecated**: make use of `sidecar.vault.talend.org/mode` to enable job mode
- HashiCorp Vault image updated to `1.3.2`

**Added**

- [VSI #20](https://github.com/Talend/vault-sidecar-injector/pull/20) - Static secrets. Feature announcement [here](https://github.com/Talend/vault-sidecar-injector/blob/master/doc/Static-vs-Dynamic-Secrets.md).

## Release v5.1.1 - 2019-12-23

**Added**
Expand Down
31 changes: 27 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
RELEASE_VERSION:=5.1.1
VSI_VERSION:=5.0.1
SHELL=/bin/bash

RELEASE_VERSION:=$(shell cat VERSION_RELEASE)
VSI_VERSION:=$(shell cat VERSION_VSI)
CHART_VERSION:=$(shell cat VERSION_CHART)

OWNER:=Talend
REPO:=vault-sidecar-injector
Expand All @@ -10,7 +13,7 @@ SRC:=$(shell find . -type f -name '*.go' -not -path "./vendor/*")
LDFLAGS=-ldflags "-X=main.VERSION=$(VSI_VERSION)"

.SILENT: ; # No need for @
.ONESHELL: ; # Single shell for a target (required to properly use all of our local variables)
.ONESHELL: ; # Single shell for a target (required to properly use local variables)
.PHONY: all clean fmt test build release image
.DEFAULT_GOAL := build

Expand All @@ -32,22 +35,42 @@ build: clean test
cd target && sha512sum vaultinjector-webhook > vaultinjector-webhook.sha512

package:
set -e
mkdir -p target && cd target
echo "Archive Helm chart ..."
mkdir -p vault-sidecar-injector && cp -R ../README.md ../deploy/helm/* ./vault-sidecar-injector
sed -i "s/version: 0.0.0/version: ${CHART_VERSION}/;s/appVersion: 0.0.0/appVersion: ${VSI_VERSION}/" ./vault-sidecar-injector/Chart.yaml
sed -i "s/tag: \"latest\" # VSI image tag/tag: \"${VSI_VERSION}\" # VSI image tag/" ./vault-sidecar-injector/values.yaml
sed -i "s/latest \*(local testing)\*, \[VERSION_VSI\](VERSION_VSI) \*(release)\*/${VSI_VERSION}/" ./vault-sidecar-injector/README.md
helm package vault-sidecar-injector
rm -R vault-sidecar-injector
helm lint ./vault-sidecar-injector-*.tgz --debug

image:
echo "Build image from sources ..."
echo "Build image using Go container and multi-stage build ..."
docker build -t talend/vault-sidecar-injector:${VSI_VERSION} .
docker tag talend/vault-sidecar-injector:${VSI_VERSION} talend/vault-sidecar-injector

image-from-build: build
echo "Build image from local build ..."
docker build -f Dockerfile.local -t talend/vault-sidecar-injector:${VSI_VERSION} .
docker tag talend/vault-sidecar-injector:${VSI_VERSION} talend/vault-sidecar-injector

release: image-from-build package
read -p "Publish image on Docker Hub (y/n)? " answer
case $$answer in \
y|Y ) \
docker login; \
docker push talend/vault-sidecar-injector:${VSI_VERSION}; \
if [ "$$?" -ne 0 ]; then \
echo "Unable to publish image"; \
exit 1; \
fi; \
;; \
* ) \
echo "Image not published on Docker Hub"; \
;; \
esac
cd target
echo "Releasing artifacts ..."
read -p "- Github user name to use for release: " username
Expand Down
329 changes: 259 additions & 70 deletions README.md

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions VERSION_CHART
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.2.0
1 change: 1 addition & 0 deletions VERSION_RELEASE
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
6.0.0
1 change: 1 addition & 0 deletions VERSION_VSI
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
6.0.0
4 changes: 2 additions & 2 deletions deploy/helm/Chart.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
apiVersion: v1
name: vault-sidecar-injector
description: A Helm chart for Talend Vault Sidecar Injector (OSS)
version: 3.1.1
version: 0.0.0
icon: https://www.talend.com/wp-content/uploads/talend-logo.svg
keywords:
- Talend
Expand All @@ -14,4 +14,4 @@ sources:
maintainers:
- name: Talend
email: [email protected]
appVersion: 5.0.1
appVersion: 0.0.0
229 changes: 229 additions & 0 deletions deploy/helm/config/injectionconfig.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
initContainers:
- name: tvsi-vault-agent-init
image: {{ include "talend-vault-sidecar-injector.injectconfig.vault.image" .Values }}
imagePullPolicy: {{ .Values.injectconfig.vault.image.pullPolicy }}
env:
- name: SKIP_SETCAP
value: "true"
- name: VAULT_ADDR
value: {{ required "Vault server's address must be specified" .Values.vault.addr | quote }}
# env var set by webhook
- name: VSI_SECRETS_TEMPLATES_PLACEHOLDER
value: ""
# env var set by webhook
- name: VSI_VAULT_ROLE
value: ""
command:
- "sh"
- "-c"
- |
cat <<EOF > vault-agent-config.hcl
pid_file = "/home/vault/pidfile"
auto_auth {
method "kubernetes" {
mount_path = "auth/{{ .Values.vault.authMethods.kubernetes.path }}"
config = {
role = "${VSI_VAULT_ROLE}"
token_path = "/var/run/secrets/talend/vault-sidecar-injector/serviceaccount/token"
}
}
sink "file" {
config = {
path = "/home/vault/.vault-token"
}
}
}
${VSI_SECRETS_TEMPLATES_PLACEHOLDER}
EOF
docker-entrypoint.sh agent -config=vault-agent-config.hcl -exit-after-auth=true {{ include "talend-vault-sidecar-injector.vault.cert.skip.verify" .Values }} -log-level={{- .Values.injectconfig.vault.loglevel }}
export VAULT_TOKEN=$(cat /home/vault/.vault-token)
vault token revoke {{ include "talend-vault-sidecar-injector.vault.cert.skip.verify" .Values }} -self
volumeMounts:
# Mount path used to share secrets. The associated volume is expected to be defined in application's manifest but in case it is not,
# a default 'secrets' volume will be injected in the requesting pod (see definition below) so that mutation process does not fail.
- name: secrets
mountPath: /opt/talend/secrets
# The name's value will be overridden by the webhook to point to container's service account volume to use for Vault authentication.
- name: TVSI_SA_SECRETS_VOL_NAME
mountPath: /var/run/secrets/talend/vault-sidecar-injector/serviceaccount
readOnly: true
{{- if .Values.injectconfig.vault.resources }}
resources:
{{ toYaml .Values.injectconfig.vault.resources | indent 6 }}
{{- end }}
containers:
# This container is only injected in K8S jobs to monitor app job's container termination and send signal to vault sidecar
- name: tvsi-job-babysitter
image: {{ include "talend-vault-sidecar-injector.injectconfig.jobbabysitter.image" .Values }}
imagePullPolicy: {{ .Values.injectconfig.jobbabysitter.image.pullPolicy }}
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
# env var set by webhook
- name: VSI_JOB_CNT_NAME
value: ""
command:
- "sh"
- "-c"
- |
jwt_sa_token=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
pod_ns=$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace)
retCode=$(curl -s -X GET -H "Authorization: Bearer $jwt_sa_token" --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt https://$KUBERNETES_SERVICE_HOST/api/v1/namespaces/$pod_ns/pods/$POD_NAME?pretty=false | jq .code)
if [ $retCode = "403" ]; then
curl -s -X GET -H "Authorization: Bearer $jwt_sa_token" --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt https://$KUBERNETES_SERVICE_HOST/api/v1/namespaces/$pod_ns/pods/$POD_NAME?pretty=false | jq .message
exit 1
fi
while true; do
cntStatus=$(curl -s -X GET -H "Authorization: Bearer $jwt_sa_token" --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt https://$KUBERNETES_SERVICE_HOST/api/v1/namespaces/$pod_ns/pods/$POD_NAME?pretty=false | jq -c --raw-output --arg cntname "${VSI_JOB_CNT_NAME}" '.status.containerStatuses[] | select(.name == $cntname).state | keys[0]')
if [ "$cntStatus" = "terminated" ]; then
echo "=> job container terminated: send signal"
touch /opt/talend/tvsi/vault-sidecars-signal-terminate
exit 0
fi
sleep 2
done
volumeMounts:
# Mount path used by injected sidecars to share data
- name: tvsi-shared
mountPath: /opt/talend/tvsi
# The name's value will be overridden by the webhook
- name: K8S_SA_SECRETS_VOL_NAME
mountPath: /var/run/secrets/kubernetes.io/serviceaccount
readOnly: true
{{- if .Values.injectconfig.jobbabysitter.resources }}
resources:
{{ toYaml .Values.injectconfig.jobbabysitter.resources | indent 6 }}
{{- end }}
- name: tvsi-vault-agent
image: {{ include "talend-vault-sidecar-injector.injectconfig.vault.image" .Values }}
imagePullPolicy: {{ .Values.injectconfig.vault.image.pullPolicy }}
env:
- name: SKIP_SETCAP
value: "true"
- name: VAULT_ADDR
value: {{ required "Vault server's address must be specified" .Values.vault.addr | quote }}
# env var set by webhook
- name: VSI_JOB_WORKLOAD
value: "false"
# env var set by webhook
- name: VSI_PROXY_CONFIG_PLACEHOLDER
value: ""
# env var set by webhook
- name: VSI_SECRETS_TEMPLATES_PLACEHOLDER
value: ""
# env var set by webhook
- name: VSI_VAULT_AUTH_METHOD
value: "kubernetes"
# env var set by webhook
- name: VSI_VAULT_ROLE
value: ""
command:
- "sh"
- "-c"
- |
if [ "${VSI_VAULT_AUTH_METHOD}" = "kubernetes" ]; then
cat <<EOF > vault-agent-config.hcl
pid_file = "/home/vault/pidfile"
auto_auth {
method "kubernetes" {
mount_path = "auth/{{ .Values.vault.authMethods.kubernetes.path }}"
config = {
role = "${VSI_VAULT_ROLE}"
token_path = "/var/run/secrets/talend/vault-sidecar-injector/serviceaccount/token"
}
}
sink "file" {
config = {
path = "/home/vault/.vault-token"
}
}
}
${VSI_PROXY_CONFIG_PLACEHOLDER}
${VSI_SECRETS_TEMPLATES_PLACEHOLDER}
EOF
elif [ "${VSI_VAULT_AUTH_METHOD}" = "approle" ]; then
cat <<EOF > vault-agent-config.hcl
pid_file = "/home/vault/pidfile"
auto_auth {
method "approle" {
mount_path = "auth/{{ .Values.vault.authMethods.approle.path }}"
config = {
role_id_file_path = "/opt/talend/secrets/{{ .Values.vault.authMethods.approle.roleid_filename }}"
secret_id_file_path = "/opt/talend/secrets/{{ .Values.vault.authMethods.approle.secretid_filename }}"
}
}
sink "file" {
config = {
path = "/home/vault/.vault-token"
}
}
}
${VSI_PROXY_CONFIG_PLACEHOLDER}
${VSI_SECRETS_TEMPLATES_PLACEHOLDER}
EOF
else
echo "Unsupported Vault Auth Method: ${VSI_VAULT_AUTH_METHOD}"
exit 1
fi
if [ "${VSI_JOB_WORKLOAD}" = "true" ]; then
docker-entrypoint.sh agent -config=vault-agent-config.hcl {{ include "talend-vault-sidecar-injector.vault.cert.skip.verify" .Values }} -log-level={{- .Values.injectconfig.vault.loglevel }} &
while true; do
if [ -f "/opt/talend/tvsi/vault-sidecars-signal-terminate" ]; then
echo "=> exit (signal received)"
export VAULT_TOKEN=$(cat /home/vault/.vault-token);
vault token revoke {{ include "talend-vault-sidecar-injector.vault.cert.skip.verify" .Values }} -self;
exit 0
fi
sleep 2
done
else
docker-entrypoint.sh agent -config=vault-agent-config.hcl {{ include "talend-vault-sidecar-injector.vault.cert.skip.verify" .Values }} -log-level={{- .Values.injectconfig.vault.loglevel }}
fi
lifecycle:
preStop:
exec:
command:
- "sh"
- "-c"
- >
export VAULT_TOKEN=$(cat /home/vault/.vault-token);
vault token revoke {{ include "talend-vault-sidecar-injector.vault.cert.skip.verify" .Values }} -self;
volumeMounts:
# Mount path used by injected sidecars to share data
- name: tvsi-shared
mountPath: /opt/talend/tvsi
# Mount path used to share secrets. The associated volume is expected to be defined in application's manifest but in case it is not,
# a default 'secrets' volume will be injected in the requesting pod (see definition below) so that mutation process does not fail.
- name: secrets
mountPath: /opt/talend/secrets
# The name's value will be overridden by the webhook to point to container's service account volume to use for Vault authentication.
- name: TVSI_SA_SECRETS_VOL_NAME
mountPath: /var/run/secrets/talend/vault-sidecar-injector/serviceaccount
readOnly: true
{{- if .Values.injectconfig.vault.resources }}
resources:
{{ toYaml .Values.injectconfig.vault.resources | indent 6 }}
{{- end }}
volumes:
- name: tvsi-shared
emptyDir:
medium: Memory
# Note: if 'secrets' volume is defined in pod's manifest then it will be considered instead of the default definition below
- name: secrets
emptyDir:
medium: Memory
6 changes: 6 additions & 0 deletions deploy/helm/config/podlifecyclehooks.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
postStart:
exec:
command:
- "sh"
- "-c"
- cat <VSI_SECRETS_VOL_MOUNTPATH>/* >/dev/null 2>&1
8 changes: 8 additions & 0 deletions deploy/helm/config/proxyconfig.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
cache {
use_auto_auth_token = true
}

listener "tcp" {
address = "127.0.0.1:<VSI_PROXY_PORT>"
tls_disable = true
}
11 changes: 11 additions & 0 deletions deploy/helm/config/templateblock.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
template {
destination = "/opt/talend/secrets/<VSI_SECRETS_DESTINATION>"
contents = <<EOH
<VSI_SECRETS_TEMPLATE_CONTENT>
EOH
command = "<VSI_SECRETS_TEMPLATE_COMMAND_TO_RUN>"
wait {
min = "1s"
max = "2s"
}
}
3 changes: 3 additions & 0 deletions deploy/helm/config/templatedefault.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{{`{{ with secret "<VSI_SECRETS_VAULT_SECRETS_PATH>" }}{{ range $k, $v := .Data }}
{{ $k }}={{ $v }}
{{ end }}{{ end }}`}}
15 changes: 15 additions & 0 deletions deploy/helm/templates/NOTES.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
Thank you for installing {{ .Chart.Name }}.

Your release is named {{ .Release.Name }}.

=====
To get status:
$ helm status {{ .Release.Name }}

To uninstall:
# Using Helm 2
$ helm delete --purge {{ .Release.Name }}

# Using Helm 3
$ helm delete {{ .Release.Name }} -n {{ .Release.Namespace }}
=====
Loading

0 comments on commit f708f20

Please sign in to comment.