[stable/unifi] Adding captive portal service (#21241)

* [stable/unifi] Adding captive portal service
Signed-off-by: Arno Dubois <arno.du@orange.fr>

Signed-off-by: Arno DUBOIS <arnodubois@sweetpunk.com>

* [stable/unifi] Annnd bumping version
Signed-off-by: Arno Dubois <arno.du@orange.fr>

Signed-off-by: Arno DUBOIS <arnodubois@sweetpunk.com>

* Added an enabled switch

Signed-off-by: Arno DUBOIS <arnodubois@sweetpunk.com>

* [stable/unifi] Fixing feedbacks

Signed-off-by: Arno DUBOIS <arnodubois@sweetpunk.com>

* [stable/unifi] Adding captive portal ingress

Signed-off-by: Arno DUBOIS <arnodubois@sweetpunk.com>

* [stable/unifi] Better table formatting

Signed-off-by: Arno DUBOIS <arnodubois@sweetpunk.com>

* [stable/unifi] Fixed ingress

Signed-off-by: Arno DUBOIS <arnodubois@sweetpunk.com>

Co-authored-by: Arno DUBOIS <arnodubois@sweetpunk.com>
This commit is contained in:
Arno DUBOIS 2020-03-06 22:35:35 +01:00 committed by Jeff Billimek
parent 6c8d01add3
commit 6a3b129a4b
No known key found for this signature in database
GPG Key ID: 214B3EF39B4956B7
7 changed files with 255 additions and 69 deletions

View File

@ -2,7 +2,7 @@ apiVersion: v1
appVersion: 5.11.50 appVersion: 5.11.50
description: Ubiquiti Network's Unifi Controller description: Ubiquiti Network's Unifi Controller
name: unifi name: unifi
version: 0.6.1 version: 0.6.2
keywords: keywords:
- ubiquiti - ubiquiti
- unifi - unifi

View File

@ -34,74 +34,89 @@ The command removes all the Kubernetes components associated with the chart and
The following tables lists the configurable parameters of the Unifi chart and their default values. The following tables lists the configurable parameters of the Unifi chart and their default values.
| Parameter | Description | Default | | Parameter | Default | Description |
| -------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | ---------------------------- | |-------------------------------------------------|------------------------------|------------------------------------------------------------------------------------------------------------------------|
| `image.repository` | Image repository | `jacobalberty/unifi` | | `image.repository` | `jacobalberty/unifi` | Image repository |
| `image.tag` | Image tag. Possible values listed [here][docker]. | `5.11.50` | | `image.tag` | `5.11.50` | Image tag. Possible values listed [here][docker]. |
| `image.pullPolicy` | Image pull policy | `IfNotPresent` | | `image.pullPolicy` | `IfNotPresent` | Image pull policy |
| `strategyType` | Specifies the strategy used to replace old Pods by new ones | `Recreate` | | `strategyType` | `Recreate` | Specifies the strategy used to replace old Pods by new ones |
| `guiService.type` | Kubernetes service type for the Unifi GUI | `ClusterIP` | | `guiService.type` | `ClusterIP` | Kubernetes service type for the Unifi GUI |
| `guiService.port` | Kubernetes port where the Unifi GUI is exposed | `8443` | | `guiService.port` | `8443` | Kubernetes port where the Unifi GUI is exposed |
| `guiService.annotations` | Service annotations for the Unifi GUI | `{}` | | `guiService.annotations` | `{}` | Service annotations for the Unifi GUI |
| `guiService.labels` | Custom labels | `{}` | | `guiService.labels` | `{}` | Custom labels |
| `guiService.loadBalancerIP` | Loadbalance IP for the Unifi GUI | `{}` | | `guiService.loadBalancerIP` | `{}` | Loadbalance IP for the Unifi GUI |
| `guiService.loadBalancerSourceRanges` | List of IP CIDRs allowed access to load balancer (if supported) | None | | `guiService.loadBalancerSourceRanges` | None | List of IP CIDRs allowed access to load balancer (if supported) |
| `guiService.externalTrafficPolicy` | Set the externalTrafficPolicy in the Service to either Cluster or Local | `Cluster` | | `guiService.externalTrafficPolicy` | `Cluster` | Set the externalTrafficPolicy in the Service to either Cluster or Local |
| `controllerService.type` | Kubernetes service type for the Unifi Controller communication | `NodePort` | | `captivePortalService.enabled` | `false` | Install the captive portal service (needed if you want guest captive portal) |
| `controllerService.port` | Kubernetes port where the Unifi Controller is exposed - this needs to be reachable by the unifi devices on the network | `8080` | | `captivePortalService.type` | `ClusterIP` | Kubernetes service type for the captive portal |
| `controllerService.annotations` | Service annotations for the Unifi Controller | `{}` | | `captivePortalService.http` | `8880` | Kubernetes port where the captive portal is exposed |
| `controllerService.labels` | Custom labels | `{}` | | `captivePortalService.https` | `8843` | Kubernetes port where the captive portal is exposed (with SSL) |
| `controllerService.loadBalancerIP` | Loadbalance IP for the Unifi Controller | `{}` | | `captivePortalService.annotations` | `{}` | Service annotations for the captive portal |
| `controllerService.loadBalancerSourceRanges` | List of IP CIDRs allowed access to load balancer (if supported) | None | | `captivePortalService.labels` | `{}` | Custom labels |
| `controllerService.externalTrafficPolicy` | Set the externalTrafficPolicy in the Service to either Cluster or Local | `Cluster` | | `captivePortalService.loadBalancerIP` | `{}` | Loadbalance IP for the Unifi GUI |
| `stunService.type` | Kubernetes service type for the Unifi STUN | `NodePort` | | `captivePortalService.loadBalancerSourceRanges` | None | List of IP CIDRs allowed access to load balancer (if supported) |
| `stunService.port` | Kubernetes UDP port where the Unifi STUN is exposed | `3478` | | `captivePortalService.externalTrafficPolicy` | `Cluster` | Set the externalTrafficPolicy in the Service to either Cluster or Local |
| `stunService.annotations` | Service annotations for the Unifi STUN | `{}` | | `captivePortalService.ingress.enabled` | `false` | Enables Ingress (for the captive portal, the main ingress needs to be enabled for the controller to be accessible) |
| `stunService.labels` | Custom labels | `{}` | | `captivePortalService.ingress.annotations` | `{}` | Ingress annotations for the captive portal |
| `stunService.loadBalancerIP` | Loadbalance IP for the Unifi STUN | `{}` | | `captivePortalService.ingress.labels` | `{}` | Custom labels for the captive portal |
| `stunService.loadBalancerSourceRanges` | List of IP CIDRs allowed access to load balancer (if supported) | None | | `captivePortalService.ingress.path` | `/` | Ingress path for the captive portal |
| `stunService.externalTrafficPolicy` | Set the externalTrafficPolicy in the Service to either Cluster or Local | `Cluster` | | `captivePortalService.ingress.hosts` | `chart-example.local` | Ingress accepted hostnames for the captive portal |
| `discoveryService.type` | Kubernetes service type for AP discovery | `NodePort` | | `captivePortalService.ingress.tls` | `[]` | Ingress TLS configuration for the captive portal |
| `discoveryService.port` | Kubernetes UDP port for AP discovery | `10001` | | `controllerService.type` | `NodePort` | Kubernetes service type for the Unifi Controller communication |
| `discoveryService.annotations` | Service annotations for AP discovery | `{}` | | `controllerService.port` | `8080` | Kubernetes port where the Unifi Controller is exposed - this needs to be reachable by the unifi devices on the network |
| `discoveryService.labels` | Custom labels | `{}` | | `controllerService.annotations` | `{}` | Service annotations for the Unifi Controller |
| `discoveryService.loadBalancerIP` | Loadbalance IP for AP discovery | `{}` | | `controllerService.labels` | `{}` | Custom labels |
| `discoveryService.loadBalancerSourceRanges` | List of IP CIDRs allowed access to load balancer (if supported) | None | | `controllerService.loadBalancerIP` | `{}` | Loadbalance IP for the Unifi Controller |
| `discoveryService.externalTrafficPolicy` | Set the externalTrafficPolicy in the Service to either Cluster or Local | `Cluster` | | `controllerService.loadBalancerSourceRanges` | None | List of IP CIDRs allowed access to load balancer (if supported) |
| `unifiedService.enabled` | Use a single service for GUI, controller, STUN, and discovery | `false` | | `controllerService.externalTrafficPolicy` | `Cluster` | Set the externalTrafficPolicy in the Service to either Cluster or Local |
| `unifiedService.type` | Kubernetes service type for the unified service | `ClusterIP` | | `stunService.type` | `NodePort` | Kubernetes service type for the Unifi STUN |
| `unifiedService.annotations` | Annotations for the unified service | `{}` | | `stunService.port` | `3478` | Kubernetes UDP port where the Unifi STUN is exposed |
| `unifiedService.labels` | Custom labels for the unified service | `{}` | | `stunService.annotations` | `{}` | Service annotations for the Unifi STUN |
| `unifiedService.loadBalancerIP` | Load balancer IP for the unified service | None | | `stunService.labels` | `{}` | Custom labels |
| `unifiedService.loadBalancerSourceRanges` | List of IP CIDRs allowed access to the load balancer (if supported) | None | | `stunService.loadBalancerIP` | `{}` | Loadbalance IP for the Unifi STUN |
| `unifiedService.externalTrafficPolicy` | Set the externalTrafficPolicy in the service to either Cluster or Local | `Cluster` | | `stunService.loadBalancerSourceRanges` | None | List of IP CIDRs allowed access to load balancer (if supported) |
| `ingress.enabled` | Enables Ingress | `false` | | `stunService.externalTrafficPolicy` | `Cluster` | Set the externalTrafficPolicy in the Service to either Cluster or Local |
| `ingress.annotations` | Ingress annotations | `{}` | | `discoveryService.type` | `NodePort` | Kubernetes service type for AP discovery |
| `ingress.labels` | Custom labels | `{}` | | `discoveryService.port` | `10001` | Kubernetes UDP port for AP discovery |
| `ingress.path` | Ingress path | `/` | | `discoveryService.annotations` | `{}` | Service annotations for AP discovery |
| `ingress.hosts` | Ingress accepted hostnames | `chart-example.local` | | `discoveryService.labels` | `{}` | Custom labels |
| `ingress.tls` | Ingress TLS configuration | `[]` | | `discoveryService.loadBalancerIP` | `{}` | Loadbalance IP for AP discovery |
| `timezone` | Timezone the Unifi controller should run as, e.g. 'America/New York' | `UTC` | | `discoveryService.loadBalancerSourceRanges` | None | List of IP CIDRs allowed access to load balancer (if supported) |
| `runAsRoot` | Run the controller as UID0 (root user); if set to false, will give container SETFCAP instead | `false` | | `discoveryService.externalTrafficPolicy` | `Cluster` | Set the externalTrafficPolicy in the Service to either Cluster or Local |
| `UID` | Run the controller as user UID | `999` | | `unifiedService.enabled` | `false` | Use a single service for GUI, controller, STUN, and discovery |
| `GID` | Run the controller as group GID | `999` | | `unifiedService.type` | `ClusterIP` | Kubernetes service type for the unified service |
| `mongodb.enabled` | Use external MongoDB for data storage | `false` | | `unifiedService.annotations` | `{}` | Annotations for the unified service |
| `mongodb.dbUri` | external MongoDB URI | `mongodb://mongo/unifi` | | `unifiedService.labels` | `{}` | Custom labels for the unified service |
| `mongodb.statDbUri` | external MongoDB statdb URI | `mongodb://mongo/unifi_stat` | | `unifiedService.loadBalancerIP` | None | Load balancer IP for the unified service |
| `mongodb.databaseName` | external MongoDB database name | `unifi` | | `unifiedService.loadBalancerSourceRanges` | None | List of IP CIDRs allowed access to the load balancer (if supported) |
| `persistence.enabled` | Use persistent volume to store data | `true` | | `unifiedService.externalTrafficPolicy` | `Cluster` | Set the externalTrafficPolicy in the service to either Cluster or Local |
| `persistence.size` | Size of persistent volume claim | `5Gi` | | `ingress.enabled` | `false` | Enables Ingress |
| `persistence.existingClaim` | Use an existing PVC to persist data | `nil` | | `ingress.annotations` | `{}` | Ingress annotations |
| `persistence.storageClass` | Type of persistent volume claim | `-` | | `ingress.labels` | `{}` | Custom labels |
| `persistence.accessModes` | Persistence access modes | `[]` | | `ingress.path` | `/` | Ingress path |
| `extraConfigFiles` | Dictionary containing files mounted to `/configmap` inside the pod (See [values.yaml](values.yaml) for examples) | `{}` | | `ingress.hosts` | `chart-example.local` | Ingress accepted hostnames |
| `extraJvmOpts` | List of additional JVM options, e.g. `["-Dlog4j.configurationFile=file:/configmap/log4j2.xml"]` | `[]` | | `ingress.tls` | `[]` | Ingress TLS configuration |
| `resources` | CPU/Memory resource requests/limits | `{}` | | `timezone` | `UTC` | Timezone the Unifi controller should run as, e.g. 'America/New York' |
| `nodeSelector` | Node labels for pod assignment | `{}` | | `runAsRoot` | `false` | Run the controller as UID0 (root user); if set to false, will give container SETFCAP instead |
| `tolerations` | Toleration labels for pod assignment | `[]` | | `UID` | `999` | Run the controller as user UID |
| `affinity` | Affinity settings for pod assignment | `{}` | | `GID` | `999` | Run the controller as group GID |
| `podAnnotations` | Key-value pairs to add as pod annotations | `{}` | | `mongodb.enabled` | `false` | Use external MongoDB for data storage |
| `deploymentAnnotations` | Key-value pairs to add as deployment annotations | `{}` | | `mongodb.dbUri` | `mongodb://mongo/unifi` | external MongoDB URI |
| `mongodb.statDbUri` | `mongodb://mongo/unifi_stat` | external MongoDB statdb URI |
| `mongodb.databaseName` | `unifi` | external MongoDB database name |
| `persistence.enabled` | `true` | Use persistent volume to store data |
| `persistence.size` | `5Gi` | Size of persistent volume claim |
| `persistence.existingClaim` | `nil` | Use an existing PVC to persist data |
| `persistence.storageClass` | `-` | Type of persistent volume claim |
| `persistence.accessModes` | `[]` | Persistence access modes |
| `extraConfigFiles` | `{}` | Dictionary containing files mounted to `/configmap` inside the pod (See [values.yaml](values.yaml) for examples) |
| `extraJvmOpts` | `[]` | List of additional JVM options, e.g. `["-Dlog4j.configurationFile=file:/configmap/log4j2.xml"]` |
| `resources` | `{}` | CPU/Memory resource requests/limits |
| `nodeSelector` | `{}` | Node labels for pod assignment |
| `tolerations` | `[]` | Toleration labels for pod assignment |
| `affinity` | `{}` | Affinity settings for pod assignment |
| `podAnnotations` | `{}` | Key-value pairs to add as pod annotations |
| `deploymentAnnotations` | `{}` | Key-value pairs to add as deployment annotations |
Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example,
@ -123,6 +138,9 @@ Read through the [values.yaml](values.yaml) file. It has several commented out s
- `guiService`: Represents the main web UI and is what one would normally point - `guiService`: Represents the main web UI and is what one would normally point
the ingress to. the ingress to.
- `captivePortalService`: This service is used to allow the captive portal webpage
to be accessible. It needs to be reachable by the clients connecting to your guest
network.
- `controllerService`: This is needed in order for the unifi devices to talk to - `controllerService`: This is needed in order for the unifi devices to talk to
the controller and must be otherwise exposed to the network where the unifi the controller and must be otherwise exposed to the network where the unifi
devices run. If you run this as a `NodePort` (the default setting), make sure devices run. If you run this as a `NodePort` (the default setting), make sure
@ -136,10 +154,12 @@ Read through the [values.yaml](values.yaml) file. It has several commented out s
article][ubnt 4] for more information. article][ubnt 4] for more information.
## Ingress and HTTPS ## Ingress and HTTPS
Unifi does [not support HTTP][unifi] so if you wish to use the guiService, you Unifi does [not support HTTP][unifi] so if you wish to use the guiService, you
need to ensure that you use a backend transport of HTTPS. need to ensure that you use a backend transport of HTTPS.
An example entry in `values.yaml` to achieve this is as follows: An example entry in `values.yaml` to achieve this is as follows:
``` ```
ingress: ingress:
enabled: true enabled: true

View File

@ -0,0 +1,39 @@
{{- if (and .Values.captivePortalService.ingress.enabled (not .Values.unifiedService.enabled)) }}
{{- $fullName := include "unifi.fullname" . -}}
{{- $ingressPath := .Values.captivePortalService.ingress.path -}}
{{- $unifiedServiceEnabled := .Values.unifiedService.enabled -}}
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: {{ $fullName }}-captive
labels:
app.kubernetes.io/name: {{ include "unifi.name" . }}
helm.sh/chart: {{ include "unifi.chart" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- with .Values.captivePortalService.ingress.annotations }}
annotations:
{{ toYaml . | indent 4 }}
{{- end }}
spec:
{{- if .Values.captivePortalService.ingress.tls }}
tls:
{{- range .Values.captivePortalService.ingress.tls }}
- hosts:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
rules:
{{- range .Values.captivePortalService.ingress.hosts }}
- host: {{ . }}
http:
paths:
- path: {{ $ingressPath }}
backend:
serviceName: {{ $fullName }}-captivePortalService
servicePort: captive-http
{{- end }}
{{- end }}

View File

@ -0,0 +1,61 @@
{{ if (and .Values.captivePortalService.enabled (not .Values.unifiedService.enabled)) }}
apiVersion: v1
kind: Service
metadata:
name: {{ template "unifi.fullname" . }}-captivePortalService
labels:
app.kubernetes.io/name: {{ include "unifi.name" . }}
helm.sh/chart: {{ include "unifi.chart" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- if .Values.captivePortalService.labels }}
{{ toYaml .Values.captivePortalService.labels | indent 4 }}
{{- end }}
{{- with .Values.captivePortalService.annotations }}
annotations:
{{ toYaml . | indent 4 }}
{{- end }}
spec:
{{- if (or (eq .Values.captivePortalService.type "ClusterIP") (empty .Values.captivePortalService.type)) }}
type: ClusterIP
{{- if .Values.captivePortalService.clusterIP }}
clusterIP: {{ .Values.captivePortalService.clusterIP }}
{{end}}
{{- else if eq .Values.captivePortalService.type "LoadBalancer" }}
type: {{ .Values.captivePortalService.type }}
{{- if .Values.captivePortalService.loadBalancerIP }}
loadBalancerIP: {{ .Values.captivePortalService.loadBalancerIP }}
{{- end }}
{{- if .Values.captivePortalService.loadBalancerSourceRanges }}
loadBalancerSourceRanges:
{{ toYaml .Values.captivePortalService.loadBalancerSourceRanges | indent 4 }}
{{- end -}}
{{- else }}
type: {{ .Values.captivePortalService.type }}
{{- end }}
{{- if .Values.captivePortalService.externalIPs }}
externalIPs:
{{ toYaml .Values.captivePortalService.externalIPs | indent 4 }}
{{- end }}
{{- if .Values.captivePortalService.externalTrafficPolicy }}
externalTrafficPolicy: {{ .Values.captivePortalService.externalTrafficPolicy }}
{{- end }}
ports:
- port: {{ .Values.captivePortalService.http }}
targetPort: captive-http
protocol: TCP
name: captive-http
{{ if (and (eq .Values.captivePortalService.type "NodePort") (not (empty .Values.captivePortalService.nodePorts.http))) }}
nodePort: {{.Values.captivePortalService.nodePorts.http}}
{{ end }}
- port: {{ .Values.captivePortalService.https }}
targetPort: captive-https
protocol: TCP
name: captive-https
{{ if (and (eq .Values.captivePortalService.type "NodePort") (not (empty .Values.captivePortalService.nodePorts.https))) }}
nodePort: {{.Values.captivePortalService.nodePorts.https}}
{{ end }}
selector:
app.kubernetes.io/name: {{ include "unifi.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{ end }}

View File

@ -50,6 +50,14 @@ spec:
- name: stun - name: stun
containerPort: 3478 containerPort: 3478
protocol: UDP protocol: UDP
{{ if .Values.captivePortalService.enabled }}
- name: captive-http
containerPort: 8880
protocol: TCP
- name: captive-https
containerPort: 8843
protocol: TCP
{{ end }}
{{- if not .Values.runAsRoot }} {{- if not .Values.runAsRoot }}
securityContext: securityContext:
capabilities: capabilities:

View File

@ -69,6 +69,23 @@ spec:
{{ if (and (eq .Values.unifiedService.type "NodePort") (not (empty .Values.guiService.nodePort))) }} {{ if (and (eq .Values.unifiedService.type "NodePort") (not (empty .Values.guiService.nodePort))) }}
nodePort: {{.Values.guiService.nodePort}} nodePort: {{.Values.guiService.nodePort}}
{{ end }} {{ end }}
{{ if .Values.captivePortalService.enabled }}
- name: captive-http
port: {{ .Values.captivePortalService.http }}
protocol: TCP
targetPort: captive-http
{{ if (and (eq .Values.unifiedService.type "NodePort") (not (empty .Values.captivePortalService.http))) }}
nodePort: {{.Values.captivePortalService.nodePorts.http}}
{{ end }}
- name: captive-https
port: {{ .Values.captivePortalService.https }}
protocol: TCP
targetPort: captive-https
{{ if (and (eq .Values.unifiedService.type "NodePort") (not (empty .Values.captivePortalService.https))) }}
nodePort: {{.Values.captivePortalService.nodePorts.https}}
{{ end }}
{{ end }}
selector: selector:
app.kubernetes.io/name: {{ include "unifi.name" . }} app.kubernetes.io/name: {{ include "unifi.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/instance: {{ .Release.Name }}

View File

@ -59,6 +59,47 @@ guiService:
## Set the externalTrafficPolicy in the Service to either Cluster or Local ## Set the externalTrafficPolicy in the Service to either Cluster or Local
# externalTrafficPolicy: Cluster # externalTrafficPolicy: Cluster
captivePortalService:
enabled: false
type: ClusterIP
http: 8880
https: 8843
## Specify the nodePort value for the LoadBalancer and NodePort service types.
## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport
##
# nodePort:
# http: 8880
# https: 8843
## Provide any additional annotations which may be required. This can be used to
## set the LoadBalancer service type to internal only.
## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer
##
annotations: {}
labels: {}
## Use loadBalancerIP to request a specific static IP,
## otherwise leave blank
##
loadBalancerIP:
# loadBalancerSourceRanges: []
## Set the externalTrafficPolicy in the Service to either Cluster or Local
# externalTrafficPolicy: Cluster
# Ingress settings only for the captive portal
ingress:
enabled: false
annotations: {}
# nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
path: /
hosts:
- chart-example.local
tls: []
# - secretName: chart-example-tls
# hosts:
# - chart-example.local
controllerService: controllerService:
type: NodePort type: NodePort
port: 8080 port: 8080