Skip to content

Add a new check that will fail upon existence of repetitive annotations/labels #429

Description

@zvigrinberg

Add an optional check that will fail upon existence of repetitive annotations or labels group ( more than 1 labels or annotations) across different manifests, and will be successful if not ( if there are no such, or if repetitive annotations or labels are grouped under Named Templates that are being used across chart' templates)

Use case and an example:

Imagine you've got a chart with deployment, service, and configmap, and all of them has a group of annotations that reflecting some general information and metadata about the application, and these annotations are repetitive

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "demo-chart.fullname" . }}
  labels:
    {{- include "demo-chart.labels" . | nindent 4 }}
spec:
  {{- if not .Values.autoscaling.enabled }}
  replicas: {{ .Values.replicaCount }}
  {{- end }}
  selector:
    matchLabels:
      {{- include "demo-chart.selectorLabels" . | nindent 6 }}
  template:
    metadata:
      {{- with .Values.podAnnotations }}
      annotations:
        audit/managed-by: {{ .Release.Service | quote }}
        audit/release-name: {{ .Release.Name | quote }}
        audit/release-namespace: {{ .Release.Namespace | quote }}
        audit/kube-version: {{ .Capabilities.KubeVersion.Version | quote }}
        audit/helm-version: {{ .Capabilities.HelmVersion.Version | default "blank" |  quote }}
        audit/template-name: {{ .Template.Name  | quote }}
        audit/microservice-revision: {{ .Values.image.tag | default "blank" | quote }}    
      labels:
        {{- include "demo-chart.selectorLabels" . | nindent 8 }}
...
...
---

apiVersion: v1
kind: Service
metadata:
  name: {{ include "demo-chart.fullname" . }}
  labels:
    {{- include "demo-chart.labels" . | nindent 4 }}
  annotations:
    audit/managed-by: {{ .Release.Service | quote }}
    audit/release-name: {{ .Release.Name | quote }}
    audit/release-namespace: {{ .Release.Namespace | quote }}
    audit/kube-version: {{ .Capabilities.KubeVersion.Version | quote }}
    audit/helm-version: {{ .Capabilities.HelmVersion.Version | default "blank" |  quote }}
    audit/template-name: {{ .Template.Name  | quote }}
    audit/microservice-revision: {{ .Values.image.tag | default "blank" | quote }}    
spec:
  type: {{ .Values.service.type }}
  ports:
    - port: {{ .Values.service.port }}
      targetPort: http
      protocol: TCP
      name: http
  selector:
    {{- include "demo-chart.selectorLabels" . | nindent 4 }}

---

apiVersion: v1
kind: ConfigMap
data:
  key1: value1
  key2: value2
metadata:
  annotations:
    audit/managed-by: {{ .Release.Service | quote }}
    audit/release-name: {{ .Release.Name | quote }}
    audit/release-namespace: {{ .Release.Namespace | quote }}
    audit/kube-version: {{ .Capabilities.KubeVersion.Version | quote }}
    audit/helm-version: {{ .Capabilities.HelmVersion.Version | default "blank" |  quote }}
    audit/template-name: {{ .Template.Name  | quote }}
    audit/microservice-revision: {{ .Values.image.tag | default "blank" | quote }}    
  name: demo

In such Case, it would be much better to put all of these annotations in one helm defined Named Template, and then use/call this template in/from all of the manifests, , this will enable code-reuse, will reduce errors, and will enable common logic to be applied to all boilerplate/common annotations/labels to be applied to manifests.

The above chart with the manifests with boilerplate annotations should fail the suggested check

So consider the above scenario, and define a Named Template called auditTrailAnnotations in chart' _helpers.tpl:

{{- define "auditTrailAnnotations" -}}
audit/managed-by: {{ .Release.Service | quote }}
audit/release-name: {{ .Release.Name | quote }}
audit/release-namespace: {{ .Release.Namespace | quote }}
{{/*{{- if not (contains "configmap" .Template.Name)  }}*/}}
{{/*audit/release-revision: {{ .Release.Revision | quote }}*/}}
{{/*{{- end }}*/}}
audit/kube-version: {{ .Capabilities.KubeVersion.Version | quote }}
audit/helm-version: {{ .Capabilities.HelmVersion.Version | default "blank" |  quote }}
audit/template-name: {{ .Template.Name  | quote }}
audit/microservice-revision: {{ .Values.image.tag | default "blank" | quote }}
{{- end }}

Now let's use this named template in all 3 manifests.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "demo-chart.fullname" . }}
  labels:
    {{- include "demo-chart.labels" . | nindent 4 }}
spec:
  {{- if not .Values.autoscaling.enabled }}
  replicas: {{ .Values.replicaCount }}
  {{- end }}
  selector:
    matchLabels:
      {{- include "demo-chart.selectorLabels" . | nindent 6 }}
  template:
    metadata:
      {{- with .Values.podAnnotations }}
      annotations:
        {{- include "auditTrailAnnotations" . | nindent 4 }}
      labels:
        {{- include "demo-chart.selectorLabels" . | nindent 8 }}
...
...
---

apiVersion: v1
kind: Service
metadata:
  name: {{ include "demo-chart.fullname" . }}
  labels:
    {{- include "demo-chart.labels" . | nindent 4 }}
  annotations:
    {{- include "auditTrailAnnotations" . | nindent 4 }}
spec:
  type: {{ .Values.service.type }}
  ports:
    - port: {{ .Values.service.port }}
      targetPort: http
      protocol: TCP
      name: http
  selector:
    {{- include "demo-chart.selectorLabels" . | nindent 4 }}

---

apiVersion: v1
kind: ConfigMap
data:
  key1: value1
  key2: value2
metadata:
  annotations:
    {{- include "auditTrailAnnotations" . | nindent 4 }}
  name: demo

This is basically resulted in same rendered manifests, but much more compact and efficient, less error prone, leveraging code-reuse.
The suggested check should succeed for the new form

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions