Compare commits

...

17 Commits
v2.0 ... master

Author SHA1 Message Date
Abhishek Dubey ae51e2ef90
Added blog link in the README 2021-09-21 11:38:07 +05:30
Abhishek Dubey f9d698061a
Update README.md 2021-08-26 11:48:26 +05:30
Abhishek Dubey f4115238fd
[Feature][Add] Added template for azure DevOps (#16)
* Added azure pipeline template

Signed-off-by: iamabhishek-dubey <abhishekbhardwaj510@gmail.com>
2021-05-19 19:06:29 +05:30
iamabhishek-dubey 8e6d3c2572 Merge branch 'master' of github.com:OT-CONTAINER-KIT/k8s-vault-webhook 2021-05-16 22:27:59 +05:30
iamabhishek-dubey dbf922906c Updated badge information
Signed-off-by: iamabhishek-dubey <abhishekbhardwaj510@gmail.com>
2021-05-16 22:27:35 +05:30
Abhishek Dubey b69fd3cb43
[Feature][Change] Updated azure devops ci pipeline (#15)
* Added few security steps in azure pipline

Signed-off-by: iamabhishek-dubey <abhishekbhardwaj510@gmail.com>
2021-05-16 22:18:31 +05:30
Abhishek Dubey 7688cfca59
Update .gitignore 2021-05-16 19:09:59 +05:30
iamabhishek-dubey a717e264b3 Updated Version in VERSION file
Signed-off-by: iamabhishek-dubey <abhishekbhardwaj510@gmail.com>
2021-05-16 19:01:18 +05:30
Abhishek Dubey 03d6543c45
[Feature][Add] Added GCP support in webhook (#14)
* Added support for azure key vault

Signed-off-by: iamabhishek-dubey <abhishekbhardwaj510@gmail.com>

* Updated architecture diagram

Signed-off-by: iamabhishek-dubey <abhishekbhardwaj510@gmail.com>

* Updated docs for Azure Support

Signed-off-by: iamabhishek-dubey <abhishekbhardwaj510@gmail.com>

* Added GCP secret manager support

Signed-off-by: iamabhishek-dubey <abhishekbhardwaj510@gmail.com>

* Updated documentation for GCP

Signed-off-by: iamabhishek-dubey <abhishekbhardwaj510@gmail.com>
2021-05-16 18:56:26 +05:30
iamabhishek-dubey 81b6394152 Updated badge for build
Signed-off-by: iamabhishek-dubey <abhishekbhardwaj510@gmail.com>
2021-05-15 22:36:17 +05:30
iamabhishek-dubey e4930eb417 Added scripts for release
Signed-off-by: iamabhishek-dubey <abhishekbhardwaj510@gmail.com>
2021-05-15 20:40:55 +05:30
iamabhishek-dubey 9664c1bc65 Added scripts for release
Signed-off-by: iamabhishek-dubey <abhishekbhardwaj510@gmail.com>
2021-05-15 19:56:32 +05:30
iamabhishek-dubey 1fc66e2a61 Added scripts for release
Signed-off-by: iamabhishek-dubey <abhishekbhardwaj510@gmail.com>
2021-05-15 18:48:35 +05:30
iamabhishek-dubey 198b1e11ec Added scripts for release
Signed-off-by: iamabhishek-dubey <abhishekbhardwaj510@gmail.com>
2021-05-15 17:46:52 +05:30
iamabhishek-dubey 832fe86c82 Added Azure DevOps CI pipeline
Signed-off-by: iamabhishek-dubey <abhishekbhardwaj510@gmail.com>
2021-05-15 17:25:52 +05:30
Abhishek Dubey ae99f5ba12
[Feature][Add] Added support for azure key vault (#12)
* Added support for azure key vault

Signed-off-by: iamabhishek-dubey <abhishekbhardwaj510@gmail.com>

* Updated architecture diagram

Signed-off-by: iamabhishek-dubey <abhishekbhardwaj510@gmail.com>

* Updated docs for Azure Support

Signed-off-by: iamabhishek-dubey <abhishekbhardwaj510@gmail.com>
2021-05-09 20:26:39 +05:30
Abhishek Dubey ca92aa7c73
[Feature][Update] Updated README with latest images (#11)
* Added Badges for Project

Signed-off-by: iamabhishek-dubey <abhishekbhardwaj510@gmail.com>

* Added Badges for Project

Signed-off-by: iamabhishek-dubey <abhishekbhardwaj510@gmail.com>

* Added Badges for Project

Signed-off-by: iamabhishek-dubey <abhishekbhardwaj510@gmail.com>

* Added Badges for Project

Signed-off-by: iamabhishek-dubey <abhishekbhardwaj510@gmail.com>

* Added AWS secret manager support

Signed-off-by: iamabhishek-dubey <abhishekbhardwaj510@gmail.com>

* Added an example for AWS

Signed-off-by: iamabhishek-dubey <abhishekbhardwaj510@gmail.com>

* Added AWS information in README

Signed-off-by: iamabhishek-dubey <abhishekbhardwaj510@gmail.com>

* Added AWS information in README

Signed-off-by: iamabhishek-dubey <abhishekbhardwaj510@gmail.com>

* Updated docs with latest information

Signed-off-by: iamabhishek-dubey <abhishekbhardwaj510@gmail.com>

* Updated README with latest info

Signed-off-by: iamabhishek-dubey <abhishekbhardwaj510@gmail.com>

* Updated README with latest info

Signed-off-by: iamabhishek-dubey <abhishekbhardwaj510@gmail.com>
2021-05-08 18:42:45 +05:30
45 changed files with 676 additions and 74 deletions

View File

@ -0,0 +1,23 @@
---
trigger:
- master
pr:
branches:
include:
- master
resources:
repositories:
- repository: golang-template
type: github
name: opstree/azure-devops-template
endpoint: OT-CONTAINER-KIT
extends:
template: golang-ci.yaml@golang-template
parameters:
ApplicationName: k8s-vault-webhook
QuayImageName: opstree/k8s-vault-webhook
GithubImageName: ot-container-kit/k8s-vault-webhook/k8s-vault-webhook
BuildDocs: true

View File

@ -1,49 +0,0 @@
---
name: CI Pipeline
on:
push:
branches:
- main
pull_request:
jobs:
build:
name: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup Go
uses: actions/setup-go@v2
with:
go-version: '1.15.0'
- name: Building code
run: |
make build-code
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Building Image
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile
push: false
tags: opstree/k8s-vault-webhook:latest
golangci:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: golangci-lint
uses: golangci/golangci-lint-action@v2
with:
version: v1.29
args: --timeout 5m0s

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
k8s-vault-webhook
docs/build/
bin

View File

@ -1,3 +1,22 @@
### v4.0
##### May 16, 2021
#### :tada: [Features Added]
- Added GCP secret Manager support
- Added CI pipeline using Azure DevOps
- Authenticate and authorize using GCP service-account and annotations
- Secret injection in pods/containers from GCP Secret Manager
### v3.0
##### May 9, 2021
#### :tada: [Features Added]
- Added Azure Key Vault support
- Fetch secrets from Azure Key Vault and inject them in pods/containers
- Pod AD identity and Service principal based authentication in Azure
### v2.0
##### May 8, 2021

View File

@ -2,7 +2,7 @@
REGISTRY ?= quay.io
REPOSITORY ?= $(REGISTRY)/opstree
ARTIFACT_NAME=k8s-vault-webhook
VERSION = 2.0
VERSION = 4.0
all: build-code build-image

View File

@ -3,8 +3,8 @@
</div>
<p align="center">
<a href="https://github.com/OT-CONTAINER-KIT/k8s-vault-webhook">
<img src="https://github.com/OT-CONTAINER-KIT/k8s-vault-webhook/workflows/CI%20Pipeline/badge.svg" alt="Github CI">
<a href="https://dev.azure.com/opstreedevops/DevOps/_build?definitionId=4">
<img src="https://dev.azure.com/opstreedevops/DevOps/_apis/build/status/k8s-vault-webhook/k8s-vault-webhook?branchName=master" alt="Azure Pipelines">
</a>
<a href="https://goreportcard.com/report/github.com/OT-CONTAINER-KIT/k8s-vault-webhook">
<img src="https://goreportcard.com/badge/github.com/OT-CONTAINER-KIT/k8s-vault-webhook" alt="GoReportCard">
@ -28,16 +28,17 @@ The motive of creating this project is to provide a dynamic secret injection to
Documentation is available here:- https://ot-container-kit.github.io/k8s-vault-webhook/
Blog Link:- https://blog.opstree.com/2021/09/14/introducing-kubernetes-vault-web-hook/
The secret managers which are currently supported:-
- **[Hashicorp Vault](https://www.vaultproject.io/)**
- **[AWS Secret Manager](https://aws.amazon.com/secrets-manager/)**
There are some secret managers which are planned to be implemented in future.
- **[Azure Key Vault](https://azure.microsoft.com/en-in/services/key-vault/)**
- **[GCP Secret Manager](https://cloud.google.com/secret-manager)**
This project is based on secret-consumer-webhook. Please check out the source code at https://github.com/innovia/secrets-consumer-webhook.
### Supported Features
- Authentication to Hashicorp vault using Kubernetes service-account
@ -45,6 +46,11 @@ There are some secret managers which are planned to be implemented in future.
- Inject secret directly to pods/containers running inside Kubernetes
- Inject secret directly to pods/containers from AWS Secret Manager
- Authentication with AWS Secret Manager with access key and iam role
- Fetch secrets from Azure Key Vault and inject them in pods/containers
- Pod AD identity and Service principal based authentication in Azure
- Authentication with AWS Secret Manager with access key and iam role
- Authenticate and authorize using GCP service-account and annotations
- Secret injection in pods/containers from GCP Secret Manager
- Support regex to inject all secrets from a certain path of Vault
- Inject secrets directly to the process of container, i.e. after the injection you cannot read secrets from the environment variable

1
VERSION Normal file
View File

@ -0,0 +1 @@
v4.0

View File

@ -1,6 +1,28 @@
package main
const (
// AnnotationGCPSecretManagerEnabled if enabled use GCP secret manager
AnnotationGCPSecretManagerEnabled = "gcp.opstree.secret.manager/enabled"
// AnnotationGCPSecretManagerProjectID the gcp project id to use for the secret manager
AnnotationGCPSecretManagerProjectID = "gcp.opstree.secret.manager/project-id"
// AnnotationGCPSecretManagerSecretName the name of the GCP secret
AnnotationGCPSecretManagerSecretName = "gcp.opstree.secret.manager/secret-name"
// AnnotationGCPSecretManagerSecretVersion the version number for the secret
AnnotationGCPSecretManagerSecretVersion = "gcp.opstree.secret.manager/secret-version"
// AnnotationGCPSecretManagerGCPServiceAccountKeySecretName is the secret name where the GCP service account credentials
// are stored and has teh permissions to access the secret
AnnotationGCPSecretManagerGCPServiceAccountKeySecretName = "gcp.opstree.secret.manager/gcp-service-account-key-secret-name"
// AnnotationAzureKeyVaultEnabled if enabled it will use Azure Key Vault
AnnotationAzureKeyVaultEnabled = "azure.opstree.secret.manager/enabled"
// AnnotationAzureKeyVaultName azure key vault name
AnnotationAzureKeyVaultName = "azure.opstree.secret.manager/vault-name"
// AnnotationAWSSecretManagerEnabled if enabled it will use AWS secret manager
AnnotationAWSSecretManagerEnabled = "aws.opstree.secret.manager/enabled"

28
azure.go Normal file
View File

@ -0,0 +1,28 @@
package main
import (
"fmt"
corev1 "k8s.io/api/core/v1"
)
type azure struct {
config struct {
enabled bool
azureKeyVaultName string
}
}
func (azure *azure) mutateContainer(container corev1.Container) corev1.Container {
container = azure.setArgs(container)
return container
}
func (azure *azure) setArgs(c corev1.Container) corev1.Container {
args := []string{"azure"}
args = append(args, fmt.Sprintf("--azure-vault-name=%s", azure.config.azureKeyVaultName))
args = append(args, "--")
c.Args = append(args, c.Args...)
return c
}

View File

@ -70,6 +70,8 @@ module.exports = {
children: [
'hashicorp-vault',
'aws-secret-manager',
'azure-integration',
'gcp-secret-manager',
]
},
{
@ -78,6 +80,8 @@ module.exports = {
children: [
'hashicorp-vault-example',
'aws-secret-manager-example',
'azure-examples',
'gcp-secret-manager-example',
]
},
{

View File

@ -13,9 +13,6 @@ The secret managers which are currently supported:-
- **[Hashicorp Vault](https://www.vaultproject.io/)**
- **[AWS Secret Manager](https://aws.amazon.com/secrets-manager/)**
There are some secret managers which are planned to be implemented in future.
- **[Azure Key Vault](https://azure.microsoft.com/en-in/services/key-vault/)**
- **[GCP Secret Manager](https://cloud.google.com/secret-manager)**
@ -31,14 +28,6 @@ There are some secret managers which are planned to be implemented in future.
## Architecture
### Hashicorp Vault
<div align="center" style="padding-top: 25px;">
<img src="./images/k8s-vault-webhook-arc-vault.png">
</div>
### AWS Secret Manager
<div align="center" style="padding-top: 25px;">
<img src="./images/k8s-vault-webhook-arc-aws.png">
<img src="./images/k8s-vault-webhook-arc.png">
</div>

View File

@ -7,9 +7,6 @@ The annotations which are currently supported:-
- **[Hashicorp Vault](https://www.vaultproject.io/)**
- **[AWS Secret Manager](https://aws.amazon.com/secrets-manager/)**
There are some other annotations which are planned to be implemented in future.
- **[Azure Key Vault](https://azure.microsoft.com/en-in/services/key-vault/)**
- **[GCP Secret Manager](https://cloud.google.com/secret-manager)**
@ -39,3 +36,20 @@ The available annotations for k8s vault webhook are:-
|`aws.secret.manager/role-arn`| AWS IAM Role to access the secret | no | |
|`aws.secret.manager/secret-name`| Name of the AWS secret | no | |
|`aws.secret.manager/previous-version`| If the secret is rotated, set to "true" | no | |
## Azure Annotations
|**Name**|**Description**|**Required**|**Default**|
|--------|---------------|------------|-----------|
|`azure.secret.manager/enabled`| Enable the Azure Key Vault | - | false |
|`azure.secret.manager/vault-name`| Name of the Azure Key Vault in which secrets are held | no | test-secret |
## GCP Annotations
|**Name**|**Description**|**Required**|**Default**|
|--------|---------------|------------|-----------|
|`gcp.opstree.secret.manager/enabled`| enable the GCP secret manager | - | false |
|`gcp.opstree.secret.manager/project-id` | GCP Project ID | Yes | - |
|`gcp.opstree.secret.manager/gcp-service-account-key-secret-name` | GCP IAM service account secret name (file name **must be** `service-account.json`) | No | Google Default Application Credentials |
|`gcp.opstree.secret.manager/secret-name` | secret name | Yes | - |
|`gcp.opstree.secret.manager/secret-version` | specify the secret version as string | No | Latest |

View File

@ -0,0 +1,83 @@
# Azure Key Vault
Let's try to create a deployment to inject secrets directly from Azure Key Vault. For example, purpose we are taking mysql as deployment and then we will try to set mysql root password using k8s-vault-webhook.
We can use our [example](https://github.com/OT-CONTAINER-KIT/k8s-vault-webhook/tree/master/example) folder.
The environment variables will get substitute automatically, we just have to provide some custom annotations.
```yaml
template:
metadata:
labels:
app: k8s-azure-mysql
tier: mysql
# Use Azure App Pod Pinding if cluster is configured in Azure
# aadpodidbinding: POD_IDENTITY_NAME
annotations:
azure.opstree.secret.manager/enabled: "true"
azure.opstree.secret.manager/vault-name: "vault-k8s-secret"
spec:
containers:
- image: opstree/mysql:latest
name: mysql
# If running outside Azure
env:
- name: AZURE_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: azure-secret
key: AZURE_CLIENT_SECRET
- name: AZURE_CLIENT_ID
valueFrom:
secretKeyRef:
name: azure-secret
key: AZURE_CLIENT_ID
- name: AZURE_TENANT_ID
valueFrom:
secretKeyRef:
name: azure-secret
key: AZURE_TENANT_ID
```
Let's try to apply the deployment manifest.
```shell
$ kubectl apply -f example/azure-mysql-example.yaml
...
deployment.apps/k8s-azure-mysql configured
```
Verify the mysql pods are running or not by using `kubectl` command line.
```shell
$ kubectl get pods
...
NAME READY STATUS RESTARTS AGE
k8s-azure-mysql-658b99f8dc-k9r58 1/1 Running 0 128m
```
Now let's try to get inside the `mysql` pod and see if the Azure Key Vault's password is working fine or not.
```shell
$ kubectl exec -it k8s-azure-mysql-658b99f8dc-k9r58 \
-- mysql -u root -pazurepassword -e "show databases;"
...
Warning: Using a password on the command line interface can be insecure.
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
+--------------------+
```
Also, try to check the value in environment variable of MySQL pod.
```shell
$ kubectl exec -it k8s-azure-mysql-658b99f8dc-k9r58 \
-- env | grep ROOT
...
No output
```

View File

@ -0,0 +1,23 @@
# Azure Key Vault
For integrating AWS Secret Manager with the K8s Vault Webhook, first we need to setup Azure Key Vault inside Azure account.
Here we will talk about the integration of Azure Key Vault inside Kubernetes.
Login into the [Azure Portal](http://portal.azure.com/#home) and select [Azure Key Vault](https://azure.microsoft.com/en-in/services/key-vault/) service.
![](./images/azure-key-vault-azure.png)
Create a secret in Settings > Secrets and click on `Generate/Import` ans specify these details for testing.
|**Key**|**Value**|
|-------|---------|
| mysql-root-password | azurepassword |
![](./images/azure-key-vault-secrets.png)
Once the details has been provided, create the secret.
![](./images/azure-key-vault-name.png)
**Since Azure Key Vault doesn't supports underscore `_`, we will use hyphen `-`. The k8s-vault-webhook will automatically replace the hyphen with underscore.**

View File

@ -1,3 +1,22 @@
### v4.0
**May 16, 2021**
**:tada: [Features Added]**
- Added GCP secret Manager support
- Added CI pipeline using Azure DevOps
- Authenticate and authorize using GCP service-account and annotations
- Secret injection in pods/containers from GCP Secret Manager
### v3.0
**May 9, 2021**
**:tada: [Features Added]**
- Added Azure Key Vault support
- Fetch secrets from Azure Key Vault and inject them in pods/containers
- Pod AD identity and Service principal based authentication in Azure
### v2.0
**May 8, 2021**

View File

@ -0,0 +1,70 @@
# GCP Secret Manager
Let's try to create a deployment to inject secrets directly from GCP Secret Manager. For example, purpose we are taking mysql as deployment and then we will try to set mysql root password using k8s-vault-webhook.
We can use our [example](https://github.com/OT-CONTAINER-KIT/k8s-vault-webhook/tree/master/example) folder.
The environment variables will get substitute automatically, we just have to provide some custom annotations.
```yaml
template:
metadata:
labels:
app: k8s-gcp-mysql
tier: mysql
annotations:
gcp.opstree.secret.manager/enabled: "true"
gcp.opstree.secret.manager/project-id: "graceful-flag-209120"
gcp.opstree.secret.manager/secret-name: "test-secret"
gcp.opstree.secret.manager/secret-version: "3"
gcp.opstree.secret.manager/gcp-service-account-key-secret-name: "gcp-sa"
spec:
containers:
- image: opstree/mysql:latest
name: mysql
ports:
- containerPort: 3306
name: mysql
```
Let's try to apply the deployment manifest.
```shell
$ kubectl apply -f example/gcp-mysql-example.yaml
...
deployment.apps/k8s-gcp-mysql configured
```
Verify the mysql pods are running or not by using `kubectl` command line.
```shell
$ kubectl get pods
...
NAME READY STATUS RESTARTS AGE
k8s-gcp-mysql-7b45bbc486-8w55w 1/1 Running 0 16h
```
Now let's try to get inside the `mysql` pod and see if the GCP Secret Manager's password is working fine or not.
```shell
$ kubectl exec -it k8s-gcp-mysql-7b45bbc486-8w55w \
-- mysql -u root -pgcppassword -e "show databases;"
...
Warning: Using a password on the command line interface can be insecure.
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
+--------------------+
```
Also, try to check the value in environment variable of MySQL pod.
```shell
$ kubectl exec -it k8s-gcp-mysql-7b45bbc486-8w55w \
-- env | grep ROOT
...
No output
```

View File

@ -0,0 +1,23 @@
# GCP Secret Manager
For integrating GCP Secret Manager with the K8s Vault Webhook, first we need to setup GCP Secret Manager inside GCP account.
Here we will talk about the integration of GCP Secret Manager inside Kubernetes.
Login into the [GCP Portal](https://console.cloud.google.com/) and select [GCP Secret Manager](https://console.cloud.google.com/security/secret-manager) service.
![](./images/gcp-secret-manager.png)
Create a secret by clicking on **Create Secret** and provide a JSON key value pair in the secret data like this:-
```json
{
"MYSQL_ROOT_PASSWORD": "gcppassword"
}
```
![](./images/gcp-secret-manager-create.png)
Once the secret details has been provided, create the secret.
**We can provide multiple key-value in form on JSON data**

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 295 KiB

After

Width:  |  Height:  |  Size: 297 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 352 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 543 KiB

View File

@ -38,3 +38,5 @@ Azure Key Vault is cloud service to securely store and accessing credentials suc
## GCP Secret Manager
GCP Secret Manager is a secure and convenient storage system for API keys, passwords, certificates, and other sensitive data. Secret Manager provides a central place and single source of truth to manage, access, and audit secrets across Google Cloud.
![](./images/gcp-secret-mananger-gcp.png)

View File

@ -0,0 +1,48 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: k8s-azure-mysql
labels:
app: k8s-azure-mysql
spec:
selector:
matchLabels:
app: k8s-azure-mysql
tier: mysql
strategy:
type: Recreate
template:
metadata:
labels:
app: k8s-azure-mysql
tier: mysql
# Use Azure App Pod Pinding if cluster is configured in Azure
# aadpodidbinding: POD_IDENTITY_NAME
annotations:
azure.opstree.secret.manager/enabled: "true"
azure.opstree.secret.manager/vault-name: "vault-k8s-secret"
spec:
containers:
- image: opstree/mysql:latest
name: mysql
# If running outside Azure
env:
- name: AZURE_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: azure-secret
key: AZURE_CLIENT_SECRET
- name: AZURE_CLIENT_ID
valueFrom:
secretKeyRef:
name: azure-secret
key: AZURE_CLIENT_ID
- name: AZURE_TENANT_ID
valueFrom:
secretKeyRef:
name: azure-secret
key: AZURE_TENANT_ID
ports:
- containerPort: 3306
name: mysql

View File

@ -0,0 +1,32 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: k8s-gcp-mysql
labels:
app: k8s-gcp-mysql
spec:
selector:
matchLabels:
app: k8s-gcp-mysql
tier: mysql
strategy:
type: Recreate
template:
metadata:
labels:
app: k8s-gcp-mysql
tier: mysql
annotations:
gcp.opstree.secret.manager/enabled: "true"
gcp.opstree.secret.manager/project-id: "graceful-flag-209120"
gcp.opstree.secret.manager/secret-name: "test-secret"
gcp.opstree.secret.manager/secret-version: "3"
gcp.opstree.secret.manager/gcp-service-account-key-secret-name: "gcp-sa"
spec:
containers:
- image: opstree/mysql:latest
name: mysql
ports:
- containerPort: 3306
name: mysql

54
gcp.go Normal file
View File

@ -0,0 +1,54 @@
package main
import (
"fmt"
corev1 "k8s.io/api/core/v1"
)
type gcp struct {
config struct {
enabled bool
projectID string
secretName string
secretVersion string
serviceAccountKeySecretName string
}
}
func (gcp *gcp) mutateContainer(container corev1.Container) corev1.Container {
container = gcp.setArgs(container)
// Mount google service account key if given
if gcp.config.serviceAccountKeySecretName != "" {
container.VolumeMounts = append(container.VolumeMounts, []corev1.VolumeMount{
{
Name: VolumeMountGoogleCloudKeyName,
MountPath: VolumeMountGoogleCloudKeyPath,
},
}...)
}
return container
}
func (gcp *gcp) setArgs(c corev1.Container) corev1.Container {
args := []string{"gcp"}
args = append(args, fmt.Sprintf("--project-id=%s", gcp.config.projectID))
if gcp.config.secretName != "" {
args = append(args, fmt.Sprintf("--secret-name=%s", gcp.config.secretName))
}
if gcp.config.secretVersion != "" {
args = append(args, fmt.Sprintf("--secret-version=%s", gcp.config.secretVersion))
}
if gcp.config.secretName != "" {
args = append(args, fmt.Sprintf("--google-application-credentials=%s", fmt.Sprintf("%s/%s", VolumeMountGoogleCloudKeyPath, GCPServiceAccountCredentialsFileName)))
}
args = append(args, "--")
c.Args = append(args, c.Args...)
return c
}

63
main.go
View File

@ -50,6 +50,20 @@ func (mw *mutatingWebhook) getVolumes(existingVolumes []corev1.Volume, secretMan
},
}
if secretManagerConfig.gcp.config.serviceAccountKeySecretName != "" {
mw.logger.Debugf("Adding Google Cloud Key Volume to podspec")
volumes = append(volumes, []corev1.Volume{
{
Name: "google-cloud-key",
VolumeSource: corev1.VolumeSource{
Secret: &corev1.SecretVolumeSource{
SecretName: secretManagerConfig.gcp.config.serviceAccountKeySecretName,
},
},
},
}...)
}
if secretManagerConfig.vault.config.tlsSecretName != "" {
mw.logger.Debugf("Adding Vault TLS Volume to podspec")
volumes = append(volumes, []corev1.Volume{
@ -248,11 +262,21 @@ func (mw *mutatingWebhook) mutateContainers(containers []corev1.Container, podSp
container.Command = []string{"/k8s-secret/k8s-secret-injector"}
container.Args = args
if secretManagerConfig.azure.config.enabled {
container = secretManagerConfig.azure.mutateContainer(container)
mutationInProgress = true
}
if secretManagerConfig.aws.config.enabled {
container = secretManagerConfig.aws.mutateContainer(container)
mutationInProgress = true
}
if secretManagerConfig.gcp.config.enabled {
container = secretManagerConfig.gcp.mutateContainer(container)
mutationInProgress = true
}
if secretManagerConfig.vault.config.enabled {
container = secretManagerConfig.vault.mutateContainer(container)
mutationInProgress = true
@ -341,6 +365,15 @@ func (mw *mutatingWebhook) parseSecretManagerConfig(obj metav1.Object) secretMan
var smCfg secretManagerConfig
annotations := obj.GetAnnotations()
smCfg.gcp.config.enabled, _ = strconv.ParseBool(annotations[AnnotationGCPSecretManagerEnabled])
smCfg.gcp.config.projectID = annotations[AnnotationGCPSecretManagerProjectID]
smCfg.gcp.config.secretName = annotations[AnnotationGCPSecretManagerSecretName]
smCfg.gcp.config.secretVersion = annotations[AnnotationGCPSecretManagerSecretVersion]
smCfg.gcp.config.serviceAccountKeySecretName = annotations[AnnotationGCPSecretManagerGCPServiceAccountKeySecretName]
smCfg.azure.config.enabled, _ = strconv.ParseBool(annotations[AnnotationAzureKeyVaultEnabled])
smCfg.azure.config.azureKeyVaultName = annotations[AnnotationAzureKeyVaultName]
smCfg.aws.config.enabled, _ = strconv.ParseBool(annotations[AnnotationAWSSecretManagerEnabled])
smCfg.aws.config.region = annotations[AnnotationAWSSecretManagerRegion]
smCfg.aws.config.roleARN = annotations[AnnotationAWSSecretManagerRoleARN]
@ -380,6 +413,16 @@ func (mw *mutatingWebhook) SecretsMutator(ctx context.Context, obj metav1.Object
switch v := obj.(type) {
case *corev1.Pod:
if smCfg.azure.config.enabled {
mw.logger.Infof("Using Azure Key Vault")
if smCfg.azure.config.azureKeyVaultName == "" {
return true, fmt.Errorf("Error getting azure key vault - make sure you set the annotation %s on the Pod", AnnotationAzureKeyVaultName)
}
return false, mw.mutatePod(v, smCfg, whcontext.GetAdmissionRequest(ctx).Namespace, whcontext.IsAdmissionRequestDryRun(ctx))
}
if smCfg.aws.config.enabled {
mw.logger.Infof("Using AWS Secret Manager")
@ -390,6 +433,24 @@ func (mw *mutatingWebhook) SecretsMutator(ctx context.Context, obj metav1.Object
return false, mw.mutatePod(v, smCfg, whcontext.GetAdmissionRequest(ctx).Namespace, whcontext.IsAdmissionRequestDryRun(ctx))
}
if smCfg.gcp.config.enabled {
var err error
mw.logger.Infof("Using GCP Secret Manager")
if smCfg.gcp.config.projectID == "" {
err = fmt.Errorf("Error getting gcp project id - make sure you set the annotation %s on the Pod", AnnotationGCPSecretManagerProjectID)
}
if smCfg.gcp.config.secretName == "" {
err = fmt.Errorf("Error getting gcp secret name - make sure you set the annotation %s on the Pod", AnnotationGCPSecretManagerSecretName)
}
if err != nil {
return true, err
}
return false, mw.mutatePod(v, smCfg, whcontext.GetAdmissionRequest(ctx).Namespace, whcontext.IsAdmissionRequestDryRun(ctx))
}
if smCfg.vault.config.enabled {
var err error
mw.logger.Info("Using Vault Secret Manager")
@ -461,7 +522,7 @@ func newK8SClient() (kubernetes.Interface, error) {
}
func init() {
viper.SetDefault("k8s_secret_injector_image", "quay.io/opstree/k8s-secret-injector:2.0")
viper.SetDefault("k8s_secret_injector_image", "quay.io/opstree/k8s-secret-injector:4.0")
viper.SetDefault("k8s_secret_injector_image_pull_policy", string(corev1.PullIfNotPresent))
viper.SetDefault("k8s_secret_injector_image_pull_secret_name", "")
viper.SetDefault("tls_cert_file", "")

9
scripts/build-docs.sh Executable file
View File

@ -0,0 +1,9 @@
#!/bin/bash
build_docs() {
cd docs; yarn install && \
yarn add -D vuepress && \
yarn build
}
build_docs

17
scripts/dockerfile-linter.sh Executable file
View File

@ -0,0 +1,17 @@
#!/bin/bash
download_hadolint() {
wget https://github.com/hadolint/hadolint/releases/download/v2.4.0/hadolint-Linux-x86_64
chmod +x hadolint-Linux-x86_64
}
execute_hadolint() {
./hadolint-Linux-x86_64 Dockerfile --ignore DL3007 --ignore DL3018
}
main() {
download_hadolint
execute_hadolint
}
main

11
scripts/gofmt.sh Executable file
View File

@ -0,0 +1,11 @@
#!/bin/bash
gofmt_files=$(go fmt ./... | wc -l)
if [[ ${gofmt_files} > 0 ]]
then
echo "Please format golang files using:- go fmt ./..."
exit 1
else
echo "All files are formated using gofmt"
fi

26
scripts/goreleaser.sh Executable file
View File

@ -0,0 +1,26 @@
#!/bin/bash
install_goreleaser() {
curl -sfL https://install.goreleaser.com/github.com/goreleaser/goreleaser.sh | sh
}
release() {
install_goreleaser
./bin/goreleaser release --rm-dist
}
compare_version() {
version=$(cat VERSION)
if ! git tag -l | grep "${version}"
then
git checkout master
echo "git tag ${version}"
git tag "${version}"
release
else
git tag -l
echo "Latest version is already updated"
fi
}
compare_version

16
scripts/gosec.sh Executable file
View File

@ -0,0 +1,16 @@
#!/bin/bash
install_gosec() {
curl -sfL https://raw.githubusercontent.com/securego/gosec/master/install.sh | sh -s latest
}
execute_gosec() {
./bin/gosec -fmt=junit-xml -out=./bin/results.xml ./... || true
}
main() {
install_gosec
execute_gosec
}
main

19
scripts/spellcheck.sh Executable file
View File

@ -0,0 +1,19 @@
#!/bin/bash
install_spellcheck() {
sudo apt-get update -y
sudo apt-get install -y aspell
}
run_spellcheck() {
aspell ../README.md
aspell ../CHANGELOG.md
aspell ../DEVELOPMENT.md
}
main() {
install_spellcheck
run_spellcheck
}
main

20
scripts/trivy-scan.sh Executable file
View File

@ -0,0 +1,20 @@
#!/bin/bash
install_trivy() {
sudo apt-get install wget apt-transport-https gnupg lsb-release -y
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | sudo apt-key add -
echo deb https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main | sudo tee -a /etc/apt/sources.list.d/trivy.list
sudo apt-get update
sudo apt-get install trivy -y
}
execute_trivy() {
trivy image --input ${IMAGE_PATH}
}
main() {
install_trivy
execute_trivy
}
main

View File

@ -1,6 +1,15 @@
package main
const (
// VolumeMountGoogleCloudKeyPath the path where the gcp service acount credentials would be mount to
VolumeMountGoogleCloudKeyPath = "/var/run/secret/cloud.google.com"
// VolumeMountGoogleCloudKeyName the name of the volume for the gcp service account
VolumeMountGoogleCloudKeyName = "google-cloud-key"
// GCPServiceAccountCredentialsFileName the name of the generated credentials file for gcp
GCPServiceAccountCredentialsFileName = "service-account.json"
// VaultTLSMountPath path where to mount the vault TLS secret
VaultTLSMountPath = "/etc/tls/"

Binary file not shown.

After

Width:  |  Height:  |  Size: 297 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 352 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 339 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 KiB

After

Width:  |  Height:  |  Size: 543 KiB

View File

@ -9,6 +9,8 @@ import (
type secretManagerConfig struct {
vault
aws
azure
gcp
// explicitSecrets bool // only get secrets that match the prefix `secret:`
}

View File

@ -1,7 +1,7 @@
package version
// version is a private field and should be set when compiling with --ldflags="-X github.com/innovia/secrets-consumer-env/pkg/version.version=X.Y.Z"
var version = "1.0"
// version is a private field
var version = "4.0"
// GetVersion returns the current version
func GetVersion() string {