diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0552f02..737075f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,13 @@
# Changelog for Vault Sidecar Injector
+## Release v7.1.0 - TO_BE_RELEASED
+
+A new `sidecar.vault.talend.org/vault-image` annotation has been added to override the default injected image. Refer to the [samples](samples) for a working example.
+
+**Added**
+
+- [VSI #43](https://github.com/Talend/vault-sidecar-injector/pull/43) - New annotation to allow injection of custom Vault image
+
## Release v7.0.2 - 2020-11-09
**Changed**
diff --git a/VERSION_CHART b/VERSION_CHART
index 2582ddd..ef8d756 100644
--- a/VERSION_CHART
+++ b/VERSION_CHART
@@ -1 +1 @@
-4.1.1
\ No newline at end of file
+4.2.0
\ No newline at end of file
diff --git a/VERSION_RELEASE b/VERSION_RELEASE
index 2f963cd..3769235 100644
--- a/VERSION_RELEASE
+++ b/VERSION_RELEASE
@@ -1 +1 @@
-7.0.2
\ No newline at end of file
+7.1.0
\ No newline at end of file
diff --git a/VERSION_VSI b/VERSION_VSI
index 73a86b1..3769235 100644
--- a/VERSION_VSI
+++ b/VERSION_VSI
@@ -1 +1 @@
-7.0.1
\ No newline at end of file
+7.1.0
\ No newline at end of file
diff --git a/cmd/vaultinjector-env/main.go b/cmd/vaultinjector-env/main.go
index 21cfec7..9eeaf7d 100644
--- a/cmd/vaultinjector-env/main.go
+++ b/cmd/vaultinjector-env/main.go
@@ -1,4 +1,4 @@
-// Copyright © 2019-2020 Talend - www.talend.com
+// Copyright © 2019-2021 Talend - www.talend.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -47,8 +47,8 @@ func init() {
// Program accepts following env vars:
//
-// VSI_ENV_LOG_JSON true/false (default) Log as JSON
-// VSI_ENV_LOG_LEVEL 0 to 6 (default: 3 fo warning) Log level
+// VSI_ENV_LOG_JSON true/false (default) Log as JSON
+// VSI_ENV_LOG_LEVEL 0 to 6 (default: 3) Log level (3 for warning, 6 to trace everything)
//
func main() {
var entrypointCmd []string
@@ -103,7 +103,7 @@ func main() {
// Replace current process with original one, providing env vars (including new ones from fetched secrets)
err = syscall.Exec(binary, entrypointCmd, env)
if err != nil {
- log.Panicln("failed to exec process", entrypointCmd, err.Error())
+ log.Fatalln("failed to exec process", entrypointCmd, err.Error())
}
}
diff --git a/doc/Usage.md b/doc/Usage.md
index eba9d2c..aea99fb 100644
--- a/doc/Usage.md
+++ b/doc/Usage.md
@@ -38,7 +38,8 @@ Following annotations in requesting pods are supported:
| Annotation | (M)andatory / (O)ptional | Apply to mode | Default Value | Supported Values | Description |
|---------------------------------------|--------------------------|-----------------|----------------------|--------------------------------|-------------|
-| `sidecar.vault.talend.org/inject` | M | N/A | | "true" / "on" / "yes" / "y" | Ask for sidecar injection to get secrets from Vault |
+| `sidecar.vault.talend.org/inject` | M | N/A | | "true" / "on" / "yes" / "y" | Ask for injection to get secrets from Vault |
+| `sidecar.vault.talend.org/vault-image` | O | N/A | "<`injectconfig.vault.image.path` Helm value>:<`injectconfig.vault.image.tag` Helm value>" | Any image with Vault installed | The image to be injected in your pod |
| `sidecar.vault.talend.org/auth` | O | N/A | "kubernetes" | "kubernetes" / "approle" | Vault Auth Method to use. **Static secrets only supports "kubernetes" authentication method** |
| `sidecar.vault.talend.org/mode` | O | N/A | "secrets" | "secrets" / "proxy" / "job" / Comma-separated values (eg "secrets,proxy") | Enable provided mode(s). **Note: `secrets` mode will be enabled if you only set `job` mode** |
| `sidecar.vault.talend.org/notify` | O | secrets | "" | Comma-separated strings | List of commands to notify application/service of secrets change, one per secrets path. **Usage context: dynamic secrets only** |
diff --git a/doc/announcements/HashiCorp-Vault-Agent-Injector.md b/doc/announcements/HashiCorp-Vault-Agent-Injector.md
index 152172a..2548c4d 100644
--- a/doc/announcements/HashiCorp-Vault-Agent-Injector.md
+++ b/doc/announcements/HashiCorp-Vault-Agent-Injector.md
@@ -1,6 +1,6 @@
# Vault Sidecar Injector vs HashiCorp Vault Agent Injector - Features Comparison
-*March 2020, [Post by Alain Saint-Sever, Principal Cloud Software Architect (@alstsever)](https://twitter.com/alstsever)*
+*March 2020 (with [updates](#changes-since-comparison)), [Post by Alain Saint-Sever, Principal Cloud Software Architect (@alstsever)](https://twitter.com/alstsever)*
- [Vault Sidecar Injector vs HashiCorp Vault Agent Injector - Features Comparison](#vault-sidecar-injector-vs-hashicorp-vault-agent-injector---features-comparison)
- [Intro](#intro)
@@ -10,6 +10,7 @@
- [HashiCorp Vault Agent Injector installation](#hashicorp-vault-agent-injector-installation)
- [Test Workloads](#test-workloads)
- [Features Comparison](#features-comparison)
+ - [Changes since comparison](#changes-since-comparison)
## Intro
@@ -135,12 +136,12 @@ Features comparison `Vault Sidecar Injector` vs `HashiCorp Vault Agent Injector`
| Custom Vault Agent config | **Not possible** | By providing K8S ConfigMap with custom Vault Agent config + using annotation to load config *(`vault.hashicorp.com/agent-configmap`)* |
| Vault AppRole Auth support | At pod level *(using annotation)* | By providing K8S ConfigMap with custom Vault Agent config + using annotation to load config *(`vault.hashicorp.com/agent-configmap`)* |
| Secrets volume mount path | Any path associated to the `secrets` Volume | Cannot be changed *(set to `/vault/secrets`)* |
-| Shared secrets volume| Injection of In-memory Volume **only** if not defined. VolumeMount is not injected if not defined ***(1)*** | Injection of both In-memory Volume and VolumeMount. **Failure** if `vault-secrets` Volume already defined |
+| Shared secrets volume| Injection of In-memory Volume **only** if not defined. VolumeMount is not injected if not defined ***([1](#changes-since-comparison))*** | Injection of both In-memory Volume and VolumeMount. **Failure** if `vault-secrets` Volume already defined |
| Resources (CPU, mem) for injected container(s) | At webhook level *(helm chart values)* | At pod level *(default values or custom via annotations)* |
| Resources (CPU, mem) for webhook | Using Helm chart values | Using Helm chart values |
| Vault server to use | At webhook level *(helm chart value)* | Both at webhook *(helm chart value)* and pod levels *(via annotation)* |
| Vault Agent's check of Vault's TLS cert | At webhook level *(helm chart value)* | At pod level *(using annotation)* |
-|Vault Agent image| At webhook level *(helm chart value)* | Both at webhook *(helm chart value)* and pod levels *(via annotation)* |
+|Vault Agent image| At webhook level *(helm chart value)* ***([2](#changes-since-comparison))*** | Both at webhook *(helm chart value)* and pod levels *(via annotation)* |
Most of the differences are less the result of technical choice than philosophical ones: the Vault Sidecar Injector is more "user friendly" in this regard by easily giving access to Vault proxy mode or other technical features through a simple annotation, where the same capabilities on HashiCorp's injector will require the user to provide a complete Vault Agent config wrapped into a Kubernetes ConfigMap. This distinct approach can also be seen with Vault Sidecar Injector's modes that completely relieve the user from knowing whether he needs an init container or a sidecar or both of them to handle a use case. On the other end, with the HashiCorp's injector, the user has control over the injected content and this "complexity" allows for greater flexibility.
@@ -148,8 +149,8 @@ Most of the differences are less the result of technical choice than philosophic
Future Vault Sidecar Injector releases will continue focusing on a feature-oriented, non-technical path to make injector usage as seamless as possible. Results from this comparison test show that there is room for some improvements on volume management that will be taking care of soon. Stay tuned !
-
+## Changes since comparison
-**Changes since comparison:**
-
-> *(1), June 2020: as of Vault Sidecar Injector release 7.0.0, volumeMount is also injected if not defined*
+> ***(1)**, June 2020: as of Vault Sidecar Injector release 7.0.0, volumeMount is also injected if not defined*
+>
+> ***(2)**, February 2021: as of Vault Sidecar Injector release 7.1.0, you can also select the image to inject at pod level (using an annotation)*
diff --git a/pkg/config/constants.go b/pkg/config/constants.go
new file mode 100644
index 0000000..d2c32be
--- /dev/null
+++ b/pkg/config/constants.go
@@ -0,0 +1,25 @@
+// Copyright © 2019-2021 Talend - www.talend.com
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package config
+
+const (
+ //--- Init Containers defined in our injection config
+ VaultAgentInitContainerName = "tvsi-vault-agent-init"
+ VSIEnvInitContainerName = "tvsi-env-init"
+
+ //--- Containers defined in our injection config
+ JobMonitoringContainerName = "tvsi-job-babysitter"
+ VaultAgentContainerName = "tvsi-vault-agent"
+)
diff --git a/pkg/context/constants.go b/pkg/context/constants.go
index 36e59e0..6d7b9d5 100644
--- a/pkg/context/constants.go
+++ b/pkg/context/constants.go
@@ -1,4 +1,4 @@
-// Copyright © 2019-2020 Talend - www.talend.com
+// Copyright © 2019-2021 Talend - www.talend.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -17,12 +17,13 @@ package context
const (
//--- Vault Sidecar Injector annotation keys (without prefix)
// Input annotations (set on incoming manifest)
- VaultInjectorAnnotationInjectKey = "inject" // Mandatory
- VaultInjectorAnnotationAuthMethodKey = "auth" // Optional. Vault Auth Method to use: kubernetes (default) or approle
- VaultInjectorAnnotationModeKey = "mode" // Optional. Comma-separated list of mode(s) to enable.
- VaultInjectorAnnotationRoleKey = "role" // Optional. To explicitly provide Vault role to use
- VaultInjectorAnnotationSATokenKey = "sa-token" // Optional. Full path to service account token used for Vault Kubernetes authentication
- VaultInjectorAnnotationWorkloadKey = "workload" // Optional and deprecated. If set to "job", supplementary container and signaling mechanism will also be injected to properly handle k8s job
+ VaultInjectorAnnotationInjectKey = "inject" // Mandatory
+ VaultInjectorAnnotationVaultImageKey = "vault-image" // Optional. Image to inject
+ VaultInjectorAnnotationAuthMethodKey = "auth" // Optional. Vault Auth Method to use: kubernetes (default) or approle
+ VaultInjectorAnnotationModeKey = "mode" // Optional. Comma-separated list of mode(s) to enable.
+ VaultInjectorAnnotationRoleKey = "role" // Optional. To explicitly provide Vault role to use
+ VaultInjectorAnnotationSATokenKey = "sa-token" // Optional. Full path to service account token used for Vault Kubernetes authentication
+ VaultInjectorAnnotationWorkloadKey = "workload" // Optional and deprecated. If set to "job", supplementary container and signaling mechanism will also be injected to properly handle k8s job
// Output annotation (set by VSI webhook)
VaultInjectorAnnotationStatusKey = "status" // Not to be set by requesting pods: set by the Webhook Admission Controller if injection ok
)
diff --git a/pkg/context/types.go b/pkg/context/types.go
index c5a0ea3..8ad98ce 100644
--- a/pkg/context/types.go
+++ b/pkg/context/types.go
@@ -1,4 +1,4 @@
-// Copyright © 2019-2020 Talend - www.talend.com
+// Copyright © 2019-2021 Talend - www.talend.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@ package context
// InjectionContext : struct to carry computed placeholders' values and context info for current injection
type InjectionContext struct {
K8sDefaultSATokenVolumeName string
+ VaultImage string
VaultInjectorSATokenVolumeName string
VaultAuthMethod string
VaultRole string
diff --git a/pkg/mode/job/constants.go b/pkg/mode/job/constants.go
index e65f711..ea65441 100644
--- a/pkg/mode/job/constants.go
+++ b/pkg/mode/job/constants.go
@@ -1,4 +1,4 @@
-// Copyright © 2019-2020 Talend - www.talend.com
+// Copyright © 2019-2021 Talend - www.talend.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -14,10 +14,12 @@
package job
+import "talend/vault-sidecar-injector/pkg/config"
+
const (
//--- Job handling - Temporary mechanism until KEP https://github.com/kubernetes/enhancements/blob/master/keps/sig-apps/sidecarcontainers.md is implemented (and we migrate on appropriate version of k8s)
- jobMonitoringContainerName = "tvsi-job-babysitter" // Name of our specific sidecar container to inject in submitted jobs
- jobListenerContainerName = "tvsi-vault-agent" // Name of the container listening for signal from job monitoring container
+ jobMonitoringContainerName = config.JobMonitoringContainerName // Name of our specific sidecar container to inject in submitted jobs
+ jobListenerContainerName = config.VaultAgentContainerName // Name of the container listening for signal from job monitoring container
//--- Job handling env vars
jobContainerNameEnv = "VSI_JOB_CNT_NAME" // Env var for name of the app job's container
diff --git a/pkg/mode/proxy/constants.go b/pkg/mode/proxy/constants.go
index 5a104c9..f30d6a2 100644
--- a/pkg/mode/proxy/constants.go
+++ b/pkg/mode/proxy/constants.go
@@ -1,4 +1,4 @@
-// Copyright © 2019-2020 Talend - www.talend.com
+// Copyright © 2019-2021 Talend - www.talend.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -14,14 +14,16 @@
package proxy
+import "talend/vault-sidecar-injector/pkg/config"
+
const (
//--- Vault Sidecar Injector modes annotation keys (without prefix)
vaultInjectorAnnotationProxyPortKey = "proxy-port" // Optional. Port assigned to local Vault proxy.
)
const (
- proxyContainerName = "tvsi-vault-agent" // Name of our proxy container to inject
- vaultProxyDefaultPort = "8200" // Default port to access local Vault proxy
+ proxyContainerName = config.VaultAgentContainerName // Name of our proxy container to inject
+ vaultProxyDefaultPort = "8200" // Default port to access local Vault proxy
)
const (
diff --git a/pkg/mode/secrets/constants.go b/pkg/mode/secrets/constants.go
index 57382a2..08ca1dc 100644
--- a/pkg/mode/secrets/constants.go
+++ b/pkg/mode/secrets/constants.go
@@ -1,4 +1,4 @@
-// Copyright © 2019-2020 Talend - www.talend.com
+// Copyright © 2019-2021 Talend - www.talend.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -14,6 +14,8 @@
package secrets
+import "talend/vault-sidecar-injector/pkg/config"
+
const (
//--- Vault Sidecar Injector modes annotation keys (without prefix)
vaultInjectorAnnotationSecretsPathKey = "secrets-path" // Optional. Full path, e.g.: "secret/", "aws/creds/", ... Several values separated by ','.
@@ -26,13 +28,13 @@ const (
)
const (
- secretsContainerName = "tvsi-vault-agent" // Name of our secrets container to inject
- secretsInitContainerName = "tvsi-vault-agent-init" // Name of our secrets init container to inject
- secretsEnvInitContainerName = "tvsi-env-init" // Name of our env process init container to inject
- templateAppSvcDefaultDestination = "secrets.properties" // Default secrets destination
- vaultDefaultSecretsEnginePath = "secret" // Default path for Vault K/V Secrets Engine if no 'secrets-path' annotation
- secretsAnnotationSeparator = "," // Generic separator for secrets annotations' values
- secretsAnnotationTemplateSeparator = "---" // Separator for secrets templates annotation's values
+ secretsContainerName = config.VaultAgentContainerName // Name of our secrets container to inject
+ secretsInitContainerName = config.VaultAgentInitContainerName // Name of our secrets init container to inject
+ secretsEnvInitContainerName = config.VSIEnvInitContainerName // Name of our env process init container to inject
+ templateAppSvcDefaultDestination = "secrets.properties" // Default secrets destination
+ vaultDefaultSecretsEnginePath = "secret" // Default path for Vault K/V Secrets Engine if no 'secrets-path' annotation
+ secretsAnnotationSeparator = "," // Generic separator for secrets annotations' values
+ secretsAnnotationTemplateSeparator = "---" // Separator for secrets templates annotation's values
)
const (
diff --git a/pkg/webhook/types.go b/pkg/webhook/types.go
index a28619f..711f9aa 100644
--- a/pkg/webhook/types.go
+++ b/pkg/webhook/types.go
@@ -1,4 +1,4 @@
-// Copyright © 2019-2020 Talend - www.talend.com
+// Copyright © 2019-2021 Talend - www.talend.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -29,6 +29,7 @@ type VaultInjector struct {
// Supported annotations (modes' annotations will be appended to this array)
var vaultInjectorAnnotationKeys = []string{
ctx.VaultInjectorAnnotationInjectKey,
+ ctx.VaultInjectorAnnotationVaultImageKey,
ctx.VaultInjectorAnnotationAuthMethodKey,
ctx.VaultInjectorAnnotationModeKey,
ctx.VaultInjectorAnnotationRoleKey,
diff --git a/pkg/webhook/update-pod.go b/pkg/webhook/update-pod.go
index 3442ed2..d242889 100644
--- a/pkg/webhook/update-pod.go
+++ b/pkg/webhook/update-pod.go
@@ -1,4 +1,4 @@
-// Copyright © 2019-2020 Talend - www.talend.com
+// Copyright © 2019-2021 Talend - www.talend.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@ import (
"strconv"
"strings"
+ "talend/vault-sidecar-injector/pkg/config"
ctx "talend/vault-sidecar-injector/pkg/context"
m "talend/vault-sidecar-injector/pkg/mode"
"talend/vault-sidecar-injector/pkg/mode/job"
@@ -84,6 +85,7 @@ func (vaultInjector *VaultInjector) computeContext(podContainers []corev1.Contai
klog.Infof("Modes status: %+v", modesStatus)
+ vaultImage := annotations[vaultInjector.VaultInjectorAnnotationsFQ[ctx.VaultInjectorAnnotationVaultImageKey]]
vaultAuthMethod := strings.ToLower(annotations[vaultInjector.VaultInjectorAnnotationsFQ[ctx.VaultInjectorAnnotationAuthMethodKey]])
vaultRole := annotations[vaultInjector.VaultInjectorAnnotationsFQ[ctx.VaultInjectorAnnotationRoleKey]]
vaultSATokenPath := annotations[vaultInjector.VaultInjectorAnnotationsFQ[ctx.VaultInjectorAnnotationSATokenKey]]
@@ -149,6 +151,7 @@ func (vaultInjector *VaultInjector) computeContext(podContainers []corev1.Contai
return &ctx.InjectionContext{
K8sDefaultSATokenVolumeName: k8sSaSecretsVolName,
+ VaultImage: vaultImage,
VaultInjectorSATokenVolumeName: vaultInjectorSaSecretsVolName,
VaultAuthMethod: vaultAuthMethod,
VaultRole: vaultRole,
@@ -243,6 +246,13 @@ func (vaultInjector *VaultInjector) addContainer(podContainers []corev1.Containe
}
}
+ // Check if custom Vault image is provided and, if so, update image for relevant containers
+ if context.VaultImage != "" {
+ if (container.Name == config.VaultAgentInitContainerName) || (container.Name == config.VaultAgentContainerName) {
+ container.Image = context.VaultImage
+ }
+ }
+
value = container
path := basePath
diff --git a/samples/app-dep-10-secrets_custom_image_notify.yaml b/samples/app-dep-10-secrets_custom_image_notify.yaml
new file mode 100644
index 0000000..cf124af
--- /dev/null
+++ b/samples/app-dep-10-secrets_custom_image_notify.yaml
@@ -0,0 +1,76 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: app10
+ namespace: default
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ com.talend.application: test
+ com.talend.service: test-app-svc
+ template:
+ metadata:
+ annotations:
+ sidecar.vault.talend.org/inject: "true"
+ sidecar.vault.talend.org/notify: "curl localhost:8888/refresh_secrets" # To be notified each time secrets are updated
+ # NOTE:
+ # For this sample to work, you cannot use default Vault docker image as curl is not installed.
+ # You have to set your own custom Vault image with the tools you depend on (here we use 'grem1in/vault-curl-jq' image instead).
+ sidecar.vault.talend.org/vault-image: "grem1in/vault-curl-jq"
+ labels:
+ com.talend.application: test
+ com.talend.service: test-app-svc
+ spec:
+ serviceAccountName: default
+ containers:
+ - name: app-container
+ image: node:14-buster
+ command:
+ - "sh"
+ - "-c"
+ - |
+ set -e
+ cat < "/my_custom_api.js"
+ const http = require("http")
+ const fs = require('fs')
+ const PORT = 8888
+ const server = http.createServer((request, response) => {
+ const { method, url, headers } = request
+
+ if (url === "/refresh_secrets") {
+ console.log("Notification received: read secrets file to update values")
+
+ fs.readFile("/opt/talend/secrets/secrets.properties", "utf8", (error, data) => {
+ if (error) {
+ console.error(error)
+ } else {
+ console.log(data)
+ }
+ })
+
+ response.statusCode = 200
+ response.end()
+ }
+ })
+
+ server.listen(PORT, error => {
+ if (error) {
+ return console.error(error)
+ }
+
+ console.log(\`Server listening on port \${PORT}\`)
+ })
+ EOF
+
+ while true; do
+ echo "Wait for secrets file availability..."
+ if [ -f "/opt/talend/secrets/secrets.properties" ]; then
+ echo "Secrets are:"
+ cat /opt/talend/secrets/secrets.properties
+ break
+ fi
+ sleep 2
+ done
+
+ node my_custom_api.js