# _helpers.tpl
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "external-dns.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}

{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "external-dns.fullname" -}}
{{- if .Values.fullnameOverride -}}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- if contains $name .Release.Name -}}
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{- end -}}

{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "external-dns.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}

{{/* Helm required labels */}}
{{- define "external-dns.labels" -}}
app.kubernetes.io/name: {{ template "external-dns.name" . }}
helm.sh/chart: {{ template "external-dns.chart" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- if .Values.podLabels }}
{{ toYaml .Values.podLabels }}
{{- end }}
{{- end -}}

{{/* matchLabels */}}
{{- define "external-dns.matchLabels" -}}
app.kubernetes.io/name: {{ template "external-dns.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end -}}

{{/* podAnnotations */}}
{{- define "external-dns.podAnnotations" -}}
{{- if .Values.podAnnotations }}
{{- toYaml .Values.podAnnotations }}
{{- end }}
{{- if .Values.metrics.podAnnotations }}
{{- toYaml .Values.metrics.podAnnotations }}
{{- end }}
{{- end -}}

{{/*
Return the proper External DNS image name
*/}}
{{- define "external-dns.image" -}}
{{- $registryName := .Values.image.registry -}}
{{- $repositoryName := .Values.image.repository -}}
{{- $tag := .Values.image.tag | toString -}}
{{/*
Helm 2.11 supports the assignment of a value to a variable defined in a different scope,
but Helm 2.9 and 2.10 doesn't support it, so we need to implement this if-else logic.
Also, we can't use a single if because lazy evaluation is not an option
*/}}
{{- if .Values.global }}
    {{- if .Values.global.imageRegistry }}
        {{- printf "%s/%s:%s" .Values.global.imageRegistry $repositoryName $tag -}}
    {{- else -}}
        {{- printf "%s/%s:%s" $registryName $repositoryName $tag -}}
    {{- end -}}
{{- else -}}
    {{- printf "%s/%s:%s" $registryName $repositoryName $tag -}}
{{- end -}}
{{- end -}}

{{/*
Return the proper Docker Image Registry Secret Names
*/}}
{{- define "external-dns.imagePullSecrets" -}}
{{/*
Helm 2.11 supports the assignment of a value to a variable defined in a different scope,
but Helm 2.9 and 2.10 does not support it, so we need to implement this if-else logic.
Also, we can not use a single if because lazy evaluation is not an option
*/}}
{{- if .Values.global }}
{{- if .Values.global.imagePullSecrets }}
imagePullSecrets:
{{- range .Values.global.imagePullSecrets }}
  - name: {{ . }}
{{- end }}
{{- else if .Values.image.pullSecrets }}
imagePullSecrets:
{{- range .Values.image.pullSecrets }}
  - name: {{ . }}
{{- end }}
{{- end -}}
{{- else if .Values.image.pullSecrets }}
imagePullSecrets:
{{- range .Values.image.pullSecrets }}
  - name: {{ . }}
{{- end }}
{{- end -}}
{{- end -}}

{{/*
Return true if a secret object should be created
*/}}
{{- define "external-dns.createSecret" -}}
{{- if and (eq .Values.provider "aws") .Values.aws.credentials.secretKey .Values.aws.credentials.accessKey (not .Values.aws.credentials.secretName) }}
    {{- true -}}
{{- else if and (eq .Values.provider "azure") (or (and .Values.azure.resourceGroup .Values.azure.tenantId .Values.azure.subscriptionId .Values.azure.aadClientId .Values.azure.aadClientSecret (not .Values.azure.useManagedIdentityExtension)) (and .Values.azure.resourceGroup .Values.azure.tenantId .Values.azure.subscriptionId .Values.azure.useManagedIdentityExtension)) (not .Values.azure.secretName) -}}
    {{- true -}}
{{- else if and (eq .Values.provider "cloudflare") (or .Values.cloudflare.apiToken .Values.cloudflare.apiKey) (not .Values.cloudflare.secretName) -}}
    {{- true -}}
{{- else if and (eq .Values.provider "designate") (or .Values.designate.username .Values.designate.password) -}}
    {{- true -}}
{{- else if and (eq .Values.provider "digitalocean") .Values.digitalocean.apiToken (not .Values.digitalocean.secretName) -}}
    {{- true -}}
{{- else if and (eq .Values.provider "google") .Values.google.serviceAccountKey (not .Values.google.serviceAccountSecret) -}}
    {{- true -}}
{{- else if and (eq .Values.provider "infoblox") (and .Values.infoblox.wapiUsername .Values.infoblox.wapiPassword) -}}
    {{- true -}}
{{- else if and (eq .Values.provider "rfc2136") .Values.rfc2136.tsigSecret -}}
    {{- true -}}
{{- else if and (eq .Values.provider "pdns") .Values.pdns.apiKey -}}
    {{- true -}}
{{- else if and (eq .Values.provider "transip") .Values.transip.apiKey -}}
    {{- true -}}
{{- else -}}
{{- end -}}
{{- end -}}

{{/*
Return the name of the Secret used to store the passwords
*/}}
{{- define "external-dns.secretName" -}}
{{- if and (eq .Values.provider "aws") .Values.aws.credentials.secretName }}
{{- .Values.aws.credentials.secretName }}
{{- else if and (eq .Values.provider "azure") .Values.azure.secretName }}
{{- .Values.azure.secretName }}
{{- else if and (eq .Values.provider "cloudflare") .Values.cloudflare.secretName }}
{{- .Values.cloudflare.secretName }}
{{- else if and (eq .Values.provider "digitalocean") .Values.digitalocean.secretName }}
{{- .Values.digitalocean.secretName }}
{{- else if and (eq .Values.provider "google") .Values.google.serviceAccountSecret }}
{{- .Values.google.serviceAccountSecret }}
{{- else -}}
{{- template "external-dns.fullname" . }}
{{- end -}}
{{- end -}}

{{- define "external-dns.aws-credentials" }}
[default]
aws_access_key_id = {{ .Values.aws.credentials.accessKey }}
aws_secret_access_key = {{ .Values.aws.credentials.secretKey }}
{{ end }}

{{- define "external-dns.aws-config" }}
[profile default]
region = {{ .Values.aws.region }}
{{ end }}

{{- define "external-dns.azure-credentials" -}}
{
  {{- if .Values.azure.cloud }}
  "cloud": "{{ .Values.azure.cloud }}",
  {{- end}}
  "tenantId": "{{ .Values.azure.tenantId }}",
  "subscriptionId": "{{ .Values.azure.subscriptionId }}",
  "resourceGroup": "{{ .Values.azure.resourceGroup }}",
  {{- if not .Values.azure.useManagedIdentityExtension }}
  "aadClientId": "{{ .Values.azure.aadClientId }}",
  "aadClientSecret": "{{ .Values.azure.aadClientSecret }}"
  {{- end }}
  {{- if .Values.azure.useManagedIdentityExtension }}
  "useManagedIdentityExtension": true
  {{- end }}
}
{{ end }}

{{/*
Compile all warnings into a single message, and call fail.
*/}}
{{- define "external-dns.validateValues" -}}
{{- $messages := list -}}
{{- $messages := append $messages (include "external-dns.validateValues.provider" .) -}}
{{- $messages := append $messages (include "external-dns.validateValues.sources" .) -}}
{{- $messages := append $messages (include "external-dns.validateValues.aws" .) -}}
{{- $messages := append $messages (include "external-dns.validateValues.infoblox.gridHost" .) -}}
{{- $messages := append $messages (include "external-dns.validateValues.infoblox.wapiPassword" .) -}}
{{- $messages := append $messages (include "external-dns.validateValues.pdns.apiUrl" .) -}}
{{- $messages := append $messages (include "external-dns.validateValues.pdns.apiKey" .) -}}
{{- $messages := append $messages (include "external-dns.validateValues.azure.resourceGroup" .) -}}
{{- $messages := append $messages (include "external-dns.validateValues.azure.tenantId" .) -}}
{{- $messages := append $messages (include "external-dns.validateValues.azure.subscriptionId" .) -}}
{{- $messages := append $messages (include "external-dns.validateValues.azure.useManagedIdentityExtensionAadClientId" .) -}}
{{- $messages := append $messages (include "external-dns.validateValues.azure.useManagedIdentityExtensionAadClientSecret" .) -}}
{{- $messages := append $messages (include "external-dns.validateValues.azure.aadClientId" .) -}}
{{- $messages := append $messages (include "external-dns.validateValues.azure.aadClientSecret" .) -}}
{{- $messages := append $messages (include "external-dns.validateValues.transip.account" .) -}}
{{- $messages := append $messages (include "external-dns.validateValues.transip.apiKey" .) -}}
{{- $messages := without $messages "" -}}
{{- $message := join "\n" $messages -}}

{{- if $message -}}
{{-   printf "\nVALUES VALIDATION:\n%s" $message | fail -}}
{{- end -}}
{{- end -}}

{{/*
Validate values of External DNS:
- must set a provider
*/}}
{{- define "external-dns.validateValues.provider" -}}
{{- if not .Values.provider -}}
external-dns: provider
    You must set a provider (options: aws, google, azure, cloudflare, ...)
    Please set the provider parameter (--set provider="xxxx")
{{- end -}}
{{- end -}}

{{/*
Validate values of External DNS:
- must provide sources to be observed for new DNS entries by ExternalDNS
*/}}
{{- define "external-dns.validateValues.sources" -}}
{{- if empty .Values.sources -}}
external-dns: sources
    You must provide sources to be observed for new DNS entries by ExternalDNS
    Please set the sources parameter (--set sources="xxxx")
{{- end -}}
{{- end -}}

{{/*
Validate values of External DNS:
- The AWS Role to assume must follow ARN format when provider is "aws"
*/}}
{{- define "external-dns.validateValues.aws" -}}
{{- if and (eq .Values.provider "aws") .Values.aws.assumeRoleArn -}}
{{- if not (regexMatch "^arn:aws:iam::.*$" .Values.aws.assumeRoleArn) -}}
external-dns: aws.assumeRoleArn
    The AWS Role to assume must follow ARN format: `arn:aws:iam::123455567:role/external-dns`
    Ref: https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html
    Please set a valid ARN (--set aws.assumeRoleARN="xxxx")
{{- end -}}
{{- end -}}
{{- end -}}

{{/*
Validate values of External DNS:
- must provide the Grid Manager host when provider is "infoblox"
*/}}
{{- define "external-dns.validateValues.infoblox.gridHost" -}}
{{- if and (eq .Values.provider "infoblox") (not .Values.infoblox.gridHost) -}}
external-dns: infoblox.gridHost
    You must provide the the Grid Manager host when provider="infoblox".
    Please set the gridHost parameter (--set infoblox.gridHost="xxxx")
{{- end -}}
{{- end -}}

{{/*
Validate values of External DNS:
- must provide a WAPI password when provider is "infoblox"
*/}}
{{- define "external-dns.validateValues.infoblox.wapiPassword" -}}
{{- if and (eq .Values.provider "infoblox") (not .Values.infoblox.wapiPassword) -}}
external-dns: infoblox.wapiPassword
    You must provide a WAPI password when provider="infoblox".
    Please set the wapiPassword parameter (--set infoblox.wapiPassword="xxxx")
{{- end -}}
{{- end -}}

{{/*
Return the appropriate apiVersion for PodSecurityPolicy.
*/}}
{{- define "podSecurityPolicy.apiVersion" -}}
{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
{{- print "policy/v1beta1" -}}
{{- else -}}
{{- print "extensions/v1beta1" -}}
{{- end -}}
{{- end -}}

{{/*
Validate values of External DNS:
- must provide the PowerDNS API URL when provider is "pdns"
*/}}
{{- define "external-dns.validateValues.pdns.apiUrl" -}}
{{- if and (eq .Values.provider "pdns") (not .Values.pdns.apiUrl) -}}
external-dns: pdns.apiUrl
    You must provide the the PowerDNS API URL when provider="pdns".
    Please set the apiUrl parameter (--set pdns.apiUrl="xxxx")
{{- end -}}
{{- end -}}

{{/*
Validate values of External DNS:
- must provide the PowerDNS API key when provider is "pdns"
*/}}
{{- define "external-dns.validateValues.pdns.apiKey" -}}
{{- if and (eq .Values.provider "pdns") (not .Values.pdns.apiKey) -}}
external-dns: pdns.apiKey
    You must provide the the PowerDNS API key when provider="pdns".
    Please set the apiKey parameter (--set pdns.apiKey="xxxx")
{{- end -}}
{{- end -}}

{{/* Check if there are rolling tags in the images */}}
{{- define "external-dns.checkRollingTags" -}}
{{- if and (contains "bitnami/" .Values.image.repository) (not (.Values.image.tag | toString | regexFind "-r\\d+$|sha256:")) }}
WARNING: Rolling tag detected ({{ .Values.image.repository }}:{{ .Values.image.tag }}), please note that it is strongly recommended to avoid using rolling tags in a production environment.
+info https://docs.bitnami.com/containers/how-to/understand-rolling-tags-containers/
{{- end }}
{{- end -}}

{{/*
Validate values of Azure DNS:
- must provide the Azure Resource Group when provider is "azure"
*/}}
{{- define "external-dns.validateValues.azure.resourceGroup" -}}
{{- if and (eq .Values.provider "azure") (not .Values.azure.resourceGroup) -}}
external-dns: azure.resourceGroup
    You must provide the Azure Resource Group when provider="azure".
    Please set the resourceGroup parameter (--set azure.resourceGroup="xxxx")
{{- end -}}
{{- end -}}

{{/*
Validate values of Azure DNS:
- must provide the Azure Tenant ID when provider is "azure" and secretName is not set
*/}}
{{- define "external-dns.validateValues.azure.tenantId" -}}
{{- if and (eq .Values.provider "azure") (not .Values.azure.tenantId) (not .Values.azure.secretName) -}}
external-dns: azure.tenantId
    You must provide the Azure Tenant ID when provider="azure".
    Please set the tenantId parameter (--set azure.tenantId="xxxx")
{{- end -}}
{{- end -}}

{{/*
Validate values of Azure DNS:
- must provide the Azure Subscription ID when provider is "azure" and secretName is not set
*/}}
{{- define "external-dns.validateValues.azure.subscriptionId" -}}
{{- if and (eq .Values.provider "azure") (not .Values.azure.subscriptionId) (not .Values.azure.secretName) -}}
external-dns: azure.subscriptionId
    You must provide the Azure Subscription ID when provider="azure".
    Please set the subscriptionId parameter (--set azure.subscriptionId="xxxx")
{{- end -}}
{{- end -}}

{{/*
Validate values of Azure DNS:
- must not provide the Azure AAD Client ID when provider is "azure", secretName is not set and MSI is enabled
*/}}
{{- define "external-dns.validateValues.azure.useManagedIdentityExtensionAadClientId" -}}
{{- if and (eq .Values.provider "azure") (not .Values.azure.secretName) .Values.azure.aadClientId .Values.azure.useManagedIdentityExtension -}}
external-dns: azure.seManagedIdentityExtension
    You must not provide the Azure AAD Client ID when provider="azure" and useManagedIdentityExtension is "true".
    Please unset the aadClientId parameter (--set azure.aadClientId="xxxx")
{{- end -}}
{{- end -}}

{{/*
Validate values of Azure DNS:
- must not provide the Azure AAD Client Secret when provider is "azure", secretName is not set and MSI is enabled
*/}}
{{- define "external-dns.validateValues.azure.useManagedIdentityExtensionAadClientSecret" -}}
{{- if and (eq .Values.provider "azure") (not .Values.azure.secretName) .Values.azure.aadClientSecret .Values.azure.useManagedIdentityExtension -}}
external-dns: azure.seManagedIdentityExtension
    You must not provide the Azure AAD Client Secret when provider="azure" and useManagedIdentityExtension is "true".
    Please unset set the aadClientSecret parameter (--set azure.aadClientSecret="xxxx")
{{- end -}}
{{- end -}}

{{/*
Validate values of Azure DNS:
- must provide the Azure AAD Client ID when provider is "azure", secretName is not set and MSI is disabled
*/}}
{{- define "external-dns.validateValues.azure.aadClientId" -}}
{{- if and (eq .Values.provider "azure") (not .Values.azure.secretName) (not .Values.azure.aadClientId) (not .Values.azure.useManagedIdentityExtension) -}}
external-dns: azure.seManagedIdentityExtension
    You must provide the Azure AAD Client ID when provider="azure" and useManagedIdentityExtension is not set.
    Please set the aadClientId parameter (--set azure.aadClientId="xxxx").
{{- end -}}
{{- end -}}

{{/*
Validate values of Azure DNS:
- must provide the Azure AAD Client Secret when provider is "azure", secretName is not set and MSI is disabled
*/}}
{{- define "external-dns.validateValues.azure.aadClientSecret" -}}
{{- if and (eq .Values.provider "azure") (not .Values.azure.secretName) (not .Values.azure.aadClientSecret) (not .Values.azure.useManagedIdentityExtension) -}}
external-dns: azure.seManagedIdentityExtension
    You must provide the Azure AAD Client Secret when provider="azure" and useManagedIdentityExtension is not set.
    Please set set the aadClientSecret parameter (--set azure.aadClientSecret="xxxx")
{{- end -}}
{{- end -}}

{{/*
Validate values of TransIP DNS:
- must provide the account name when provider is "transip"
*/}}
{{- define "external-dns.validateValues.transip.account" -}}
{{- if and (eq .Values.provider "transip") (not .Values.transip.account) -}}
external-dns: transip.account
    You must provide the TransIP account name when provider="transip".
    Please set the account parameter (--set transip.account="xxxx")
{{- end -}}
{{- end -}}

{{/*
Validate values of TransIP DNS:
- must provide the API key when provider is "transip"
*/}}
{{- define "external-dns.validateValues.transip.apiKey" -}}
{{- if and (eq .Values.provider "transip") (not .Values.transip.apiKey) -}}
external-dns: transip.apiKey
    You must provide the TransIP API key when provider="transip".
    Please set the apiKey parameter (--set transip.apiKey="xxxx")
{{- end -}}
{{- end -}}
 # clusterrole.yaml
{{- if .Values.rbac.create }}
apiVersion: rbac.authorization.k8s.io/{{ .Values.rbac.apiVersion }}
kind: ClusterRole
metadata:
  name: {{ template "external-dns.fullname" . }}
  labels: {{ include "external-dns.labels" . | nindent 4 }}
rules:
- apiGroups:
  - ""
  resources:
  - services
  - pods
  - nodes
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - extensions
  - "networking.k8s.io" # k8s 1.14+
  resources:
  - ingresses
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - networking.istio.io
  resources:
  - gateways
  verbs:
  - get
  - list
  - watch
{{- if or .Values.crd.create .Values.crd.apiversion }}
- apiGroups:
  {{- if .Values.crd.create }}
  - externaldns.k8s.io
  {{- else }}
  - {{ $api := splitn "/" 2 .Values.crd.apiversion }}{{ $api._0 }}
  {{- end }}
  resources:
  {{- if .Values.crd.create }}
  - dnsendpoints
  {{- else }}
  - {{ printf "%ss" (.Values.crd.kind | lower) }}
  {{- end }}
  verbs:
  - get
  - list
  - watch
- apiGroups:
  {{- if .Values.crd.create }}
  - externaldns.k8s.io
  {{- else }}
  - {{ $api := splitn "/" 2 .Values.crd.apiversion }}{{ $api._0 }}
  {{- end }}
  resources:
  {{- if .Values.crd.create }}
  - dnsendpoints/status
  {{- else }}
  - {{ printf "%ss/status" (.Values.crd.kind | lower) }}
  {{- end }}
  verbs:
  - update
{{- end }}
{{- end }}
 # clusterrolebinding.yaml
{{- if .Values.rbac.create }}
apiVersion: rbac.authorization.k8s.io/{{ .Values.rbac.apiVersion }}
kind: ClusterRoleBinding
metadata:
  name: {{ template "external-dns.fullname" . }}
  labels: {{ include "external-dns.labels" . | nindent 4 }}
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: {{ template "external-dns.fullname" . }}
subjects:
- kind: ServiceAccount
  name: {{ template "external-dns.fullname" . }}
  namespace: {{ .Release.Namespace }}
{{- end }}
 # configmap.yaml
{{- if and (eq .Values.provider "designate") .Values.designate.customCA.enabled }}
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ template "external-dns.fullname" . }}
  labels: {{ include "external-dns.labels" . | nindent 4 }}
data:
  {{ .Values.designate.customCA.filename }}: |
{{ .Values.designate.customCA.content | indent 4 }}
{{- end }}
 # crd.yaml
{{- if .Values.crd.create }}
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  creationTimestamp: null
  labels:
    api: externaldns
    kubebuilder.k8s.io: 1.0.0
  name: dnsendpoints.externaldns.k8s.io
spec:
  group: externaldns.k8s.io
  names:
    kind: DNSEndpoint
    plural: dnsendpoints
  scope: Namespaced
  subresources:
    status: {}
  validation:
    openAPIV3Schema:
      properties:
        apiVersion:
          type: string
        kind:
          type: string
        metadata:
          type: object
        spec:
          properties:
            endpoints:
              items:
                properties:
                  dnsName:
                    type: string
                  labels:
                    type: object
                  providerSpecific:
                    items:
                      properties:
                        name: 
                          type: string
                        value:
                          type: string
                      type: object
                    type: array
                  recordTTL:
                    format: int64
                    type: integer
                  recordType:
                    type: string
                  targets:
                    items:
                      type: string
                    type: array
                type: object
              type: array
          type: object
        status:
          properties:
            observedGeneration:
              format: int64
              type: integer
          type: object
  version: v1alpha1
{{- end }}
 # deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ template "external-dns.fullname" . }}
  labels: {{ include "external-dns.labels" . | nindent 4 }}
spec:
  replicas: {{ .Values.replicas }}
  selector:
    matchLabels: {{ include "external-dns.matchLabels" . | nindent 6 }}
  template:
    metadata:
      labels: {{ include "external-dns.labels" . | nindent 8 }}
      annotations:
        {{- if or .Values.podAnnotations .Values.metrics.enabled }}
        {{ include "external-dns.podAnnotations" . | nindent 8 }}
        {{- end }}
        {{- if (include "external-dns.createSecret" .) }}
        checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }}
        {{- end }}
        {{- if and (eq .Values.provider "designate") .Values.designate.customCA.enabled }}
        checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
        {{- end }}
    spec:
{{- include "external-dns.imagePullSecrets" . | indent 6 }}
      {{- if .Values.podSecurityContext }}
      securityContext: {{ toYaml .Values.podSecurityContext | nindent 8 }}
      {{- end }}
      {{- with .Values.affinity }}
      affinity: {{ tpl (toYaml .) $ | nindent 8 }}
      {{- end }}
      {{- with .Values.nodeSelector }}
      nodeSelector: {{ tpl (toYaml .) $ | nindent 8 }}
      {{- end }}
      {{- with .Values.tolerations }}
      tolerations: {{ tpl (toYaml .) $ | nindent 8 }}
      {{- end }}
      {{- if .Values.rbac.create }}
      serviceAccountName: {{ template "external-dns.fullname" . }}
      {{- else }}
      serviceAccountName: {{ .Values.rbac.serviceAccountName | quote }}
      {{- end }}
      {{- if .Values.priorityClassName }}
      priorityClassName: {{ .Values.priorityClassName | quote }}
      {{- end }}
      containers:
      - name: external-dns
        image: "{{ template "external-dns.image" . }}"
        imagePullPolicy: {{ .Values.image.pullPolicy | quote }}
        args:
        # Generic arguments
        {{- if .Values.logLevel }}
        - --log-level={{ .Values.logLevel }}
        {{- end }}
        {{- if .Values.logFormat }}
        - --log-format={{ .Values.logFormat }}
        {{- end }}
        {{- if .Values.dryRun }}
        - --dry-run
        {{- end }}
        {{- if .Values.triggerLoopOnEvent }}
        - --events
        {{- end }}
        {{- if .Values.namespace }}
        - --namespace={{ .Values.namespace }}
        {{- end }}
        {{- if .Values.fqdnTemplates }}
        - --fqdn-template={{ join "," .Values.fqdnTemplates }}{{/* Explicitly wants comma separated list */}}
        {{- end }}
        {{- if .Values.combineFQDNAnnotation }}
        - --combine-fqdn-annotation
        {{- end }}
        {{- if and .Values.ignoreHostnameAnnotation .Values.fqdnTemplates }}
        - --ignore-hostname-annotation
        {{- end }}
        {{- if .Values.publishInternalServices }}
        - --publish-internal-services
        {{- end }}
        {{- if .Values.publishHostIP }}
        - --publish-host-ip
        {{- end }}
        {{- range .Values.serviceTypeFilter }}
        - --service-type-filter={{ . }}
        {{- end }}
        {{- range .Values.domainFilters }}
        - --domain-filter={{ . }}
        {{- end }}
        {{- range .Values.zoneIdFilters }}
        - --zone-id-filter={{ . }}
        {{- end }}
        - --policy={{ .Values.policy }}
        - --provider={{ .Values.provider }}
        - --registry={{ .Values.registry }}
        - --interval={{ .Values.interval }}
        {{- if eq .Values.registry "txt" }}
        {{- if .Values.txtOwnerId }}
        - --txt-owner-id={{ .Values.txtOwnerId }}
        {{- end }}
        {{- if .Values.txtPrefix }}
        - --txt-prefix={{ .Values.txtPrefix }}
        {{- end }}
        {{- end }}
        {{- if .Values.annotationFilter }}
        - --annotation-filter={{ .Values.annotationFilter }}
        {{- end }}
        {{- if .Values.crd.apiversion }}
        - --crd-source-apiversion={{ .Values.crd.apiversion }}
        {{- end }}
        {{- if .Values.crd.kind }}
        - --crd-source-kind={{ .Values.crd.kind }}
        {{- end }}
        {{- range .Values.istioIngressGateways }}
        - --istio-ingress-gateway={{ . }}
        {{- end }}
        {{- range .Values.sources }}
        - --source={{ . }}
        {{- end }}
        # AWS arguments
        {{- if or (eq .Values.provider "aws") (eq .Values.provider "aws-sd") }}
        {{- if .Values.aws.zoneType }}
        - --aws-zone-type={{ .Values.aws.zoneType }}
        {{- end }}
        {{- if .Values.aws.assumeRoleArn }}
        - --aws-assume-role={{ .Values.aws.assumeRoleArn }}
        {{- end }}
        {{- if .Values.aws.batchChangeSize }}
        - --aws-batch-change-size={{ .Values.aws.batchChangeSize }}
        {{- end }}
        {{- end }}
        {{- range .Values.aws.zoneTags }}
        - --aws-zone-tags={{ . }}
        {{- end }}
        {{- if .Values.aws.preferCNAME }}
        - --aws-prefer-cname
        {{- end }}
        {{- if and (kindIs "bool" .Values.aws.evaluateTargetHealth) (not .Values.aws.evaluateTargetHealth) }}
        - --no-aws-evaluate-target-health
        {{- end }}
        # Azure Arguments
        {{- if or (eq .Values.provider "azure") (eq .Values.provider "azure-private-dns") }}
        {{- if .Values.azure.resourceGroup }}
        - --azure-resource-group={{ .Values.azure.resourceGroup }}
        {{- end }}
        {{- if .Values.azure.subscriptionId }}
        - --azure-subscription-id={{ .Values.azure.subscriptionId }}
        {{- end }}
        {{- end }}
        # Cloudflare arguments
        {{- if eq .Values.provider "cloudflare" }}
          {{- if .Values.cloudflare.proxied }}
        - --cloudflare-proxied
          {{- end }}
        {{- end }}
        # Google Arguments
        {{- if eq .Values.provider "google" }}
        - --google-project={{ .Values.google.project }}
        {{- end }}
        # Infloblox Arguments
        {{- if eq .Values.provider "infoblox" }}
        - --infoblox-grid-host={{ .Values.infoblox.gridHost }}
          {{- if .Values.infoblox.domainFilter }}
        - --domain-filter={{ .Values.infoblox.domainFilter }}
          {{- end }}
          {{- if .Values.infoblox.wapiPort }}
        - --infoblox-wapi-port={{ .Values.infoblox.wapiPort }}
          {{- end }}
          {{- if .Values.infoblox.wapiVersion }}
        - --infoblox-wapi-version={{ .Values.infoblox.wapiVersion }}
          {{- end }}
          {{- if .Values.infoblox.noSslVerify }}
        - --no-infoblox-ssl-verify
          {{- else }}
        - --infoblox-ssl-verify
          {{- end }}
        {{- end }}
        # RFC 2136 arguments
        {{- if eq .Values.provider "rfc2136" }}
        - --rfc2136-host={{ required "rfc2136.host must be supplied for provider 'rfc2136'" .Values.rfc2136.host }}
        - --rfc2136-port={{ .Values.rfc2136.port }}
        - --rfc2136-zone={{ required "rfc2136.zone must be supplied for provider 'rfc2136'" .Values.rfc2136.zone }}
          {{- if .Values.rfc2136.tsigKeyname }}
        - --rfc2136-tsig-secret-alg={{ .Values.rfc2136.tsigSecretAlg }}
        - --rfc2136-tsig-keyname={{ .Values.rfc2136.tsigKeyname }}
            {{- if .Values.rfc2136.tsigAxfr }}
        - --rfc2136-tsig-axfr
            {{- end }}
          {{- else }}
        - --rfc2136-insecure
          {{- end }}
        {{- end }}
        # PowerDNS arguments
        {{- if eq .Values.provider "pdns" }}
        - --pdns-server={{ .Values.pdns.apiUrl }}:{{ .Values.pdns.apiPort }}
        - --pdns-api-key=$(PDNS_API_KEY)
        {{- end }}
        # TransIP arguments
        {{- if eq .Values.provider "transip" }}
        - --transip-account={{ .Values.transip.account }}
        - --transip-keyfile=/transip/transip-api-key
        {{- end }}
        # Extra arguments
        {{- range $key, $value := .Values.extraArgs }}
          {{- if $value }}
        - --{{ $key }}={{ $value }}
          {{- else }}
        - --{{ $key }}
          {{- end }}
        {{- end }}
        env:
        # AWS environment variables
        {{- if or (eq .Values.provider "aws") (eq .Values.provider "aws-sd") }}
        {{- if .Values.aws.region }}
        - name: AWS_DEFAULT_REGION
          value: {{ .Values.aws.region }}
        {{- end }}
        {{- if .Values.aws.roleArn }}
        - name: AWS_CONFIG_FILE
          value: {{ .Values.aws.credentials.mountPath }}/config
        {{- end }}
        {{- if and .Values.aws.credentials.secretKey .Values.aws.credentials.accessKey }}
        - name: AWS_SHARED_CREDENTIALS_FILE
          value: {{ .Values.aws.credentials.mountPath }}/credentials
        {{- end }}
        {{- end }}
        # Azure Private DNS variables
        {{- if eq .Values.provider "azure-private-dns" }}
        {{- if .Values.azure.tenantId }}
        - name: AZURE_TENANT_ID
          value: {{ .Values.azure.tenantId }}
        {{- end }}
        {{- if .Values.azure.aadClientId }}
        - name: AZURE_CLIENT_ID
          value: {{ .Values.azure.aadClientId }}
        {{- end }}
        {{- if .Values.azure.aadClientSecret }}
        - name: AZURE_CLIENT_SECRET
          value: {{ .Values.azure.aadClientSecret }}
        {{- end }}
        {{- end }}
        # Cloudflare environment variables
        {{- if eq .Values.provider "cloudflare" }}
        {{- if or .Values.cloudflare.apiToken .Values.cloudflare.secretName }}
        - name: CF_API_TOKEN
          valueFrom:
            secretKeyRef:
              name: {{ template "external-dns.secretName" . }}
              key: cloudflare_api_token
        {{- else if or .Values.cloudflare.apiKey .Values.cloudflare.secretName }}
        - name: CF_API_KEY
          valueFrom:
            secretKeyRef:
              name: {{ template "external-dns.secretName" . }}
              key: cloudflare_api_key
        - name: CF_API_EMAIL
          value: {{ required "cloudflare.email is required if cloudflare.apiToken is not provided" .Values.cloudflare.email | quote }}
        {{- end }}
        {{- end }}
        # CoreDNS environment variables
        {{- if eq .Values.provider "coredns" }}
        - name: ETCD_URLS
          value: {{ .Values.coredns.etcdEndpoints | quote }}
        {{- if .Values.coredns.etcdTLS.enabled }}
        - name: ETCD_CERT_FILE
          value: {{ .Values.coredns.etcdTLS.mountPath }}/{{ .Values.coredns.etcdTLS.certFilename }}
        - name: ETCD_KEY_FILE
          value: {{ .Values.coredns.etcdTLS.mountPath }}/{{ .Values.coredns.etcdTLS.keyFilename }}
        - name: ETCD_CA_FILE
          value: {{ .Values.coredns.etcdTLS.mountPath }}/{{ .Values.coredns.etcdTLS.caFilename }}
        {{- end }}
        {{- end }}
        # Designate environment variables
        {{- if eq .Values.provider "designate" }}
        {{- if .Values.designate.customCA.enabled }}
        - name: OPENSTACK_CA_FILE
          value: {{ .Values.designate.customCA.mountPath }}/{{ .Values.designate.customCA.filename }}
        {{- else if .Values.designate.customCAHostPath }}
        - name: OPENSTACK_CA_FILE
          value: {{ .Values.designate.customCAHostPath }}
        {{- end }}
        {{- if .Values.designate.username}}
        - name: OS_USERNAME
          valueFrom:
            secretKeyRef:
              name: {{ template "external-dns.secretName" . }}
              key: designate_username
        {{- end }}
        {{- if .Values.designate.password}}
        - name: OS_PASSWORD
          valueFrom:
            secretKeyRef:
              name: {{ template "external-dns.secretName" . }}
              key: designate_password
        {{- end }}
        {{- if .Values.designate.authUrl }}
        - name: OS_AUTH_URL
          value: {{ .Values.designate.authUrl }}
        {{- end }}
        {{- if .Values.designate.regionName }}
        - name: OS_REGION_NAME
          value: {{ .Values.designate.regionName }}
        {{- end }}
        {{- if .Values.designate.userDomainName }}
        - name: OS_USER_DOMAIN_NAME
          value: {{ .Values.designate.userDomainName }}
        {{- end }}
        {{- if .Values.designate.projectName }}
        - name: OS_PROJECT_NAME
          value: {{ .Values.designate.projectName }}
        {{- end }}
        {{- end }}
        # DigitalOcean environment variables
        {{- if and (eq .Values.provider "digitalocean") (or .Values.digitalocean.apiToken .Values.digitalocean.secretName) }}
        - name: DO_TOKEN
          valueFrom:
            secretKeyRef:
              name: {{ template "external-dns.secretName" . }}
              key: digitalocean_api_token
        {{- end }}
        # Google environment variables
        {{- if eq .Values.provider "google" }}
        {{- if or .Values.google.serviceAccountSecret .Values.google.serviceAccountKey }}
        - name: GOOGLE_APPLICATION_CREDENTIALS
          value: /etc/secrets/service-account/credentials.json
        {{- end }}
        {{- end }}
        # Infloblox environment variables
        {{- if eq .Values.provider "infoblox" }}
        {{- if .Values.infoblox.wapiConnectionPoolSize }}
        - name: EXTERNAL_DNS_INFOBLOX_HTTP_POOL_CONNECTIONS
          value: "{{ .Values.infoblox.wapiConnectionPoolSize }}"
        {{- end }}
        {{- if .Values.infoblox.wapiHttpTimeout }}
        - name: EXTERNAL_DNS_INFOBLOX_HTTP_REQUEST_TIMEOUT
          value: "{{ .Values.infoblox.wapiHttpTimeout }}"
        {{- end }}
        {{- if and .Values.infoblox.wapiUsername .Values.infoblox.wapiPassword }}
        - name: EXTERNAL_DNS_INFOBLOX_WAPI_USERNAME
          valueFrom:
            secretKeyRef:
              name: {{ template "external-dns.secretName" . }}
              key: infoblox_wapi_username
        - name: EXTERNAL_DNS_INFOBLOX_WAPI_PASSWORD
          valueFrom:
            secretKeyRef:
              name: {{ template "external-dns.secretName" . }}
              key: infoblox_wapi_password
        {{- end }}
        {{- end }}
        # RFC 2136 environment variables
        {{- if and .Values.rfc2136.tsigSecret }}
        - name: EXTERNAL_DNS_RFC2136_TSIG_SECRET
          valueFrom:
            secretKeyRef:
              name: {{ template "external-dns.secretName" . }}
              key: rfc2136_tsig_secret
        {{- end }}
        # PowerDNS environment variables
        {{- if and (eq .Values.provider "pdns") .Values.pdns.apiKey }}
        - name: PDNS_API_KEY
          valueFrom:
            secretKeyRef:
              name: {{ template "external-dns.secretName" . }}
              key: pdns_api_key
        {{- end }}
        # Extra environment variables
        {{- if .Values.extraEnv }}
        {{ toYaml .Values.extraEnv | nindent 8 }}
        {{- end }}
        ports:
        - name: http
          containerPort: {{ .Values.service.port }}
        readinessProbe: {{ toYaml .Values.readinessProbe | nindent 10 }}
        livenessProbe: {{ toYaml .Values.livenessProbe | nindent 10 }}
        {{- if .Values.securityContext }}
        securityContext: {{ toYaml .Values.securityContext | nindent 10 }}
        {{- end }}
        {{- if .Values.resources }}
        resources: {{ toYaml .Values.resources | nindent 10 }}
        {{- end }}
        volumeMounts:
        # AWS mountPath(s)
        {{- if and (eq .Values.provider "aws") (or (and .Values.aws.credentials.secretKey .Values.aws.credentials.accessKey) .Values.aws.credentials.secretName) }}
        - name: aws-credentials
          mountPath: {{ .Values.aws.credentials.mountPath }}
          readOnly: true
        {{- end }}
        # Azure mountPath(s)
        {{- if eq .Values.provider "azure" }}
        - name: azure-config-file
          {{- if or .Values.azure.secretName (and .Values.azure.resourceGroup .Values.azure.tenantId .Values.azure.subscriptionId) }}
          mountPath: /etc/kubernetes/
          {{- else if not .Values.azure.useManagedIdentityExtension }}
          mountPath: /etc/kubernetes/azure.json
          {{- end }}
          readOnly: true
        {{- end }}
        # CoreDNS mountPath(s)
        {{- if and (eq .Values.provider "coredns") (.Values.coredns.etcdTLS.enabled) }}
        - name: {{ .Values.coredns.etcdTLS.secretName }}
          mountPath: {{ .Values.coredns.etcdTLS.mountPath }}
          readOnly: true
        {{- end }}
        # Google mountPath(s)
        {{- if and (eq .Values.provider "google") (or .Values.google.serviceAccountKey .Values.google.serviceAccountSecret) }}
        - name: google-service-account
          mountPath: /etc/secrets/service-account/
        {{- end }}
        # Designate mountPath(s)
        {{- if eq .Values.provider "designate" }}
        {{- if and (.Values.designate.customCAHostPath) (.Values.designate.customCA.enabled) }}
        {{- fail "designate.customCAHostPath cannot be specified with designate.customCA.enabled set to true"}}
        {{- else if .Values.designate.customCA.enabled }}
        - name: designate-custom-ca
          mountPath: {{ .Values.designate.customCA.mountPath }}
          readOnly: true
        {{- else if .Values.designate.customCAHostPath }}
        - name: designate-custom-ca-hostpath
          mountPath: {{ .Values.designate.customCAHostPath }}
          readOnly: true
        {{- end }}
        {{- end }}
        # TransIP mountPath(s)
        {{- if (eq .Values.provider "transip") }}
        - name: transip-api-key
          mountPath: /transip
          readOnly: true
        {{- end }}
        # Extra volume mount(s)
        {{- if .Values.extraVolumeMounts }}
{{ toYaml .Values.extraVolumeMounts | indent 8 }}
        {{- end }}
      volumes:
      # AWS volume(s)
      {{- if and (eq .Values.provider "aws") (or (and .Values.aws.credentials.secretKey .Values.aws.credentials.accessKey) .Values.aws.credentials.secretName) }}
      - name: aws-credentials
        secret:
          secretName: {{ template "external-dns.secretName" . }}
      {{- end }}
      # Azure volume(s)
      {{- if eq .Values.provider "azure" }}
      - name: azure-config-file
        {{- if or .Values.azure.secretName (and .Values.azure.resourceGroup .Values.azure.tenantId .Values.azure.subscriptionId) }}
        secret:
          secretName: {{ template "external-dns.secretName" . }}
        {{- else if not .Values.azure.useManagedIdentityExtension }}
        hostPath:
          path: /etc/kubernetes/azure.json
          type: File
        {{- end }}
      {{- end }}
      # CoreDNS volume(s)
      {{- if and (eq .Values.provider "coredns") (.Values.coredns.etcdTLS.enabled) }}
      - name: {{ .Values.coredns.etcdTLS.secretName }}
        secret:
          secretName: {{ .Values.coredns.etcdTLS.secretName }}
          defaultMode: 400
      {{- end }}
      # Google volume(s)
      {{- if and (eq .Values.provider "google") (or .Values.google.serviceAccountKey .Values.google.serviceAccountSecret) }}
      - name: google-service-account
        secret:
          secretName: {{ template "external-dns.secretName" . }}
          {{- if and .Values.google.serviceAccountSecret .Values.google.serviceAccountSecretKey }}
          items:
          - key: {{ .Values.google.serviceAccountSecretKey | quote }}
            path: credentials.json
          {{- end }}
      {{- end }}
      # Designate volume(s)
      {{- if eq .Values.provider "designate" }}
      {{- if .Values.designate.customCA.enabled }}
      - name: designate-custom-ca
        configMap:
          name: {{ template "external-dns.fullname" . }}
          items:
          - key: {{ .Values.designate.customCA.filename }}
            path: {{ .Values.designate.customCA.filename }}
      {{- else if .Values.designate.customCAHostPath }}
      - name: designate-custom-ca-hostpath
        hostPath:
          path: {{ .Values.designate.customCAHostPath }}
      {{- end }}
      {{- end }}
      # TransIP volume(s)
      {{- if (eq .Values.provider "transip") }}
      - name: transip-api-key
        secret:
          name: {{ template "external-dns.fullname" . }}
      {{- end }}
      # Extra volume(s)
      {{- if .Values.extraVolumes }}
{{ toYaml .Values.extraVolumes | indent 6 }}
      {{- end }}
 # psp-clusterrole.yaml
{{- if .Values.rbac.pspEnabled }}
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: {{ template "external-dns.fullname" . }}-psp
  labels: {{ include "external-dns.labels" . | nindent 4 }}
rules:
- apiGroups: ['extensions']
  resources: ['podsecuritypolicies']
  verbs:     ['use']
  resourceNames:
  - {{ template "external-dns.fullname" . }}
{{- end }}
 # psp-clusterrolebinding.yaml
{{- if .Values.rbac.pspEnabled }}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: {{ template "external-dns.fullname" . }}-psp
  labels: {{ include "external-dns.labels" . | nindent 4 }}
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: {{ template "external-dns.fullname" . }}-psp
subjects:
  - kind: ServiceAccount
    name: {{ template "external-dns.fullname" . }}
    namespace: {{ .Release.Namespace }}
{{- end }}
 # psp.yaml
{{- if .Values.rbac.pspEnabled }}
apiVersion: {{ template "podSecurityPolicy.apiVersion" . }}
kind: PodSecurityPolicy
metadata:
  name: {{ template "external-dns.fullname" . }}
  labels: {{ include "external-dns.labels" . | nindent 4 }}
spec:
  privileged: false
  allowPrivilegeEscalation: false
  requiredDropCapabilities:
  - ALL
  volumes:
  - 'configMap'
  - 'emptyDir'
  - 'projected'
  - 'secret'
  - 'downwardAPI'
  - 'hostPath'
  hostNetwork: false
  hostIPC: false
  hostPID: false
  runAsUser:
    rule: 'MustRunAs'
    ranges:
    - min: 1001
      max: 1001
  seLinux:
    rule: 'RunAsAny'
  supplementalGroups:
    rule: 'MustRunAs'
    ranges:
    - min: 1001
      max: 1001
  fsGroup:
    rule: 'MustRunAs'
    ranges:
    - min: 1001
      max: 1001
{{- end }}
 # secret.yaml
{{- if (include "external-dns.createSecret" .) }}
apiVersion: v1
kind: Secret
metadata:
  name: {{ template "external-dns.fullname" . }}
  labels: {{ include "external-dns.labels" . | nindent 4 }}
type: Opaque
data:
  {{- if eq .Values.provider "aws" }}
  credentials: {{ include "external-dns.aws-credentials" . | b64enc | quote }}
  {{- if .Values.aws.region }}
  config: {{ include "external-dns.aws-config" . | b64enc | quote }}
  {{- end }}
  {{- end }}
  {{- if eq .Values.provider "azure" }}
  azure.json: {{ include "external-dns.azure-credentials" . | b64enc | quote }}
  {{- end }}
  {{- if eq .Values.provider "google" }}
  credentials.json: {{ .Values.google.serviceAccountKey | b64enc | quote }}
  {{- end }}
  {{- if eq .Values.provider "cloudflare" }}
  {{- if .Values.cloudflare.apiToken }}
  cloudflare_api_token: {{ .Values.cloudflare.apiToken | b64enc | quote }}
  {{- else }}
  cloudflare_api_key: {{ required "cloudflare.apiKey is required if cloudflare.apiToken is not provided" .Values.cloudflare.apiKey | b64enc | quote }}
  {{- end }}
  {{- end }}
  {{- if eq .Values.provider "designate" }}
  {{- if .Values.designate.username }}
  designate_username: {{ .Values.designate.username | b64enc | quote }}
  {{- end }}
  {{- if .Values.designate.password }}
  designate_password: {{ .Values.designate.password | b64enc | quote }}
  {{- end }}
  {{- end }}
  {{- if eq .Values.provider "digitalocean" }}
  digitalocean_api_token: {{ .Values.digitalocean.apiToken | b64enc | quote }}
  {{- end }}
  {{- if eq .Values.provider "infoblox" }}
  infoblox_wapi_username: {{ .Values.infoblox.wapiUsername | b64enc | quote }}
  infoblox_wapi_password: {{ .Values.infoblox.wapiPassword | b64enc | quote }}
  {{- end }}
  {{- if eq .Values.provider "pdns" }}
  pdns_api_key: {{ .Values.pdns.apiKey | b64enc | quote }}
  {{- end }}
  {{- if eq .Values.provider "rfc2136" }}
  rfc2136_tsig_secret: {{ .Values.rfc2136.tsigSecret | b64enc | quote }}
  {{- end }}
  {{- if eq .Values.provider "transip" }}
  transip-api-key: {{ .Values.transip.apiKey | b64enc | quote }}
  {{- end }}
{{- end }}
 # service.yaml
apiVersion: v1
kind: Service
metadata:
  name: {{ template "external-dns.fullname" . }}
  labels: {{ include "external-dns.labels" . | nindent 4 }}
  {{- if .Values.service.annotations }}
  annotations: {{ toYaml .Values.service.annotations | nindent 4 }}
  {{- end }}
spec:
  {{- if .Values.service.clusterIP }}
  clusterIP: {{ .Values.service.clusterIP }}
  {{- end }}
  {{- if .Values.service.externalIPs }}
  externalIPs: {{ toYaml .Values.service.externalIPs | nindent 4 }}
  {{- end }}
  {{- if .Values.service.loadBalancerIP }}
  loadBalancerIP: {{ .Values.service.loadBalancerIP }}
  {{- end }}
  {{- if .Values.service.loadBalancerSourceRanges }}
  loadBalancerSourceRanges: {{ toYaml .Values.service.loadBalancerSourceRanges | nindent 4 }}
  {{- end }}
  ports:
  - name: http
    port: {{ .Values.service.port }}
    protocol: TCP
    targetPort: http
    {{- if and (eq .Values.service.type "NodePort") (not (empty .Values.service.nodePort)) }}
    nodePort: {{ .Values.service.nodePort  }}
    {{- end }}
  selector: {{ include "external-dns.matchLabels" . | nindent 6 }}
  type: {{ .Values.service.type }}
 # serviceaccount.yaml
{{- if .Values.rbac.create }}
apiVersion: v1
kind: ServiceAccount
metadata:
  name: {{ template "external-dns.fullname" . }}
  labels: {{ include "external-dns.labels" . | nindent 4 }}
  {{- if .Values.rbac.serviceAccountAnnotations }}
  annotations: {{ toYaml .Values.rbac.serviceAccountAnnotations | nindent 4 }}
  {{- end }}
{{- end }}
 # servicemonitor.yaml
{{- if and .Values.metrics.enabled .Values.metrics.serviceMonitor.enabled }}
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: {{ template "external-dns.fullname" . }}
  {{- with .Values.metrics.serviceMonitor.namespace }}
  namespace: {{ . }}
  {{- end }}
  labels: {{ include "external-dns.labels" . | nindent 4 }}
    {{- with .Values.metrics.serviceMonitor.selector }}
    {{ toYaml . | nindent 4 }}
    {{- end }}
spec:
  endpoints:
    - port: http
      path: /metrics
      {{- with .Values.metrics.serviceMonitor.interval }}
      interval: {{ . }}
      {{- end }}
      {{- with .Values.metrics.serviceMonitor.scrapeTimeout }}
      scrapeTimeout: {{ . }}
      {{- end }}
  namespaceSelector:
    matchNames:
      - {{ .Release.Namespace }}
  selector:
    matchLabels: {{ include "external-dns.matchLabels" . | nindent 6 }}
{{- end }}

## Global Docker image parameters
## Please, note that this will override the image parameters, including dependencies, configured to use the global value
## Current available global Docker image parameters: imageRegistry and imagePullSecrets
##
# global:
#   imageRegistry: myRegistryName
#   imagePullSecrets:
#     - myRegistryKeySecretName

## Bitnami external-dns image version
## ref: https://hub.docker.com/r/bitnami/external-dns/tags/
##
image:
  registry: docker.io
  repository: bitnami/external-dns
  tag: 0.7.0-debian-10-r0
  ## Specify a imagePullPolicy
  ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent'
  ## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images
  ##
  pullPolicy: IfNotPresent
  ## Optionally specify an array of imagePullSecrets.
  ## Secrets must be manually created in the namespace.
  ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
  ##
  # pullSecrets:
  #   - myRegistryKeySecretName

## String to partially override external-dns.fullname template (will maintain the release name)
# nameOverride:

## String to fully override external-dns.fullname template
# fullnameOverride:

## K8s resources type to be observed for new DNS entries by ExternalDNS
##
sources:
- service
- ingress
# - crd

## DNS provider where the DNS records will be created. Available providers are:
## - aws, azure, azure-private-dns, cloudflare, coredns, designate, digitalocean, google, infoblox, rfc2136, transip
##
provider: aws

## Flags related to processing sources
## ref: https://github.com/kubernetes-sigs/external-dns/blob/master/pkg/apis/externaldns/types.go#L272
##
## Limit sources of endpoints to a specific namespace (default: all namespaces)
##
namespace: ""
## Templated strings that are used to generate DNS names from sources that don't define a hostname themselves
##
fqdnTemplates: []
## Combine FQDN template and annotations instead of overwriting
##
combineFQDNAnnotation: false
## Ignore hostname annotation when generating DNS names, valid only when fqdn-template is set
##
ignoreHostnameAnnotation: false
## Allow external-dns to publish DNS records for ClusterIP services
##
publishInternalServices: false
## Allow external-dns to publish host-ip for headless services
##
publishHostIP: false
## The service types to take care about (default: all, options: ClusterIP, NodePort, LoadBalancer, ExternalName)
##
serviceTypeFilter: []

## AWS configuration to be set via arguments/env. variables
##
aws:
  ## AWS credentials
  ##
  credentials:
    secretKey: ""
    accessKey: ""
    ## pre external-dns 0.5.9 home dir should be `/root/.aws`
    ##
    mountPath: "/.aws"
    ## Use an existing secret with key "credentials" defined.
    ## This ignores aws.credentials.secretKey, and aws.credentials.accessKey
    ##
    # secretName:

  ## AWS region
  ##
  region: "us-east-1"
  ## Zone Filter. Available values are: public, private
  ##
  zoneType: ""
  ## AWS Role to assume
  ##
  assumeRoleArn: ""
  ## Maximum number of changes that will be applied in each batch
  ##
  batchChangeSize: 1000
  ## AWS Zone tags
  ##
  zoneTags: []
  ## Enable AWS Prefer CNAME. Available values are: true, false
  ##
  preferCNAME: ""
  ## Enable AWS evaluation of target health. Available values are: true, false
  ##
  evaluateTargetHealth: ""
## Azure configuration to be set via arguments/env. variables
##
azure:
  ## When a secret to load azure.json is not specified,
  ## the host's /etc/kubernetes/azure.json will be used
  ##
  ## Deprecated: please use tenantId, subscriptionId, aadClientId and aadClientSecret values instead.
  ##
  secretName: ""
  ## Azure resource group to use
  ##
  cloud: ""
  ## Azure Cloud to use
  ##
  resourceGroup: ""
  ## Azure tenant ID to use
  ##
  tenantId: ""
  ## Azure subscription ID to use
  ##
  subscriptionId: ""
  ## Azure Application Client ID to use
  ##
  aadClientId: ""
  ## Azure Application Client Secret to use
  ##
  aadClientSecret: ""
  ## If you use Azure MSI, this should be set to true
  ##
  useManagedIdentityExtension: false

## Cloudflare configuration to be set via arguments/env. variables
##
cloudflare:
  ## `CF_API_TOKEN` to set in the environment
  ##
  apiToken: ""
  ## `CF_API_KEY` to set in the environment
  ##
  apiKey: ""
  ## Use an existing secret with keys "cloudflare_api_token" or "cloudflare_api_key" defined.
  ## This ignores cloudflare.apiToken, and cloudflare.apiKey
  ##
  # secretName:
  ## `CF_API_EMAIL` to set in the environment
  ##
  email: ""
  ## Enable the proxy feature of Cloudflare
  ##
  proxied: true

## CoreDNS configuration to be set via arguments/env variables
##
coredns:
  ## Comma-separated list of the etcd endpoints
  ## Secure (https) endpoints can be used as well, in that case `etcdTLS` section
  ## should be filled in accordingly
  ##
  etcdEndpoints: "http://etcd-extdns:2379"
  ## Configuration of the secure communication and client authentication to the etcd cluster
  ## If enabled all the values under this key must hold a valid data
  ##
  etcdTLS:
    ## Enable or disable secure communication and client authentication to the etcd cluster
    ##
    enabled: false
    ## Name of the existing secret containing cert files for client communication
    ## ref: https://github.com/etcd-io/etcd/blob/master/Documentation/op-guide/security.md
    ## ref (secret creation):
    ##  https://github.com/bitnami/charts/tree/master/bitnami/etcd#configure-certificates-for-client-communication
    ##
    secretName: "etcd-client-certs"
    ## Location of the mounted certificates inside external-dns pod
    ##
    mountPath: "/etc/coredns/tls/etcd"
    ## CA PEM file used to sign etcd TLS cert, should exist in the secret provided above
    ##
    caFilename: "ca.crt"
    ## Certificate PEM file, should exist in the secret provided above
    ## Will be used by external-dns to authenticate against etcd
    ##
    certFilename: "cert.pem"
    ## Private key PEM file, should exist in the secret provided above
    ## Will be used by external-dns to authenticate against etcd
    ##
    keyFilename: "key.pem"

## OpenStack Designate provider configuration to be set via arguments/env. variables
##
designate:
  ## Use a custom CA (optional)
  ##
  customCA:
    enabled: false
    ## The content of the custom CA file
    ##
    content: ""
    ## Location to mount custom CA
    ##
    mountPath: "/config/designate"
    ## Custom CA filename
    ##
    filename: "designate-ca.pem"

  ## Use a host path custom CA (optional)
  ##  This conflicts setting the above customCA to true and chart rendering will fail if you set customCA to true and specify customCAHostPath
  # customCAHostPath: /path/to/cafile

  ## Set Openstack environment variables (optional).  Username and password will be saved in a kubernetes secret.
  ## The alternative to this is to export the necessary Openstack environment variables in the extraEnv argument.
  # username: "someuser"
  # password: "p@55w0rd"
  # authUrl: "https://mykeystone.example.net:5000/v3/"
  # regionName: "dev"
  # userDomainName: "development"
  # projectName: "myteamname"
## DigitalOcean configuration to be set via arguments/env. variables
##
digitalocean:
  ## `DO_TOKEN` to set in the environment
  ##
  apiToken: ""
  ## Use an existing secret with key "digitalocean_api_token" defined.
  ## This ignores digitalocean.apiToken
  ##
  # secretName:

## Google configuration to be set via arguments/env. variables
##
google:
  ## Google Project to use
  ##
  project: ""
  ## Google Application Credentials
  ##
  serviceAccountSecret: ""
  serviceAccountSecretKey: "credentials.json"
  serviceAccountKey: ""

## Infoblox configuration to be set via arguments/env. variables
##
infoblox:
  ## Required keys
  ##
  wapiUsername: "admin"
  wapiPassword: ""
  gridHost: ""
  ## Optional keys
  ##
  domainFilter: ""
  noSslVerify: false
  wapiPort: ""
  wapiVersion: ""
  wapiConnectionPoolSize: ""
  wapiHttpTimeout: ""

## RFC 2136 configuration to be set via arguments/env. variables
##
rfc2136:
  host: ""
  port: 53
  zone: ""
  tsigSecret: ""
  tsigSecretAlg: hmac-sha256
  tsigKeyname: externaldns-key
  tsigAxfr: true

## PowerDNS configuration to be set via arguments/env. variables
##
pdns:
  apiUrl: ""
  apiPort: "8081"
  apiKey: ""

## TransIP configuration to be set via arguments/env. variables
##
transip:
  ## Account name to be used
  ##
  account: ""
  ##
  ## API key that is authorised for the account
  apiKey: ""

## Limit possible target zones by domain suffixes (optional)
##
domainFilters: []
## Limit possible target zones by zone id (optional)
##
zoneIdFilters: []
## Filter sources managed by external-dns via annotation using label selector semantics (optional)
##
annotationFilter: ""
## When enabled, prints DNS record changes rather than actually performing them
##
dryRun: false
## When enabled, triggers run loop on create/update/delete events (optional, in addition of regular interval)
##
triggerLoopOnEvent: false
## Adjust the interval for DNS updates
##
interval: "1m"
## Verbosity of the ExternalDNS logs. Available values are:
## - panic, debug, info, warn, error, fatal
##
logLevel: info
## Formats of the ExternalDNS logs. Available values are:
## - text, json
##
logFormat: text
## Modify how DNS records are sychronized between sources and providers (options: sync, upsert-only)
##
policy: upsert-only
## Registry Type. Available types are: txt, noop
## ref: https://github.com/kubernetes-sigs/external-dns/blob/master/docs/proposal/registry.md
##
registry: "txt"
## TXT Registry Identifier
##
txtOwnerId: ""
## Prefix to create a TXT record with a name following the pattern prefix.<CNAME record>
##
# txtPrefix: ""
## Load balancer service to be used; ie: custom-istio-namespace/custom-istio-ingressgateway.
## Omit to use the default (istio-system/istio-ingressgateway)
##
istioIngressGateways: []

## Extra Arguments to passed to external-dns
##
extraArgs: {}
## Extra env. variable to set on external-dns container.
##
## extraEnv:
## - name: VARNAME1
##   value: value1
## - name: VARNAME2
##   valueFrom:
##     secretKeyRef:
##       name: existing-secret
##       key: varname2-key
extraEnv: []

## Replica count
##
replicas: 1

## Affinity for pod assignment (this value is evaluated as a template)
## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity
##
affinity: {}
## Node labels for pod assignment (this value is evaluated as a template)
## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector
##
nodeSelector: {}
## Tolerations for pod assignment (this value is evaluated as a template)
## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#taints-and-tolerations-beta-feature
##
tolerations: []
## Annotations for external-dns pods
##
podAnnotations: {}
## Additional labels for the pod(s).
##
podLabels: {}
## Pod priority class name
##
priorityClassName: ""

## Options for the source type "crd"
##
crd:
  ## Install and use the integrated DNSEndpoint CRD
  create: false
  ## Change these to use an external DNSEndpoint CRD (E.g. from kubefed)
  apiversion: ""
  kind: ""

## Kubernetes svc configutarion
##
service:
  ## Kubernetes svc type
  ##
  type: ClusterIP
  port: 7979
  ## Specify the nodePort value for the LoadBalancer and NodePort service types for the client port
  ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport
  ##
  # nodePort:
  ## Static clusterIP or None for headless services
  ##
  # clusterIP: ""
  ## External IP list to use with ClusterIP service type
  ##
  externalIPs: []
  ## Use loadBalancerIP to request a specific static IP,
  ## otherwise leave blank
  ##
  # loadBalancerIP:
  ## Address that are allowed when svc is LoadBalancer
  ##
  loadBalancerSourceRanges: []
  ## Provide any additional annotations which may be required. This can be used to
  ## set the LoadBalancer service type to internal only.
  ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer
  ##
  annotations: {}

## RBAC parameteres
## https://kubernetes.io/docs/reference/access-authn-authz/rbac/
##
rbac:
  create: true
  ## Service Account for pods
  ## https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/
  ##
  serviceAccountName: default
  ## Annotations for the Service Account
  ##
  serviceAccountAnnotations: {}
  ## RBAC API version
  ##
  apiVersion: v1beta1
  ## Podsecuritypolicy
  ##
  pspEnabled: false

## Kubernetes Security Context
## https://kubernetes.io/docs/tasks/configure-pod-container/security-context/
##
securityContext: {}
  # allowPrivilegeEscalation: false
  # readOnlyRootFilesystem: true
  # capabilities:
  #   drop: ["ALL"]
podSecurityContext:
  fsGroup: 1001
  runAsUser: 1001
  # runAsNonRoot: true

## Configure resource requests and limits
## ref: http://kubernetes.io/docs/user-guide/compute-resources/
##
resources: {}
#  limits:
#    cpu: 50m
#    memory: 50Mi
#  requests:
#    memory: 50Mi
#    cpu: 10m

## Liveness Probe. The block is directly forwarded into the deployment, so you can use whatever livenessProbe configuration you want.
## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/
##
livenessProbe:
  httpGet:
    path: /healthz
    port: http
  initialDelaySeconds: 10
  periodSeconds: 10
  timeoutSeconds: 5
  failureThreshold: 2
  successThreshold: 1
## Readiness Probe. The block is directly forwarded into the deployment, so you can use whatever readinessProbe configuration you want.
## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/
##
readinessProbe:
  httpGet:
    path: /healthz
    port: http
  initialDelaySeconds: 5
  periodSeconds: 10
  timeoutSeconds: 5
  failureThreshold: 6
  successThreshold: 1

## Configure extra volumes
extraVolumes: []

## Configure extra volumeMounts
extraVolumeMounts: []

## Prometheus Exporter / Metrics
##
metrics:
  enabled: false
  ## Metrics exporter pod Annotation and Labels
  ##
  # podAnnotations:
  #   prometheus.io/scrape: "true"
  #   prometheus.io/port: "7979"

  ## Prometheus Operator ServiceMonitor configuration
  ##
  serviceMonitor:
    enabled: false
    ## Namespace in which Prometheus is running
    ##
    # namespace: monitoring

    ## Interval at which metrics should be scraped.
    ## ref: https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#endpoint
    ##
    # interval: 10s

    ## Timeout after which the scrape is ended
    ## ref: https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#endpoint
    ##
    # scrapeTimeout: 10s

    ## ServiceMonitor selector labels
    ## ref: https://github.com/bitnami/charts/tree/master/bitnami/prometheus-operator#prometheus-configuration
    ##
    # selector:
    #   prometheus: my-prometheus
