[powerdns] Introduce Powerdns chart (#308)

* initial commit for powerdns

Signed-off-by: Ryan Holt <ryan@ryanholt.net>

* add auto-create zone, bump chart version

Signed-off-by: Ryan Holt <ryan@ryanholt.net>

* add selector for db type

Signed-off-by: Ryan Holt <ryan@ryanholt.net>

* fix indent

Signed-off-by: Ryan Holt <ryan@ryanholt.net>

* fix path mount for conf.d

Signed-off-by: Ryan Holt <ryan@ryanholt.net>

* fix indent

Signed-off-by: Ryan Holt <ryan@ryanholt.net>

* add liveness & readiness probes. Bump chart

Signed-off-by: Ryan Holt <ryan@ryanholt.net>

* add more sleep

Signed-off-by: Ryan Holt <ryan@ryanholt.net>

* add startupProbe

Signed-off-by: Ryan Holt <ryan@ryanholt.net>

* replace homepage with home

Signed-off-by: Ryan Holt <ryan@ryanholt.net>

* remove trailing space

Signed-off-by: Ryan Holt <ryan@ryanholt.net>

* fix maintainer to be github username

Signed-off-by: Ryan Holt <ryan@ryanholt.net>

* add newline to end of file for linting

Signed-off-by: Ryan Holt <ryan@ryanholt.net>

* opinionate the chart -- generate an api_key

Signed-off-by: Ryan Holt <ryan@ryanholt.net>

* disable dependent charts by default

Signed-off-by: Ryan Holt <ryan@ryanholt.net>

* add default values for dependent charts (disabled)

Signed-off-by: Ryan Holt <ryan@ryanholt.net>

* add newline (lint)

Signed-off-by: Ryan Holt <ryan@ryanholt.net>

* add check for lifecycle

Signed-off-by: Ryan Holt <ryan@ryanholt.net>

* add default values for automated tests

Signed-off-by: Ryan Holt <ryan@ryanholt.net>

* update default mysql/postgres host to match dependent chart

Signed-off-by: Ryan Holt <ryan@ryanholt.net>

* update pdnspass to be the same for mysql and pdns chart

Signed-off-by: Ryan Holt <ryan@ryanholt.net>

* fixed a broken conditional

Signed-off-by: Ryan Holt <ryan@ryanholt.net>

* disable persistence on mariadb by default

Signed-off-by: Ryan Holt <ryan@ryanholt.net>

* found the missing toggle

Signed-off-by: Ryan Holt <ryan@ryanholt.net>

* mysql=mariadb

Signed-off-by: Ryan Holt <ryan@ryanholt.net>

* try using a templated mysql host name

Signed-off-by: Ryan Holt <ryan@ryanholt.net>

* fix linting problem

Signed-off-by: Ryan Holt <ryan@ryanholt.net>

* maybe this will work?

Signed-off-by: Ryan Holt <ryan@ryanholt.net>

* another attempt

Signed-off-by: Ryan Holt <ryan@ryanholt.net>

* how about this?

Signed-off-by: Ryan Holt <ryan@ryanholt.net>

* trying this

Signed-off-by: Ryan Holt <ryan@ryanholt.net>

* try this one out

Signed-off-by: Ryan Holt <ryan@ryanholt.net>

* this might work

Signed-off-by: Ryan Holt <ryan@ryanholt.net>

* remove special characters from domain name, attempt to fix configmap

Signed-off-by: Ryan Holt <ryan@ryanholt.net>

* try it with quotes

Signed-off-by: Ryan Holt <ryan@ryanholt.net>

* add 'quote'

Signed-off-by: Ryan Holt <ryan@ryanholt.net>

* needs to be = not :

Signed-off-by: Ryan Holt <ryan@ryanholt.net>

* remove the quote option

Signed-off-by: Ryan Holt <ryan@ryanholt.net>

* remove bbenc64

Signed-off-by: Ryan Holt <ryan@ryanholt.net>

* add probes and optional exclude

Signed-off-by: Ryan Holt <ryan@ryanholt.net>

* flip to ClusterIP as default

Signed-off-by: Ryan Holt <ryan@ryanholt.net>

* remove ci exclusions, bump chart to v1

Signed-off-by: Ryan Holt <ryan@ryanholt.net>

Co-authored-by: Jeff Billimek <jeff@billimek.com>
This commit is contained in:
Ryan Holt 2020-08-07 11:53:50 -04:00 committed by GitHub
parent db26e398d2
commit ddd4788598
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 517 additions and 0 deletions

22
charts/powerdns/.helmignore Executable file
View File

@ -0,0 +1,22 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/

21
charts/powerdns/Chart.yaml Executable file
View File

@ -0,0 +1,21 @@
apiVersion: v2
appVersion: "latest"
description: PowerDNS is a DNS server, written in C++ and licensed under the GPL. It runs on most Unix derivatives. PowerDNS features a large number of different backends ranging from simple BIND style zonefiles to relational databases and load balancing/failover algorithms. A DNS recursor is provided as a separate program.
name: powerdns
version: 1.0.0
home: https://www.powerdns.com/
sources:
- http://www.github.com/PowerDNS/
icon: https://www.powerdns.com/img/pDNS_logo_positive_claim_down_screen_xsmall.png
maintainers:
- name: carpenike
email: ryan@ryanholt.net
dependencies:
- name: postgresql
version: 9.1.2
repository: https://charts.bitnami.com/bitnami
condition: postgres.enabled
- name: mariadb
version: 7.7.1
repository: https://charts.bitnami.com/bitnami
condition: mariadb.enabled

View File

@ -0,0 +1,15 @@
1. Get the application URL by running these commands:
{{- if contains "NodePort" .Values.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "powerdns.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.service.type }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "powerdns.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "powerdns.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
echo http://$SERVICE_IP:{{ .Values.service.port }}
{{- else if contains "ClusterIP" .Values.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "powerdns.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl port-forward $POD_NAME 8080:80
{{- end }}

View File

@ -0,0 +1,56 @@
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "powerdns.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 "powerdns.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 "powerdns.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Common labels
*/}}
{{- define "powerdns.labels" -}}
app.kubernetes.io/name: {{ include "powerdns.name" . }}
helm.sh/chart: {{ include "powerdns.chart" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end -}}
{{/*
Create the name of the service account to use
*/}}
{{- define "powerdns.serviceAccountName" -}}
{{- if .Values.serviceAccount.create -}}
{{ default (include "powerdns.fullname" .) .Values.serviceAccount.name }}
{{- else -}}
{{ default "default" .Values.serviceAccount.name }}
{{- end -}}
{{- end -}}

View File

@ -0,0 +1,30 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "powerdns.fullname" . }}
labels:
app.kubernetes.io/name: {{ include "powerdns.name" . }}
helm.sh/chart: {{ include "powerdns.chart" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
data:
01-general-config.conf: |
{{ range $key, $value := .Values.powerdns.config -}}
{{ $key }}={{ $value }}
{{ end }}
00-api-key.conf: |
api=yes
{{ if .Values.powerdns.api_key }}
api-key={{ .Values.powerdns.api_key }}
{{ else }}
api-key={{ randAlphaNum 24 }}
{{ end }}
webserver=yes
# IP Address of web server to listen on
webserver-address=0.0.0.0
# Port of web server to listen on
webserver-port=8081
# Web server access is only allowed from these subnets
webserver-allow-from=0.0.0.0/0,::/0

View File

@ -0,0 +1,154 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "powerdns.fullname" . }}
labels:
{{ include "powerdns.labels" . | indent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app.kubernetes.io/name: {{ include "powerdns.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
template:
metadata:
labels:
app.kubernetes.io/name: {{ include "powerdns.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ template "powerdns.serviceAccountName" . }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: {{ .Chart.Name }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.image.repository }}:{{ tpl .Values.image.tag . }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
volumeMounts:
- name: config
mountPath: /etc/pdns/conf.d
env:
{{- if .Values.postgres.enabled }}
- name: PGSQL_HOST
valueFrom:
secretKeyRef:
name: {{ include "powerdns.fullname" . }}
key: postgres_host
- name: PGSQL_PORT
valueFrom:
secretKeyRef:
name: {{ include "powerdns.fullname" . }}
key: postgres_port
- name: PGSQL_USERNAME
valueFrom:
secretKeyRef:
name: {{ include "powerdns.fullname" . }}
key: postgres_username
- name: PGSQL_PASSWORD
valueFrom:
secretKeyRef:
name: {{ include "powerdns.fullname" . }}
key: postgres_password
- name: PGSQL_DATABASE
valueFrom:
secretKeyRef:
name: {{ include "powerdns.fullname" . }}
key: postgres_database
- name: PGSQL_DNSSEC
value: {{if (.Values.powerdns.dnssec)}}"yes"{{else}}"no"{{ end }}
{{ end }}
{{- if .Values.mariadb.enabled }}
- name: MYSQL_HOST
valueFrom:
secretKeyRef:
name: {{ include "powerdns.fullname" . }}
key: mysql_host
- name: MYSQL_USER
valueFrom:
secretKeyRef:
name: {{ include "powerdns.fullname" . }}
key: mysql_username
- name: MYSQL_PASS
valueFrom:
secretKeyRef:
name: {{ include "powerdns.fullname" . }}
key: mysql_password
- name: MYSQL_DB
valueFrom:
secretKeyRef:
name: {{ include "powerdns.fullname" . }}
key: mysql_database
- name: MYSQL_DNSSEC
value: {{if (.Values.powerdns.dnssec)}}"yes"{{else}}"no"{{ end }}
{{ end }}
ports:
- name: dns-tcp
containerPort: 53
protocol: TCP
- name: dns-udp
containerPort: 53
protocol: UDP
- name: dns-webserver
containerPort: 8081
protocol: TCP
{{- if .Values.probes.liveness.enabled }}
livenessProbe:
httpGet:
path: /
port: dns-webserver
initialDelaySeconds: {{ .Values.probes.liveness.initialDelaySeconds }}
failureThreshold: {{ .Values.probes.liveness.failureThreshold }}
timeoutSeconds: {{ .Values.probes.liveness.timeoutSeconds }}
{{ end }}
{{- if .Values.probes.readiness.enabled }}
readinessProbe:
httpGet:
path: /
port: dns-webserver
initialDelaySeconds: {{ .Values.probes.readiness.initialDelaySeconds }}
failureThreshold: {{ .Values.probes.readiness.failureThreshold }}
timeoutSeconds: {{ .Values.probes.readiness.timeoutSeconds }}
{{ end }}
{{- if .Values.probes.startup.enabled }}
startupProbe:
httpGet:
path: /
port: dns-webserver
failureThreshold: {{ .Values.probes.startup.failureThreshold }}
periodSeconds: {{ .Values.probes.startup.periodSeconds }}
{{ end }}
{{- if .Values.mariadb.enabled }}
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "a=0;while [ $a -lt 200 ];do sleep 5;a=$[a+1];echo 'stage: '$a;if nc -vz {{ .Values.powerdns.mysql.host }} 3306;then (! pdnsutil list-zone {{ .Values.powerdns.domain }} 2>/dev/null) && pdnsutil create-zone {{ .Values.powerdns.domain }};echo 'End Stage';a=200;fi;done"]
{{ end }}
{{- if .Values.postgres.enabled }}
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "a=0;while [ $a -lt 200 ];do sleep 5;a=$[a+1];echo 'stage: '$a;if nc -vz {{ .Values.powerdns.postgres.host }} 5432;then (! pdnsutil list-zone {{ .Values.powerdns.domain }} 2>/dev/null) && pdnsutil create-zone {{ .Values.powerdns.domain }};echo 'End Stage';a=200;fi;done"]
{{ end }}
resources:
{{- toYaml .Values.resources | nindent 12 }}
volumes:
- name: config
configMap:
name: {{ template "powerdns.fullname" . }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}

View File

@ -0,0 +1,22 @@
apiVersion: v1
kind: Secret
metadata:
name: {{ include "powerdns.fullname" . }}
labels:
{{ include "powerdns.labels" . | indent 4 }}
type: Opaque
data:
{{- if .Values.postgres.enabled }}
postgres_host: "{{ printf (include "powerdns.fullname" "-postgres" ) | b64enc }}"
postgres_port: "{{ .Values.powerdns.postgres.port | toString | b64enc }}"
postgres_username: "{{ .Values.powerdns.postgres.username | b64enc }}"
postgres_password: "{{ .Values.powerdns.postgres.password | toString | b64enc }}"
postgres_database: "{{ .Values.powerdns.postgres.database | b64enc }}"
{{ end }}
{{- if .Values.mariadb.enabled }}
{{- $mysqltmp := printf "%s-%s" .Release.Name "mariadb"}}
mysql_host: "{{ $mysqltmp | b64enc }}"
mysql_username: "{{ .Values.powerdns.mysql.username | b64enc }}"
mysql_password: "{{ .Values.powerdns.mysql.password | toString | b64enc }}"
mysql_database: "{{ .Values.powerdns.mysql.database | b64enc }}"
{{ end }}

View File

@ -0,0 +1,81 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "powerdns.fullname" . }}-udp
{{- if .Values.service.annotations }}
annotations:
{{ toYaml .Values.service.annotations | indent 4 }}
{{- end }}
labels:
{{ include "powerdns.labels" . | indent 4 }}
spec:
type: {{ .Values.service.type }}
{{ if .Values.service.loadBalancerIP }}
loadBalancerIP: {{ .Values.service.loadBalancerIP }}
{{ end }}
{{- if .Values.service.externalIPs }}
externalIPs:
{{ toYaml .Values.service.externalIPs | indent 4 }}
{{- end }}
{{- if (.Values.service.externalTrafficPolicy) }}
externalTrafficPolicy: "{{ .Values.service.externalTrafficPolicy }}"
{{- end }}
ports:
- name: dns-udp
port: 53
protocol: UDP
selector:
app.kubernetes.io/name: {{ include "powerdns.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
---
apiVersion: v1
kind: Service
metadata:
name: {{ include "powerdns.fullname" . }}-tcp
{{- if .Values.service.annotations }}
annotations:
{{ toYaml .Values.service.annotations | indent 4 }}
{{- end }}
labels:
{{ include "powerdns.labels" . | indent 4 }}
spec:
type: {{ .Values.service.type }}
{{ if .Values.service.loadBalancerIP }}
loadBalancerIP: {{ .Values.service.loadBalancerIP }}
{{ end }}
{{- if .Values.service.externalIPs }}
externalIPs:
{{ toYaml .Values.service.externalIPs | indent 4 }}
{{- end }}
{{- if (.Values.service.externalTrafficPolicy) }}
externalTrafficPolicy: "{{ .Values.service.externalTrafficPolicy }}"
{{- end }}
ports:
- name: dns-tcp
port: 53
protocol: TCP
selector:
app.kubernetes.io/name: {{ include "powerdns.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{ if (.Values.powerdns.api_key) }}
---
apiVersion: v1
kind: Service
metadata:
name: {{ include "powerdns.fullname" . }}-webserver
{{- if .Values.service.annotations }}
annotations:
{{ toYaml .Values.service.annotations | indent 4 }}
{{- end }}
labels:
{{ include "powerdns.labels" . | indent 4 }}
spec:
type: ClusterIP
ports:
- port: 8081
targetPort: dns-webserver
protocol: TCP
selector:
app.kubernetes.io/name: {{ include "powerdns.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}

View File

@ -0,0 +1,8 @@
{{- if .Values.serviceAccount.create -}}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ template "powerdns.serviceAccountName" . }}
labels:
{{ include "powerdns.labels" . | indent 4 }}
{{- end -}}

108
charts/powerdns/values.yaml Executable file
View File

@ -0,0 +1,108 @@
# Default values for powerdns.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 1
image:
repository: psitrax/powerdns
tag: v4.3.0
pullPolicy: Always
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
serviceAccount:
# Specifies whether a service account should be created
create: true
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name:
podSecurityContext: {}
# fsGroup: 2000
securityContext: {}
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
service:
## Set external traffic policy to: "Local" to preserve source IP on
## providers supporting it
## Ref: https://kubernetes.io/docs/tutorials/services/source-ip/#source-ip-for-services-with-typeloadbalancer
externalTrafficPolicy: ""
type: ClusterIP
port: 53
resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
nodeSelector: {}
tolerations: []
affinity: {}
powerdns:
domain: mydomain.local
postgres:
host: powerdns-postgres
port: 5432
username: pdns
password: pdnspass
database: pdns
mysql:
host: powerdns-mariadb
port: 3306
username: pdns
password: pdnspass
database: pdns
dnssec: true
config: {}
mariadb:
enabled: true
db:
name: pdns
user: pdns
password: pdnspass
replication:
enabled: false
rootUser:
password: pdnsrootpass
master:
persistence:
enabled: false
postgres:
enabled: false
# Probes configuration
probes:
liveness:
enabled: true
initialDelaySeconds: 30
failureThreshold: 5
timeoutSeconds: 10
readiness:
enabled: true
initialDelaySeconds: 30
failureThreshold: 5
timeoutSeconds: 10
startup:
enabled: false
failureThreshold: 30
periodSeconds: 10