From da0f3ea05f472d37a6ce078210ad557fd85ddd67 Mon Sep 17 00:00:00 2001 From: Erki Aas Date: Thu, 14 Aug 2025 20:28:42 +0300 Subject: [PATCH] Add unifi controller --- argocd/applications/unifi.yaml | 18 ++++ rook-ceph/storage-classes.yaml | 26 +++++ unifi/kustomization.yaml | 8 ++ unifi/unifi-mongo.yaml | 68 ++++++++++++ unifi/unifi.yaml | 186 +++++++++++++++++++++++++++++++++ 5 files changed, 306 insertions(+) create mode 100644 argocd/applications/unifi.yaml create mode 100644 unifi/kustomization.yaml create mode 100644 unifi/unifi-mongo.yaml create mode 100644 unifi/unifi.yaml diff --git a/argocd/applications/unifi.yaml b/argocd/applications/unifi.yaml new file mode 100644 index 0000000..a301c28 --- /dev/null +++ b/argocd/applications/unifi.yaml @@ -0,0 +1,18 @@ +--- +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: unifi + namespace: unifi +spec: + project: k-space.ee + source: + repoURL: 'git@git.k-space.ee:k-space/kube.git' + path: unifi + targetRevision: HEAD + destination: + server: 'https://kubernetes.default.svc' + namespace: unifi + syncPolicy: + automated: + prune: true diff --git a/rook-ceph/storage-classes.yaml b/rook-ceph/storage-classes.yaml index 5050be3..3c48304 100644 --- a/rook-ceph/storage-classes.yaml +++ b/rook-ceph/storage-classes.yaml @@ -156,6 +156,32 @@ volumeBindingMode: WaitForFirstConsumer --- apiVersion: storage.k8s.io/v1 kind: StorageClass +metadata: + name: unifi + annotations: + kubernetes.io/description: | + Storage class for Unifi and similar applications + deployed in highly available fashion utilizing application level + replication needing persistent volume. +provisioner: rook-ceph.rbd.csi.ceph.com +parameters: + clusterID: rook-ceph + csi.storage.k8s.io/controller-expand-secret-name: rook-csi-rbd-provisioner + csi.storage.k8s.io/controller-expand-secret-namespace: rook-ceph + csi.storage.k8s.io/fstype: xfs + csi.storage.k8s.io/node-stage-secret-name: rook-csi-rbd-node + csi.storage.k8s.io/node-stage-secret-namespace: rook-ceph + csi.storage.k8s.io/provisioner-secret-name: rook-csi-rbd-provisioner + csi.storage.k8s.io/provisioner-secret-namespace: rook-ceph + imageFeatures: layering + imageFormat: '2' + pool: ks-nvme +reclaimPolicy: Retain +allowVolumeExpansion: true +volumeBindingMode: WaitForFirstConsumer +--- +apiVersion: storage.k8s.io/v1 +kind: StorageClass metadata: name: hdd-ceph annotations: diff --git a/unifi/kustomization.yaml b/unifi/kustomization.yaml new file mode 100644 index 0000000..d946665 --- /dev/null +++ b/unifi/kustomization.yaml @@ -0,0 +1,8 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +namespace: &ns unifi + +resources: +- unifi-mongo.yaml +- unifi.yaml diff --git a/unifi/unifi-mongo.yaml b/unifi/unifi-mongo.yaml new file mode 100644 index 0000000..98cb4fd --- /dev/null +++ b/unifi/unifi-mongo.yaml @@ -0,0 +1,68 @@ +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: unifi-mongo-init + namespace: unifi +data: + init-mongo.js: | + db.getSiblingDB("unifi").createUser({user: "unifi", pwd: "unifipass", roles: [{role: "dbOwner", db: "unifi"}]}); + db.getSiblingDB("unifi_stat").createUser({user: "unifi",pwd: "unifipass",roles: [{role: "dbOwner", db: "unifi_stat"}]}); +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: unifi-db + namespace: unifi +spec: + selector: + matchLabels: + app: unifi-db + serviceName: "router-manager-db" + replicas: 1 + minReadySeconds: 10 + template: + metadata: + labels: + app: unifi-db + spec: + terminationGracePeriodSeconds: 10 + containers: + - name: mongodb + image: mongo:4 + ports: + - containerPort: 27017 + name: mongo + volumeMounts: + - name: data + mountPath: /data/db + - name: unifi-mongo-init + mountPath: /docker-entrypoint-initdb.d/init-mongo.js + subPath: init-mongo.js + volumes: + - name: unifi-mongo-init + configMap: + name: unifi-mongo-init + volumeClaimTemplates: + - metadata: + name: data + spec: + accessModes: [ "ReadWriteOnce" ] + storageClassName: unifi + resources: + requests: + storage: 10Gi +--- +apiVersion: v1 +kind: Service +metadata: + name: unifi-db + namespace: unifi +spec: + ports: + - port: 27017 + name: mongo + targetPort: 27017 + selector: + app: unifi-db + type: ClusterIP diff --git a/unifi/unifi.yaml b/unifi/unifi.yaml new file mode 100644 index 0000000..43298d4 --- /dev/null +++ b/unifi/unifi.yaml @@ -0,0 +1,186 @@ +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: unifi-app + namespace: unifi +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + storageClassName: unifi +--- +kind: StatefulSet +apiVersion: apps/v1 +metadata: + name: unifi + namespace: unifi +spec: + serviceName: "unifi" + replicas: 1 + selector: + matchLabels: + name: unifi + template: + metadata: + name: unifi + labels: + name: unifi + spec: + containers: + - name: unifi + image: lscr.io/linuxserver/unifi-network-application:latest + env: + - name: PUID + value: '1000' + - name: GUID + value: '1000' + - name: TZ + value: Etc/UTC + - name: MONGO_USER + value: "unifi" + - name: MONGO_PASSWORD + value: "unifipass" + - name: MONGO_HOST + value: unifi-db + - name: MONGO_DBNAME + value: "unifi" + - name: MONGO_PORT + value: "27017" + ports: + - containerPort: 3478 + protocol: UDP + - containerPort: 10001 + protocol: UDP + - containerPort: 8080 + protocol: TCP + - containerPort: 8443 + protocol: TCP + - containerPort: 1900 + protocol: UDP + - containerPort: 8843 + protocol: TCP + - containerPort: 8880 + protocol: TCP + - containerPort: 6789 + protocol: TCP + - containerPort: 5514 + protocol: UDP + volumeMounts: + - name: unifi-persistent-storage + mountPath: /config + volumes: + - name: unifi-persistent-storage + persistentVolumeClaim: + claimName: unifi-app +--- +kind: Service +apiVersion: v1 +metadata: + name: lb-unifi + namespace: unifi + annotations: + metallb.universe.tf/allow-shared-ip: 'true' +spec: + type: LoadBalancer + externalTrafficPolicy: Local + loadBalancerIP: 172.21.102.1 + selector: + name: unifi + ports: + - name: '8080' + protocol: TCP + port: 8080 + targetPort: 8080 + - name: '8443' + protocol: TCP + port: 8443 + targetPort: 8443 + - name: '1900' + protocol: TCP + port: 1900 + targetPort: 1900 + - name: '8843' + protocol: TCP + port: 8843 + targetPort: 8843 + - name: '8880' + protocol: TCP + port: 8880 + targetPort: 8880 + - name: '6789' + protocol: TCP + port: 6789 + targetPort: 6789 +--- +kind: Service +apiVersion: v1 +metadata: + name: lb-unifi-udp + namespace: unifi + annotations: + metallb.universe.tf/allow-shared-ip: 'true' +spec: + type: LoadBalancer + externalTrafficPolicy: Local + loadBalancerIP: 172.21.102.1 + selector: + name: unifi + ports: + - name: '3478' + protocol: UDP + port: 3478 + targetPort: 3478 + - name: '10001' + protocol: UDP + port: 10001 + targetPort: 10001 + - name: '5514' + protocol: UDP + port: 5514 + targetPort: 5514 + selector: + name: unifi + type: LoadBalancer + externalTrafficPolicy: Local +--- +apiVersion: traefik.io/v1alpha1 +kind: ServersTransport +metadata: + name: unifi + namespace: unifi +spec: + insecureSkipVerify: true +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: unifi + namespace: unifi + annotations: + traefik.ingress.kubernetes.io/router.tls: "true" + kubernetes.io/ingress.class: traefik + traefik.ingress.kubernetes.io/router.entrypoints: websecure + external-dns.alpha.kubernetes.io/target: traefik.k-space.ee +spec: + rules: + - host: "unifi.k-space.ee" + http: + paths: + - pathType: Prefix + path: / + backend: + service: + name: lb-unifi + port: + number: 8443 +--- +apiVersion: codemowers.cloud/v1beta1 +kind: OIDCMiddlewareClient +metadata: + name: unifi + namespace: unifi +spec: + uri: 'https://unifi.k-space.ee/'