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

[metricbeat] Support secrets #778

Merged
merged 2 commits into from
Sep 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions metricbeat/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,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