Skip to content
This repository has been archived by the owner on May 16, 2023. It is now read-only.

Commit

Permalink
[metricbeat] Support secrets (#778)
Browse files Browse the repository at this point in the history
  • Loading branch information
erihanse authored and Gavin Williams committed Sep 10, 2020
1 parent a3d081f commit 59b9786
Show file tree
Hide file tree
Showing 4 changed files with 190 additions and 0 deletions.
1 change: 1 addition & 0 deletions metricbeat/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ as a reference. They are also used in the automated testing of this chart.
| `priorityClassName` | The name of the [PriorityClass][]. No default is supplied as the PriorityClass must be created first | `""` |
| `readinessProbe` | Parameters to pass to readiness [probe][] checks for values such as timeouts and thresholds | see [values.yaml][] |
| `replicas` | The replica count for the Metricbeat deployment talking to kube-state-metrics | `1` |
| `secrets` | Allows creating a secret from variables or a file. To add secrets from file, add suffix `.filepath` to the key of the secret key. The value will be encoded to base64. | See [values.yaml][] |
| `serviceAccount` | Custom [serviceAccount][] that Metricbeat will use during execution. By default will use the service account created by this chart | `""` |
| `serviceAccountAnnotations` | Annotations to be added to the ServiceAccount that is created by this chart. | `{}` |
| `terminationGracePeriod` | Termination period (in seconds) to wait before killing Metricbeat pod process on pod shutdown | `30` |
Expand Down
27 changes: 27 additions & 0 deletions metricbeat/templates/secret.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{{- if .Values.secrets }}
{{- $fullName := include "metricbeat.fullname" . -}}
{{- range .Values.secrets }}
---
apiVersion: v1
kind: Secret
metadata:
name: {{ printf "%s-%s" $fullName .name | quote }}
labels:
app: {{ $fullName | quote }}
chart: {{ $.Chart.Name | quote }}
heritage: {{ $.Release.Service | quote }}
release: {{ $.Release.Name | quote }}
{{- range $key, $value := $.Values.labels }}
{{ $key }}: {{ $value | quote }}
{{- end }}
data:
{{- range $key, $val := .value }}
{{- if hasSuffix "filepath" $key }}
{{ $key | replace ".filepath" "" }}: {{ $.Files.Get $val | b64enc | quote }}
{{ else }}
{{ $key }}: {{ $val | b64enc | quote }}
{{- end }}
{{- end }}
type: Opaque
{{- end }}
{{- end }}
146 changes: 146 additions & 0 deletions metricbeat/tests/metricbeat_test.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import os
import sys
import base64

sys.path.insert(1, os.path.join(sys.path[0], "../../helpers"))
from helpers import helm_template
Expand Down Expand Up @@ -1229,3 +1230,148 @@ def test_custom_kube_stat_metrics_host():
][1]["value"]
== "kube-state-metrics.kube-system:9999"
)


def test_adding_a_secret():
content = "LS1CRUdJTiBgUFJJVkFURSB"
config = """
secrets:
- name: "env"
value:
ELASTICSEARCH_PASSWORD: {elk_pass}
""".format(
elk_pass=content
)
content_b64 = base64.b64encode(content.encode("ascii")).decode("ascii")

r = helm_template(config)
secret_name = name + "-env"
s = r["secret"][secret_name]
assert s["metadata"]["labels"]["app"] == name
assert len(r["secret"]) == 1
assert len(s["data"]) == 1
assert s["data"] == {"ELASTICSEARCH_PASSWORD": content_b64}


def test_adding_secret_from_file():
content = """
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEApCt3ychnqZHsS
DylPFZn55xDaDcWco1oNFdBGzFjw+
zkuMFMOv7ab+yOFwHeEeAAEkEgy1u
Da1vIscBs1K0kbEFRSqySLuNHWiJp
wK2cI/gJc+S9Qd9Qsn0XGjmjQ6P2p
ot2hvCOtnei998OmDSYORKBq2jiv/
-----END RSA PRIVATE KEY-----
"""
config = """
secrets:
- name: "tls"
value:
cert.key.filepath: "secrets/private.key"
"""
content_b64 = base64.b64encode(content.encode("ascii")).decode("ascii")
work_dir = os.path.join(os.path.abspath(os.getcwd()), "secrets")
filename = os.path.join(work_dir, "private.key")
os.makedirs(os.path.dirname(filename), exist_ok=True)
with open(filename, "w") as f:
f.write(content)

with open(filename, "r") as f:
data = f.read()
assert data == content

r = helm_template(config)
secret_name = name + "-tls"
s = r["secret"][secret_name]
assert s["metadata"]["labels"]["app"] == name
assert len(r["secret"]) == 1
assert len(s["data"]) == 1
assert s["data"] == {
"cert.key": content_b64,
}

os.remove(filename)
os.rmdir(work_dir)


def test_adding_multiple_data_secret():
content = {
"elk_pass": "LS1CRUdJTiBgUFJJVkFURSB",
"api_key": "ui2CsdUadTiBasRJRkl9tvNnw",
}
config = """
secrets:
- name: "env"
value:
ELASTICSEARCH_PASSWORD: {elk_pass}
api_key: {api_key}
""".format(
elk_pass=content["elk_pass"], api_key=content["api_key"]
)
content_b64 = {
"elk_pass": base64.b64encode(content["elk_pass"].encode("ascii")).decode(
"ascii"
),
"api_key": base64.b64encode(content["api_key"].encode("ascii")).decode("ascii"),
}

r = helm_template(config)
secret_name = name + "-env"
s = r["secret"][secret_name]
assert s["metadata"]["labels"]["app"] == name
assert len(r["secret"]) == 1
assert len(s["data"]) == 2
assert s["data"] == {
"ELASTICSEARCH_PASSWORD": content_b64["elk_pass"],
"api_key": content_b64["api_key"],
}


def test_adding_multiple_secrets():
content = {
"elk_pass": "LS1CRUdJTiBgUFJJVkFURSB",
"cert_crt": "LS0tLS1CRUdJTiBlRJRALKJDDQVRFLS0tLS0K",
"cert_key": "LS0tLS1CRUdJTiBgUFJJVkFURSBLRVktLS0tLQo",
}
config = """
secrets:
- name: "env"
value:
ELASTICSEARCH_PASSWORD: {elk_pass}
- name: "tls"
value:
cert.crt: {cert_crt}
cert.key: {cert_key}
""".format(
elk_pass=content["elk_pass"],
cert_crt=content["cert_crt"],
cert_key=content["cert_key"],
)
content_b64 = {
"elk_pass": base64.b64encode(content["elk_pass"].encode("ascii")).decode(
"ascii"
),
"cert_crt": base64.b64encode(content["cert_crt"].encode("ascii")).decode(
"ascii"
),
"cert_key": base64.b64encode(content["cert_key"].encode("ascii")).decode(
"ascii"
),
}

r = helm_template(config)
secret_names = {"env": name + "-env", "tls": name + "-tls"}
s_env = r["secret"][secret_names["env"]]
s_tls = r["secret"][secret_names["tls"]]
assert len(r["secret"]) == 2
assert len(s_env["data"]) == 1
assert s_env["data"] == {
"ELASTICSEARCH_PASSWORD": content_b64["elk_pass"],
}
assert len(s_tls["data"]) == 2
assert s_tls["data"] == {
"cert.crt": content_b64["cert_crt"],
"cert.key": content_b64["cert_key"],
}
16 changes: 16 additions & 0 deletions metricbeat/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,22 @@ kube_state_metrics:
# host is used only when kube_state_metrics.enabled: false
host: ""

# Add sensitive data to k8s secrets
secrets: []
# - name: "env"
# value:
# ELASTICSEARCH_PASSWORD: "LS1CRUdJTiBgUFJJVkFURSB"
# api_key: ui2CsdUadTiBasRJRkl9tvNnw
# - name: "tls"
# value:
# ca.crt: |
# LS0tLS1CRUdJT0K
# LS0tLS1CRUdJT0K
# LS0tLS1CRUdJT0K
# LS0tLS1CRUdJT0K
# cert.crt: "LS0tLS1CRUdJTiBlRJRklDQVRFLS0tLS0K"
# cert.key.filepath: "secrets.crt" # The path to file should be relative to the `values.yaml` file.

# DEPRECATED
affinity: {}
envFrom: []
Expand Down

0 comments on commit 59b9786

Please sign in to comment.