From 96563a953f1eccec75c4f0f970908ce2b5c5ff3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20R=C3=BCger?= Date: Tue, 9 Jun 2020 11:14:32 +0200 Subject: [PATCH] feat: Encode chart information into metadata MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As a helm user we want to retrieve information about state of our helm deployments, so that we can have a cluster-level dashboard for it. Our approach was employing https://github.com/sstarcher/helm-exporter to expose helm metadata via prometheus. Unfortunately with the chosen secret storage backend, read access is required to get the information about deployed chart and application versions. Kubernetes does not allow to differentiate between different types of secrets on a namespace, so providing read access to secrets could leak other secret information (API Tokens, Certificate Keys, Credentials) through such an exporter. This change exposes chart and application versions in the metadata, so we don't have to provide read access to secrets for helm-exporter anymore, but helm-exporter could simply use a "list" RBAC permission to read the metadata. Signed-off-by: Manuel RĂ¼ger --- pkg/chart/chart.go | 8 ++++++++ pkg/chart/chart_test.go | 1 + pkg/storage/driver/mock_test.go | 9 +++++++++ pkg/storage/driver/secrets.go | 2 ++ 4 files changed, 20 insertions(+) diff --git a/pkg/chart/chart.go b/pkg/chart/chart.go index bd75375a4..582eec543 100644 --- a/pkg/chart/chart.go +++ b/pkg/chart/chart.go @@ -129,6 +129,14 @@ func (ch *Chart) AppVersion() string { return ch.Metadata.AppVersion } +// Version returns the chartversion of the chart. +func (ch *Chart) Version() string { + if ch.Metadata == nil { + return "" + } + return ch.Metadata.Version +} + // CRDs returns a list of File objects in the 'crds/' directory of a Helm chart. // Deprecated: use CRDObjects() func (ch *Chart) CRDs() []*File { diff --git a/pkg/chart/chart_test.go b/pkg/chart/chart_test.go index ef8cec3ad..f666b8a82 100644 --- a/pkg/chart/chart_test.go +++ b/pkg/chart/chart_test.go @@ -94,6 +94,7 @@ func TestMetadata(t *testing.T) { is.Equal("foo.yaml", chrt.Name()) is.Equal("1.0.0", chrt.AppVersion()) + is.Equal("1.0.0", chrt.Version()) is.Equal(nil, chrt.Validate()) } diff --git a/pkg/storage/driver/mock_test.go b/pkg/storage/driver/mock_test.go index c0236ece8..322400e87 100644 --- a/pkg/storage/driver/mock_test.go +++ b/pkg/storage/driver/mock_test.go @@ -31,6 +31,7 @@ import ( kblabels "k8s.io/apimachinery/pkg/labels" corev1 "k8s.io/client-go/kubernetes/typed/core/v1" + chart "helm.sh/helm/v3/pkg/chart" rspb "helm.sh/helm/v3/pkg/release" ) @@ -40,6 +41,14 @@ func releaseStub(name string, vers int, namespace string, status rspb.Status) *r Version: vers, Namespace: namespace, Info: &rspb.Info{Status: status}, + Chart: &chart.Chart{ + Metadata: &chart.Metadata{ + APIVersion: "v1", + Name: "hello", + Version: "0.1.0", + AppVersion: "0.2.0", + }, + }, } } diff --git a/pkg/storage/driver/secrets.go b/pkg/storage/driver/secrets.go index 44280f70f..6f9328d5e 100644 --- a/pkg/storage/driver/secrets.go +++ b/pkg/storage/driver/secrets.go @@ -224,6 +224,8 @@ func newSecretsObject(key string, rls *rspb.Release, lbs labels) (*v1.Secret, er lbs.set("owner", owner) lbs.set("status", rls.Info.Status.String()) lbs.set("version", strconv.Itoa(rls.Version)) + lbs.set("appVersion", rls.Chart.AppVersion()) + lbs.set("chartVersion", rls.Chart.Version()) // create and return secret object. // Helm 3 introduced setting the 'Type' field