auth-proxy: proxies only authenticated requests to upstream, redirects to login page otherwise (#103)
* auth-proxy: inspects authenticated user
* ingress: chart and use in rpuppy
* auth-proxy: make it optional in rpuppy
* kratos: whitelist env pub/priv domains for auth return_to addr
* url-shortener: put behind auth-proxy
* pihole: replace oauth2-client with auth-proxy
* auth-proxy: fix upstream uri generation
* pihole: remove old chart using oauth2
* auth-proxy: remove temporary values file
* url-shortener: check x-user header for authentication
* auth: fix allowed_return_urls list
* auth-proxy: fix current address generation logic
---------
Co-authored-by: Giorgi Lekveishvili <lekva@gl-mbp-m1-max.local>
diff --git a/apps/url-shortener/main.go b/apps/url-shortener/main.go
index b1db1f9..bb805e4 100644
--- a/apps/url-shortener/main.go
+++ b/apps/url-shortener/main.go
@@ -157,8 +157,11 @@
}
func getLoggedInUser(r *http.Request) (string, error) {
- // TODO(dato): should make a request to get loggedin user
- return "tabo", nil
+ if user := r.Header.Get("X-User"); user != "" {
+ return user, nil
+ } else {
+ return "", fmt.Errorf("unauthenticated")
+ }
}
type Server struct {
diff --git a/charts/auth-proxy/.helmignore b/charts/auth-proxy/.helmignore
new file mode 100644
index 0000000..0e8a0eb
--- /dev/null
+++ b/charts/auth-proxy/.helmignore
@@ -0,0 +1,23 @@
+# 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
+*.orig
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
diff --git a/charts/auth-proxy/Chart.yaml b/charts/auth-proxy/Chart.yaml
new file mode 100644
index 0000000..1578a6c
--- /dev/null
+++ b/charts/auth-proxy/Chart.yaml
@@ -0,0 +1,6 @@
+apiVersion: v2
+name: auth-proxy
+description: A Helm chart for pCloud auth-proxy
+type: application
+version: 0.0.1
+appVersion: "0.0.1"
diff --git a/charts/auth-proxy/templates/install.yaml b/charts/auth-proxy/templates/install.yaml
new file mode 100644
index 0000000..63310c6
--- /dev/null
+++ b/charts/auth-proxy/templates/install.yaml
@@ -0,0 +1,44 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: auth-proxy
+ namespace: {{ .Release.Namespace }}
+spec:
+ type: ClusterIP
+ selector:
+ app: auth-proxy
+ ports:
+ - name: {{ .Values.portName }}
+ port: 80
+ targetPort: {{ .Values.portName }}
+ protocol: TCP
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: auth-proxy
+ namespace: {{ .Release.Namespace }}
+spec:
+ selector:
+ matchLabels:
+ app: auth-proxy
+ replicas: 1
+ template:
+ metadata:
+ labels:
+ app: auth-proxy
+ spec:
+ containers:
+ - name: auth-proxy
+ image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ ports:
+ - name: {{ .Values.portName }}
+ containerPort: 8080
+ protocol: TCP
+ command:
+ - server
+ - --port=8080
+ - --whoami-addr={{ .Values.whoAmIAddr }}
+ - --login-addr={{ .Values.loginAddr }}
+ - --upstream={{ .Values.upstream }}
diff --git a/charts/auth-proxy/values.yaml b/charts/auth-proxy/values.yaml
new file mode 100644
index 0000000..9f61b34
--- /dev/null
+++ b/charts/auth-proxy/values.yaml
@@ -0,0 +1,8 @@
+image:
+ repository: giolekva/auth-proxy
+ tag: latest
+ pullPolicy: Always
+upstream: bar.svc.cluster.local
+whoAmIAddr: https://accounts.example.com/sessions/whoami
+loginAddr: https://accounts-ui.example.com/login
+portName: http
diff --git a/charts/ingress/.helmignore b/charts/ingress/.helmignore
new file mode 100644
index 0000000..0e8a0eb
--- /dev/null
+++ b/charts/ingress/.helmignore
@@ -0,0 +1,23 @@
+# 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
+*.orig
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
diff --git a/charts/ingress/Chart.yaml b/charts/ingress/Chart.yaml
new file mode 100644
index 0000000..28df2c4
--- /dev/null
+++ b/charts/ingress/Chart.yaml
@@ -0,0 +1,6 @@
+apiVersion: v2
+name: rpuppy
+description: A Helm chart to configure ingress
+type: application
+version: 0.0.1
+appVersion: "0.0.1"
diff --git a/charts/ingress/templates/install.yaml b/charts/ingress/templates/install.yaml
new file mode 100644
index 0000000..173186c
--- /dev/null
+++ b/charts/ingress/templates/install.yaml
@@ -0,0 +1,33 @@
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ name: ingress
+ namespace: {{ .Release.Namespace }}
+ {{- if .Values.certificateIssuer }}
+ annotations:
+ acme.cert-manager.io/http01-edit-in-place: "true"
+ cert-manager.io/cluster-issuer: {{ .Values.certificateIssuer }}
+ {{- end }}
+spec:
+ ingressClassName: {{ .Values.ingressClassName }}
+ {{- if .Values.certificateIssuer }}
+ tls:
+ - hosts:
+ - {{ .Values.domain }}
+ secretName: cert-rpuppy
+ {{- end }}
+ rules:
+ - host: {{ .Values.domain }}
+ http:
+ paths:
+ - path: /
+ pathType: Prefix
+ backend:
+ service:
+ name: {{ .Values.service.name }}
+ port:
+ {{- if .Values.service.port.name }}
+ name: {{ .Values.service.port.name }}
+ {{- else }}
+ number: {{ .Values.service.port.number }}
+ {{- end}}
diff --git a/charts/ingress/values.yaml b/charts/ingress/values.yaml
new file mode 100644
index 0000000..18477aa
--- /dev/null
+++ b/charts/ingress/values.yaml
@@ -0,0 +1,8 @@
+ingressClassName: ingress-public
+certificateIssuer: example-public
+domain: woof.example.com
+service:
+ name: woof
+ port:
+ number: 80
+ name: ""
diff --git a/charts/pihole/.helmignore b/charts/pihole/.helmignore
index 0e8a0eb..4c2748c 100644
--- a/charts/pihole/.helmignore
+++ b/charts/pihole/.helmignore
@@ -14,10 +14,14 @@
*.swp
*.bak
*.tmp
-*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
-.vscode/
+
+# Manually added entries
+ci/
+examples/
+Makefile
+README.md.gotmpl
diff --git a/charts/pihole/Chart.lock b/charts/pihole/Chart.lock
deleted file mode 100644
index 4265f24..0000000
--- a/charts/pihole/Chart.lock
+++ /dev/null
@@ -1,6 +0,0 @@
-dependencies:
-- name: pihole
- repository: file://charts/pihole
- version: 2.20.0
-digest: sha256:ee1f774f0b478c89c0c4f0f2273693cf7625c96c5685e44ebc0626258a9edeaf
-generated: "2023-12-18T13:55:22.037837+04:00"
diff --git a/charts/pihole/Chart.yaml b/charts/pihole/Chart.yaml
index 00d0aac..8b087a8 100644
--- a/charts/pihole/Chart.yaml
+++ b/charts/pihole/Chart.yaml
@@ -1,10 +1,15 @@
-apiVersion: v2
+apiVersion: v1
+appVersion: 2023.11.0
+description: Installs pihole in kubernetes
+home: https://github.com/MoJo2600/pihole-kubernetes/tree/master/charts/pihole
+icon: https://i2.wp.com/pi-hole.net/wp-content/uploads/2016/12/Vortex-R.png
+maintainers:
+- email: christian.erhardt@mojo2k.de
+ name: MoJo2600
name: pihole
-description: A Helm chart for PCloud Pihole service
-type: application
-version: 0.0.1
-appVersion: "0.0.1"
-dependencies:
-- name: pihole
- version: 2.20.1
- repository: https://mojo2600.github.io/pihole-kubernetes/
+sources:
+- https://github.com/MoJo2600/pihole-kubernetes/tree/master/charts/pihole
+- https://pi-hole.net/
+- https://github.com/pi-hole
+- https://github.com/pi-hole/docker-pi-hole
+version: 2.20.1
diff --git a/charts/pihole/README.md b/charts/pihole/README.md
new file mode 100644
index 0000000..610a521
--- /dev/null
+++ b/charts/pihole/README.md
@@ -0,0 +1,403 @@
+# pihole
+
+Installs pihole in kubernetes
+
+  <!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
+[](#contributors-)
+<!-- ALL-CONTRIBUTORS-BADGE:END -->
+
+## Source Code
+
+* <https://github.com/MoJo2600/pihole-kubernetes/tree/master/charts/pihole>
+* <https://pi-hole.net/>
+* <https://github.com/pi-hole>
+* <https://github.com/pi-hole/docker-pi-hole>
+
+## Installation
+
+Jeff Geerling on YouTube made a video about the installation of this chart:
+
+[](https://youtu.be/IafVCHkJbtI?t=2655)
+
+### Add Helm repository
+
+```shell
+helm repo add mojo2600 https://mojo2600.github.io/pihole-kubernetes/
+helm repo update
+```
+
+### Configure the chart
+
+The following items can be set via `--set` flag during installation or configured by editing the `values.yaml` directly.
+
+#### Configure the way how to expose pihole service:
+
+- **Ingress**: The ingress controller must be installed in the Kubernetes cluster.
+- **ClusterIP**: Exposes the service on a cluster-internal IP. Choosing this value makes the service only reachable from within the cluster.
+- **LoadBalancer**: Exposes the service externally using a cloud provider’s load balancer.
+
+## My settings in values.yaml
+
+```console
+dnsmasq:
+ customDnsEntries:
+ - address=/nas/192.168.178.10
+
+ customCnameEntries:
+ - cname=foo.nas,nas
+
+persistentVolumeClaim:
+ enabled: true
+
+serviceWeb:
+ loadBalancerIP: 192.168.178.252
+ annotations:
+ metallb.universe.tf/allow-shared-ip: pihole-svc
+ type: LoadBalancer
+
+serviceDns:
+ loadBalancerIP: 192.168.178.252
+ annotations:
+ metallb.universe.tf/allow-shared-ip: pihole-svc
+ type: LoadBalancer
+```
+
+## Configuring Upstream DNS Resolvers
+
+By default, `pihole-kubernetes` will configure pod DNS automatically to use Google's `8.8.8.8` nameserver for upstream
+DNS resolution. You can configure this, or opt-out of pod DNS configuration completely.
+
+### Changing The Upstream DNS Resolver
+
+For example, to use Cloudflare's resolver:
+
+```yaml
+podDnsConfig:
+ enabled: true
+ policy: "None"
+ nameservers:
+ - 127.0.0.1
+ - 1.1.1.1
+```
+
+### Disabling Pod DNS Configuration
+
+If you have other DNS policy at play (for example, when running a service mesh), you may not want to have
+`pihole-kubernetes` control this behavior. In that case, you can disable DNS configuration on `pihole` pods:
+
+```yaml
+podDnsConfig:
+ enabled: false
+```
+
+## Upgrading
+
+### To 2.0.0
+
+This version splits the DHCP service into its own resource and puts the configuration to `serviceDhcp`.
+
+**If you have not changed any configuration for `serviceDns`, you don’t need to do anything.**
+
+If you have changed your `serviceDns` configuration, **copy** your `serviceDns` section into a new `serviceDhcp` section.
+
+### To 1.8.22
+
+To enhance compatibility for Traefik, we split the TCP and UDP service into Web and DNS. This means, if you have a dedicated configuration for the service, you have to
+update your `values.yaml` and add a new configuration for this new service.
+
+Before (In my case, with metallb):
+```
+serviceTCP:
+ loadBalancerIP: 192.168.178.252
+ annotations:
+ metallb.universe.tf/allow-shared-ip: pihole-svc
+
+serviceUDP:
+ loadBalancerIP: 192.168.178.252
+ annotations:
+ metallb.universe.tf/allow-shared-ip: pihole-svc
+```
+
+After:
+```
+serviceWeb:
+ loadBalancerIP: 192.168.178.252
+ annotations:
+ metallb.universe.tf/allow-shared-ip: pihole-svc
+
+serviceDns:
+ loadBalancerIP: 192.168.178.252
+ annotations:
+ metallb.universe.tf/allow-shared-ip: pihole-svc
+```
+
+Version 1.8.22 has switched from the deprecated ingress api `extensions/v1beta1` to the go forward version `networking.k8s.io/v1`. This means that your cluster must be running 1.19.x as this api is not available on older versions. If necessary to run on an older Kubernetes Version, it can be done by modifying the ingress.yaml and changing the api definition back. The backend definition would also change from:
+
+```
+ backend:
+ service:
+ name: \{\{ $serviceName \}\}
+ port:
+ name: http
+```
+to:
+```
+ backend:
+ serviceName: \{\{ $serviceName \}\}
+ servicePort: http
+```
+
+## Uninstallation
+
+To uninstall/delete the `my-release` deployment (NOTE: `--purge` is default behaviour in Helm 3+ and will error):
+
+```bash
+helm delete --purge my-release
+```
+
+## Configuration
+
+The following table lists the configurable parameters of the pihole chart and the default values.
+
+## Values
+
+| Key | Type | Default | Description |
+|-----|------|---------|-------------|
+| DNS1 | string | `"8.8.8.8"` | default upstream DNS 1 server to use |
+| DNS2 | string | `"8.8.4.4"` | default upstream DNS 2 server to use |
+| adlists | object | `{}` | list of adlists to import during initial start of the container |
+| admin | object | `{"existingSecret":"","passwordKey":"password"}` | Use an existing secret for the admin password. |
+| admin.enabled | bool | `true` | If set to false admin password will be disabled, adminPassword specified above and the pre-existing secret (if specified) will be ignored. |
+| admin.existingSecret | string | `""` | Specify an existing secret to use as admin password |
+| admin.passwordKey | string | `"password"` | Specify the key inside the secret to use |
+| adminPassword | string | `"admin"` | Administrator password when not using an existing secret (see below) |
+| affinity | object | `{}` | |
+| antiaff.avoidRelease | string | `"pihole1"` | Here you can set the pihole release (you set in `helm install <releasename> ...`) you want to avoid |
+| antiaff.enabled | bool | `false` | set to true to enable antiaffinity (example: 2 pihole DNS in the same cluster) |
+| antiaff.strict | bool | `true` | Here you can choose between preferred or required |
+| antiaff.namespaces | '[]' | list of namespaces to include in anti-affinity settings
+| blacklist | object | `{}` | list of blacklisted domains to import during initial start of the container |
+| customVolumes.config | object | `{}` | any volume type can be used here |
+| customVolumes.enabled | bool | `false` | set this to true to enable custom volumes |
+| dnsHostPort.enabled | bool | `false` | set this to true to enable dnsHostPort |
+| dnsHostPort.port | int | `53` | default port for this pod |
+| dnsmasq.additionalHostsEntries | list | `[]` | Dnsmasq reads the /etc/hosts file to resolve ips. You can add additional entries if you like |
+| dnsmasq.customCnameEntries | list | `[]` | Here we specify custom cname entries that should point to `A` records or elements in customDnsEntries array. The format should be: - cname=cname.foo.bar,foo.bar - cname=cname.bar.foo,bar.foo - cname=cname record,dns record |
+| dnsmasq.customDnsEntries | list | `[]` | Add custom dns entries to override the dns resolution. All lines will be added to the pihole dnsmasq configuration. |
+| dnsmasq.customSettings | string | `nil` | Other options |
+| dnsmasq.staticDhcpEntries | list | `[]` | Static DHCP config |
+| dnsmasq.upstreamServers | list | `[]` | Add upstream dns servers. All lines will be added to the pihole dnsmasq configuration |
+| doh.enabled | bool | `false` | set to true to enabled DNS over HTTPs via cloudflared |
+| doh.envVars | object | `{}` | Here you can pass environment variables to the DoH container, for example: |
+| doh.name | string | `"cloudflared"` | |
+| doh.probes | object | `{"liveness":{"enabled":true,"failureThreshold":10,"initialDelaySeconds":60,"probe":{"exec":{"command":["nslookup","-po=5053","cloudflare.com","127.0.0.1"]}},"timeoutSeconds":5}}` | Probes configuration |
+| doh.probes.liveness | object | `{"enabled":true,"failureThreshold":10,"initialDelaySeconds":60,"probe":{"exec":{"command":["nslookup","-po=5053","cloudflare.com","127.0.0.1"]}},"timeoutSeconds":5}` | Configure the healthcheck for the doh container |
+| doh.probes.liveness.enabled | bool | `true` | set to true to enable liveness probe |
+| doh.probes.liveness.failureThreshold | int | `10` | defines the failure threshold for the liveness probe |
+| doh.probes.liveness.initialDelaySeconds | int | `60` | defines the initial delay for the liveness probe |
+| doh.probes.liveness.probe | object | `{"exec":{"command":["nslookup","-po=5053","cloudflare.com","127.0.0.1"]}}` | customize the liveness probe |
+| doh.probes.liveness.timeoutSeconds | int | `5` | defines the timeout in secondes for the liveness probe |
+| doh.pullPolicy | string | `"IfNotPresent"` | |
+| doh.repository | string | `"crazymax/cloudflared"` | |
+| doh.tag | string | `"latest"` | |
+| dualStack.enabled | bool | `false` | set this to true to enable creation of DualStack services or creation of separate IPv6 services if `serviceDns.type` is set to `"LoadBalancer"` |
+| extraEnvVars | object | `{}` | extraEnvironmentVars is a list of extra enviroment variables to set for pihole to use |
+| extraEnvVarsSecret | object | `{}` | extraEnvVarsSecret is a list of secrets to load in as environment variables. |
+| extraInitContainers | list | `[]` | any initContainers you might want to run before starting pihole |
+| extraObjects | list | `[]` | any extra kubernetes manifests you might want |
+| extraVolumeMounts | object | `{}` | any extra volume mounts you might want |
+| extraVolumes | object | `{}` | any extra volumes you might want |
+| ftl | object | `{}` | values that should be added to pihole-FTL.conf |
+| hostNetwork | string | `"false"` | should the container use host network |
+| hostname | string | `""` | hostname of pod |
+| image.pullPolicy | string | `"IfNotPresent"` | the pull policy |
+| image.repository | string | `"pihole/pihole"` | the repostory to pull the image from |
+| image.tag | string | `""` | the docker tag, if left empty it will get it from the chart's appVersion |
+| ingress | object | `{"annotations":{},"enabled":false,"hosts":["chart-example.local"],"path":"/","tls":[]}` | Configuration for the Ingress |
+| ingress.annotations | object | `{}` | Annotations for the ingress |
+| ingress.enabled | bool | `false` | Generate a Ingress resource |
+| maxSurge | int | `1` | The maximum number of Pods that can be created over the desired number of `ReplicaSet` during updating. |
+| maxUnavailable | int | `1` | The maximum number of Pods that can be unavailable during updating |
+| monitoring.podMonitor | object | `{"enabled":false}` | Preferably adding prometheus scrape annotations rather than enabling podMonitor. |
+| monitoring.podMonitor.enabled | bool | `false` | set this to true to enable podMonitor |
+| monitoring.sidecar | object | `{"enabled":false,"image":{"pullPolicy":"IfNotPresent","repository":"ekofr/pihole-exporter","tag":"v0.3.0"},"port":9617,"resources":{"limits":{"memory":"128Mi"}}}` | Sidecar configuration |
+| monitoring.sidecar.enabled | bool | `false` | set this to true to enable podMonitor as sidecar |
+| nodeSelector | object | `{}` | |
+| persistentVolumeClaim | object | `{"accessModes":["ReadWriteOnce"],"annotations":{},"enabled":false,"size":"500Mi"}` | `spec.PersitentVolumeClaim` configuration |
+| persistentVolumeClaim.annotations | object | `{}` | Annotations for the `PersitentVolumeClaim` |
+| persistentVolumeClaim.enabled | bool | `false` | set to true to use pvc |
+| podAnnotations | object | `{}` | Additional annotations for pods |
+| podDnsConfig.enabled | bool | `true` | |
+| podDnsConfig.nameservers[0] | string | `"127.0.0.1"` | |
+| podDnsConfig.nameservers[1] | string | `"8.8.8.8"` | |
+| podDnsConfig.policy | string | `"None"` | |
+| privileged | string | `"false"` | should container run in privileged mode |
+| capabilities | object | `{}` | Linux capabilities that container should run with |
+| probes | object | `{"liveness":{"type": "httpGet","enabled":true,"failureThreshold":10,"initialDelaySeconds":60,"port":"http","scheme":"HTTP","timeoutSeconds":5},"readiness":{"enabled":true,"failureThreshold":3,"initialDelaySeconds":60,"port":"http","scheme":"HTTP","timeoutSeconds":5}}` | Probes configuration |
+| probes.liveness.enabled | bool | `true` | Generate a liveness probe |
+| probes.liveness.type | string | `httpGet` | Defines the type of liveness probe. (httpGet, command) |
+| probes.liveness.command | list | [] | A list of commands to execute as a liveness probe (Requires `type` to be set to `command`) |
+| probes.readiness.enabled | bool | `true` | Generate a readiness probe |
+| regex | object | `{}` | list of blacklisted regex expressions to import during initial start of the container |
+| replicaCount | int | `1` | The number of replicas |
+| resources | object | `{}` | lines, adjust them as necessary, and remove the curly braces after 'resources:'. |
+| serviceDhcp | object | `{"annotations":{},"enabled":true,"externalTrafficPolicy":"Local","loadBalancerIP":"","loadBalancerIPv6":"","nodePort":"","port":67,"type":"NodePort"}` | Configuration for the DHCP service on port 67 |
+| serviceDhcp.annotations | object | `{}` | Annotations for the DHCP service |
+| serviceDhcp.enabled | bool | `true` | Generate a Service resource for DHCP traffic |
+| serviceDhcp.externalTrafficPolicy | string | `"Local"` | `spec.externalTrafficPolicy` for the DHCP Service |
+| serviceDhcp.loadBalancerIP | string | `""` | A fixed `spec.loadBalancerIP` for the DHCP Service |
+| serviceDhcp.loadBalancerIPv6 | string | `""` | A fixed `spec.loadBalancerIP` for the IPv6 DHCP Service |
+| serviceDhcp.nodePort | string | `""` | Optional node port for the DHCP service |
+| serviceDhcp.port | int | `67` | The port of the DHCP service |
+| serviceDhcp.type | string | `"NodePort"` | `spec.type` for the DHCP Service |
+| serviceDns | object | `{"annotations":{},"externalTrafficPolicy":"Local","loadBalancerIP":"","loadBalancerIPv6":"","mixedService":false,"nodePort":"","port":53,"type":"NodePort"}` | Configuration for the DNS service on port 53 |
+| serviceDns.annotations | object | `{}` | Annotations for the DNS service |
+| serviceDns.externalTrafficPolicy | string | `"Local"` | `spec.externalTrafficPolicy` for the DHCP Service |
+| serviceDns.loadBalancerIP | string | `""` | A fixed `spec.loadBalancerIP` for the DNS Service |
+| serviceDns.loadBalancerIPv6 | string | `""` | A fixed `spec.loadBalancerIP` for the IPv6 DNS Service |
+| serviceDns.mixedService | bool | `false` | deploys a mixed (TCP + UDP) Service instead of separate ones |
+| serviceDns.nodePort | string | `""` | Optional node port for the DNS service |
+| serviceDns.port | int | `53` | The port of the DNS service |
+| serviceDns.type | string | `"NodePort"` | `spec.type` for the DNS Service |
+| serviceWeb | object | `{"annotations":{},"externalTrafficPolicy":"Local","http":{"enabled":true,"nodePort":"","port":80},"https":{"enabled":true,"nodePort":"","port":443},"loadBalancerIP":"","loadBalancerIPv6":"","type":"ClusterIP"}` | Configuration for the web interface service |
+| serviceWeb.annotations | object | `{}` | Annotations for the DHCP service |
+| serviceWeb.externalTrafficPolicy | string | `"Local"` | `spec.externalTrafficPolicy` for the web interface Service |
+| serviceWeb.http | object | `{"enabled":true,"nodePort":"","port":80}` | Configuration for the HTTP web interface listener |
+| serviceWeb.http.enabled | bool | `true` | Generate a service for HTTP traffic |
+| serviceWeb.http.nodePort | string | `""` | Optional node port for the web HTTP service |
+| serviceWeb.http.port | int | `80` | The port of the web HTTP service |
+| serviceWeb.https | object | `{"enabled":true,"nodePort":"","port":443}` | Configuration for the HTTPS web interface listener |
+| serviceWeb.https.enabled | bool | `true` | Generate a service for HTTPS traffic |
+| serviceWeb.https.nodePort | string | `""` | Optional node port for the web HTTPS service |
+| serviceWeb.https.port | int | `443` | The port of the web HTTPS service |
+| serviceWeb.loadBalancerIP | string | `""` | A fixed `spec.loadBalancerIP` for the web interface Service |
+| serviceWeb.loadBalancerIPv6 | string | `""` | A fixed `spec.loadBalancerIP` for the IPv6 web interface Service |
+| serviceWeb.type | string | `"ClusterIP"` | `spec.type` for the web interface Service |
+| strategyType | string | `"RollingUpdate"` | The `spec.strategyTpye` for updates |
+| tolerations | list | `[]` | |
+| topologySpreadConstraints | list | `[]` | Specify a priorityClassName priorityClassName: "" Reference: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ |
+| virtualHost | string | `"pi.hole"` | |
+| webHttp | string | `"80"` | port the container should use to expose HTTP traffic |
+| webHttps | string | `"443"` | port the container should use to expose HTTPS traffic |
+| whitelist | object | `{}` | list of whitelisted domains to import during initial start of the container |
+
+## Maintainers
+
+| Name | Email | Url |
+| ---- | ------ | --- |
+| MoJo2600 | <christian.erhardt@mojo2k.de> | |
+
+## Remarks
+
+### MetalLB 0.8.1+
+
+pihole seems to work without issue in MetalLB 0.8.1+
+
+### MetalLB 0.7.3
+
+MetalLB 0.7.3 has a bug, where the service is not announced anymore, when the pod changes (e.g. update of a deployment). My workaround is to restart the `metallb-speaker-*` pods.
+
+## Credits
+
+[Pi-hole®](https://pi-hole.net/)
+
+## Contributing
+
+Feel free to contribute by making a [pull request](https://github.com/MoJo2600/pihole-kubernetes/pull/new/master).
+
+Please read [Contribution Guide](../../CONTRIBUTING.md) for more information on how you can contribute to this Chart.
+
+## Contributors ✨
+
+Thanks goes to these wonderful people:
+
+<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
+<!-- prettier-ignore-start -->
+<!-- markdownlint-disable -->
+<table>
+ <tr>
+ <td align="center"><a href="http://www.mojo2k.de"><img src="https://avatars1.githubusercontent.com/u/2462817?v=4" width="100px;" alt=""/><br /><sub><b>Christian Erhardt</b></sub></a></td>
+ <td align="center"><a href="https://billimek.com/"><img src="https://avatars0.githubusercontent.com/u/6393612?v=4" width="100px;" alt=""/><br /><sub><b>Jeff Billimek</b></sub></a></td>
+ <td align="center"><a href="https://github.com/imle"><img src="https://avatars3.githubusercontent.com/u/4809109?v=4" width="100px;" alt=""/><br /><sub><b>Steven Imle</b></sub></a></td>
+ <td align="center"><a href="https://github.com/jetersen"><img src="https://avatars2.githubusercontent.com/u/1661688?v=4" width="100px;" alt=""/><br /><sub><b>Joseph Petersen</b></sub></a></td>
+ <td align="center"><a href="https://github.com/SiM22"><img src="https://avatars2.githubusercontent.com/u/5759618?v=4" width="100px;" alt=""/><br /><sub><b>Simon Garcia</b></sub></a></td>
+ <td align="center"><a href="https://github.com/AndyG-0"><img src="https://avatars1.githubusercontent.com/u/29743443?v=4" width="100px;" alt=""/><br /><sub><b>Andy Gilbreath</b></sub></a></td>
+ <td align="center"><a href="https://github.com/northerngit"><img src="https://avatars0.githubusercontent.com/u/4513272?v=4" width="100px;" alt=""/><br /><sub><b>James Wilson</b></sub></a></td>
+ </tr>
+ <tr>
+ <td align="center"><a href="https://github.com/jskswamy"><img src="https://avatars2.githubusercontent.com/u/232449?v=4" width="100px;" alt=""/><br /><sub><b>Krishnaswamy Subramanian</b></sub></a></td>
+ <td align="center"><a href="https://github.com/luqasn"><img src="https://avatars2.githubusercontent.com/u/274902?v=4" width="100px;" alt=""/><br /><sub><b>Lucas Romero</b></sub></a></td>
+ <td align="center"><a href="https://github.com/konturn"><img src="https://avatars0.githubusercontent.com/u/35545508?v=4" width="100px;" alt=""/><br /><sub><b>konturn</b></sub></a></td>
+ <td align="center"><a href="https://github.com/tdorsey"><img src="https://avatars3.githubusercontent.com/u/1218404?v=4" width="100px;" alt=""/><br /><sub><b>tdorsey</b></sub></a></td>
+ <td align="center"><a href="https://github.com/alesz"><img src="https://avatars0.githubusercontent.com/u/12436980?v=4" width="100px;" alt=""/><br /><sub><b>Ales Zelenik</b></sub></a></td>
+ <td align="center"><a href="https://github.com/dtourde"><img src="https://avatars1.githubusercontent.com/u/49169262?v=4" width="100px;" alt=""/><br /><sub><b>Damien TOURDE</b></sub></a></td>
+ <td align="center"><a href="https://github.com/putz612"><img src="https://avatars3.githubusercontent.com/u/952758?v=4" width="100px;" alt=""/><br /><sub><b>Jason Sievert</b></sub></a></td>
+ </tr>
+ <tr>
+ <td align="center"><a href="https://github.com/joshua-nord"><img src="https://avatars2.githubusercontent.com/u/1181300?v=4" width="100px;" alt=""/><br /><sub><b>joshua-nord</b></sub></a></td>
+ <td align="center"><a href="https://maximilianbo.de/"><img src="https://avatars3.githubusercontent.com/u/9051309?v=4" width="100px;" alt=""/><br /><sub><b>Maximilian Bode</b></sub></a></td>
+ <td align="center"><a href="https://github.com/raackley"><img src="https://avatars0.githubusercontent.com/u/1700688?v=4" width="100px;" alt=""/><br /><sub><b>raackley</b></sub></a></td>
+ <td align="center"><a href="https://github.com/StoicPerlman"><img src="https://avatars1.githubusercontent.com/u/3152359?v=4" width="100px;" alt=""/><br /><sub><b>Sam Kleiner</b></sub></a></td>
+ <td align="center"><a href="https://arpankapoor.com/"><img src="https://avatars3.githubusercontent.com/u/3677810?v=4" width="100px;" alt=""/><br /><sub><b>Arpan Kapoor</b></sub></a></td>
+ <td align="center"><a href="https://github.com/chrodriguez"><img src="https://avatars1.githubusercontent.com/u/1460882?v=4" width="100px;" alt=""/><br /><sub><b>Christian Rodriguez</b></sub></a></td>
+ <td align="center"><a href="http://dave-cahill.com/"><img src="https://avatars0.githubusercontent.com/u/361096?v=4" width="100px;" alt=""/><br /><sub><b>Dave Cahill</b></sub></a></td>
+ </tr>
+ <tr>
+ <td align="center"><a href="https://github.com/golgoth31"><img src="https://avatars2.githubusercontent.com/u/5741421?v=4" width="100px;" alt=""/><br /><sub><b>golgoth31</b></sub></a></td>
+ <td align="center"><a href="https://greg.jeanmart.me/"><img src="https://avatars3.githubusercontent.com/u/506784?v=4" width="100px;" alt=""/><br /><sub><b>Greg Jeanmart</b></sub></a></td>
+ <td align="center"><a href="https://github.com/ballj"><img src="https://avatars1.githubusercontent.com/u/38097813?v=4" width="100px;" alt=""/><br /><sub><b>Joseph Ball</b></sub></a></td>
+ <td align="center"><a href="http://www.oneko.org/"><img src="https://avatars2.githubusercontent.com/u/4233214?v=4" width="100px;" alt=""/><br /><sub><b>Karlos</b></sub></a></td>
+ <td align="center"><a href="https://github.com/dza89"><img src="https://avatars0.githubusercontent.com/u/20373984?v=4" width="100px;" alt=""/><br /><sub><b>dza89</b></sub></a></td>
+ <td align="center"><a href="https://github.com/mikewhitley"><img src="https://avatars0.githubusercontent.com/u/52802633?v=4" width="100px;" alt=""/><br /><sub><b>mikewhitley</b></sub></a></td>
+ <td align="center"><a href="https://github.com/Vashiru"><img src="https://avatars2.githubusercontent.com/u/11370057?v=4" width="100px;" alt=""/><br /><sub><b>Vashiru</b></sub></a></td>
+ </tr>
+ <tr>
+ <td align="center"><a href="https://github.com/sam-kleiner"><img src="https://avatars.githubusercontent.com/u/63059772?v=4" width="100px;" alt=""/><br /><sub><b>sam-kleiner</b></sub></a></td>
+ <td align="center"><a href="https://www.linkedin.com/in/alexgorbatchev/"><img src="https://avatars.githubusercontent.com/u/65633?v=4" width="100px;" alt=""/><br /><sub><b>Alex Gorbatchev</b></sub></a></td>
+ <td align="center"><a href="https://github.com/c-yco"><img src="https://avatars.githubusercontent.com/u/355591?v=4" width="100px;" alt=""/><br /><sub><b>Alexander Rabenstein</b></sub></a></td>
+ <td align="center"><a href="http://tibbon.com/"><img src="https://avatars.githubusercontent.com/u/82880?v=4" width="100px;" alt=""/><br /><sub><b>David Fisher</b></sub></a></td>
+ <td align="center"><a href="https://github.com/utkuozdemir"><img src="https://avatars.githubusercontent.com/u/1465819?v=4" width="100px;" alt=""/><br /><sub><b>Utku Özdemir</b></sub></a></td>
+ <td align="center"><a href="https://mor.re/"><img src="https://avatars.githubusercontent.com/u/7683567?v=4" width="100px;" alt=""/><br /><sub><b>Morre Meyer</b></sub></a></td>
+ <td align="center"><a href="https://github.com/johnsondnz"><img src="https://avatars.githubusercontent.com/u/7608966?v=4" width="100px;" alt=""/><br /><sub><b>Donald Johnson</b></sub></a></td>
+ </tr>
+ <tr>
+ <td align="center"><a href="https://winston.milli.ng/"><img src="https://avatars.githubusercontent.com/u/6162814?v=4" width="100px;" alt=""/><br /><sub><b>Winston R. Milling</b></sub></a></td>
+ <td align="center"><a href="https://github.com/larivierec"><img src="https://avatars.githubusercontent.com/u/3633214?v=4" width="100px;" alt=""/><br /><sub><b>Christopher Larivière</b></sub></a></td>
+ <td align="center"><a href="https://sievenpiper.co/"><img src="https://avatars.githubusercontent.com/u/1131882?v=4" width="100px;" alt=""/><br /><sub><b>Justin Sievenpiper</b></sub></a></td>
+ <td align="center"><a href="https://github.com/beastob"><img src="https://avatars.githubusercontent.com/u/76816315?v=4" width="100px;" alt=""/><br /><sub><b>beastob</b></sub></a></td>
+ <td align="center"><a href="https://niftyside.io/"><img src="https://avatars.githubusercontent.com/u/653739?v=4" width="100px;" alt=""/><br /><sub><b>Daniel Mühlbachler-Pietrzykowski</b></sub></a></td>
+ <td align="center"><a href="https://github.com/consideRatio"><img src="https://avatars.githubusercontent.com/u/3837114?v=4" width="100px;" alt=""/><br /><sub><b>Erik Sundell</b></sub></a></td>
+ <td align="center"><a href="https://github.com/Ornias1993"><img src="https://avatars.githubusercontent.com/u/7613738?v=4" width="100px;" alt=""/><br /><sub><b>Kjeld Schouten-Lebbing</b></sub></a></td>
+ </tr>
+ <tr>
+ <td align="center"><a href="https://github.com/mrwulf"><img src="https://avatars.githubusercontent.com/u/2494769?v=4" width="100px;" alt=""/><br /><sub><b>Brandon Wulf</b></sub></a></td>
+ <td align="center"><a href="https://github.com/DerRockWolf"><img src="https://avatars.githubusercontent.com/u/50499906?v=4" width="100px;" alt=""/><br /><sub><b>DerRockWolf</b></sub></a></td>
+ <td align="center"><a href="https://github.com/brnl"><img src="https://avatars.githubusercontent.com/u/3243133?v=4" width="100px;" alt=""/><br /><sub><b>brnl</b></sub></a></td>
+ <td align="center"><a href="https://rafaelgaspar.xyz/"><img src="https://avatars.githubusercontent.com/u/5567?v=4" width="100px;" alt=""/><br /><sub><b>Rafael Gaspar</b></sub></a></td>
+ <td align="center"><a href="https://chadimasri.com/"><img src="https://avatars.githubusercontent.com/u/1502811?v=4" width="100px;" alt=""/><br /><sub><b>Chadi El Masri</b></sub></a></td>
+ <td align="center"><a href="https://github.com/dfoulkes"><img src="https://avatars.githubusercontent.com/u/8113674?v=4" width="100px;" alt=""/><br /><sub><b>Dan Foulkes</b></sub></a></td>
+ <td align="center"><a href="https://github.com/george124816"><img src="https://avatars.githubusercontent.com/u/26443736?v=4" width="100px;" alt=""/><br /><sub><b>George Rodrigues</b></sub></a></td>
+ </tr>
+ <tr>
+ <td align="center"><a href="https://pascaliske.dev/"><img src="https://avatars.githubusercontent.com/u/7473880?v=4" width="100px;" alt=""/><br /><sub><b>Pascal Iske</b></sub></a></td>
+ <td align="center"><a href="https://www.reyth.dev/"><img src="https://avatars.githubusercontent.com/u/23526880?v=4" width="100px;" alt=""/><br /><sub><b>Theo REY</b></sub></a></td>
+ <td align="center"><a href="https://github.com/piwi3910"><img src="https://avatars.githubusercontent.com/u/12539757?v=4" width="100px;" alt=""/><br /><sub><b>Watteel Pascal</b></sub></a></td>
+ <td align="center"><a href="https://github.com/frittenlab"><img src="https://avatars.githubusercontent.com/u/29921946?v=4" width="100px;" alt=""/><br /><sub><b>simon</b></sub></a></td>
+ <td align="center"><a href="https://github.com/FernFerret"><img src="https://avatars.githubusercontent.com/u/72811?v=4" width="100px;" alt=""/><br /><sub><b>Eric</b></sub></a></td>
+ <td align="center"><a href="https://github.com/vince-vibin"><img src="https://avatars.githubusercontent.com/u/99386370?v=4" width="100px;" alt=""/><br /><sub><b>Vincent</b></sub></a></td>
+ <td align="center"><a href="https://github.com/Keydrain"><img src="https://avatars.githubusercontent.com/u/5723055?v=4" width="100px;" alt=""/><br /><sub><b>Clint</b></sub></a></td>
+ </tr>
+ <tr>
+ <td align="center"><a href="https://github.com/tamcore"><img src="https://avatars.githubusercontent.com/u/319917?v=4" width="100px;" alt=""/><br /><sub><b>Philipp B.</b></sub></a></td>
+ </tr>
+</table>
+
+<!-- markdownlint-restore -->
+<!-- prettier-ignore-end -->
+
+<!-- ALL-CONTRIBUTORS-LIST:END -->
+
+This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
+
+----------------------------------------------
+Autogenerated from chart metadata using [helm-docs v1.10.0](https://github.com/norwoodj/helm-docs/releases/v1.10.0)
diff --git a/charts/pihole/charts/pihole-2.20.0.tgz b/charts/pihole/charts/pihole-2.20.0.tgz
deleted file mode 100644
index bb4abb8..0000000
--- a/charts/pihole/charts/pihole-2.20.0.tgz
+++ /dev/null
Binary files differ
diff --git a/charts/pihole/charts/pihole-2.20.1.tgz b/charts/pihole/charts/pihole-2.20.1.tgz
deleted file mode 100644
index 6a64f80..0000000
--- a/charts/pihole/charts/pihole-2.20.1.tgz
+++ /dev/null
Binary files differ
diff --git a/charts/pihole/templates/NOTES.txt b/charts/pihole/templates/NOTES.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/charts/pihole/templates/NOTES.txt
diff --git a/charts/pihole/templates/_helpers.tpl b/charts/pihole/templates/_helpers.tpl
new file mode 100644
index 0000000..72aef75
--- /dev/null
+++ b/charts/pihole/templates/_helpers.tpl
@@ -0,0 +1,39 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "pihole.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 "pihole.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 "pihole.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Default password secret name.
+*/}}
+{{- define "pihole.password-secret" -}}
+{{- printf "%s-%s" (include "pihole.fullname" .) "password" | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
diff --git a/charts/pihole/templates/configmap-adlists.yaml b/charts/pihole/templates/configmap-adlists.yaml
new file mode 100644
index 0000000..7a496f0
--- /dev/null
+++ b/charts/pihole/templates/configmap-adlists.yaml
@@ -0,0 +1,16 @@
+{{ if .Values.adlists }}
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: {{ template "pihole.fullname" . }}-adlists
+ labels:
+ app: {{ template "pihole.name" . }}
+ chart: {{ template "pihole.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+data:
+ adlists.list: |
+ {{- range .Values.adlists }}
+ {{ . }}
+ {{- end }}
+{{ end }}
diff --git a/charts/pihole/templates/configmap-blacklist.yaml b/charts/pihole/templates/configmap-blacklist.yaml
new file mode 100644
index 0000000..d34b964
--- /dev/null
+++ b/charts/pihole/templates/configmap-blacklist.yaml
@@ -0,0 +1,16 @@
+{{ if .Values.blacklist }}
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: {{ template "pihole.fullname" . }}-blacklist
+ labels:
+ app: {{ template "pihole.name" . }}
+ chart: {{ template "pihole.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+data:
+ blacklist.txt: |
+ {{- range .Values.blacklist }}
+ {{ . }}
+ {{- end }}
+{{ end }}
diff --git a/charts/pihole/templates/configmap-regex.yaml b/charts/pihole/templates/configmap-regex.yaml
new file mode 100644
index 0000000..9d3bd6b
--- /dev/null
+++ b/charts/pihole/templates/configmap-regex.yaml
@@ -0,0 +1,16 @@
+{{ if .Values.regex }}
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: {{ template "pihole.fullname" . }}-regex
+ labels:
+ app: {{ template "pihole.name" . }}
+ chart: {{ template "pihole.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+data:
+ regex.list: |
+ {{- range .Values.regex }}
+ {{ . }}
+ {{- end }}
+{{ end }}
diff --git a/charts/pihole/templates/configmap-static-dhcp.yaml b/charts/pihole/templates/configmap-static-dhcp.yaml
new file mode 100644
index 0000000..c0005f5
--- /dev/null
+++ b/charts/pihole/templates/configmap-static-dhcp.yaml
@@ -0,0 +1,16 @@
+{{ if .Values.dnsmasq.staticDhcpEntries }}
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: {{ template "pihole.fullname" . }}-static-dhcp
+ labels:
+ app: {{ template "pihole.name" . }}
+ chart: {{ template "pihole.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+data:
+ pihole-static-dhcp.conf: |
+ {{- range .Values.dnsmasq.staticDhcpEntries }}
+ {{ . }}
+ {{- end }}
+{{ end }}
diff --git a/charts/pihole/templates/configmap-whitelist.yaml b/charts/pihole/templates/configmap-whitelist.yaml
new file mode 100644
index 0000000..ecd953d
--- /dev/null
+++ b/charts/pihole/templates/configmap-whitelist.yaml
@@ -0,0 +1,16 @@
+{{ if .Values.whitelist }}
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: {{ template "pihole.fullname" . }}-whitelist
+ labels:
+ app: {{ template "pihole.name" . }}
+ chart: {{ template "pihole.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+data:
+ whitelist.txt: |
+ {{- range .Values.whitelist }}
+ {{ . }}
+ {{- end }}
+{{ end }}
diff --git a/charts/pihole/templates/configmap.yaml b/charts/pihole/templates/configmap.yaml
new file mode 100644
index 0000000..af63f87
--- /dev/null
+++ b/charts/pihole/templates/configmap.yaml
@@ -0,0 +1,32 @@
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: {{ template "pihole.fullname" . }}-custom-dnsmasq
+ labels:
+ app: {{ template "pihole.name" . }}
+ chart: {{ template "pihole.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+data:
+ 02-custom.conf: |
+ addn-hosts=/etc/addn-hosts
+ {{- range .Values.dnsmasq.upstreamServers }}
+ {{ . }}
+ {{- end }}
+ {{- range .Values.dnsmasq.customDnsEntries }}
+ {{ . }}
+ {{- end }}
+ {{- if .Values.serviceDns.loadBalancerIP }}
+ dhcp-option=6,{{ .Values.serviceDns.loadBalancerIP }}
+ {{- end }}
+ {{- range .Values.dnsmasq.customSettings }}
+ {{ . }}
+ {{- end }}
+ addn-hosts: |
+ {{- range .Values.dnsmasq.additionalHostsEntries }}
+ {{ . }}
+ {{- end }}
+ 05-pihole-custom-cname.conf: |
+ {{- range .Values.dnsmasq.customCnameEntries }}
+ {{ . }}
+ {{- end }}
diff --git a/charts/pihole/templates/deployment.yaml b/charts/pihole/templates/deployment.yaml
new file mode 100644
index 0000000..082f767
--- /dev/null
+++ b/charts/pihole/templates/deployment.yaml
@@ -0,0 +1,349 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: {{ template "pihole.fullname" . }}
+ labels:
+ app: {{ template "pihole.name" . }}
+ chart: {{ template "pihole.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+ replicas: {{ .Values.replicaCount }}
+ strategy:
+ type: {{ .Values.strategyType }}
+ {{- if eq .Values.strategyType "RollingUpdate" }}
+ rollingUpdate:
+ maxSurge: {{ .Values.maxSurge }}
+ maxUnavailable: {{ .Values.maxUnavailable }}
+ {{- end }}
+ selector:
+ matchLabels:
+ app: {{ template "pihole.name" . }}
+ release: {{ .Release.Name }}
+ template:
+ metadata:
+ annotations:
+ checksum.config.adlists: {{ include (print $.Template.BasePath "/configmap-adlists.yaml") . | sha256sum | trunc 63 }}
+ checksum.config.blacklist: {{ include (print $.Template.BasePath "/configmap-blacklist.yaml") . | sha256sum | trunc 63 }}
+ checksum.config.regex: {{ include (print $.Template.BasePath "/configmap-regex.yaml") . | sha256sum | trunc 63 }}
+ checksum.config.whitelist: {{ include (print $.Template.BasePath "/configmap-whitelist.yaml") . | sha256sum | trunc 63 }}
+ checksum.config.dnsmasqConfig: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum | trunc 63 }}
+ checksum.config.staticDhcpConfig: {{ include (print $.Template.BasePath "/configmap-static-dhcp.yaml") . | sha256sum | trunc 63 }}
+{{- with .Values.podAnnotations }}
+{{ toYaml . | indent 8 }}
+{{- end }}
+ labels:
+ app: {{ template "pihole.name" . }}
+ release: {{ .Release.Name }}
+ spec:
+ {{- if .Values.antiaff.enabled }}
+ affinity:
+ podAntiAffinity:
+ {{- if .Values.antiaff.strict }}
+ requiredDuringSchedulingIgnoredDuringExecution:
+ - labelSelector:
+ {{- else }}
+ preferredDuringSchedulingIgnoredDuringExecution:
+ - weight: 100
+ podAffinityTerm:
+ labelSelector:
+ {{- end }}
+ matchExpressions:
+ - key: release
+ operator: In
+ values:
+ - {{ .Values.antiaff.avoidRelease }}
+ {{- if .Values.antiaff.namespaces}}
+ namespaces:
+ {{- toYaml .Values.antiaff.namespaces | nindent 14 }}
+ {{- end }}
+ topologyKey: "kubernetes.io/hostname"
+ {{- end }}
+ {{- if .Values.podDnsConfig.enabled }}
+ dnsPolicy: {{ .Values.podDnsConfig.policy }}
+ dnsConfig:
+ nameservers:
+ {{- toYaml .Values.podDnsConfig.nameservers | nindent 8 }}
+ {{- end }}
+ hostname: {{ .Values.hostname }}
+ hostNetwork: {{ .Values.hostNetwork }}
+ {{- with .Values.extraInitContainers }}
+ initContainers:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ containers:
+ {{- if .Values.extraContainers }}
+ {{- toYaml .Values.extraContainers | nindent 8 }}
+ {{- end }}
+ {{- if .Values.monitoring.sidecar.enabled }}
+ - name: exporter
+ image: "{{ .Values.monitoring.sidecar.image.repository }}:{{ .Values.monitoring.sidecar.image.tag }}"
+ imagePullPolicy: {{ .Values.monitoring.sidecar.image.pullPolicy }}
+ terminationMessagePath: /dev/termination-log
+ terminationMessagePolicy: File
+ env:
+ - name: PIHOLE_HOSTNAME
+ valueFrom:
+ fieldRef:
+ fieldPath: status.podIP
+ - name: PIHOLE_PORT
+ value: "{{ .Values.webHttp }}"
+ - name: PIHOLE_PASSWORD
+ {{- if .Values.admin.enabled }}
+ valueFrom:
+ secretKeyRef:
+ key: {{ .Values.admin.passwordKey | default "password" }}
+ name: {{ .Values.admin.existingSecret | default (include "pihole.password-secret" .) }}
+ {{- else }}
+ value: ""
+ {{- end }}
+ resources:
+{{ toYaml .Values.monitoring.sidecar.resources | indent 12 }}
+ ports:
+ - containerPort: {{ .Values.monitoring.sidecar.port }}
+ name: prometheus
+ protocol: TCP
+ {{- end }}
+ {{- if .Values.doh.enabled }}
+ - name: cloudflared
+ image: "{{ .Values.doh.repository }}:{{ .Values.doh.tag }}"
+ imagePullPolicy: {{ .Values.doh.pullPolicy }}
+ terminationMessagePath: /dev/termination-log
+ terminationMessagePolicy: File
+ resources:
+ limits:
+ memory: 128Mi
+ ports:
+ - containerPort: 5053
+ name: cloudflared-udp
+ protocol: UDP
+ - containerPort: 49312
+ name: cloudflared-met
+ protocol: TCP
+ {{- if .Values.doh.envVars }}
+ env:
+ {{- range $key, $value := .Values.doh.envVars }}
+ - name: {{ $key | quote }}
+ value: {{ $value | quote }}
+ {{- end }}
+ {{- end }}
+ {{- if .Values.doh.probes.liveness.enabled }}
+ livenessProbe:
+{{ toYaml .Values.doh.probes.liveness.probe | indent 12 }}
+ initialDelaySeconds: {{ .Values.doh.probes.liveness.initialDelaySeconds }}
+ failureThreshold: {{ .Values.doh.probes.liveness.failureThreshold }}
+ timeoutSeconds: {{ .Values.doh.probes.liveness.timeoutSeconds }}
+ {{- end }}
+ {{- end }}
+ - name: {{ .Chart.Name }}
+ env:
+ - name: 'WEB_PORT'
+ value: "{{ .Values.webHttp }}"
+ - name: VIRTUAL_HOST
+ value: {{ .Values.virtualHost }}
+ - name: WEBPASSWORD
+ {{- if .Values.admin.enabled }}
+ valueFrom:
+ secretKeyRef:
+ key: {{ .Values.admin.passwordKey | default "password" }}
+ name: {{ .Values.admin.existingSecret | default (include "pihole.password-secret" .) }}
+ {{- else }}
+ value: ""
+ {{- end }}
+ {{- range $key, $value := .Values.extraEnvVars }}
+ - name: {{ $key | quote }}
+ value: {{ $value | quote }}
+ {{- end }}
+ {{- range $key, $value := .Values.extraEnvVarsSecret }}
+ - name: {{ $key | quote }}
+ valueFrom:
+ secretKeyRef:
+ key: {{ $value.key | quote }}
+ name: {{ $value.name | quote }}
+ {{- end }}
+ {{- if .Values.doh.enabled }}
+ - name: 'DNS1'
+ value: "127.0.0.1#5053"
+ - name: DNS2
+ value: "127.0.0.1#5053"
+ {{- else }}
+ {{- if .Values.DNS1 }}
+ - name: 'PIHOLE_DNS_'
+ value: {{ if .Values.DNS2 }}{{ ( printf "%v;%v" .Values.DNS1 .Values.DNS2 ) | squote }}{{ else }}{{ .Values.DNS1 | squote }}{{ end }}
+ {{- end }}
+ {{- end }}
+ {{- range $key, $value := .Values.ftl }}
+ - name: 'FTLCONF_{{ $key }}'
+ value: {{ $value | quote }}
+ {{- end }}
+ image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ securityContext:
+ privileged: {{ .Values.privileged }}
+ {{- if .Values.capabilities }}
+ capabilities:
+ {{- toYaml .Values.capabilities | nindent 14 }}
+ {{- end }}
+ ports:
+ - containerPort: {{ .Values.webHttp }}
+ name: http
+ protocol: TCP
+ - containerPort: 53
+ name: dns
+ protocol: TCP
+ {{- if .Values.dnsHostPort.enabled }}
+ hostPort: {{ .Values.dnsHostPort.port }}
+ {{- end }}
+ - containerPort: 53
+ name: dns-udp
+ protocol: UDP
+ {{- if .Values.dnsHostPort.enabled }}
+ hostPort: {{ .Values.dnsHostPort.port }}
+ {{- end }}
+ - containerPort: {{ .Values.webHttps }}
+ name: https
+ protocol: TCP
+ - containerPort: 67
+ name: client-udp
+ protocol: UDP
+ {{- if .Values.probes.liveness.enabled }}
+ livenessProbe:
+ {{- if eq .Values.probes.liveness.type "command" }}
+ exec:
+ command: {{ .Values.probes.liveness.command | required "An array of command(s) is required if 'type' is set to 'command'." | toYaml | nindent 16 }}
+ {{- else }}
+ httpGet:
+ path: /admin/index.php
+ port: {{ .Values.probes.liveness.port }}
+ scheme: {{ .Values.probes.liveness.scheme }}
+ {{- end }}
+ initialDelaySeconds: {{ .Values.probes.liveness.initialDelaySeconds }}
+ failureThreshold: {{ .Values.probes.liveness.failureThreshold }}
+ timeoutSeconds: {{ .Values.probes.liveness.timeoutSeconds }}
+
+ {{- end }}
+ {{- if .Values.probes.readiness.enabled }}
+ readinessProbe:
+ httpGet:
+ path: /admin/index.php
+ port: {{ .Values.probes.readiness.port }}
+ scheme: {{ .Values.probes.readiness.scheme }}
+ initialDelaySeconds: {{ .Values.probes.readiness.initialDelaySeconds }}
+ failureThreshold: {{ .Values.probes.readiness.failureThreshold }}
+ timeoutSeconds: {{ .Values.probes.readiness.timeoutSeconds }}
+ {{- end }}
+ volumeMounts:
+ - mountPath: /etc/pihole
+ name: config
+ {{- if .Values.persistentVolumeClaim.subPath }}
+ subPath: {{ .Values.persistentVolumeClaim.subPath }}
+ {{- end }}
+ - mountPath: /etc/dnsmasq.d/02-custom.conf
+ name: custom-dnsmasq
+ subPath: 02-custom.conf
+ - mountPath: /etc/addn-hosts
+ name: custom-dnsmasq
+ subPath: addn-hosts
+ {{- if .Values.dnsmasq.customCnameEntries }}
+ - mountPath: /etc/dnsmasq.d/05-pihole-custom-cname.conf
+ name: custom-dnsmasq
+ subPath: 05-pihole-custom-cname.conf
+ {{- end }}
+ {{- if .Values.adlists }}
+ - mountPath: /etc/pihole/adlists.list
+ name: adlists
+ subPath: adlists.list
+ {{- end }}
+ {{- if .Values.blacklist }}
+ - mountPath: /etc/pihole/blacklist.txt
+ name: blacklist
+ subPath: blacklist.txt
+ {{- end }}
+ {{- if .Values.regex }}
+ - mountPath: /etc/pihole/regex.list
+ name: regex
+ subPath: regex.list
+ {{- end }}
+ {{- if .Values.whitelist }}
+ - mountPath: /etc/pihole/whitelist.txt
+ name: whitelist
+ subPath: whitelist.txt
+ {{- end }}
+ {{- if .Values.dnsmasq.staticDhcpEntries }}
+ - mountPath: /etc/dnsmasq.d/04-pihole-static-dhcp.conf
+ name: static-dhcp
+ subPath: pihole-static-dhcp.conf
+ {{- end }}
+ {{- range $key, $value := .Values.extraVolumeMounts }}
+ - name: {{ $key }}
+{{- toYaml $value | nindent 12 }}
+ {{- end }}
+ resources:
+{{ toYaml .Values.resources | indent 12 }}
+ {{- with .Values.nodeSelector }}
+ nodeSelector:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.affinity }}
+ affinity:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- with .Values.tolerations }}
+ tolerations:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ {{- if .Values.priorityClassName }}
+ priorityClassName: "{{ .Values.priorityClassName }}"
+ {{- end }}
+ {{- with .Values.topologySpreadConstraints }}
+ topologySpreadConstraints:
+{{ toYaml . | indent 8 }}
+ {{- end }}
+ volumes:
+ - name: config
+ {{- if .Values.persistentVolumeClaim.enabled }}
+ persistentVolumeClaim:
+ claimName: {{ if .Values.persistentVolumeClaim.existingClaim }}{{ .Values.persistentVolumeClaim.existingClaim }}{{- else }}{{ template "pihole.fullname" . }}{{- end }}
+ {{- else if .Values.customVolumes.enabled }}
+{{- toYaml .Values.customVolumes.config | nindent 8 }}
+ {{- else }}
+ emptyDir: {}
+ {{- end }}
+ - configMap:
+ defaultMode: 420
+ name: {{ template "pihole.fullname" . }}-custom-dnsmasq
+ name: custom-dnsmasq
+ {{- if .Values.adlists }}
+ - configMap:
+ defaultMode: 420
+ name: {{ template "pihole.fullname" . }}-adlists
+ name: adlists
+ {{- end }}
+ {{- if .Values.whitelist }}
+ - configMap:
+ defaultMode: 420
+ name: {{ template "pihole.fullname" . }}-whitelist
+ name: whitelist
+ {{- end }}
+ {{- if .Values.dnsmasq.staticDhcpEntries }}
+ - configMap:
+ defaultMode: 420
+ name: {{ template "pihole.fullname" . }}-static-dhcp
+ name: static-dhcp
+ {{- end }}
+ {{- if .Values.blacklist }}
+ - configMap:
+ defaultMode: 420
+ name: {{ template "pihole.fullname" . }}-blacklist
+ name: blacklist
+ {{- end }}
+ {{- if .Values.regex }}
+ - configMap:
+ defaultMode: 420
+ name: {{ template "pihole.fullname" . }}-regex
+ name: regex
+ {{- end }}
+ {{- range $key, $value := .Values.extraVolumes }}
+ - name: {{ $key }}
+{{- toYaml $value | nindent 8 }}
+ {{- end }}
diff --git a/charts/pihole/templates/extra-manifests.yaml b/charts/pihole/templates/extra-manifests.yaml
new file mode 100644
index 0000000..a9bb3b6
--- /dev/null
+++ b/charts/pihole/templates/extra-manifests.yaml
@@ -0,0 +1,4 @@
+{{ range .Values.extraObjects }}
+---
+{{ tpl (toYaml .) $ }}
+{{ end }}
diff --git a/charts/pihole/templates/ingress.yaml b/charts/pihole/templates/ingress.yaml
new file mode 100644
index 0000000..fb5a081
--- /dev/null
+++ b/charts/pihole/templates/ingress.yaml
@@ -0,0 +1,38 @@
+{{- if .Values.ingress.enabled -}}
+{{- $serviceName := printf "%s-%s" (include "pihole.fullname" .) "web" -}}
+{{- $ingressPath := .Values.ingress.path -}}
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ name: {{ template "pihole.fullname" . }}
+ labels:
+ app: {{ template "pihole.name" . }}
+ chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+ {{- with .Values.ingress.annotations }}
+ annotations:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+spec:
+{{- if .Values.ingress.ingressClassName }}
+ ingressClassName: {{ .Values.ingress.ingressClassName }}
+{{- end }}
+{{- if .Values.ingress.tls }}
+ tls:
+{{ toYaml .Values.ingress.tls | indent 4 }}
+{{- end }}
+ rules:
+ {{- range .Values.ingress.hosts }}
+ - host: {{ . | quote }}
+ http:
+ paths:
+ - path: {{ $ingressPath }}
+ pathType: ImplementationSpecific
+ backend:
+ service:
+ name: {{ $serviceName }}
+ port:
+ name: http
+ {{- end }}
+{{- end }}
diff --git a/charts/pihole/templates/oauth2-proxy-config.yaml b/charts/pihole/templates/oauth2-proxy-config.yaml
deleted file mode 100644
index 5aebbb0..0000000
--- a/charts/pihole/templates/oauth2-proxy-config.yaml
+++ /dev/null
@@ -1,58 +0,0 @@
-apiVersion: dodo.cloud.dodo.cloud/v1
-kind: ResourceRenderer
-metadata:
- name: config-renderer
- namespace: {{ .Release.Namespace }}
-spec:
- secretName: {{ .Values.oauth2.secretName }}
- resourceTemplate: |
- apiVersion: v1
- kind: ConfigMap
- metadata:
- name: {{ .Values.configName }}
- namespace: {{ .Release.Namespace }}
- data:
- oauth2-proxy.cfg: |
- http_address = "0.0.0.0:8080"
-
- reverse_proxy = true
-
- ## the OAuth Redirect URL.
- # defaults to the "https://" + requested host header + "/oauth2/callback"
- # redirect_url = "http://pihole.pcloud/oauth2/callback"
-
- upstreams = [
- "http://pihole-web.{{ .Release.Namespace}}.svc"
- ]
-
- email_domains = [
- "*"
- ]
-
- standard_logging = false
- request_logging = false
- auth_logging = false
-
- pass_basic_auth = true
- pass_user_headers = true
- pass_host_header = true
-
- ## The OAuth Client ID, Secret
- client_id = "{{`{{ .client_id }}`}}"
- client_secret = "{{`{{ .client_secret }}`}}"
-
- ## Pass OAuth Access token to upstream via "X-Forwarded-Access-Token"
- pass_access_token = false
-
- cookie_name = "_oauth2_proxy_pihole"
- cookie_secret = "{{ .Values.oauth2.cookieSecret }}"
- cookie_domains = "{{ .Values.domain }}"
- cookie_expire = "168h"
- cookie_refresh = "100h"
- cookie_secure = true
- cookie_httponly = true
-
- provider = "oidc"
- oidc_issuer_url = "{{ .Values.oauth2.issuer }}"
- provider_display_name = "PCloud"
- profile_url = "{{ .Values.profileUrl }}"
diff --git a/charts/pihole/templates/oauth2-proxy.yaml b/charts/pihole/templates/oauth2-proxy.yaml
deleted file mode 100644
index 2d62f7b..0000000
--- a/charts/pihole/templates/oauth2-proxy.yaml
+++ /dev/null
@@ -1,84 +0,0 @@
----
-apiVersion: v1
-kind: Service
-metadata:
- name: pihole-oauth2-proxy
- namespace: {{ .Release.Namespace }}
-spec:
- type: ClusterIP
- selector:
- app: pihole-oauth2-proxy
- ports:
- - name: http
- port: 80
- targetPort: http
- protocol: TCP
----
-apiVersion: networking.k8s.io/v1
-kind: Ingress
-metadata:
- name: ingress
- namespace: {{ .Release.Namespace }}
-spec:
- ingressClassName: {{ .Values.ingressClassName }}
- tls:
- - hosts:
- - {{ .Values.domain }}
- rules:
- - host: {{ .Values.domain }}
- http:
- paths:
- - path: /
- pathType: Prefix
- backend:
- service:
- name: pihole-oauth2-proxy
- port:
- name: http
----
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: pihole-oauth2-proxy
- namespace: {{ .Release.Namespace }}
-spec:
- selector:
- matchLabels:
- app: pihole-oauth2-proxy
- replicas: 1
- template:
- metadata:
- labels:
- app: pihole-oauth2-proxy
- spec:
- volumes:
- - name: config
- configMap:
- name: {{ .Values.configName }}
- containers:
- - name: pihole-oauth2-proxy
- image: quay.io/oauth2-proxy/oauth2-proxy:v7.2.0
- imagePullPolicy: Always
- ports:
- - name: http
- containerPort: 8080
- protocol: TCP
- command:
- - oauth2-proxy
- - --config=/etc/oauth2-proxy/oauth2-proxy.cfg
- volumeMounts:
- - name: config
- mountPath: /etc/oauth2-proxy
- readOnly: true
- resources:
- requests:
- memory: "10Mi"
- cpu: "10m"
- limits:
- memory: "20Mi"
- cpu: "100m"
- tolerations:
- - key: "pcloud"
- operator: "Equal"
- value: "role"
- effect: "NoSchedule"
diff --git a/charts/pihole/templates/pdb.yaml b/charts/pihole/templates/pdb.yaml
new file mode 100644
index 0000000..5103178
--- /dev/null
+++ b/charts/pihole/templates/pdb.yaml
@@ -0,0 +1,21 @@
+{{- if .Values.podDisruptionBudget.enabled -}}
+apiVersion: policy/v1
+kind: PodDisruptionBudget
+metadata:
+ name: {{ template "pihole.fullname" . }}-pdb
+ labels:
+ app: {{ template "pihole.name" . }}
+ chart: {{ template "pihole.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+spec:
+{{- if .Values.podDisruptionBudget.minAvailable }}
+ minAvailable: {{ .Values.podDisruptionBudget.minAvailable }}
+{{- end }}
+{{- if .Values.podDisruptionBudget.maxUnavailable }}
+ maxUnavailable: {{ .Values.podDisruptionBudget.maxUnavailable }}
+{{- end }}
+ selector:
+ matchLabels:
+ app: {{ template "pihole.name" . }}
+{{- end }}
diff --git a/charts/pihole/templates/podmonitor.yaml b/charts/pihole/templates/podmonitor.yaml
new file mode 100644
index 0000000..bb3be7d
--- /dev/null
+++ b/charts/pihole/templates/podmonitor.yaml
@@ -0,0 +1,43 @@
+{{- if .Values.monitoring.podMonitor.enabled }}
+apiVersion: monitoring.coreos.com/v1
+kind: PodMonitor
+metadata:
+ labels:
+ app: {{ template "pihole.name" . }}
+ chart: {{ template "pihole.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+ {{- with .Values.monitoring.podMonitor.labels }}
+ {{- . | toYaml | nindent 4 }}
+ {{- end }}
+ name: {{ template "pihole.fullname" . }}-prometheus-exporter
+{{- if .Values.monitoring.podMonitor.namespace }}
+ namespace: {{ .Values.monitoring.podMonitor.namespace }}
+{{- end }}
+spec:
+ podMetricsEndpoints:
+ - port: prometheus
+ path: /metrics
+{{- if .Values.monitoring.podMonitor.interval }}
+ interval: {{ .Values.monitoring.podMonitor.interval }}
+{{- end }}
+{{- if .Values.monitoring.podMonitor.bearerTokenFile }}
+ bearerTokenFile: {{ .Values.monitoring.podMonitor.bearerTokenFile }}
+{{- end }}
+{{- if .Values.monitoring.podMonitor.bearerTokenSecret }}
+ bearerTokenSecret:
+ name: {{ .Values.monitoring.podMonitor.bearerTokenSecret.name }}
+ key: {{ .Values.monitoring.podMonitor.bearerTokenSecret.key }}
+ {{- if .Values.monitoring.podMonitor.bearerTokenSecret.optional }}
+ optional: {{ .Values.monitoring.podMonitor.bearerTokenSecret.optional }}
+ {{- end }}
+{{- end }}
+ jobLabel: {{ template "pihole.fullname" . }}-prometheus-exporter
+ namespaceSelector:
+ matchNames:
+ - {{ .Release.Namespace }}
+ selector:
+ matchLabels:
+ app: {{ template "pihole.name" . }}
+ release: {{ .Release.Name }}
+{{- end }}
diff --git a/charts/pihole/templates/secret.yaml b/charts/pihole/templates/secret.yaml
new file mode 100644
index 0000000..e603cbb
--- /dev/null
+++ b/charts/pihole/templates/secret.yaml
@@ -0,0 +1,18 @@
+{{- if and .Values.admin.enabled (not .Values.admin.existingSecret) }}
+apiVersion: v1
+kind: Secret
+metadata:
+ name: {{ template "pihole.password-secret" . }}
+ labels:
+ app: {{ template "pihole.name" . }}
+ chart: {{ template "pihole.chart" . }}
+ heritage: {{ .Release.Service }}
+ release: {{ .Release.Name }}
+type: Opaque
+data:
+ {{- if .Values.adminPassword }}
+ password: {{ .Values.adminPassword | b64enc | quote }}
+ {{- else }}
+ password: {{ randAlphaNum 40 | b64enc | quote }}
+ {{- end }}
+{{- end }}
diff --git a/charts/pihole/templates/service-dhcp.yaml b/charts/pihole/templates/service-dhcp.yaml
new file mode 100644
index 0000000..3df2ad9
--- /dev/null
+++ b/charts/pihole/templates/service-dhcp.yaml
@@ -0,0 +1,75 @@
+{{- if .Values.serviceDhcp.enabled }}
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ template "pihole.fullname" . }}-dhcp
+ labels:
+ app: {{ template "pihole.name" . }}
+ chart: {{ template "pihole.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+{{- if .Values.serviceDhcp.annotations }}
+ annotations:
+{{ toYaml .Values.serviceDhcp.annotations | indent 4 }}
+{{- end }}
+spec:
+ type: {{ .Values.serviceDhcp.type }}
+ {{- if and (.Values.dualStack.enabled) (not (eq .Values.serviceDhcp.type "LoadBalancer")) }}
+ ipFamilies:
+ - IPv4
+ - IPv6
+ ipFamilyPolicy: PreferDualStack
+ {{- end }}
+ {{- if .Values.serviceDhcp.loadBalancerIP }}
+ loadBalancerIP: {{ .Values.serviceDhcp.loadBalancerIP }}
+ {{- end }}
+ {{- if or (eq .Values.serviceDhcp.type "NodePort") (eq .Values.serviceDhcp.type "LoadBalancer") }}
+ externalTrafficPolicy: {{ .Values.serviceDhcp.externalTrafficPolicy }}
+ {{- end }}
+ ports:
+ - port: {{ .Values.serviceDhcp.port }}
+ targetPort: client-udp
+ {{- if and (.Values.serviceDhcp.nodePort) (eq .Values.serviceDhcp.type "NodePort") }}
+ nodePort: {{ .Values.serviceDhcp.nodePort }}
+ {{- end }}
+ protocol: UDP
+ name: client-udp
+ selector:
+ app: {{ template "pihole.name" . }}
+ release: {{ .Release.Name }}
+---
+{{- if and (.Values.dualStack.enabled) (eq .Values.serviceDhcp.type "LoadBalancer") -}}
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ template "pihole.fullname" . }}-dhcp-ivp6
+ labels:
+ app: {{ template "pihole.name" . }}
+ chart: {{ template "pihole.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+{{- if .Values.serviceDhcp.annotations }}
+ annotations:
+{{ toYaml .Values.serviceDhcp.annotations | indent 4 }}
+{{- end }}
+spec:
+ type: {{ .Values.serviceDhcp.type }}
+ ipFamilies:
+ - IPv6
+ ipFamilyPolicy: SingleStack
+ {{- if .Values.serviceDhcp.loadBalancerIPv6 }}
+ loadBalancerIP: {{ .Values.serviceDhcp.loadBalancerIPv6 }}
+ {{- end }}
+ {{- if or (eq .Values.serviceDhcp.type "NodePort") (eq .Values.serviceDhcp.type "LoadBalancer") }}
+ externalTrafficPolicy: {{ .Values.serviceDhcp.externalTrafficPolicy }}
+ {{- end }}
+ ports:
+ - port: 67
+ targetPort: client-udp
+ protocol: UDP
+ name: client-udp
+ selector:
+ app: {{ template "pihole.name" . }}
+ release: {{ .Release.Name }}
+{{- end }}
+{{- end }}
diff --git a/charts/pihole/templates/service-dns-tcp.yaml b/charts/pihole/templates/service-dns-tcp.yaml
new file mode 100644
index 0000000..9206260
--- /dev/null
+++ b/charts/pihole/templates/service-dns-tcp.yaml
@@ -0,0 +1,87 @@
+{{- if not .Values.serviceDns.mixedService }}
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ template "pihole.fullname" . }}-dns-tcp
+ labels:
+ app: {{ template "pihole.name" . }}
+ chart: {{ template "pihole.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+{{- if .Values.serviceDns.annotations }}
+ annotations:
+{{ toYaml .Values.serviceDns.annotations | indent 4 }}
+{{- end }}
+spec:
+ type: {{ .Values.serviceDns.type }}
+ {{- if and (.Values.dualStack.enabled) (not (eq .Values.serviceDns.type "LoadBalancer")) }}
+ ipFamilies:
+ - IPv4
+ - IPv6
+ ipFamilyPolicy: PreferDualStack
+ {{- end }}
+ {{- if .Values.serviceDns.loadBalancerIP }}
+ loadBalancerIP: {{ .Values.serviceDns.loadBalancerIP }}
+ {{- end }}
+ {{- if or (eq .Values.serviceDns.type "NodePort") (eq .Values.serviceDns.type "LoadBalancer") }}
+ externalTrafficPolicy: {{ .Values.serviceDns.externalTrafficPolicy }}
+ {{- end }}
+ ports:
+ - port: {{ .Values.serviceDns.port }}
+ targetPort: dns
+ {{- if and (.Values.serviceDns.nodePort) (eq .Values.serviceDns.type "NodePort") }}
+ nodePort: {{ .Values.serviceDns.nodePort }}
+ {{- end }}
+ protocol: TCP
+ name: dns
+ {{- if .Values.monitoring.sidecar.enabled }}
+ - port: {{ .Values.monitoring.sidecar.port }}
+ targetPort: prometheus
+ protocol: TCP
+ name: prometheus
+ {{- end }}
+ selector:
+ app: {{ template "pihole.name" . }}
+ release: {{ .Release.Name }}
+---
+{{- if and (.Values.dualStack.enabled) (eq .Values.serviceDns.type "LoadBalancer") -}}
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ template "pihole.fullname" . }}-dns-tcp-ipv6
+ labels:
+ app: {{ template "pihole.name" . }}
+ chart: {{ template "pihole.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+{{- if .Values.serviceDns.annotations }}
+ annotations:
+{{ toYaml .Values.serviceDns.annotations | indent 4 }}
+{{- end }}
+spec:
+ type: {{ .Values.serviceDns.type }}
+ ipFamilies:
+ - IPv6
+ ipFamilyPolicy: SingleStack
+ {{- if .Values.serviceDns.loadBalancerIPv6 }}
+ loadBalancerIP: {{ .Values.serviceDns.loadBalancerIPv6 }}
+ {{- end }}
+ {{- if or (eq .Values.serviceDns.type "NodePort") (eq .Values.serviceDns.type "LoadBalancer") }}
+ externalTrafficPolicy: {{ .Values.serviceDns.externalTrafficPolicy }}
+ {{- end }}
+ ports:
+ - port: {{ .Values.serviceDns.port }}
+ targetPort: dns
+ protocol: TCP
+ name: dns
+ {{- if .Values.monitoring.sidecar.enabled }}
+ - port: {{ .Values.monitoring.sidecar.port }}
+ targetPort: prometheus
+ protocol: TCP
+ name: prometheus
+ {{- end }}
+ selector:
+ app: {{ template "pihole.name" . }}
+ release: {{ .Release.Name }}
+{{- end }}
+{{- end }}
diff --git a/charts/pihole/templates/service-dns-udp.yaml b/charts/pihole/templates/service-dns-udp.yaml
new file mode 100644
index 0000000..34835d4
--- /dev/null
+++ b/charts/pihole/templates/service-dns-udp.yaml
@@ -0,0 +1,75 @@
+{{- if not .Values.serviceDns.mixedService }}
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ template "pihole.fullname" . }}-dns-udp
+ labels:
+ app: {{ template "pihole.name" . }}
+ chart: {{ template "pihole.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+{{- if .Values.serviceDns.annotations }}
+ annotations:
+{{ toYaml .Values.serviceDns.annotations | indent 4 }}
+{{- end }}
+spec:
+ type: {{ .Values.serviceDns.type }}
+ {{- if and (.Values.dualStack.enabled) (not (eq .Values.serviceDns.type "LoadBalancer")) }}
+ ipFamilies:
+ - IPv4
+ - IPv6
+ ipFamilyPolicy: PreferDualStack
+ {{- end }}
+ {{- if .Values.serviceDns.loadBalancerIP }}
+ loadBalancerIP: {{ .Values.serviceDns.loadBalancerIP }}
+ {{- end }}
+ {{- if or (eq .Values.serviceDns.type "NodePort") (eq .Values.serviceDns.type "LoadBalancer") }}
+ externalTrafficPolicy: {{ .Values.serviceDns.externalTrafficPolicy }}
+ {{- end }}
+ ports:
+ - port: {{ .Values.serviceDns.port }}
+ targetPort: dns-udp
+ {{- if and (.Values.serviceDns.nodePort) (eq .Values.serviceDns.type "NodePort") }}
+ nodePort: {{ .Values.serviceDns.nodePort }}
+ {{- end }}
+ protocol: UDP
+ name: dns-udp
+ selector:
+ app: {{ template "pihole.name" . }}
+ release: {{ .Release.Name }}
+---
+{{- if and (.Values.dualStack.enabled) (eq .Values.serviceDns.type "LoadBalancer") -}}
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ template "pihole.fullname" . }}-dns-udp-ipv6
+ labels:
+ app: {{ template "pihole.name" . }}
+ chart: {{ template "pihole.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+{{- if .Values.serviceDns.annotations }}
+ annotations:
+{{ toYaml .Values.serviceDns.annotations | indent 4 }}
+{{- end }}
+spec:
+ type: {{ .Values.serviceDns.type }}
+ ipFamilies:
+ - IPv6
+ ipFamilyPolicy: SingleStack
+ {{- if .Values.serviceDns.loadBalancerIPv6 }}
+ loadBalancerIP: {{ .Values.serviceDns.loadBalancerIPv6 }}
+ {{- end }}
+ {{- if or (eq .Values.serviceDns.type "NodePort") (eq .Values.serviceDns.type "LoadBalancer") }}
+ externalTrafficPolicy: {{ .Values.serviceDns.externalTrafficPolicy }}
+ {{- end }}
+ ports:
+ - port: {{ .Values.serviceDns.port }}
+ targetPort: dns-udp
+ protocol: UDP
+ name: dns-udp
+ selector:
+ app: {{ template "pihole.name" . }}
+ release: {{ .Release.Name }}
+{{- end }}
+{{- end }}
diff --git a/charts/pihole/templates/service-dns.yaml b/charts/pihole/templates/service-dns.yaml
new file mode 100644
index 0000000..0772138
--- /dev/null
+++ b/charts/pihole/templates/service-dns.yaml
@@ -0,0 +1,92 @@
+{{- if .Values.serviceDns.mixedService }}
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ template "pihole.fullname" . }}-dns
+ labels:
+ app: {{ template "pihole.name" . }}
+ chart: {{ template "pihole.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+{{- if .Values.serviceDns.annotations }}
+ annotations:
+{{ toYaml .Values.serviceDns.annotations | indent 4 }}
+{{- end }}
+spec:
+ type: {{ .Values.serviceDns.type }}
+ {{- if .Values.serviceDns.loadBalancerIP }}
+ loadBalancerIP: {{ .Values.serviceDns.loadBalancerIP }}
+ {{- end }}
+ {{- if or (eq .Values.serviceDns.type "NodePort") (eq .Values.serviceDns.type "LoadBalancer") }}
+ externalTrafficPolicy: {{ .Values.serviceDns.externalTrafficPolicy }}
+ {{- end }}
+ ports:
+ - port: {{ .Values.serviceDns.port }}
+ targetPort: dns
+ {{- if .Values.serviceDns.nodePort }}
+ nodePort: {{ .Values.serviceDns.nodePort }}
+ {{- end }}
+ protocol: TCP
+ name: dns
+ - port: {{ .Values.serviceDns.port }}
+ targetPort: dns-udp
+ {{- if and (.Values.serviceDns.nodePort) (eq .Values.serviceDns.type "NodePort") }}
+ nodePort: {{ .Values.serviceDns.nodePort }}
+ {{- end }}
+ protocol: UDP
+ name: dns-udp
+ {{- if .Values.monitoring.sidecar.enabled }}
+ - port: {{ .Values.monitoring.sidecar.port }}
+ targetPort: prometheus
+ protocol: TCP
+ name: prometheus
+ {{- end }}
+ selector:
+ app: {{ template "pihole.name" . }}
+ release: {{ .Release.Name }}
+---
+{{- if and (.Values.dualStack.enabled) (eq .Values.serviceDns.type "LoadBalancer") -}}
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ template "pihole.fullname" . }}-dns-ipv6
+ labels:
+ app: {{ template "pihole.name" . }}
+ chart: {{ template "pihole.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+{{- if .Values.serviceDns.annotations }}
+ annotations:
+{{ toYaml .Values.serviceDns.annotations | indent 4 }}
+{{- end }}
+spec:
+ type: {{ .Values.serviceDns.type }}
+ ipFamilies:
+ - IPv6
+ ipFamilyPolicy: SingleStack
+ {{- if .Values.serviceDns.loadBalancerIPv6 }}
+ loadBalancerIP: {{ .Values.serviceDns.loadBalancerIPv6 }}
+ {{- end }}
+ {{- if or (eq .Values.serviceDns.type "NodePort") (eq .Values.serviceDns.type "LoadBalancer") }}
+ externalTrafficPolicy: {{ .Values.serviceDns.externalTrafficPolicy }}
+ {{- end }}
+ ports:
+ - port: {{ .Values.serviceDns.port }}
+ targetPort: dns
+ protocol: TCP
+ name: dns
+ - port: {{ .Values.serviceDns.port }}
+ targetPort: dns-udp
+ protocol: UDP
+ name: dns-udp
+ {{- if .Values.monitoring.sidecar.enabled }}
+ - port: {{ .Values.monitoring.sidecar.port }}
+ targetPort: prometheus
+ protocol: TCP
+ name: prometheus
+ {{- end }}
+ selector:
+ app: {{ template "pihole.name" . }}
+ release: {{ .Release.Name }}
+{{- end }}
+{{- end }}
diff --git a/charts/pihole/templates/service-web.yaml b/charts/pihole/templates/service-web.yaml
new file mode 100644
index 0000000..ace4603
--- /dev/null
+++ b/charts/pihole/templates/service-web.yaml
@@ -0,0 +1,102 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ template "pihole.fullname" . }}-web
+ labels:
+ app: {{ template "pihole.name" . }}
+ chart: {{ template "pihole.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+{{- if .Values.serviceWeb.annotations }}
+ annotations:
+{{ toYaml .Values.serviceWeb.annotations | indent 4 }}
+{{- end }}
+spec:
+ type: {{ .Values.serviceWeb.type }}
+ {{- if and (.Values.dualStack.enabled) (not (eq .Values.serviceWeb.type "LoadBalancer")) }}
+ ipFamilies:
+ - IPv4
+ - IPv6
+ ipFamilyPolicy: PreferDualStack
+ {{- end }}
+ {{- if .Values.serviceWeb.loadBalancerIP }}
+ loadBalancerIP: {{ .Values.serviceWeb.loadBalancerIP }}
+ {{- end }}
+ {{- if or (eq .Values.serviceWeb.type "NodePort") (eq .Values.serviceWeb.type "LoadBalancer") }}
+ externalTrafficPolicy: {{ .Values.serviceWeb.externalTrafficPolicy }}
+ {{- end }}
+ ports:
+ {{- if .Values.serviceWeb.http.enabled }}
+ - port: {{ .Values.serviceWeb.http.port }}
+ targetPort: http
+ {{- if and (.Values.serviceWeb.http.nodePort) (eq .Values.serviceWeb.type "NodePort") }}
+ nodePort: {{ .Values.serviceWeb.http.nodePort }}
+ {{- end }}
+ protocol: TCP
+ name: http
+ {{- end }}
+ {{- if .Values.serviceWeb.https.enabled }}
+ - port: {{ .Values.serviceWeb.https.port }}
+ targetPort: https
+ {{- if and (.Values.serviceWeb.https.nodePort) (eq .Values.serviceWeb.type "NodePort") }}
+ nodePort: {{ .Values.serviceWeb.https.nodePort }}
+ {{- end }}
+ protocol: TCP
+ name: https
+ {{- end }}
+ {{- if .Values.doh.enabled }}
+ - port: 49312
+ protocol: TCP
+ name: cloudflared-met
+ {{- end }}
+ selector:
+ app: {{ template "pihole.name" . }}
+ release: {{ .Release.Name }}
+---
+{{- if and (.Values.dualStack.enabled) (eq .Values.serviceWeb.type "LoadBalancer") -}}
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ template "pihole.fullname" . }}-web-ipv6
+ labels:
+ app: {{ template "pihole.name" . }}
+ chart: {{ template "pihole.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+{{- if .Values.serviceWeb.annotations }}
+ annotations:
+{{ toYaml .Values.serviceWeb.annotations | indent 4 }}
+{{- end }}
+spec:
+ type: {{ .Values.serviceWeb.type }}
+ ipFamilies:
+ - IPv6
+ ipFamilyPolicy: SingleStack
+ {{- if .Values.serviceWeb.loadBalancerIPv6 }}
+ loadBalancerIP: {{ .Values.serviceWeb.loadBalancerIPv6 }}
+ {{- end }}
+ {{- if or (eq .Values.serviceWeb.type "NodePort") (eq .Values.serviceWeb.type "LoadBalancer") }}
+ externalTrafficPolicy: {{ .Values.serviceWeb.externalTrafficPolicy }}
+ {{- end }}
+ ports:
+ {{- if .Values.serviceWeb.http.enabled }}
+ - port: {{ .Values.serviceWeb.http.port }}
+ targetPort: http
+ protocol: TCP
+ name: http
+ {{- end }}
+ {{- if .Values.serviceWeb.https.enabled }}
+ - port: {{ .Values.serviceWeb.https.port }}
+ targetPort: https
+ protocol: TCP
+ name: https
+ {{- end }}
+ {{- if .Values.doh.enabled }}
+ - port: 49312
+ protocol: TCP
+ name: cloudflared-met
+ {{- end }}
+ selector:
+ app: {{ template "pihole.name" . }}
+ release: {{ .Release.Name }}
+{{- end }}
diff --git a/charts/pihole/templates/tests/test-pihole-endpoint.yml b/charts/pihole/templates/tests/test-pihole-endpoint.yml
new file mode 100644
index 0000000..dd50c04
--- /dev/null
+++ b/charts/pihole/templates/tests/test-pihole-endpoint.yml
@@ -0,0 +1,14 @@
+apiVersion: v1
+kind: Pod
+metadata:
+ name: "{{ .Release.Name }}-smoke-test"
+ annotations:
+ "helm.sh/hook": test
+spec:
+ containers:
+ - name: hook1-container
+ image: curlimages/curl
+ imagePullPolicy: IfNotPresent
+ command: ['sh', '-c', 'curl http://{{ template "pihole.fullname" . }}-web:80/']
+ restartPolicy: Never
+ terminationGracePeriodSeconds: 0
diff --git a/charts/pihole/templates/volume-claim.yaml b/charts/pihole/templates/volume-claim.yaml
new file mode 100644
index 0000000..3b140be
--- /dev/null
+++ b/charts/pihole/templates/volume-claim.yaml
@@ -0,0 +1,31 @@
+{{- if .Values.persistentVolumeClaim.enabled -}}
+{{- if not .Values.persistentVolumeClaim.existingClaim -}}
+apiVersion: "v1"
+kind: "PersistentVolumeClaim"
+metadata:
+{{- if .Values.persistentVolumeClaim.annotations }}
+ annotations:
+{{ toYaml .Values.persistentVolumeClaim.annotations | indent 4 }}
+{{- end }}
+ labels:
+ app: {{ template "pihole.name" . }}
+ chart: {{ .Chart.Name }}-{{ .Chart.Version }}
+ component: "{{ .Values.persistentVolumeClaim.name }}"
+ heritage: {{ .Release.Service }}
+ release: {{ .Release.Name }}
+ name: {{ template "pihole.fullname" . }}
+spec:
+ accessModes:
+{{ toYaml .Values.persistentVolumeClaim.accessModes | indent 4 }}
+{{- if .Values.persistentVolumeClaim.storageClass }}
+{{- if (eq "-" .Values.persistentVolumeClaim.storageClass) }}
+ storageClassName: ""
+{{- else }}
+ storageClassName: "{{ .Values.persistentVolumeClaim.storageClass }}"
+{{- end }}
+{{- end }}
+ resources:
+ requests:
+ storage: "{{ .Values.persistentVolumeClaim.size }}"
+{{- end -}}
+{{- end -}}
\ No newline at end of file
diff --git a/charts/pihole/values.yaml b/charts/pihole/values.yaml
index 542fcd3..6a6d32e 100644
--- a/charts/pihole/values.yaml
+++ b/charts/pihole/values.yaml
@@ -1,11 +1,538 @@
-pihole: {}
-oauth2:
- cookieSecret: "1234123443214321"
- secretName: oauth2-client
- issuer: https://oidc-issuer.example.com
-configName: oauth2-proxy
-domain: pihole.p.example.com
-profileUrl: https://profile.example.com
-ingressClassName: private
+# Default values for pihole.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+# -- The number of replicas
+replicaCount: 1
+# -- The `spec.strategyTpye` for updates
+strategyType: RollingUpdate
+
+# -- The maximum number of Pods that can be created over the desired number of `ReplicaSet` during updating.
+maxSurge: 1
+
+# -- The maximum number of Pods that can be unavailable during updating
+maxUnavailable: 1
+
+image:
+ # -- the repostory to pull the image from
+ repository: "pihole/pihole"
+ # -- the docker tag, if left empty it will get it from the chart's appVersion
+ tag: ""
+ # -- the pull policy
+ pullPolicy: IfNotPresent
+
+dualStack:
+ # -- set this to true to enable creation of DualStack services or creation of separate IPv6 services if `serviceDns.type` is set to `"LoadBalancer"`
+ enabled: false
+
+dnsHostPort:
+ # -- set this to true to enable dnsHostPort
+ enabled: false
+ # -- default port for this pod
+ port: 53
+
+# -- Configuration for the DNS service on port 53
+serviceDns:
+ # -- deploys a mixed (TCP + UDP) Service instead of separate ones
+ mixedService: false
+
+ # -- `spec.type` for the DNS Service
+ type: NodePort
+
+ # -- The port of the DNS service
+ port: 53
+
+ # -- Optional node port for the DNS service
+ nodePort: ""
+
+ # -- `spec.externalTrafficPolicy` for the DHCP Service
+ externalTrafficPolicy: Local
+
+ # -- A fixed `spec.loadBalancerIP` for the DNS Service
+ loadBalancerIP: ""
+ # -- A fixed `spec.loadBalancerIP` for the IPv6 DNS Service
+ loadBalancerIPv6: ""
+
+ # -- Annotations for the DNS service
+ annotations:
+ {}
+ # metallb.universe.tf/address-pool: network-services
+ # metallb.universe.tf/allow-shared-ip: pihole-svc
+
+# -- Configuration for the DHCP service on port 67
+serviceDhcp:
+ # -- Generate a Service resource for DHCP traffic
+ enabled: true
+
+ # -- `spec.type` for the DHCP Service
+ type: NodePort
+
+ # -- The port of the DHCP service
+ port: 67
+
+ # -- Optional node port for the DHCP service
+ nodePort: ""
+
+ # -- `spec.externalTrafficPolicy` for the DHCP Service
+ externalTrafficPolicy: Local
+
+ # -- A fixed `spec.loadBalancerIP` for the DHCP Service
+ loadBalancerIP: ""
+ # -- A fixed `spec.loadBalancerIP` for the IPv6 DHCP Service
+ loadBalancerIPv6: ""
+
+ # -- Annotations for the DHCP service
+ annotations:
+ {}
+ # metallb.universe.tf/address-pool: network-services
+ # metallb.universe.tf/allow-shared-ip: pihole-svc
+
+# -- Configuration for the web interface service
+serviceWeb:
+ # -- Configuration for the HTTP web interface listener
+ http:
+ # -- Generate a service for HTTP traffic
+ enabled: true
+
+ # -- The port of the web HTTP service
+ port: 80
+
+ # -- Optional node port for the web HTTP service
+ nodePort: ""
+
+ # -- Configuration for the HTTPS web interface listener
+ https:
+ # -- Generate a service for HTTPS traffic
+ enabled: true
+
+ # -- The port of the web HTTPS service
+ port: 443
+
+ # -- Optional node port for the web HTTPS service
+ nodePort: ""
+
+ # -- `spec.type` for the web interface Service
+ type: ClusterIP
+
+ # -- `spec.externalTrafficPolicy` for the web interface Service
+ externalTrafficPolicy: Local
+
+ # -- A fixed `spec.loadBalancerIP` for the web interface Service
+ loadBalancerIP: ""
+ # -- A fixed `spec.loadBalancerIP` for the IPv6 web interface Service
+ loadBalancerIPv6: ""
+
+ # -- Annotations for the DHCP service
+ annotations:
+ {}
+ # metallb.universe.tf/address-pool: network-services
+ # metallb.universe.tf/allow-shared-ip: pihole-svc
+
+virtualHost: pi.hole
+
+# -- Configuration for the Ingress
+ingress:
+ # -- Generate a Ingress resource
+ enabled: false
+
+ # -- Specify an ingressClassName
+ # ingressClassName: nginx
+
+ # -- Annotations for the ingress
+ annotations:
+ {}
+ # kubernetes.io/ingress.class: nginx
+ # kubernetes.io/tls-acme: "true"
+ path: /
+ hosts:
+ # virtualHost (default value is pi.hole) will be appended to the hosts
+ - chart-example.local
+ tls: []
+ # - secretName: chart-example-tls
+ # hosts:
+ # #- virtualHost (default value is pi.hole) will be appended to the hosts
+ # - chart-example.local
+
+# -- Probes configuration
+probes:
+ # -- probes.liveness -- Configure the healthcheck for the ingress controller
+ liveness:
+ # -- Generate a liveness probe
+ # 'type' defaults to httpGet, can be set to 'command' to use a command type liveness probe.
+ type: httpGet
+ # command:
+ # - /bin/bash
+ # - -c
+ # - /bin/true
+ enabled: true
+ initialDelaySeconds: 60
+ failureThreshold: 10
+ timeoutSeconds: 5
+ port: http
+ scheme: HTTP
+ readiness:
+ # -- Generate a readiness probe
+ enabled: true
+ initialDelaySeconds: 60
+ failureThreshold: 3
+ timeoutSeconds: 5
+ port: http
+ scheme: HTTP
+
+# -- 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:'.
+resources:
+ {}
+ # limits:
+ # cpu: 100m
+ # memory: 128Mi
+ # requests:
+ # cpu: 100m
+ # memory: 128Mi
+
+# -- `spec.PersitentVolumeClaim` configuration
+persistentVolumeClaim:
+ # -- set to true to use pvc
+ enabled: false
+
+ # -- specify an existing `PersistentVolumeClaim` to use
+ # existingClaim: ""
+
+ # -- Annotations for the `PersitentVolumeClaim`
+ annotations: {}
+
+ accessModes:
+ - ReadWriteOnce
+
+ size: "500Mi"
+
+ ## If defined, storageClassName: <storageClass>
+ ## If set to "-", storageClassName: "", which disables dynamic provisioning
+ ## If undefined (the default) or set to null, no storageClassName spec is
+ ## set, choosing the default provisioner. (gp2 on AWS, standard on
+ ## GKE, AWS & OpenStack)
+ ##
+ # storageClass: "-"
+
+ ## If subPath is set mount a sub folder of a volume instead of the root of the volume.
+ ## This is especially handy for volume plugins that don't natively support sub mounting (like glusterfs).
+
+ ## subPath: "pihole"
+
+nodeSelector: {}
+
+tolerations: []
+
+# -- Specify a priorityClassName
+# priorityClassName: ""
+
+# Reference: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/
+topologySpreadConstraints: []
+# - maxSkew: <integer>
+# topologyKey: <string>
+# whenUnsatisfiable: <string>
+# labelSelector: <object>
+
+affinity: {}
+
+# -- Administrator password when not using an existing secret (see below)
+adminPassword: "admin"
+
+# -- Use an existing secret for the admin password.
+admin:
+ # -- If set to false admin password will be disabled, adminPassword specified above and the pre-existing secret (if specified) will be ignored.
+ enabled: true
+ # -- Specify an existing secret to use as admin password
+ existingSecret: ""
+ # -- Specify the key inside the secret to use
+ passwordKey: "password"
+
+# -- extraEnvironmentVars is a list of extra enviroment variables to set for pihole to use
+extraEnvVars:
+ {}
+ # TZ: UTC
+
+# -- extraEnvVarsSecret is a list of secrets to load in as environment variables.
+extraEnvVarsSecret:
+ {}
+ # env_var:
+ # name: secret-name
+ # key: secret-key
+
+# -- default upstream DNS 1 server to use
+DNS1: "8.8.8.8"
+# -- default upstream DNS 2 server to use
+DNS2: "8.8.4.4"
+
+antiaff:
+ # -- set to true to enable antiaffinity (example: 2 pihole DNS in the same cluster)
+ enabled: false
+ # -- Here you can set the pihole release (you set in `helm install <releasename> ...`)
+ # you want to avoid
+ avoidRelease: pihole1
+ # -- Here you can choose between preferred or required
+ strict: true
+ # -- Here you can pass namespaces to be part of those inclueded in anti-affinity
+ namespaces: []
+
+doh:
+ # -- set to true to enabled DNS over HTTPs via cloudflared
+ enabled: false
+ name: "cloudflared"
+ repository: "crazymax/cloudflared"
+ tag: latest
+ pullPolicy: IfNotPresent
+ # -- Here you can pass environment variables to the DoH container, for example:
+ envVars:
+ {}
+ # TUNNEL_DNS_UPSTREAM: "https://1.1.1.2/dns-query,https://1.0.0.2/dns-query"
+
+ # -- Probes configuration
+ probes:
+ # -- Configure the healthcheck for the doh container
+ liveness:
+ # -- set to true to enable liveness probe
+ enabled: true
+ # -- customize the liveness probe
+ probe:
+ exec:
+ command:
+ - nslookup
+ - -po=5053
+ - cloudflare.com
+ - "127.0.0.1"
+ # -- defines the initial delay for the liveness probe
+ initialDelaySeconds: 60
+ # -- defines the failure threshold for the liveness probe
+ failureThreshold: 10
+ # -- defines the timeout in secondes for the liveness probe
+ timeoutSeconds: 5
+
+dnsmasq:
+ # -- Add upstream dns servers. All lines will be added to the pihole dnsmasq configuration
+ upstreamServers: []
+ # - server=/foo.bar/192.168.178.10
+ # - server=/bar.foo/192.168.178.11
+
+ # -- Add custom dns entries to override the dns resolution. All lines will be added to the pihole dnsmasq configuration.
+ customDnsEntries: []
+ # - address=/foo.bar/192.168.178.10
+ # - address=/bar.foo/192.168.178.11
+
+ # -- Dnsmasq reads the /etc/hosts file to resolve ips. You can add additional entries if you like
+ additionalHostsEntries: []
+ # - 192.168.0.3 host4
+ # - 192.168.0.4 host5
+
+ # -- Static DHCP config
+ staticDhcpEntries: []
+ # staticDhcpEntries:
+ # - dhcp-host=MAC_ADDRESS,IP_ADDRESS,HOSTNAME
+
+ # -- Other options
+ customSettings:
+ # otherSettings:
+ # - rebind-domain-ok=/plex.direct/
+
+ # -- Here we specify custom cname entries that should point to `A` records or
+ # elements in customDnsEntries array.
+ # The format should be:
+ # - cname=cname.foo.bar,foo.bar
+ # - cname=cname.bar.foo,bar.foo
+ # - cname=cname record,dns record
+ customCnameEntries: []
+ # Here we specify custom cname entries that should point to `A` records or
+ # elements in customDnsEntries array.
+ # The format should be:
+ # - cname=cname.foo.bar,foo.bar
+ # - cname=cname.bar.foo,bar.foo
+ # - cname=cname record,dns record
+
+# -- list of adlists to import during initial start of the container
+adlists:
+ {}
+ # If you want to provide blocklists, add them here.
+ # - https://hosts-file.net/grm.txt
+ # - https://reddestdream.github.io/Projects/MinimalHosts/etc/MinimalHostsBlocker/minimalhosts
+
+# -- list of whitelisted domains to import during initial start of the container
+whitelist:
+ {}
+ # If you want to provide whitelisted domains, add them here.
+ # - clients4.google.com
+
+# -- list of blacklisted domains to import during initial start of the container
+blacklist:
+ {}
+ # If you want to have special domains blacklisted, add them here
+ # - *.blackist.com
+
+# -- list of blacklisted regex expressions to import during initial start of the container
+regex:
+ {}
+ # Add regular expression blacklist items
+ # - (^|\.)facebook\.com$
+
+# -- values that should be added to pihole-FTL.conf
+ftl:
+ {}
+ # Add values for pihole-FTL.conf
+ # MAXDBDAYS: 14
+
+# -- port the container should use to expose HTTP traffic
+webHttp: "80"
+
+# -- port the container should use to expose HTTPS traffic
+webHttps: "443"
+
+# -- hostname of pod
+hostname: ""
+
+# -- should the container use host network
+hostNetwork: "false"
+
+# -- should container run in privileged mode
+privileged: "false"
+
+# linux capabilities container should run with
+capabilities:
+ {}
+ # add:
+ # - NET_ADMIN
+
+customVolumes:
+ # -- set this to true to enable custom volumes
+ enabled: false
+ # -- any volume type can be used here
+ config:
+ {}
+ # hostPath:
+ # path: "/mnt/data"
+
+# -- any extra volumes you might want
+extraVolumes:
+ {}
+ # external-conf:
+ # configMap:
+ # name: pi-hole-lighttpd-external-conf
+
+# -- any extra volume mounts you might want
+extraVolumeMounts:
+ {}
+ # external-conf:
+ # mountPath: /etc/lighttpd/external.conf
+ # subPath: external.conf
+
+extraContainers:
+ []
+ # - name: pihole-logwatcher
+ # image: your-registry/pihole-logwatcher
+ # imagePullPolicy: Always
+ # resources:
+ # requests:
+ # cpu: 100m
+ # memory: 5Mi
+ # limits:
+ # cpu: 100m
+ # memory: 5Mi
+ # volumeMounts:
+ # - name: pihole-logs
+ # mountPath: /var/log/pihole
+
+# -- any extra kubernetes manifests you might want
+extraObjects:
+ []
+ # - apiVersion: v1
+ # kind: ConfigMap
+ # metadata:
+ # name: pi-hole-lighttpd-external-conf
+ # data:
+ # external.conf: |
+ # $HTTP["host"] =~ "example.foo" {
+ # # If we're using a non-standard host for pihole, ensure the Pi-hole
+ # # Block Page knows that this is not a blocked domain
+ # setenv.add-environment = ("fqdn" => "true")
+ #
+ # # Enable the SSL engine with a cert, only for this specific host
+ # $SERVER["socket"] == ":443" {
+ # ssl.engine = "enable"
+ # ssl.pemfile = "/etc/ssl/lighttpd-private/tls.crt"
+ # ssl.privkey = "/etc/ssl/lighttpd-private/tls.key"
+ # ssl.ca-file = "/etc/ssl/lighttpd-private/ca.crt"
+ # ssl.honor-cipher-order = "enable"
+ # ssl.cipher-list = "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"
+ # ssl.use-sslv2 = "disable"
+ # ssl.use-sslv3 = "disable"
+ # }
+ # }
+ #
+ # # Redirect HTTP to HTTPS
+ # $HTTP["scheme"] == "http" {
+ # $HTTP["host"] =~ ".*" {
+ # url.redirect = (".*" => "https://%0$0")
+ # }
+ # }
+
+# -- Additional annotations for pods
+podAnnotations:
+ {}
+ # Example below allows Prometheus to scape on metric port (requires pihole-exporter sidecar enabled)
+ # prometheus.io/port: '9617'
+ # prometheus.io/scrape: 'true'
+
+# -- any initContainers you might want to run before starting pihole
+extraInitContainers:
+ []
+ # - name: copy-config
+ # image: busybox
+ # args:
+ # - sh
+ # - -c
+ # - |
+ # cp /etc/lighttpd-cm/external.conf /etc/lighttpd/
+ # ls -l /etc/lighttpd/
+ # volumeMounts:
+ # - name: external-conf-cm
+ # mountPath: /etc/lighttpd-cm/
+ # - name: external-conf
+ # mountPath: /etc/lighttpd/
+
+monitoring:
+ # -- Preferably adding prometheus scrape annotations rather than enabling podMonitor.
+ podMonitor:
+ # -- set this to true to enable podMonitor
+ enabled: false
+ # -- Sidecar configuration
+ sidecar:
+ # -- set this to true to enable podMonitor as sidecar
+ enabled: false
+ port: 9617
+ image:
+ repository: ekofr/pihole-exporter
+ tag: v0.3.0
+ pullPolicy: IfNotPresent
+ resources:
+ limits:
+ memory: 128Mi
+ # requests:
+ # cpu: 100m
+ # memory: 128Mi
+
+podDnsConfig:
+ enabled: true
+ policy: "None"
+ nameservers:
+ - 127.0.0.1
+ - 8.8.8.8
+
+# -- configure a Pod Disruption Budget
+podDisruptionBudget:
+ # -- set to true to enable creating the PDB
+ enabled: false
+ # -- minimum number of pods Kubernetes should try to have running at all times
+ minAvailable: 1
+ # -- maximum number of pods Kubernetes will allow to be unavailable. Cannot set both `minAvailable` and `maxAvailable`
+ # maxUnavailable: 1
diff --git a/charts/rpuppy/templates/install.yaml b/charts/rpuppy/templates/install.yaml
index c7c3800..5cde9c9 100644
--- a/charts/rpuppy/templates/install.yaml
+++ b/charts/rpuppy/templates/install.yaml
@@ -8,55 +8,10 @@
selector:
app: rpuppy
ports:
- - name: http
+ - name: {{ .Values.portName }}
port: 80
- targetPort: http
+ targetPort: {{ .Values.portName }}
protocol: TCP
-# ---
-# apiVersion: cert-manager.io/v1
-# kind: Certificate
-# metadata:
-# name: rpuppy
-# namespace: {{ .Release.Namespace }}
-# # annotations:
-# # helm.sh/resource-policy: keep
-# spec:
-# secretName: cert-rpuppy
-# dnsNames:
-# - {{ .Values.domain }}
-# issuerRef:
-# kind: ClusterIssuer
-# name: {{ .Values.certificateIssuer}}
----
-apiVersion: networking.k8s.io/v1
-kind: Ingress
-metadata:
- name: ingress
- namespace: {{ .Release.Namespace }}
- {{- if .Values.certificateIssuer }}
- annotations:
- acme.cert-manager.io/http01-edit-in-place: "true"
- cert-manager.io/cluster-issuer: {{ .Values.certificateIssuer }}
- {{- end }}
-spec:
- ingressClassName: {{ .Values.ingressClassName }}
- {{- if .Values.certificateIssuer }}
- tls:
- - hosts:
- - {{ .Values.domain }}
- secretName: cert-rpuppy
- {{- end }}
- rules:
- - host: {{ .Values.domain }}
- http:
- paths:
- - path: /
- pathType: Prefix
- backend:
- service:
- name: rpuppy
- port:
- name: http
---
apiVersion: apps/v1
kind: Deployment
@@ -78,10 +33,12 @@
image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- - name: http
+ - name: {{ .Values.portName }}
containerPort: 8080
protocol: TCP
- command: ["rpuppy", "--port=8080"]
+ command:
+ - rpuppy
+ - --port=8080
resources:
requests:
memory: "10Mi"
diff --git a/charts/rpuppy/values.yaml b/charts/rpuppy/values.yaml
index c53fccb..0830d1e 100644
--- a/charts/rpuppy/values.yaml
+++ b/charts/rpuppy/values.yaml
@@ -2,6 +2,4 @@
repository: giolekva/rpuppy
tag: latest
pullPolicy: Always
-ingressClassName: ingress-public
-certificateIssuer: example-public
-domain: woof.example.com
+portName: http
diff --git a/charts/url-shortener/templates/install.yaml b/charts/url-shortener/templates/install.yaml
index 5e96fea..e562b02 100644
--- a/charts/url-shortener/templates/install.yaml
+++ b/charts/url-shortener/templates/install.yaml
@@ -8,40 +8,10 @@
selector:
app: url-shortener
ports:
- - name: http
+ - name: {{ .Values.portName }}
protocol: TCP
port: 80
- targetPort: {{ .Values.port }}
----
-apiVersion: networking.k8s.io/v1
-kind: Ingress
-metadata:
- name: ingress
- namespace: {{ .Release.Namespace }}
-{{- if .Values.certificateIssuer }}
- annotations:
- acme.cert-manager.io/http01-edit-in-place: "true"
- cert-manager.io/cluster-issuer: {{ .Values.certificateIssuer }}
-{{- end }}
-spec:
- ingressClassName: {{ .Values.ingressClassName }}
-{{- if .Values.certificateIssuer }}
- tls:
- - hosts:
- - {{ .Values.domain }}
- secretName: cert-url-shortener
-{{- end }}
- rules:
- - host: {{ .Values.domain }}
- http:
- paths:
- - path: /
- pathType: Prefix
- backend:
- service:
- name: url-shortener
- port:
- name: http
+ targetPort: {{ .Values.portName }}
---
apiVersion: apps/v1
kind: Deployment
@@ -62,12 +32,12 @@
- name: url-shortener
image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
ports:
- - name: http
- containerPort: {{ .Values.port }}
+ - name: {{ .Values.portName }}
+ containerPort: 8080
protocol: TCP
command:
- url-shortener
- - --port={{ .Values.port }}
+ - --port=8080
- --db-path=/data/urls.db
volumeMounts:
- name: url-shortener
diff --git a/charts/url-shortener/values.yaml b/charts/url-shortener/values.yaml
index a62dc10..3b0d837 100644
--- a/charts/url-shortener/values.yaml
+++ b/charts/url-shortener/values.yaml
@@ -1,11 +1,7 @@
image:
repository: giolekva/url-shortener
- name: url-shortener
tag: latest
pullPolicy: Always
-ingressClassName: ingress-public
-certificateIssuer: example-public
-domain: url-shortener.example.com
storage:
size: 1Gi
-port: 8080
+portName: http
diff --git a/core/auth/proxy/Dockerfile b/core/auth/proxy/Dockerfile
new file mode 100644
index 0000000..6e8d93c
--- /dev/null
+++ b/core/auth/proxy/Dockerfile
@@ -0,0 +1,5 @@
+FROM gcr.io/distroless/static:nonroot
+
+ARG TARGETARCH
+
+COPY server_${TARGETARCH} /usr/bin/server
diff --git a/core/auth/proxy/Makefile b/core/auth/proxy/Makefile
new file mode 100644
index 0000000..053ab05
--- /dev/null
+++ b/core/auth/proxy/Makefile
@@ -0,0 +1,39 @@
+repo_name ?= giolekva
+podman ?= docker
+ifeq ($(podman), podman)
+manifest_dest=docker://docker.io/$(repo_name)/pcloud-installer:latest
+endif
+
+clean:
+ rm -f server server_*
+
+build: clean
+ go build -o server *.go
+
+build_arm64: export CGO_ENABLED=0
+build_arm64: export GO111MODULE=on
+build_arm64: export GOOS=linux
+build_arm64: export GOARCH=arm64
+build_arm64:
+ go build -o server_arm64 *.go
+
+build_amd64: export CGO_ENABLED=0
+build_amd64: export GO111MODULE=on
+build_amd64: export GOOS=linux
+build_amd64: export GOARCH=amd64
+build_amd64:
+ go build -o server_amd64 *.go
+
+push_arm64: clean build_arm64
+ $(podman) build --platform linux/arm64 --tag=$(repo_name)/auth-proxy:arm64 .
+ $(podman) push $(repo_name)/auth-proxy:arm64
+
+push_amd64: clean build_amd64
+ $(podman) build --platform linux/amd64 --tag=$(repo_name)/auth-proxy:amd64 .
+ $(podman) push $(repo_name)/auth-proxy:amd64
+
+
+push: push_arm64 push_amd64
+ $(podman) manifest create $(repo_name)/auth-proxy:latest $(repo_name)/auth-proxy:arm64 $(repo_name)/auth-proxy:amd64
+ $(podman) manifest push $(repo_name)/auth-proxy:latest $(manifest_dest)
+ $(podman) manifest rm $(repo_name)/auth-proxy:latest
diff --git a/core/auth/proxy/main.go b/core/auth/proxy/main.go
new file mode 100644
index 0000000..8b3d837
--- /dev/null
+++ b/core/auth/proxy/main.go
@@ -0,0 +1,156 @@
+package main
+
+import (
+ "bytes"
+ "context"
+ "crypto/tls"
+ "encoding/json"
+ "flag"
+ "fmt"
+ "io"
+ "log"
+ "net/http"
+ "net/http/cookiejar"
+ "net/url"
+ "strings"
+)
+
+var port = flag.Int("port", 3000, "Port to listen on")
+var whoAmIAddr = flag.String("whoami-addr", "", "Kratos whoami endpoint address")
+var loginAddr = flag.String("login-addr", "", "Login page address")
+var upstream = flag.String("upstream", "", "Upstream service address")
+
+type user struct {
+ Identity struct {
+ Traits struct {
+ Username string `json:"username"`
+ } `json:"traits"`
+ } `json:"identity"`
+}
+
+type authError struct {
+ Error struct {
+ Status string `json:"status"`
+ } `json:"error"`
+}
+
+func getAddr(r *http.Request) (*url.URL, error) {
+ return url.Parse(fmt.Sprintf(
+ "%s://%s%s",
+ r.Header["X-Forwarded-Scheme"][0],
+ r.Header["X-Forwarded-Host"][0],
+ r.URL.RequestURI()))
+}
+
+func handle(w http.ResponseWriter, r *http.Request) {
+ user, err := queryWhoAmI(r.Cookies())
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+ if user == nil {
+ if r.Method != http.MethodGet {
+ http.Error(w, "Unauthorized", http.StatusUnauthorized)
+ return
+ }
+ curr, err := getAddr(r)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+ addr := fmt.Sprintf("%s?return_to=%s", *loginAddr, curr.String())
+ http.Redirect(w, r, addr, http.StatusSeeOther)
+ return
+ }
+ rc := r.Clone(context.Background())
+ rc.Header.Add("X-User", user.Identity.Traits.Username)
+ ru, err := url.Parse(fmt.Sprintf("http://%s%s", *upstream, r.URL.RequestURI()))
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+ rc.URL = ru
+ rc.RequestURI = ""
+ client := &http.Client{
+ Transport: &http.Transport{
+ TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
+ },
+ CheckRedirect: func(req *http.Request, via []*http.Request) error {
+ return http.ErrUseLastResponse
+ },
+ }
+ resp, err := client.Do(rc)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+ for name, values := range resp.Header {
+ for _, value := range values {
+ w.Header().Add(name, value)
+ }
+ }
+ w.WriteHeader(resp.StatusCode)
+ if _, err := io.Copy(w, resp.Body); err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+}
+
+func queryWhoAmI(cookies []*http.Cookie) (*user, error) {
+ jar, err := cookiejar.New(nil)
+ if err != nil {
+ return nil, err
+ }
+ client := &http.Client{
+ Jar: jar,
+ Transport: &http.Transport{
+ TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
+ },
+ }
+ addr, err := url.Parse(*whoAmIAddr)
+ if err != nil {
+ return nil, err
+ }
+ client.Jar.SetCookies(addr, cookies)
+ resp, err := client.Get(*whoAmIAddr)
+ if err != nil {
+ return nil, err
+ }
+ data := make(map[string]any)
+ if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
+ return nil, err
+ }
+ // TODO(gio): remove debugging
+ b, err := json.MarshalIndent(data, "", " ")
+ if err != nil {
+ return nil, err
+ }
+ fmt.Println(string(b))
+ var buf bytes.Buffer
+ if err := json.NewEncoder(&buf).Encode(data); err != nil {
+ return nil, err
+ }
+ tmp := buf.String()
+ if resp.StatusCode == http.StatusOK {
+ u := &user{}
+ if err := json.NewDecoder(strings.NewReader(tmp)).Decode(u); err != nil {
+ return nil, err
+ }
+ return u, nil
+ }
+ e := &authError{}
+ if err := json.NewDecoder(strings.NewReader(tmp)).Decode(e); err != nil {
+ return nil, err
+ }
+ if e.Error.Status == "Unauthorized" {
+ return nil, nil
+ }
+ return nil, fmt.Errorf("Unknown error: %s", tmp)
+}
+
+func main() {
+ flag.Parse()
+ http.HandleFunc("/", handle)
+ fmt.Printf("Starting HTTP server on port: %d\n", *port)
+ log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", *port), nil))
+}
diff --git a/core/auth/ui/Makefile b/core/auth/ui/Makefile
index f3b9b63..23ae76b 100644
--- a/core/auth/ui/Makefile
+++ b/core/auth/ui/Makefile
@@ -1,5 +1,8 @@
repo_name ?= dtabidze
podman ?= docker
+ifeq ($(podman), podman)
+manifest_dest=docker://docker.io/$(repo_name)/pcloud-installer:latest
+endif
clean:
rm -f server server_*
@@ -32,5 +35,5 @@
push: push_arm64 push_amd64
$(podman) manifest create $(repo_name)/auth-ui:latest $(repo_name)/auth-ui:arm64 $(repo_name)/auth-ui:amd64
- $(podman) manifest push $(repo_name)/auth-ui:latest
+ $(podman) manifest push $(repo_name)/auth-ui:latest $(manifest_dest)
$(podman) manifest rm $(repo_name)/auth-ui:latest
diff --git a/core/auth/ui/main.go b/core/auth/ui/main.go
index 7cb1f4d..3de264c 100644
--- a/core/auth/ui/main.go
+++ b/core/auth/ui/main.go
@@ -239,9 +239,14 @@
// HttpOnly: true,
// })
}
+ returnTo := r.Form.Get("return_to")
flow, ok := r.Form["flow"]
if !ok {
- http.Redirect(w, r, s.kratos+"/self-service/login/browser", http.StatusSeeOther)
+ addr := s.kratos + "/self-service/login/browser"
+ if returnTo != "" {
+ addr += fmt.Sprintf("?return_to=%s", returnTo)
+ }
+ http.Redirect(w, r, addr, http.StatusSeeOther)
return
}
csrfToken, err := getCSRFToken("login", flow[0], r.Cookies())
@@ -289,6 +294,32 @@
return resp, nil
}
+func postFormToKratos(flowType, flow string, cookies []*http.Cookie, data url.Values) (*http.Response, error) {
+ jar, err := cookiejar.New(nil)
+ if err != nil {
+ return nil, err
+ }
+ client := &http.Client{
+ Jar: jar,
+ Transport: &http.Transport{
+ TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
+ },
+ CheckRedirect: func(req *http.Request, via []*http.Request) error {
+ return http.ErrUseLastResponse
+ },
+ }
+ b, err := url.Parse(*kratos + "/self-service/" + flowType + "/browser")
+ if err != nil {
+ return nil, err
+ }
+ client.Jar.SetCookies(b, cookies)
+ resp, err := client.PostForm(fmt.Sprintf(*kratos+"/self-service/"+flowType+"?flow=%s", flow), data)
+ if err != nil {
+ return nil, err
+ }
+ return resp, nil
+}
+
type logoutResp struct {
LogoutURL string `json:"logout_url"`
}
@@ -360,6 +391,7 @@
if err != nil {
return err
}
+ fmt.Printf("++ %s\n", respBody)
t, err := regogo.Get(string(respBody), "input.ui.messages[0].type")
if err != nil {
return err
@@ -384,21 +416,17 @@
http.Redirect(w, r, s.kratos+"/self-service/login/browser", http.StatusSeeOther)
return
}
- req := loginReq{
- CSRFToken: r.FormValue("csrf_token"),
- Method: "password",
- Password: r.FormValue("password"),
- Username: r.FormValue("username"),
+ req := url.Values{
+ "csrf_token": []string{r.FormValue("csrf_token")},
+ "method": []string{"password"},
+ "password": []string{r.FormValue("password")},
+ "identifier": []string{r.FormValue("username")},
}
- var reqBody bytes.Buffer
- if err := json.NewEncoder(&reqBody).Encode(req); err != nil {
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }
- resp, err := postToKratos("login", flow[0], r.Cookies(), &reqBody)
- if err == nil {
- err = extractError(resp.Body)
- }
+ resp, err := postFormToKratos("login", flow[0], r.Cookies(), req)
+ fmt.Printf("--- %d\n", resp.StatusCode)
+ var vv bytes.Buffer
+ io.Copy(&vv, resp.Body)
+ fmt.Println(vv.String())
if err != nil {
if challenge, _ := r.Cookie("login_challenge"); challenge != nil {
redirectTo, err := s.hydra.LoginRejectChallenge(challenge.Value, err.Error())
@@ -429,7 +457,11 @@
http.Redirect(w, r, redirectTo, http.StatusSeeOther)
return
}
- http.Redirect(w, r, "/", http.StatusSeeOther)
+ if resp.StatusCode == http.StatusSeeOther {
+ http.Redirect(w, r, resp.Header.Get("Location"), http.StatusSeeOther)
+ } else {
+ http.Redirect(w, r, "/", http.StatusSeeOther)
+ }
}
func (s *Server) logout(w http.ResponseWriter, r *http.Request) {
diff --git a/core/installer/app.go b/core/installer/app.go
index 6c83376..8cfb2b5 100644
--- a/core/installer/app.go
+++ b/core/installer/app.go
@@ -147,7 +147,7 @@
...
}
-helm: {
+helmValidate: {
for key, value in helm {
"\(key)": #Helm & value & {
name: key
@@ -184,7 +184,7 @@
}
output: {
- for name, r in helm {
+ for name, r in helmValidate {
"\(name)": #HelmRelease & {
_name: name
_chart: r.chart
diff --git a/core/installer/repoio.go b/core/installer/repoio.go
index 374f75f..5b90327 100644
--- a/core/installer/repoio.go
+++ b/core/installer/repoio.go
@@ -388,6 +388,7 @@
}
switch def.Kind() {
case KindBoolean:
+ ret[k] = v
case KindString:
ret[k] = v
case KindNetwork:
diff --git a/core/installer/values-tmpl/core-auth.cue b/core/installer/values-tmpl/core-auth.cue
index 99840ab..192f806 100644
--- a/core/installer/values-tmpl/core-auth.cue
+++ b/core/installer/values-tmpl/core-auth.cue
@@ -225,6 +225,10 @@
}
selfservice: {
default_browser_return_url: "https://accounts-ui.\(global.domain)"
+ allowed_return_urls: [
+ "https://*.\(global.domain)/",
+ "https://*.\(global.privateDomain)",
+ ]
methods: {
password: {
enabled: true
diff --git a/core/installer/values-tmpl/pihole.cue b/core/installer/values-tmpl/pihole.cue
index a1ec66a..35d4c51 100644
--- a/core/installer/values-tmpl/pihole.cue
+++ b/core/installer/values-tmpl/pihole.cue
@@ -1,6 +1,7 @@
input: {
network: #Network
subdomain: string
+ requireAuth: bool
}
_domain: "\(input.subdomain).\(input.network.domain)"
@@ -18,17 +19,15 @@
tag: "v5.8.1"
pullPolicy: "IfNotPresent"
}
+ authProxy: {
+ repository: "giolekva"
+ name: "auth-proxy"
+ tag: "latest"
+ pullPolicy: "Always"
+ }
}
charts: {
- oauth2Client: {
- chart: "charts/oauth2-client"
- sourceRef: {
- kind: "GitRepository"
- name: "pcloud"
- namespace: global.id
- }
- }
pihole: {
chart: "charts/pihole"
sourceRef: {
@@ -37,80 +36,110 @@
namespace: global.id
}
}
-}
-
-_oauth2ClientSecretName: "oauth2-client"
-
-helm: {
- "oauth2-client": {
- chart: charts.oauth2Client
- values: {
- name: "oauth2-client"
- secretName: _oauth2ClientSecretName
- grantTypes: ["authorization_code"]
- responseTypes: ["code"]
- scope: "openid profile email"
- redirectUris: ["https://\(_domain)/oauth2/callback"]
- hydraAdmin: "http://hydra-admin.\(global.namespacePrefix)core-auth.svc.cluster.local"
+ ingress: {
+ chart: "charts/ingress"
+ sourceRef: {
+ kind: "GitRepository"
+ name: "pcloud"
+ namespace: global.id
}
}
+ authProxy: {
+ chart: "charts/auth-proxy"
+ sourceRef: {
+ kind: "GitRepository"
+ name: "pcloud"
+ namespace: global.id
+ }
+ }
+}
+
+_piholeServiceName: "pihole-web"
+_authProxyServiceName: "auth-proxy"
+_httpPortName: "http"
+_serviceWebPort: 80
+
+helm: {
pihole: {
chart: charts.pihole
values: {
- domain: _domain
- pihole: {
- fullnameOverride: "pihole"
- persistentVolumeClaim: { // TODO(gio): create volume separately as a dependency
+ fullnameOverride: "pihole"
+ persistentVolumeClaim: { // TODO(gio): create volume separately as a dependency
+ enabled: true
+ size: "5Gi"
+ }
+ admin: {
+ enabled: false
+ }
+ ingress: {
+ enabled: false
+ }
+ serviceDhcp: {
+ enabled: false
+ }
+ serviceDns: {
+ type: "ClusterIP"
+ }
+ serviceWeb: {
+ type: "ClusterIP"
+ http: {
enabled: true
- size: "5Gi"
+ port: _serviceWebPort
}
- admin: {
+ https: {
enabled: false
}
- ingress: {
- enabled: false
+ }
+ virtualHost: _domain
+ resources: {
+ requests: {
+ cpu: "250m"
+ memory: "100M"
}
- serviceDhcp: {
- enabled: false
+ limits: {
+ cpu: "500m"
+ memory: "250M"
}
- serviceDns: {
- type: "ClusterIP"
- }
- serviceWeb: {
- type: "ClusterIP"
- http: {
- enabled: true
- }
- https: {
- enabled: false
- }
- }
- virtualHost: _domain
- resources: {
- requests: {
- cpu: "250m"
- memory: "100M"
- }
- limits: {
- cpu: "500m"
- memory: "250M"
- }
- }
+ }
+ image: {
+ repository: images.pihole.fullName
+ tag: images.pihole.tag
+ pullPolicy: images.pihole.pullPolicy
+ }
+ }
+ }
+ if input.requireAuth {
+ "auth-proxy": {
+ chart: charts.authProxy
+ values: {
image: {
- repository: images.pihole.fullName
- tag: images.pihole.tag
- pullPolicy: images.pihole.pullPolicy
+ repository: images.authProxy.fullName
+ tag: images.authProxy.tag
+ pullPolicy: images.authProxy.pullPolicy
}
+ upstream: "\(_piholeServiceName).\(release.namespace).svc.cluster.local"
+ whoAmIAddr: "https://accounts.\(global.domain)/sessions/whoami"
+ loginAddr: "https://accounts-ui.\(global.domain)/login"
+ portName: _httpPortName
}
- oauth2: {
- cookieSecret: "1234123443214321"
- secretName: _oauth2ClientSecretName
- issuer: "https://hydra.\(global.domain)"
- }
- configName: "oauth2-proxy"
- profileUrl: "https://accounts-ui.\(global.domain)"
+ }
+ }
+ ingress: {
+ chart: charts.ingress
+ values: {
+ domain: _domain
ingressClassName: input.network.ingressClass
certificateIssuer: input.network.certificateIssuer
+ service: {
+ if input.requireAuth {
+ name: _authProxyServiceName
+ port: name: _httpPortName
+ }
+ if !input.requireAuth {
+ name: _piholeServiceName
+ port: number: _serviceWebPort
+ }
+ }
}
}
}
diff --git a/core/installer/values-tmpl/rpuppy.cue b/core/installer/values-tmpl/rpuppy.cue
index 8950d6c..ff316a0 100644
--- a/core/installer/values-tmpl/rpuppy.cue
+++ b/core/installer/values-tmpl/rpuppy.cue
@@ -1,6 +1,7 @@
input: {
network: #Network
subdomain: string
+ requireAuth: bool
}
_domain: "\(input.subdomain).\(input.network.domain)"
@@ -18,6 +19,12 @@
tag: "latest"
pullPolicy: "Always"
}
+ authProxy: {
+ repository: "giolekva"
+ name: "auth-proxy"
+ tag: "latest"
+ pullPolicy: "Always"
+ }
}
charts: {
@@ -29,20 +36,71 @@
namespace: global.id
}
}
+ ingress: {
+ chart: "charts/ingress"
+ sourceRef: {
+ kind: "GitRepository"
+ name: "pcloud"
+ namespace: global.id
+ }
+ }
+ authProxy: {
+ chart: "charts/auth-proxy"
+ sourceRef: {
+ kind: "GitRepository"
+ name: "pcloud"
+ namespace: global.id
+ }
+ }
}
+_rpuppyServiceName: "rpuppy"
+_authProxyServiceName: "auth-proxy"
+_httpPortName: "http"
+
helm: {
rpuppy: {
chart: charts.rpuppy
values: {
- ingressClassName: input.network.ingressClass
- certificateIssuer: input.network.certificateIssuer
- domain: _domain
image: {
repository: images.rpuppy.fullName
tag: images.rpuppy.tag
pullPolicy: images.rpuppy.pullPolicy
}
+ portName: _httpPortName
+ }
+ }
+ if input.requireAuth {
+ "auth-proxy": {
+ chart: charts.authProxy
+ values: {
+ image: {
+ repository: images.authProxy.fullName
+ tag: images.authProxy.tag
+ pullPolicy: images.authProxy.pullPolicy
+ }
+ upstream: "\(_rpuppyServiceName).\(release.namespace).svc.cluster.local"
+ whoAmIAddr: "https://accounts.\(global.domain)/sessions/whoami"
+ loginAddr: "https://accounts-ui.\(global.domain)/login"
+ portName: _httpPortName
+ }
+ }
+ }
+ ingress: {
+ chart: charts.ingress
+ values: {
+ domain: _domain
+ ingressClassName: input.network.ingressClass
+ certificateIssuer: input.network.certificateIssuer
+ service: {
+ if input.requireAuth {
+ name: _authProxyServiceName
+ }
+ if !input.requireAuth {
+ name: _rpuppyServiceName
+ }
+ port: name: _httpPortName
+ }
}
}
}
diff --git a/core/installer/values-tmpl/url-shortener.cue b/core/installer/values-tmpl/url-shortener.cue
index a3f6d3b..7d854e8 100644
--- a/core/installer/values-tmpl/url-shortener.cue
+++ b/core/installer/values-tmpl/url-shortener.cue
@@ -1,6 +1,7 @@
input: {
network: #Network
subdomain: string
+ requireAuth: bool
}
_domain: "\(input.subdomain).\(input.network.domain)"
@@ -18,6 +19,12 @@
tag: "latest"
pullPolicy: "Always"
}
+ authProxy: {
+ repository: "giolekva"
+ name: "auth-proxy"
+ tag: "latest"
+ pullPolicy: "Always"
+ }
}
charts: {
@@ -29,15 +36,32 @@
namespace: global.id
}
}
+ ingress: {
+ chart: "charts/ingress"
+ sourceRef: {
+ kind: "GitRepository"
+ name: "pcloud"
+ namespace: global.id
+ }
+ }
+ authProxy: {
+ chart: "charts/auth-proxy"
+ sourceRef: {
+ kind: "GitRepository"
+ name: "pcloud"
+ namespace: global.id
+ }
+ }
}
+_urlShortenerServiceName: "url-shortener"
+_authProxyServiceName: "auth-proxy"
+_httpPortName: "http"
+
helm: {
"url-shortener": {
chart: charts.urlShortener
values: {
- ingressClassName: input.network.ingressClass
- certificateIssuer: input.network.certificateIssuer
- domain: _domain
storage: {
size: "1Gi"
}
@@ -46,7 +70,40 @@
tag: images.urlShortener.tag
pullPolicy: images.urlShortener.pullPolicy
}
- port: 8080
+ portName: _httpPortName
}
}
+ if input.requireAuth {
+ "auth-proxy": {
+ chart: charts.authProxy
+ values: {
+ image: {
+ repository: images.authProxy.fullName
+ tag: images.authProxy.tag
+ pullPolicy: images.authProxy.pullPolicy
+ }
+ upstream: "\(_urlShortenerServiceName).\(release.namespace).svc.cluster.local"
+ whoAmIAddr: "https://accounts.\(global.domain)/sessions/whoami"
+ loginAddr: "https://accounts-ui.\(global.domain)/login"
+ portName: _httpPortName
+ }
+ }
+ }
+ ingress: {
+ chart: charts.ingress
+ values: {
+ domain: _domain
+ ingressClassName: input.network.ingressClass
+ certificateIssuer: input.network.certificateIssuer
+ service: {
+ if input.requireAuth {
+ name: _authProxyServiceName
+ }
+ if !input.requireAuth {
+ name: _urlShortenerServiceName
+ }
+ port: name: _httpPortName
+ }
+ }
+ }
}
diff --git a/core/installer/welcome/appmanager-tmpl/app.html b/core/installer/welcome/appmanager-tmpl/app.html
index 4fa4766..aebbd39 100644
--- a/core/installer/welcome/appmanager-tmpl/app.html
+++ b/core/installer/welcome/appmanager-tmpl/app.html
@@ -7,7 +7,7 @@
<label for="{{ $name }}">
<span>{{ $name }}</span>
</label>
- <input type="checkbox" role="swtich" name="{{ $name }}" oninput="valueChanged({{ $name }}, this.value)" {{ if $readonly }}disabled{{ end }} {{ if index $data $name }}checked{{ end }}/>
+ <input type="checkbox" role="swtich" name="{{ $name }}" oninput="valueChanged({{ $name }}, this.checked)" {{ if $readonly }}disabled{{ end }} {{ if index $data $name }}checked{{ end }}/>
{{ else if eq $schema.Kind 1 }}
<label for="{{ $name }}">
<span>{{ $name }}</span>