{{ if .Values.prometheus.enabled -}}
---
###
### Prometheus
###
kind: ConfigMap
apiVersion: v1
metadata:
  name: prometheus-config
  namespace: {{ .Release.Namespace }}
  labels:
    linkerd.io/extension: viz
    component: prometheus
    namespace: {{.Release.Namespace}}
    {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }}
  annotations:
    {{ include "partials.annotations.created-by" . }}
data:
  prometheus.yml: |-
    global:
      {{- if .Values.prometheus.globalConfig -}}
      {{- toYaml .Values.prometheus.globalConfig | trim | nindent 6 }}
      {{- end}}

    rule_files:
    - /etc/prometheus/*_rules.yml
    - /etc/prometheus/*_rules.yaml

    scrape_configs:
    - job_name: 'prometheus'
      static_configs:
      - targets: ['localhost:9090']

    #  Required for: https://grafana.com/grafana/dashboards/315
    - job_name: 'kubernetes-nodes-cadvisor'
      scheme: https
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
        insecure_skip_verify: true
      bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
      kubernetes_sd_configs:
      - role: node
      relabel_configs:
      - action: labelmap
        regex: __meta_kubernetes_node_label_(.+)
      - target_label: __address__
        replacement: kubernetes.default.svc:443
      - source_labels: [__meta_kubernetes_node_name]
        regex: (.+)
        target_label: __metrics_path__
        replacement: /api/v1/nodes/$1/proxy/metrics/cadvisor
      metric_relabel_configs:
      - source_labels: [__name__]
        regex: '(container|machine)_(cpu|memory|network|fs)_(.+)'
        action: keep
      - source_labels: [__name__]
        regex: 'container_memory_failures_total' # unneeded large metric
        action: drop

    - job_name: 'linkerd-controller'
      kubernetes_sd_configs:
      - role: pod
        namespaces:
          names:
          - '{{.Values.linkerdNamespace}}'
          - '{{.Release.Namespace}}'
      relabel_configs:
      - source_labels:
        - __meta_kubernetes_pod_container_port_name
        action: keep
        regex: admin
      - source_labels: [__meta_kubernetes_pod_container_name]
        action: replace
        target_label: component

    - job_name: 'linkerd-multicluster-controller'
      kubernetes_sd_configs:
      - role: pod
      relabel_configs:
      - source_labels:
        - __meta_kubernetes_pod_label_component
        - __meta_kubernetes_pod_container_port_name
        action: keep
        regex: (linkerd-service-mirror|controller);admin$
      - source_labels: [__meta_kubernetes_pod_container_name]
        action: replace
        target_label: component

    - job_name: 'linkerd-proxy'
      kubernetes_sd_configs:
      - role: pod
      relabel_configs:
      - source_labels:
        - __meta_kubernetes_pod_container_name
        - __meta_kubernetes_pod_container_port_name
        - __meta_kubernetes_pod_label_linkerd_io_control_plane_ns
        action: keep
        regex: ^{{default .Values.proxyContainerName "linkerd-proxy" .Values.proxyContainerName}};linkerd-admin;{{.Values.linkerdNamespace}}$
      - source_labels: [__meta_kubernetes_namespace]
        action: replace
        target_label: namespace
      - source_labels: [__meta_kubernetes_pod_name]
        action: replace
        target_label: pod
      # special case k8s' "job" label, to not interfere with prometheus' "job"
      # label
      # __meta_kubernetes_pod_label_linkerd_io_proxy_job=foo =>
      # k8s_job=foo
      - source_labels: [__meta_kubernetes_pod_label_linkerd_io_proxy_job]
        action: replace
        target_label: k8s_job
      # drop __meta_kubernetes_pod_label_linkerd_io_proxy_job
      - action: labeldrop
        regex: __meta_kubernetes_pod_label_linkerd_io_proxy_job
      # __meta_kubernetes_pod_label_linkerd_io_proxy_deployment=foo =>
      # deployment=foo
      - action: labelmap
        regex: __meta_kubernetes_pod_label_linkerd_io_proxy_(.+)
      # drop all labels that we just made copies of in the previous labelmap
      - action: labeldrop
        regex: __meta_kubernetes_pod_label_linkerd_io_proxy_(.+)
      # __meta_kubernetes_pod_label_linkerd_io_foo=bar =>
      # foo=bar
      - action: labelmap
        regex: __meta_kubernetes_pod_label_linkerd_io_(.+)
      # Copy all pod labels to tmp labels
      - action: labelmap
        regex: __meta_kubernetes_pod_label_(.+)
        replacement: __tmp_pod_label_$1
      # Take `linkerd_io_` prefixed labels and copy them without the prefix
      - action: labelmap
        regex: __tmp_pod_label_linkerd_io_(.+)
        replacement:  __tmp_pod_label_$1
      # Drop the `linkerd_io_` originals
      - action: labeldrop
        regex: __tmp_pod_label_linkerd_io_(.+)
      # Copy tmp labels into real labels
      - action: labelmap
        regex: __tmp_pod_label_(.+)
      {{- if .Values.prometheus.metricRelabelConfigs }}
      metric_relabel_configs:
      {{- toYaml .Values.prometheus.metricRelabelConfigs | trim | nindent 6 }}
      {{- end}}

    {{- if .Values.prometheus.scrapeConfigs }}
    {{- toYaml .Values.prometheus.scrapeConfigs | trim | nindent 4 }}
    {{- end }}

    {{-  if (or .Values.prometheus.alertmanagers .Values.prometheus.alertRelabelConfigs) }}
    alerting:
      alert_relabel_configs:
        {{- if .Values.prometheus.alertRelabelConfigs }}
        {{- toYaml .Values.prometheus.alertRelabelConfigs | trim | nindent 6 }}
        {{- end }}
      alertmanagers:
        {{- if .Values.prometheus.alertmanagers }}
        {{- toYaml .Values.prometheus.alertmanagers | trim | nindent 6 }}
        {{- end }}
    {{- end }}

    {{- if .Values.prometheus.remoteWrite }}
    remote_write:
      {{- toYaml .Values.prometheus.remoteWrite | trim | nindent 6 }}
    {{- end }}
---
kind: Service
apiVersion: v1
metadata:
  name: prometheus
  namespace: {{ .Release.Namespace }}
  labels:
    linkerd.io/extension: viz
    component: prometheus
    namespace: {{.Release.Namespace}}
    {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }}
  annotations:
    {{ include "partials.annotations.created-by" . }}
    linkerd.io/inject: enabled
spec:
  type: ClusterIP
  selector:
    linkerd.io/extension: viz
    component: prometheus
  ports:
  - name: admin
    port: 9090
    targetPort: 9090
---
apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    {{ include "partials.annotations.created-by" . }}
    linkerd.io/inject: enabled
    config.linkerd.io/proxy-await: "enabled"
  labels:
    linkerd.io/extension: viz
    app.kubernetes.io/name: prometheus
    app.kubernetes.io/part-of: Linkerd
    app.kubernetes.io/version: {{.Values.linkerdVersion}}
    component: prometheus
    namespace: {{.Release.Namespace}}
    {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }}
  name: prometheus
  namespace: {{ .Release.Namespace }}
spec:
  replicas: 1
  revisionHistoryLimit: {{.Values.revisionHistoryLimit}}
  {{- if .Values.prometheus.persistence }}
  strategy:
    type: Recreate
  {{- end }}
  selector:
    matchLabels:
      linkerd.io/extension: viz
      component: prometheus
      namespace: {{.Release.Namespace}}
  template:
    metadata:
      annotations:
        {{ include "partials.annotations.created-by" . }}
        {{- with .Values.prometheus.proxy }}
        {{- include "partials.proxy.config.annotations" .resources | nindent 8 }}
        {{- end }}
        {{- with .Values.podAnnotations }}{{ toYaml . | trim | nindent 8 }}{{- end }}
        {{- with .Values.prometheus.podAnnotations }}{{ toYaml . | trim | nindent 8 }}{{- end }}
        linkerd.io/inject: enabled
        config.alpha.linkerd.io/proxy-wait-before-exit-seconds: "0"
      labels:
        linkerd.io/extension: viz
        component: prometheus
        namespace: {{.Release.Namespace}}
        {{- with .Values.podLabels }}{{ toYaml . | trim | nindent 8 }}{{- end }}
    spec:
      {{- if .Values.prometheus.tolerations -}}
      {{- include "linkerd.tolerations" (dict "Values" .Values.prometheus) | nindent 6 }}
      {{- end -}}
      {{- include "linkerd.node-selector" (dict "Values" .Values.prometheus) | nindent 6 }}
      automountServiceAccountToken: false
      containers:
      {{- if .Values.prometheus.sidecarContainers -}}
      {{- toYaml .Values.prometheus.sidecarContainers | trim | nindent 6 }}
      {{- end}}
      - args:
        {{- if not (hasKey .Values.prometheus.args "log.level") }}
        - --log.level={{.Values.prometheus.logLevel | default .Values.defaultLogLevel}}
        {{- end }}
        {{- if not (hasKey .Values.prometheus.args "log.format") }}
        - --log.format={{.Values.prometheus.logFormat | default .Values.defaultLogFormat | replace "plain" "logfmt" }}
        {{- end }}
        {{- range $key, $value := .Values.prometheus.args}}
        - --{{ $key }}{{ if $value }}={{ $value }}{{ end }}
        {{- end }}
        image: {{.Values.prometheus.image.registry}}/{{.Values.prometheus.image.name}}:{{.Values.prometheus.image.tag}}
        imagePullPolicy: {{.Values.prometheus.image.pullPolicy | default .Values.defaultImagePullPolicy}}
        livenessProbe:
          httpGet:
            path: /-/healthy
            port: 9090
          initialDelaySeconds: 30
          timeoutSeconds: 30
        name: prometheus
        ports:
        - containerPort: 9090
          name: admin
        readinessProbe:
          httpGet:
            path: /-/ready
            port: 9090
          initialDelaySeconds: 30
          timeoutSeconds: 30
        {{- if .Values.prometheus.resources -}}
        {{- include "partials.resources" .Values.prometheus.resources | nindent 8 }}
        {{- end }}
        securityContext:
          allowPrivilegeEscalation: false
          capabilities:
            drop:
            - ALL
          readOnlyRootFilesystem: true
          runAsGroup: 65534
          runAsNonRoot: true
          runAsUser: 65534
          seccompProfile:
            type: RuntimeDefault
        volumeMounts:
      {{- range .Values.prometheus.ruleConfigMapMounts }}
        - name: {{ .name }}
          mountPath: /etc/prometheus/{{ .subPath }}
          subPath: {{ .subPath }}
          readOnly: true
      {{- end }}
        - mountPath: /data
          name: data
        - mountPath: /etc/prometheus/prometheus.yml
          name: prometheus-config
          subPath: prometheus.yml
          readOnly: true
        - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
          name: kube-api-access
          readOnly: true
      securityContext:
        fsGroup: 65534
        seccompProfile:
          type: RuntimeDefault
      serviceAccountName: prometheus
      volumes:
    {{- range .Values.prometheus.ruleConfigMapMounts }}
      - name: {{ .name }}
        configMap:
          name: {{ .configMap }}
    {{- end }}
      - name: data
    {{- if .Values.prometheus.persistence }}
        persistentVolumeClaim:
          claimName: prometheus
    {{- else }}
        emptyDir: {}
    {{- end }}
      - configMap:
          name: prometheus-config
        name: prometheus-config
      - {{- include "partials.volumes.manual-mount-service-account-token" . | indent 8 | trimPrefix (repeat 7 " ") }}
{{- if .Values.prometheus.persistence }}
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  labels:
    linkerd.io/extension: viz
    app.kubernetes.io/name: prometheus
    app.kubernetes.io/part-of: Linkerd
    app.kubernetes.io/version: {{.Values.linkerdVersion}}
    component: prometheus
    {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }}
  name: prometheus
  namespace: {{ .Release.Namespace }}
spec:
  accessModes:
    - {{ .Values.prometheus.persistence.accessMode | quote }}
  resources:
    requests:
      storage: {{ .Values.prometheus.persistence.size | quote }}
{{- if .Values.prometheus.persistence.storageClass }}
  storageClassName: "{{ .Values.prometheus.persistence.storageClass }}"
{{- end }}
{{- end }}
{{ end -}}
