diff --git a/apps/holyarrs/deployment.yaml b/apps/holyarrs/deployment.yaml new file mode 100644 index 0000000..2bcaf33 --- /dev/null +++ b/apps/holyarrs/deployment.yaml @@ -0,0 +1,74 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: holyarrs + namespace: holyarrs +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: holyarrs + strategy: + type: Recreate + template: + metadata: + labels: + app.kubernetes.io/name: holyarrs + spec: + containers: + - env: + - name: TZ + value: Etc/UTC + - name: HOLYARRS_ALLOWED_HOSTS + value: holyarrs.whyredfire.dev + # Traefik's pods + - name: HOLYARRS_TRUSTED_PROXIES + value: 10.42.0.0/16 + image: holyarrs/holyarrs:1.0.9@sha256:3d941aa8a78d4474cc016a0d994b2531aa8692015aaad487cbdee136e8dd4226 + livenessProbe: + httpGet: + path: /healthz + port: http + initialDelaySeconds: 10 + periodSeconds: 30 + name: holyarrs + ports: + - containerPort: 6262 + name: http + readinessProbe: + httpGet: + path: /healthz + port: http + resources: + limits: + cpu: 1000m + memory: 1Gi + requests: + cpu: 50m + memory: 192Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + volumeMounts: + - mountPath: /config + name: config + # Same path as Jellyfin; one mount so imports hardlink instead of copy + - mountPath: /media + name: media + # Owner of /srv/media, same as qBittorrent + securityContext: + fsGroup: 1000 + runAsGroup: 1000 + runAsNonRoot: true + runAsUser: 1000 + seccompProfile: + type: RuntimeDefault + volumes: + - name: config + persistentVolumeClaim: + claimName: holyarrs-config + - hostPath: + path: /srv/media + name: media diff --git a/apps/holyarrs/httproute.yaml b/apps/holyarrs/httproute.yaml new file mode 100644 index 0000000..bbe70ec --- /dev/null +++ b/apps/holyarrs/httproute.yaml @@ -0,0 +1,23 @@ +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + annotations: + argocd.argoproj.io/sync-wave: "2" + name: holyarrs + namespace: holyarrs +spec: + hostnames: + - holyarrs.whyredfire.dev + parentRefs: + - kind: Gateway + name: traefik-gateway + namespace: traefik + sectionName: websecure + rules: + - backendRefs: + - name: holyarrs + port: 6262 + matches: + - path: + type: PathPrefix + value: / diff --git a/apps/holyarrs/kustomization.yaml b/apps/holyarrs/kustomization.yaml new file mode 100644 index 0000000..d5e7205 --- /dev/null +++ b/apps/holyarrs/kustomization.yaml @@ -0,0 +1,8 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - pvc.yaml + - deployment.yaml + - service.yaml + - httproute.yaml + - networkpolicy.yaml diff --git a/apps/holyarrs/networkpolicy.yaml b/apps/holyarrs/networkpolicy.yaml new file mode 100644 index 0000000..7b56dba --- /dev/null +++ b/apps/holyarrs/networkpolicy.yaml @@ -0,0 +1,62 @@ +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: holyarrs + namespace: holyarrs +spec: + # Metadata and indexers are on the internet; in the cluster it only talks + # to Jellyfin and qBittorrent + egress: + - ports: + - port: 53 + protocol: UDP + - port: 53 + protocol: TCP + to: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: kube-system + podSelector: + matchLabels: + k8s-app: kube-dns + - ports: + - port: 8096 + protocol: TCP + to: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: jellyfin + podSelector: + matchLabels: + app.kubernetes.io/name: jellyfin + - ports: + - port: 8080 + protocol: TCP + to: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: qbit + podSelector: + matchLabels: + app.kubernetes.io/name: qbittorrent + - to: + - ipBlock: + cidr: 0.0.0.0/0 + except: + - 10.0.0.0/8 + - 172.16.0.0/12 + - 192.168.0.0/16 + ingress: + - from: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: traefik + ports: + - port: 6262 + protocol: TCP + podSelector: + matchLabels: + app.kubernetes.io/name: holyarrs + policyTypes: + - Ingress + - Egress diff --git a/apps/holyarrs/pvc.yaml b/apps/holyarrs/pvc.yaml new file mode 100644 index 0000000..2cb425b --- /dev/null +++ b/apps/holyarrs/pvc.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: holyarrs-config + namespace: holyarrs +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi diff --git a/apps/holyarrs/service.yaml b/apps/holyarrs/service.yaml new file mode 100644 index 0000000..d036086 --- /dev/null +++ b/apps/holyarrs/service.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Service +metadata: + name: holyarrs + namespace: holyarrs +spec: + ports: + - name: http + port: 6262 + targetPort: http + selector: + app.kubernetes.io/name: holyarrs diff --git a/apps/jellyfin/kustomization.yaml b/apps/jellyfin/kustomization.yaml index dcb0595..ed1ae6d 100644 --- a/apps/jellyfin/kustomization.yaml +++ b/apps/jellyfin/kustomization.yaml @@ -3,3 +3,4 @@ kind: Kustomization resources: - httproute-local.yaml - httproute.yaml + - networkpolicy-holyarrs.yaml diff --git a/apps/jellyfin/networkpolicy-holyarrs.yaml b/apps/jellyfin/networkpolicy-holyarrs.yaml new file mode 100644 index 0000000..5038ed2 --- /dev/null +++ b/apps/jellyfin/networkpolicy-holyarrs.yaml @@ -0,0 +1,25 @@ +# Lets HolyArrs ask Jellyfin to rescan after imports and sign people in. +# Adds to the chart's policy, which only admits traefik. +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: jellyfin-from-holyarrs + namespace: jellyfin +spec: + ingress: + - from: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: holyarrs + podSelector: + matchLabels: + app.kubernetes.io/name: holyarrs + ports: + - port: 8096 + protocol: TCP + podSelector: + matchLabels: + app.kubernetes.io/name: jellyfin + app.kubernetes.io/instance: jellyfin + policyTypes: + - Ingress diff --git a/apps/qbit/networkpolicy.yaml b/apps/qbit/networkpolicy.yaml index ab2dd6e..7cb2ce0 100644 --- a/apps/qbit/networkpolicy.yaml +++ b/apps/qbit/networkpolicy.yaml @@ -20,6 +20,17 @@ spec: ports: - port: 8080 protocol: TCP + # HolyArrs sends releases and follows downloads through the Web API + - from: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: holyarrs + podSelector: + matchLabels: + app.kubernetes.io/name: holyarrs + ports: + - port: 8080 + protocol: TCP podSelector: matchLabels: app.kubernetes.io/name: qbittorrent diff --git a/argocd-apps/apps/holyarrs.yaml b/argocd-apps/apps/holyarrs.yaml new file mode 100644 index 0000000..d6f5657 --- /dev/null +++ b/argocd-apps/apps/holyarrs.yaml @@ -0,0 +1,24 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + annotations: + argocd.argoproj.io/client-side-apply-migration-manager: argocd-controller + argocd.argoproj.io/sync-wave: "3" + name: holyarrs + namespace: argocd +spec: + destination: + namespace: holyarrs + server: https://kubernetes.default.svc + project: default + source: + path: apps/holyarrs + repoURL: https://gitea.whyredfire.dev/whyredfire/gitops.git + targetRevision: main + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + - ServerSideApply=true diff --git a/argocd-apps/apps/kustomization.yaml b/argocd-apps/apps/kustomization.yaml index 20f89b7..f2578fa 100644 --- a/argocd-apps/apps/kustomization.yaml +++ b/argocd-apps/apps/kustomization.yaml @@ -6,6 +6,7 @@ resources: - betterslcm.yaml - garage.yaml - garage-ui.yaml + - holyarrs.yaml - jellyfin.yaml - pgweb.yaml - pixelos-applications.yaml