Compare commits
38
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
14dc5247b7 | ||
|
|
68d1a174db | ||
|
|
7efc62e216 | ||
|
|
f50b33cadf | ||
|
|
f96737c576 | ||
|
|
53d7e716f8 | ||
|
|
61e4ee2ba8 | ||
|
|
b447c57e78 | ||
|
|
4f3cf541a4 | ||
|
|
6463c38f68 | ||
|
|
b86aaf3f88 | ||
|
|
c9944cfce8 | ||
|
|
717d1ad619 | ||
|
|
40f30412aa | ||
|
|
3f73e7cd3a | ||
|
|
a7543cb78b | ||
|
|
229e0cf5d8 | ||
|
|
b7cf7632c6 | ||
|
|
b77b0a4d0d | ||
|
|
2485b3ad38 | ||
|
|
a49c852666 | ||
|
|
3aa2cf7616 | ||
|
|
0a36c324da | ||
|
|
8d3578f020 | ||
|
|
10f1a88802 | ||
|
|
4dd46a8e7b | ||
|
|
859d1a7c65 | ||
|
|
0575a50d9e | ||
|
|
33b7b58849 | ||
|
|
dab7c10eca | ||
|
|
378f7e3429 | ||
|
|
fdc08827fb | ||
|
|
3d504c2f62 | ||
|
|
d56deb096e | ||
|
|
222965ba47 | ||
|
|
394bf91c37 | ||
|
|
2f7bc33b84 | ||
|
|
6c045e2e56 |
@@ -103,6 +103,16 @@ data:
|
||||
slug: paperless-proxy
|
||||
state: absent
|
||||
|
||||
# syncthing.paperless.renner.uno is gated by authentik-gate-sync
|
||||
# (kubernetes/apps/paperless/syncthing.yaml), which admits this group.
|
||||
# Members are managed in Authentik.
|
||||
- model: authentik_core.group
|
||||
identifiers:
|
||||
name: Paperless Admins
|
||||
state: present
|
||||
attrs:
|
||||
is_superuser: false
|
||||
|
||||
# vscode.home.renner.uno is gated by authentik-gate-sync
|
||||
# (kubernetes/apps/home-assistant/vscode-ingress.yaml), which admits this
|
||||
# group. Members are managed in Authentik.
|
||||
|
||||
@@ -23,7 +23,7 @@ spec:
|
||||
type: RuntimeDefault
|
||||
containers:
|
||||
- name: gitea-mcp
|
||||
image: docker.gitea.com/gitea-mcp-server:1.11.0 # {"$imagepolicy": "flux-system:gitea-mcp"}
|
||||
image: docker.gitea.com/gitea-mcp-server:1.12.0 # {"$imagepolicy": "flux-system:gitea-mcp"}
|
||||
# Image has no ENTRYPOINT (binary is in CMD), so args alone would replace it.
|
||||
command:
|
||||
- /app/gitea-mcp
|
||||
|
||||
@@ -64,7 +64,7 @@ spec:
|
||||
type: RuntimeDefault
|
||||
containers:
|
||||
- name: shelly-manager
|
||||
image: gitea.renner.uno/konairius/shelly-manager:2026-10-29-0949 # {"$imagepolicy": "flux-system:shelly-manager"}
|
||||
image: gitea.renner.uno/konairius/shelly-manager:2026-10-30-1343 # {"$imagepolicy": "flux-system:shelly-manager"}
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- name: http
|
||||
@@ -106,6 +106,9 @@ spec:
|
||||
# The URL devices download firmware from: Service shelly-manager-firmware.
|
||||
- name: Firmware__PublicBaseUrl
|
||||
value: http://firmware.shelly-manager.renner.uno
|
||||
# Battery devices get their update when they call in.
|
||||
- name: Firmware__SleepyRollout
|
||||
value: "true"
|
||||
- name: ShellyManager__DnsSuffix
|
||||
value: iot.renner.uno
|
||||
# BLE radios: ESP32 esphome bluetooth_proxy nodes (e.g. the M5 Atom
|
||||
|
||||
@@ -223,7 +223,7 @@ spec:
|
||||
type: RuntimeDefault
|
||||
containers:
|
||||
- name: controller
|
||||
image: gitea.renner.uno/konairius/mqtt-account-controller:2026-10-28-0657 # {"$imagepolicy": "flux-system:mqtt-account-controller"}
|
||||
image: gitea.renner.uno/konairius/mqtt-account-controller:2026-10-29-1634 # {"$imagepolicy": "flux-system:mqtt-account-controller"}
|
||||
env:
|
||||
- name: BROKER_URL
|
||||
value: ssl://mosquitto.home-assistant.svc.cluster.local:8884
|
||||
|
||||
@@ -30,7 +30,7 @@ spec:
|
||||
type: RuntimeDefault
|
||||
containers:
|
||||
- name: controller
|
||||
image: gitea.renner.uno/gitea_admin/kuma-sync:2026-10-29-1349 # {"$imagepolicy": "flux-system:kuma-sync"}
|
||||
image: gitea.renner.uno/gitea_admin/kuma-sync:2026-10-30-1314 # {"$imagepolicy": "flux-system:kuma-sync"}
|
||||
env:
|
||||
- name: KUMA_URL
|
||||
value: https://kuma.renner.uno
|
||||
|
||||
@@ -142,4 +142,4 @@ spec:
|
||||
- "[fd02:47::1]:53"
|
||||
- "10.2.47.1:53"
|
||||
labels:
|
||||
dns_name: syncthing.paperless.renner.uno
|
||||
dns_name: sync.paperless.renner.uno
|
||||
|
||||
@@ -158,43 +158,69 @@ spec:
|
||||
relabel_rules = loki.relabel.syslog.rules
|
||||
}
|
||||
|
||||
// UniFi UDM SIEM Server (Network app) — UDP/5514. UDM emits CEF
|
||||
// (Common Event Format), not RFC syslog: payload starts with
|
||||
// "<bsd-ts> <iso-ts> <device-name> CEF:0|Vendor|Product|...".
|
||||
// raw listener captures verbatim; loki.process.udm_cef extracts
|
||||
// CEF header + UNIFI* extension fields and promotes a curated
|
||||
// low-cardinality set to labels.
|
||||
// UniFi activity logging — UDP/5514, one target for two payloads:
|
||||
// the UDM SIEM events in CEF ("<bsd-ts> <device-name> CEF:0|...")
|
||||
// and plain syslog from the UDM (log_all_contents) and from every
|
||||
// adopted AP/switch (debug). raw listener captures verbatim;
|
||||
// loki.process.udm_cef sets `source` per payload type.
|
||||
loki.source.syslog "udp_5514" {
|
||||
listener {
|
||||
address = "0.0.0.0:5514"
|
||||
protocol = "udp"
|
||||
syslog_format = "raw"
|
||||
labels = { job = "syslog", listener = "udp-5514", source = "udm-siem" }
|
||||
labels = { job = "syslog", listener = "udp-5514" }
|
||||
}
|
||||
forward_to = [loki.process.udm_cef.receiver]
|
||||
}
|
||||
|
||||
// CEF parser for UDM SIEM payload. The listener also receives the
|
||||
// UDM's plain syslog (log_all_contents), which does not match and
|
||||
// passes through unlabelled. CEF extension keys differ per event
|
||||
// type, so the regex anchors only on the header
|
||||
// (vendor|product|product_version|sig_id|name|sev), UNIFIcategory,
|
||||
// UNIFIhost and the trailing msg. The full raw line stays the log
|
||||
// content.
|
||||
loki.process "udm_cef" {
|
||||
forward_to = [loki.write.default.receiver]
|
||||
|
||||
stage.regex {
|
||||
expression = "CEF:\\d+\\|(?P<vendor>[^|]*)\\|(?P<product>[^|]*)\\|(?P<product_version>[^|]*)\\|(?P<signature_id>[^|]*)\\|(?P<event_name>[^|]*)\\|(?P<cef_severity>[^|]*)\\|UNIFIcategory=(?P<category>.+?) UNIFIhost=(?P<unifi_host>.+?) \\S+=.* msg=(?P<msg>.+)$"
|
||||
// CEF: extension keys differ per event type, so the regex
|
||||
// anchors only on the header
|
||||
// (vendor|product|product_version|sig_id|name|sev),
|
||||
// UNIFIcategory, UNIFIhost and the trailing msg. The full raw
|
||||
// line stays the log content.
|
||||
stage.match {
|
||||
selector = "{listener=\"udp-5514\"} |= \"CEF:\""
|
||||
|
||||
stage.static_labels {
|
||||
values = { source = "udm-siem" }
|
||||
}
|
||||
|
||||
stage.regex {
|
||||
expression = "CEF:\\d+\\|(?P<vendor>[^|]*)\\|(?P<product>[^|]*)\\|(?P<product_version>[^|]*)\\|(?P<signature_id>[^|]*)\\|(?P<event_name>[^|]*)\\|(?P<cef_severity>[^|]*)\\|UNIFIcategory=(?P<category>.+?) UNIFIhost=(?P<unifi_host>.+?) \\S+=.* msg=(?P<msg>.+)$"
|
||||
}
|
||||
|
||||
stage.labels {
|
||||
values = {
|
||||
vendor = "vendor",
|
||||
product = "product",
|
||||
signature_id = "signature_id",
|
||||
event_name = "event_name",
|
||||
category = "category",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage.labels {
|
||||
values = {
|
||||
vendor = "vendor",
|
||||
product = "product",
|
||||
signature_id = "signature_id",
|
||||
event_name = "event_name",
|
||||
category = "category",
|
||||
// Plain syslog. UDM: "<ts> <host> <host> <app>[pid]: ...";
|
||||
// AP/switch: "<ts> <host> <mac>,<model>-<fw>: [: ]<app>[pid]: ...".
|
||||
stage.match {
|
||||
selector = "{listener=\"udp-5514\"} != \"CEF:\""
|
||||
|
||||
stage.static_labels {
|
||||
values = { source = "unifi-syslog" }
|
||||
}
|
||||
|
||||
stage.regex {
|
||||
expression = "^\\S+ +\\d+ \\S+ (?P<host>\\S+) (?:[0-9a-f]{12},\\S+:(?: :)? |\\S+ )(?P<app>[A-Za-z0-9_./+-]+)"
|
||||
}
|
||||
|
||||
stage.labels {
|
||||
values = {
|
||||
host = "host",
|
||||
app = "app",
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ spec:
|
||||
prober: dns
|
||||
timeout: 5s
|
||||
dns:
|
||||
query_name: syncthing.paperless.renner.uno
|
||||
query_name: sync.paperless.renner.uno
|
||||
query_type: A
|
||||
valid_rcodes: [NOERROR]
|
||||
validate_answer_rrs:
|
||||
|
||||
@@ -39,8 +39,14 @@ spec:
|
||||
replication_factor: 1
|
||||
storage:
|
||||
type: filesystem
|
||||
# retention_period is only enforced by the compactor with
|
||||
# retention_enabled; Loki keeps logs forever otherwise.
|
||||
compactor:
|
||||
working_directory: /var/loki/compactor
|
||||
retention_enabled: true
|
||||
delete_request_store: filesystem
|
||||
limits_config:
|
||||
retention_period: 2160h
|
||||
retention_period: 8760h
|
||||
ingestion_rate_mb: 10
|
||||
ingestion_burst_size_mb: 20
|
||||
max_streams_per_user: 10000
|
||||
|
||||
@@ -54,7 +54,7 @@ spec:
|
||||
# stdlib only; Flux keeps the tag in lockstep via the shared image
|
||||
# policy) — no extra dependency.
|
||||
- name: reconcile-publish-ip
|
||||
image: ghcr.io/music-assistant/server:2.10.8 # {"$imagepolicy": "flux-system:music-assistant"}
|
||||
image: ghcr.io/music-assistant/server:2.10.9 # {"$imagepolicy": "flux-system:music-assistant"}
|
||||
command: ["/app/venv/bin/python", "/scripts/reconcile.py"]
|
||||
volumeMounts:
|
||||
- name: data
|
||||
@@ -67,7 +67,7 @@ spec:
|
||||
# the stock file is the one it was written against (2.10.7 = 2.10.8);
|
||||
# any other version keeps the stock provider.
|
||||
- name: pocketcasts-overlay
|
||||
image: ghcr.io/music-assistant/server:2.10.8 # {"$imagepolicy": "flux-system:music-assistant"}
|
||||
image: ghcr.io/music-assistant/server:2.10.9 # {"$imagepolicy": "flux-system:music-assistant"}
|
||||
command:
|
||||
- /bin/sh
|
||||
- -euc
|
||||
@@ -88,7 +88,7 @@ spec:
|
||||
readOnly: true
|
||||
containers:
|
||||
- name: music-assistant
|
||||
image: ghcr.io/music-assistant/server:2.10.8 # {"$imagepolicy": "flux-system:music-assistant"}
|
||||
image: ghcr.io/music-assistant/server:2.10.9 # {"$imagepolicy": "flux-system:music-assistant"}
|
||||
env:
|
||||
- name: LOG_LEVEL
|
||||
value: info
|
||||
|
||||
@@ -93,7 +93,7 @@ spec:
|
||||
type: RuntimeDefault
|
||||
containers:
|
||||
- name: lidarr
|
||||
image: lscr.io/linuxserver/lidarr:3.1.6.5079-ls46 # {"$imagepolicy": "flux-system:lidarr"}
|
||||
image: ghcr.io/linuxserver/lidarr:3.1.6.5079-ls46 # {"$imagepolicy": "flux-system:lidarr"}
|
||||
env:
|
||||
- name: PUID
|
||||
value: "1000"
|
||||
@@ -140,7 +140,7 @@ spec:
|
||||
drop: ["ALL"]
|
||||
add: ["CHOWN", "DAC_OVERRIDE", "FOWNER", "SETGID", "SETUID"]
|
||||
- name: reconcile
|
||||
image: lscr.io/linuxserver/lidarr:3.1.6.5079-ls46 # {"$imagepolicy": "flux-system:lidarr"}
|
||||
image: ghcr.io/linuxserver/lidarr:3.1.6.5079-ls46 # {"$imagepolicy": "flux-system:lidarr"}
|
||||
command: ["sh", "/scripts/reconcile.sh"]
|
||||
volumeMounts:
|
||||
- name: config
|
||||
|
||||
@@ -182,7 +182,7 @@ spec:
|
||||
drop: ["ALL"]
|
||||
containers:
|
||||
- name: paperless
|
||||
image: ghcr.io/paperless-ngx/paperless-ngx:3.3.4 # {"$imagepolicy": "flux-system:paperless-ngx"}
|
||||
image: ghcr.io/paperless-ngx/paperless-ngx:3.4.1 # {"$imagepolicy": "flux-system:paperless-ngx"}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 8000
|
||||
|
||||
@@ -52,11 +52,8 @@ spec:
|
||||
- name: syncthing
|
||||
image: syncthing/syncthing:2.1.7@sha256:2b71da7c0d0a91a6ae5285ad079226fecc0a365d08b27720e1f7037b018f7546
|
||||
env:
|
||||
# UI bind: any-interface so the ClusterIP Service can reach
|
||||
# it. Network exposure is gated by the absence of an Ingress
|
||||
# and the namespace default-deny CNP — set a UI password in
|
||||
# the Syncthing UI on first port-forward access before
|
||||
# publishing it.
|
||||
# UI bind: any-interface so the ClusterIP Service can reach it.
|
||||
# External access goes through the syncthing-ui Ingress only.
|
||||
- name: STGUIADDRESS
|
||||
value: "0.0.0.0:8384"
|
||||
- name: PUID
|
||||
@@ -115,10 +112,6 @@ spec:
|
||||
persistentVolumeClaim:
|
||||
claimName: paperless-consume
|
||||
---
|
||||
# UI Service — ClusterIP only. Access via `kubectl -n paperless
|
||||
# port-forward svc/syncthing-ui 8384:8384` for first-time setup
|
||||
# (set admin password). Future Ingress + Authentik gate is a
|
||||
# separate change once auth is configured.
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
@@ -132,6 +125,36 @@ spec:
|
||||
port: 8384
|
||||
targetPort: ui
|
||||
---
|
||||
# LAN-only UI: Paperless Admins through the Authentik gate.
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: syncthing-ui
|
||||
namespace: paperless
|
||||
labels:
|
||||
dns.renner.uno/internal: "true"
|
||||
annotations:
|
||||
traefik.ingress.kubernetes.io/router.middlewares: authentik-gate@kubernetescrd
|
||||
cert-manager.io/cluster-issuer: letsencrypt-cluster
|
||||
auth.renner.uno/group: Paperless Admins
|
||||
spec:
|
||||
ingressClassName: traefik
|
||||
rules:
|
||||
- host: syncthing.paperless.renner.uno
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: syncthing-ui
|
||||
port:
|
||||
number: 8384
|
||||
tls:
|
||||
- secretName: syncthing-ui-tls
|
||||
hosts:
|
||||
- syncthing.paperless.renner.uno
|
||||
---
|
||||
# Sync ports — LAN-reachable LoadBalancer. Peers (phones, laptops)
|
||||
# connect here for the dropbox sync. external-dns publishes the
|
||||
# hostname into UniFi DNS only (no cloudflare label); off-LAN peers
|
||||
@@ -146,7 +169,7 @@ metadata:
|
||||
dns.renner.uno/internal: "true"
|
||||
annotations:
|
||||
io.cilium/lb-ipam-ips: "10.2.99.85,fd99::85"
|
||||
external-dns.kubernetes.io/hostname: syncthing.paperless.renner.uno
|
||||
external-dns.kubernetes.io/hostname: sync.paperless.renner.uno
|
||||
spec:
|
||||
type: LoadBalancer
|
||||
externalTrafficPolicy: Local
|
||||
|
||||
@@ -34,7 +34,7 @@ spec:
|
||||
# Image automation, range 3.x (see image-automation/woodpecker.yaml).
|
||||
# MUST stay version-matched with woodpecker-server (gRPC parity) — both
|
||||
# track the same range/filter so they bump together on each release.
|
||||
image: woodpeckerci/woodpecker-agent:v3.20.0 # {"$imagepolicy": "flux-system:woodpecker-agent"}
|
||||
image: woodpeckerci/woodpecker-agent:v3.20.1 # {"$imagepolicy": "flux-system:woodpecker-agent"}
|
||||
env:
|
||||
- name: WOODPECKER_SERVER
|
||||
value: woodpecker.woodpecker.svc.cluster.local:9000 # in-cluster gRPC, replaces LXC :9000
|
||||
|
||||
@@ -40,7 +40,7 @@ spec:
|
||||
# minor + patch auto-update within 3.x; only the 4.0 major is held for
|
||||
# a reviewed bump. Safe now the DB is postgres (the old sqlite-surprise
|
||||
# -bump hazard is gone). Stays in lockstep with the agent.
|
||||
image: woodpeckerci/woodpecker-server:v3.20.0 # {"$imagepolicy": "flux-system:woodpecker-server"}
|
||||
image: woodpeckerci/woodpecker-server:v3.20.1 # {"$imagepolicy": "flux-system:woodpecker-server"}
|
||||
env:
|
||||
- name: WOODPECKER_HOST
|
||||
value: https://ci.renner.uno
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: youtrack
|
||||
namespace: youtrack
|
||||
labels:
|
||||
app.kubernetes.io/name: youtrack
|
||||
spec:
|
||||
replicas: 1
|
||||
# One process owns the database directory.
|
||||
strategy:
|
||||
type: Recreate
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: youtrack
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: youtrack
|
||||
spec:
|
||||
automountServiceAccountToken: false
|
||||
enableServiceLinks: false
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
# The image's service account.
|
||||
runAsUser: 13001
|
||||
runAsGroup: 13001
|
||||
fsGroup: 13001
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
containers:
|
||||
- name: youtrack
|
||||
image: jetbrains/youtrack:2026.2.19728@sha256:c5e9cedc6fb1d7bcc9b3b56fc3f63e563623e1cd39396161eb70957991583950
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop: ["ALL"]
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 8080
|
||||
resources:
|
||||
requests:
|
||||
cpu: 250m
|
||||
memory: 2Gi
|
||||
limits:
|
||||
memory: 4Gi
|
||||
startupProbe:
|
||||
tcpSocket:
|
||||
port: http
|
||||
periodSeconds: 10
|
||||
failureThreshold: 60
|
||||
readinessProbe:
|
||||
tcpSocket:
|
||||
port: http
|
||||
periodSeconds: 10
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
port: http
|
||||
periodSeconds: 30
|
||||
failureThreshold: 4
|
||||
volumeMounts:
|
||||
- name: youtrack
|
||||
mountPath: /opt/youtrack/data
|
||||
subPath: data
|
||||
- name: youtrack
|
||||
mountPath: /opt/youtrack/conf
|
||||
subPath: conf
|
||||
- name: youtrack
|
||||
mountPath: /opt/youtrack/logs
|
||||
subPath: logs
|
||||
- name: youtrack
|
||||
mountPath: /opt/youtrack/backups
|
||||
subPath: backups
|
||||
volumes:
|
||||
- name: youtrack
|
||||
persistentVolumeClaim:
|
||||
claimName: youtrack
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: youtrack
|
||||
namespace: youtrack
|
||||
spec:
|
||||
selector:
|
||||
app.kubernetes.io/name: youtrack
|
||||
ports:
|
||||
- name: http
|
||||
port: 8080
|
||||
targetPort: http
|
||||
@@ -0,0 +1,27 @@
|
||||
# LAN-only (UDM record via dns.renner.uno/internal); no public label until login goes through Authentik.
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: youtrack
|
||||
namespace: youtrack
|
||||
labels:
|
||||
dns.renner.uno/internal: "true"
|
||||
annotations:
|
||||
cert-manager.io/cluster-issuer: letsencrypt-cluster
|
||||
spec:
|
||||
ingressClassName: traefik
|
||||
tls:
|
||||
- hosts:
|
||||
- youtrack.renner.uno
|
||||
secretName: youtrack-tls
|
||||
rules:
|
||||
- host: youtrack.renner.uno
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: youtrack
|
||||
port:
|
||||
number: 8080
|
||||
@@ -0,0 +1,7 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
resources:
|
||||
- pvc.yaml
|
||||
- deployment.yaml
|
||||
- ingress.yaml
|
||||
- oidcclient.yaml
|
||||
@@ -0,0 +1,13 @@
|
||||
# Authentik OIDC client, created by authentik-gate-sync; issuer https://auth.renner.uno/application/o/youtrack/.
|
||||
apiVersion: auth.renner.uno/v1alpha1
|
||||
kind: OIDCClient
|
||||
metadata:
|
||||
name: youtrack
|
||||
namespace: youtrack
|
||||
spec:
|
||||
launchURL: https://youtrack.renner.uno
|
||||
group: YouTrack Users
|
||||
redirectURIs:
|
||||
# YouTrack generates the callback when the auth module is created; pin it strict once known.
|
||||
- matchingMode: regex
|
||||
url: ^https://youtrack\.renner\.uno/.*$
|
||||
@@ -0,0 +1,17 @@
|
||||
# YouTrack data, conf, logs and backups (subPaths); Velero youtrack-daily.
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: youtrack
|
||||
namespace: youtrack
|
||||
labels:
|
||||
app.kubernetes.io/name: youtrack
|
||||
annotations:
|
||||
kustomize.toolkit.fluxcd.io/prune: disabled
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
storageClassName: ceph-block
|
||||
resources:
|
||||
requests:
|
||||
storage: 20Gi
|
||||
@@ -394,3 +394,31 @@ spec:
|
||||
status.validationErrors.exists(e, e.startsWith('No backups found for schedule')))))
|
||||
current: >-
|
||||
has(status.phase) && (status.phase == 'Completed' || status.phase == 'FailedValidation')
|
||||
---
|
||||
apiVersion: kustomize.toolkit.fluxcd.io/v1
|
||||
kind: Kustomization
|
||||
metadata:
|
||||
name: restore-youtrack
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 10m
|
||||
timeout: 1h
|
||||
sourceRef:
|
||||
kind: GitRepository
|
||||
name: flux-system
|
||||
path: ./kubernetes/restore/youtrack
|
||||
prune: true
|
||||
wait: true
|
||||
dependsOn:
|
||||
- name: restore-gitea
|
||||
- name: velero-backups-synced
|
||||
- name: infrastructure-ceph-cluster
|
||||
healthCheckExprs:
|
||||
- apiVersion: velero.io/v1
|
||||
kind: Restore
|
||||
failed: >-
|
||||
has(status.phase) && (status.phase in ['Failed', 'PartiallyFailed'] ||
|
||||
(status.phase == 'FailedValidation' && !(has(status.validationErrors) &&
|
||||
status.validationErrors.exists(e, e.startsWith('No backups found for schedule')))))
|
||||
current: >-
|
||||
has(status.phase) && (status.phase == 'Completed' || status.phase == 'FailedValidation')
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
apiVersion: kustomize.toolkit.fluxcd.io/v1
|
||||
kind: Kustomization
|
||||
metadata:
|
||||
name: youtrack
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 10m
|
||||
retryInterval: 1m
|
||||
timeout: 15m
|
||||
sourceRef:
|
||||
kind: GitRepository
|
||||
name: flux-system
|
||||
path: ./kubernetes/apps/youtrack
|
||||
prune: true
|
||||
wait: true
|
||||
# OIDCClient Ready tracks Authentik (e.g. the group exists), not this apply.
|
||||
healthCheckExprs:
|
||||
- apiVersion: auth.renner.uno/v1alpha1
|
||||
kind: OIDCClient
|
||||
current: "true"
|
||||
dependsOn:
|
||||
- name: restore-youtrack
|
||||
- name: infrastructure
|
||||
- name: infrastructure-crds
|
||||
- name: infrastructure-ceph-cluster
|
||||
@@ -4,7 +4,7 @@ metadata:
|
||||
name: lidarr
|
||||
namespace: flux-system
|
||||
spec:
|
||||
image: lscr.io/linuxserver/lidarr
|
||||
image: ghcr.io/linuxserver/lidarr
|
||||
interval: 1h
|
||||
---
|
||||
# Tags are <maj>.<min>.<patch>.<build>-ls<n>. Two numbers move, and BOTH
|
||||
|
||||
@@ -83,6 +83,11 @@ metadata:
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: youtrack
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: immich
|
||||
---
|
||||
|
||||
@@ -32,6 +32,7 @@ resources:
|
||||
- wordpress-ns.yaml
|
||||
- ai-ns.yaml
|
||||
- navidrome-ns.yaml
|
||||
- youtrack-ns.yaml
|
||||
- uptime-monitor-ns.yaml
|
||||
- kuma-sync-ns.yaml
|
||||
- cloudflare-lb-sync-ns.yaml
|
||||
|
||||
@@ -145,8 +145,8 @@ spec:
|
||||
# Allow Syncthing peer-to-peer sync from the LAN/world.
|
||||
# - 22000 TCP+QUIC: actual sync traffic between peers.
|
||||
# - 21027 UDP: local-discovery broadcast packets from peers on the LAN.
|
||||
# UI (8384) is intentionally NOT listed — accessed via port-forward
|
||||
# until an Ingress + Authentik gate is added.
|
||||
# UI (8384) is intentionally NOT listed — authentik-gate-sync generates the
|
||||
# CNP syncthing-ui-gate that admits traefik.
|
||||
apiVersion: cilium.io/v2
|
||||
kind: CiliumNetworkPolicy
|
||||
metadata:
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
apiVersion: cilium.io/v2
|
||||
kind: CiliumNetworkPolicy
|
||||
metadata:
|
||||
name: default-deny-ingress
|
||||
namespace: youtrack
|
||||
spec:
|
||||
endpointSelector: {}
|
||||
ingress:
|
||||
- fromEndpoints:
|
||||
- matchLabels:
|
||||
"k8s:io.kubernetes.pod.namespace": youtrack
|
||||
- fromEndpoints:
|
||||
- matchLabels:
|
||||
"k8s:io.kubernetes.pod.namespace": ingress
|
||||
app.kubernetes.io/name: traefik
|
||||
- fromEndpoints:
|
||||
- matchLabels:
|
||||
"k8s:io.kubernetes.pod.namespace": monitoring
|
||||
- fromEntities:
|
||||
- host
|
||||
- remote-node
|
||||
# ICMP — all standard ICMPv4 + ICMPv6 from any cluster pod. See
|
||||
# home-assistant-ns.yaml for the rationale (CT-RELATED path not
|
||||
# passing related ICMP empirically; per-namespace shape, mirroring
|
||||
# commit 3c517a0's verified-safe pattern with the 66dbe9f type set).
|
||||
- fromEndpoints:
|
||||
- matchExpressions:
|
||||
- key: io.kubernetes.pod.namespace
|
||||
operator: Exists
|
||||
icmps:
|
||||
- fields:
|
||||
- { type: 0, family: IPv4 }
|
||||
- { type: 3, family: IPv4 }
|
||||
- { type: 8, family: IPv4 }
|
||||
- { type: 11, family: IPv4 }
|
||||
- { type: 12, family: IPv4 }
|
||||
- { type: 1, family: IPv6 }
|
||||
- { type: 2, family: IPv6 }
|
||||
- { type: 3, family: IPv6 }
|
||||
- { type: 4, family: IPv6 }
|
||||
- { type: 128, family: IPv6 }
|
||||
- { type: 129, family: IPv6 }
|
||||
- { type: 133, family: IPv6 }
|
||||
- { type: 134, family: IPv6 }
|
||||
- { type: 135, family: IPv6 }
|
||||
- { type: 136, family: IPv6 }
|
||||
- { type: 143, family: IPv6 }
|
||||
egress:
|
||||
- toEndpoints:
|
||||
- matchLabels:
|
||||
"k8s:io.kubernetes.pod.namespace": youtrack
|
||||
- toEndpoints:
|
||||
- matchLabels:
|
||||
"k8s:io.kubernetes.pod.namespace": ingress
|
||||
app.kubernetes.io/name: traefik
|
||||
- toEndpoints:
|
||||
- matchLabels:
|
||||
"k8s:io.kubernetes.pod.namespace": kube-system
|
||||
k8s-app: kube-dns
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "53"
|
||||
protocol: UDP
|
||||
# host/remote-node: kubelet probes + node-local reach (Ceph mons on host net)
|
||||
- toEntities:
|
||||
- host
|
||||
- remote-node
|
||||
# ICMP — egress mirror; see ingress block above.
|
||||
- toEndpoints:
|
||||
- matchExpressions:
|
||||
- key: io.kubernetes.pod.namespace
|
||||
operator: Exists
|
||||
icmps:
|
||||
- fields:
|
||||
- { type: 0, family: IPv4 }
|
||||
- { type: 3, family: IPv4 }
|
||||
- { type: 8, family: IPv4 }
|
||||
- { type: 11, family: IPv4 }
|
||||
- { type: 12, family: IPv4 }
|
||||
- { type: 1, family: IPv6 }
|
||||
- { type: 2, family: IPv6 }
|
||||
- { type: 3, family: IPv6 }
|
||||
- { type: 4, family: IPv6 }
|
||||
- { type: 128, family: IPv6 }
|
||||
- { type: 129, family: IPv6 }
|
||||
- { type: 133, family: IPv6 }
|
||||
- { type: 134, family: IPv6 }
|
||||
- { type: 135, family: IPv6 }
|
||||
- { type: 136, family: IPv6 }
|
||||
- { type: 143, family: IPv6 }
|
||||
---
|
||||
# Outbound HTTPS: OIDC discovery/token/JWKS at auth.renner.uno (Traefik VIP, matched as traefik
|
||||
# pods above) and JetBrains services (license, update check), mail-free.
|
||||
apiVersion: cilium.io/v2
|
||||
kind: CiliumNetworkPolicy
|
||||
metadata:
|
||||
name: youtrack-egress-https
|
||||
namespace: youtrack
|
||||
spec:
|
||||
endpointSelector: {}
|
||||
egress:
|
||||
- toEntities:
|
||||
- world
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "443"
|
||||
protocol: TCP
|
||||
@@ -369,3 +369,23 @@ spec:
|
||||
labelSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: synapse
|
||||
---
|
||||
apiVersion: velero.io/v1
|
||||
kind: Schedule
|
||||
metadata:
|
||||
name: youtrack-daily
|
||||
namespace: velero
|
||||
labels:
|
||||
app.kubernetes.io/part-of: homelab-backup
|
||||
spec:
|
||||
# Daily at 10:15 local, next free stagger slot after matrix-daily at 09:45.
|
||||
schedule: "15 10 * * *"
|
||||
useOwnerReferencesInBackup: false
|
||||
template:
|
||||
includedNamespaces:
|
||||
- youtrack
|
||||
includedResources:
|
||||
- persistentvolumeclaims
|
||||
storageLocation: default
|
||||
ttl: 720h0m0s
|
||||
snapshotMoveData: true
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
resources:
|
||||
- restore.yaml
|
||||
@@ -0,0 +1,7 @@
|
||||
apiVersion: velero.io/v1
|
||||
kind: Restore
|
||||
metadata:
|
||||
name: youtrack
|
||||
namespace: velero
|
||||
spec:
|
||||
scheduleName: youtrack-daily
|
||||
Reference in New Issue
Block a user