This commit is contained in:
2023-10-19 13:07:09 +02:00
parent fb3e9f56eb
commit a6ae543cfe
40 changed files with 963 additions and 1080 deletions

View File

@@ -1,39 +0,0 @@
locals {
app-name = var.component == var.instance ? var.instance : format("%s-%s", var.component, var.instance)
main-group = format("app-%s", local.app-name)
}
data "authentik_group" "akadmin" {
name = "authentik Admins"
}
resource "authentik_group" "groups" {
name = local.main-group
attributes = jsonencode({"${local.app-name}" = true})
}
resource "authentik_application" "prj_app" {
name = "${var.instance}"
slug = "${var.component}-${var.instance}"
group = var.app-group
protocol_provider = authentik_provider_oauth2.oauth2.id
meta_launch_url = format("https://%s.%s", var.sub-domain, var.domain-name)
meta_icon = format("https://%s.%s/%s", var.sub-domain, var.domain-name, "apps/theming/favicon")
}
resource "authentik_policy_expression" "policy" {
name = local.main-group
expression = <<-EOF
attr = request.user.group_attributes()
return attr['${local.app-name}'] if '${local.app-name}' in attr else False
EOF
}
resource "authentik_policy_binding" "prj_access_users" {
target = authentik_application.prj_app.uuid
policy = authentik_policy_expression.policy.id
order = 0
}
resource "authentik_policy_binding" "prj_access_vynil" {
target = authentik_application.prj_app.uuid
group = data.authentik_group.akadmin.id
order = 1
}

View File

@@ -5,7 +5,7 @@ metadata:
name: nextcloud-metrics
labels:
app.kubernetes.io/name: nextcloud
helm.sh/chart: nextcloud-4.3.1
helm.sh/chart: nextcloud-4.3.5
app.kubernetes.io/instance: nextcloud
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: metrics

View File

@@ -5,7 +5,7 @@ metadata:
name: nextcloud
labels:
app.kubernetes.io/name: nextcloud
helm.sh/chart: nextcloud-4.3.1
helm.sh/chart: nextcloud-4.3.5
app.kubernetes.io/instance: nextcloud
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: app
@@ -31,7 +31,7 @@ spec:
spec:
containers:
- name: nextcloud
image: nextcloud:27.0.2-apache
image: nextcloud:27.1.2-apache
imagePullPolicy: IfNotPresent
env:
- name: POSTGRES_HOST

View File

@@ -5,7 +5,7 @@ metadata:
name: nextcloud
labels:
app.kubernetes.io/name: nextcloud
helm.sh/chart: nextcloud-4.3.1
helm.sh/chart: nextcloud-4.3.5
app.kubernetes.io/instance: nextcloud
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: app

View File

@@ -1,27 +1,7 @@
locals {
collabora-labels = merge(local.common-labels, {
"app.kubernetes.io/component" = "collabora"
})
dns-collabora = "collabora.${local.dns-name}"
collabora-middlewares = ["${var.instance}-https"]
collabora-service = {
"name" = "${var.instance}-collabora"
"port" = {
"number" = 80
}
}
collabora-rules = [ for v in [local.dns-collabora] : {
"host" = "${v}"
"http" = {
"paths" = [{
"backend" = {
"service" = local.collabora-service
}
"path" = "/"
"pathType" = "Prefix"
}]
}
}]
collabora-labels = merge(local.common-labels, {
"app.kubernetes.io/component" = "collabora"
})
}
resource "kubectl_manifest" "collabora_deploy" {
@@ -96,63 +76,3 @@ resource "kubectl_manifest" "collabora_deploy" {
- SYS_ADMIN
EOF
}
resource "kubectl_manifest" "collabora_svc" {
count = var.apps.collabora ? 1 : 0
yaml_body = <<-EOF
apiVersion: v1
kind: Service
metadata:
name: "${var.instance}-collabora"
namespace: "${var.namespace}"
labels: ${jsonencode(local.collabora-labels)}
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 9980
protocol: TCP
name: http
selector: ${jsonencode(local.collabora-labels)}
EOF
}
resource "kubectl_manifest" "collabora_certificate" {
count = var.apps.collabora ? 1 : 0
yaml_body = <<-EOF
apiVersion: "cert-manager.io/v1"
kind: "Certificate"
metadata:
name: "${var.instance}-collabora"
namespace: "${var.namespace}"
labels: ${jsonencode(local.collabora-labels)}
spec:
secretName: "${var.instance}-collabora-cert"
dnsNames: [${jsonencode(local.dns-collabora)}]
issuerRef:
name: "${var.issuer}"
kind: "ClusterIssuer"
group: "cert-manager.io"
EOF
}
resource "kubectl_manifest" "collabora_ing" {
count = var.apps.collabora ? 1 : 0
yaml_body = <<-EOF
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: "${var.instance}-collabora"
namespace: "${var.namespace}"
labels: ${jsonencode(local.collabora-labels)}
annotations:
"traefik.ingress.kubernetes.io/router.middlewares": "${join(",", [for m in local.collabora-middlewares : format("%s-%s@kubernetescrd", var.namespace, m)])}"
spec:
ingressClassName: "${var.ingress-class}"
rules: ${jsonencode(local.collabora-rules)}
tls:
- hosts: [${local.dns-collabora}]
secretName: "${var.instance}-collabora-cert"
EOF
}

View File

@@ -6,111 +6,6 @@ metadata:
name: nextcloud
description: null
options:
apps:
default:
audioplayer: false
bookmarks: false
bpm: false
calendar: false
collabora: false
contacts: false
deck: false
groupfolders: true
mindmap: false
music: false
notes: false
onlyoffice: false
passman: false
spreed: false
tables: false
tasks: false
texteditor: true
examples:
- audioplayer: false
bookmarks: false
bpm: false
calendar: false
collabora: false
contacts: false
deck: false
groupfolders: true
mindmap: false
music: false
notes: false
onlyoffice: false
passman: false
spreed: false
tables: false
tasks: false
texteditor: true
properties:
audioplayer:
default: false
type: boolean
bookmarks:
default: false
type: boolean
bpm:
default: false
type: boolean
calendar:
default: false
type: boolean
collabora:
default: false
type: boolean
contacts:
default: false
type: boolean
deck:
default: false
type: boolean
groupfolders:
default: true
type: boolean
mindmap:
default: false
type: boolean
music:
default: false
type: boolean
notes:
default: false
type: boolean
onlyoffice:
default: false
type: boolean
passman:
default: false
type: boolean
spreed:
default: false
type: boolean
tables:
default: false
type: boolean
tasks:
default: false
type: boolean
texteditor:
default: true
type: boolean
type: object
domain-name:
default: your_company.com
examples:
- your_company.com
type: string
domain:
default: your-company
examples:
- your-company
type: string
sub-domain:
default: files
examples:
- files
type: string
images:
default:
collabora:
@@ -274,23 +169,39 @@ options:
type: string
type: object
type: object
storage:
default:
accessMode: ReadWriteOnce
size: 10Gi
ingress-class:
default: traefik
examples:
- accessMode: ReadWriteOnce
size: 10Gi
- traefik
type: string
hpa:
default:
avg-cpu: 50
max-replicas: 5
min-replicas: 1
examples:
- avg-cpu: 50
max-replicas: 5
min-replicas: 1
properties:
accessMode:
default: ReadWriteOnce
enum:
- ReadWriteOnce
- ReadOnlyMany
- ReadWriteMany
type: string
size:
default: 10Gi
avg-cpu:
default: 50
type: integer
max-replicas:
default: 5
type: integer
min-replicas:
default: 1
type: integer
type: object
admin:
default:
name: nextcloud_admin
examples:
- name: nextcloud_admin
properties:
name:
default: nextcloud_admin
type: string
type: object
app-group:
@@ -298,6 +209,31 @@ options:
examples:
- ''
type: string
postgres:
default:
replicas: 1
storage: 5Gi
version: '14'
examples:
- replicas: 1
storage: 5Gi
version: '14'
properties:
replicas:
default: 1
type: integer
storage:
default: 5Gi
type: string
version:
default: '14'
type: string
type: object
domain:
default: your-company
examples:
- your-company
type: string
backups:
default:
enable: false
@@ -404,11 +340,125 @@ options:
default: false
type: boolean
type: object
storage:
default:
accessMode: ReadWriteOnce
size: 10Gi
examples:
- accessMode: ReadWriteOnce
size: 10Gi
properties:
accessMode:
default: ReadWriteOnce
enum:
- ReadWriteOnce
- ReadOnlyMany
- ReadWriteMany
type: string
size:
default: 10Gi
type: string
type: object
sub-domain:
default: files
examples:
- files
type: string
openid-name:
default: vynil
examples:
- vynil
type: string
apps:
default:
audioplayer: false
bookmarks: false
bpm: false
calendar: false
collabora: false
contacts: false
deck: false
groupfolders: true
mindmap: false
music: false
notes: false
onlyoffice: false
passman: false
spreed: false
tables: false
tasks: false
texteditor: true
examples:
- audioplayer: false
bookmarks: false
bpm: false
calendar: false
collabora: false
contacts: false
deck: false
groupfolders: true
mindmap: false
music: false
notes: false
onlyoffice: false
passman: false
spreed: false
tables: false
tasks: false
texteditor: true
properties:
audioplayer:
default: false
type: boolean
bookmarks:
default: false
type: boolean
bpm:
default: false
type: boolean
calendar:
default: false
type: boolean
collabora:
default: false
type: boolean
contacts:
default: false
type: boolean
deck:
default: false
type: boolean
groupfolders:
default: true
type: boolean
mindmap:
default: false
type: boolean
music:
default: false
type: boolean
notes:
default: false
type: boolean
onlyoffice:
default: false
type: boolean
passman:
default: false
type: boolean
spreed:
default: false
type: boolean
tables:
default: false
type: boolean
tasks:
default: false
type: boolean
texteditor:
default: true
type: boolean
type: object
redis:
default:
exporter:
@@ -442,66 +492,16 @@ options:
default: 2Gi
type: string
type: object
ingress-class:
default: traefik
examples:
- traefik
type: string
hpa:
default:
avg-cpu: 50
max-replicas: 5
min-replicas: 1
examples:
- avg-cpu: 50
max-replicas: 5
min-replicas: 1
properties:
avg-cpu:
default: 50
type: integer
max-replicas:
default: 5
type: integer
min-replicas:
default: 1
type: integer
type: object
admin:
default:
name: nextcloud_admin
examples:
- name: nextcloud_admin
properties:
name:
default: nextcloud_admin
type: string
type: object
postgres:
default:
replicas: 1
storage: 5Gi
version: '14'
examples:
- replicas: 1
storage: 5Gi
version: '14'
properties:
replicas:
default: 1
type: integer
storage:
default: 5Gi
type: string
version:
default: '14'
type: string
type: object
issuer:
default: letsencrypt-prod
examples:
- letsencrypt-prod
type: string
domain-name:
default: your_company.com
examples:
- your_company.com
type: string
dependencies:
- dist: null
category: share
@@ -519,4 +519,5 @@ providers:
postgresql: null
restapi: null
http: null
gitea: null
tfaddtype: null

View File

@@ -1,75 +0,0 @@
locals {
dns-names = [local.dns-name]
middlewares = ["${var.instance}-https","${var.instance}-sslenforce","${var.instance}-redirectdav","${var.instance}-redirectindex"]
service = {
"name" = "${var.component}"
"port" = {
"number" = 80
}
}
rules = [ for v in local.dns-names : {
"host" = "${v}"
"http" = {
"paths" = [{
"backend" = {
"service" = local.service
}
"path" = "/"
"pathType" = "Prefix"
}]
}
}]
}
resource "kubectl_manifest" "prj_certificate" {
yaml_body = <<-EOF
apiVersion: "cert-manager.io/v1"
kind: "Certificate"
metadata:
name: "${var.instance}"
namespace: "${var.namespace}"
labels: ${jsonencode(local.common-labels)}
spec:
secretName: "${var.instance}-cert"
dnsNames: ${jsonencode(local.dns-names)}
issuerRef:
name: "${var.issuer}"
kind: "ClusterIssuer"
group: "cert-manager.io"
EOF
}
resource "kubectl_manifest" "prj_https_redirect" {
yaml_body = <<-EOF
apiVersion: "traefik.containo.us/v1alpha1"
kind: "Middleware"
metadata:
name: "${var.instance}-https"
namespace: "${var.namespace}"
labels: ${jsonencode(local.common-labels)}
spec:
redirectScheme:
scheme: "https"
permanent: true
EOF
}
resource "kubectl_manifest" "prj_ingress" {
force_conflicts = true
yaml_body = <<-EOF
apiVersion: "networking.k8s.io/v1"
kind: "Ingress"
metadata:
name: "${var.instance}"
namespace: "${var.namespace}"
labels: ${jsonencode(local.common-labels)}
annotations:
"traefik.ingress.kubernetes.io/router.middlewares": "${join(",", [for m in local.middlewares : format("%s-%s@kubernetescrd", var.namespace, m)])}"
spec:
ingressClassName: "${var.ingress-class}"
rules: ${jsonencode(local.rules)}
tls:
- hosts: ${jsonencode(local.dns-names)}
secretName: "${var.instance}-cert"
EOF
}

View File

@@ -13,6 +13,7 @@ spec:
replacement: "https://$${1}/remote.php/dav/"
EOF
}
resource "kubectl_manifest" "redirectindex" {
yaml_body = <<-EOF
apiVersion: traefik.containo.us/v1alpha1

View File

@@ -6,7 +6,7 @@ metadata:
namespace: "vynil-cloud"
labels:
app.kubernetes.io/name: nextcloud
helm.sh/chart: nextcloud-4.3.1
helm.sh/chart: nextcloud-4.3.5
app.kubernetes.io/instance: nextcloud
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: metrics

View File

@@ -1,65 +0,0 @@
resource "kubectl_manifest" "oauth2-secret" {
ignore_fields = ["metadata.annotations"]
yaml_body = <<-EOF
apiVersion: "secretgenerator.mittwald.de/v1alpha1"
kind: "StringSecret"
metadata:
name: "${var.component}-${var.instance}-id"
namespace: "${var.namespace}"
labels: ${jsonencode(local.common-labels)}
spec:
forceRegenerate: false
fields:
- fieldName: "client-id"
length: "32"
EOF
}
data "kubernetes_secret_v1" "oauth2-client-id" {
depends_on = [kubectl_manifest.oauth2-secret]
metadata {
name = kubectl_manifest.oauth2-secret.name
namespace = var.namespace
}
}
data "authentik_certificate_key_pair" "ca" {
name = "authentik Self-signed Certificate"
}
data "authentik_scope_mapping" "oauth2" {
managed_list = [
"goauthentik.io/providers/oauth2/scope-email",
"goauthentik.io/providers/oauth2/scope-openid",
"goauthentik.io/providers/oauth2/scope-profile"
]
}
data "authentik_flow" "default-authorization-flow" {
slug = "default-provider-authorization-implicit-consent"
}
data "authentik_flow" "default-authentication-flow" {
slug = "default-authentication-flow"
}
resource "authentik_provider_oauth2" "oauth2" {
name = "${var.component}-${var.instance}"
client_id = "${data.kubernetes_secret_v1.oauth2-client-id.data["client-id"]}"
authentication_flow = data.authentik_flow.default-authentication-flow.id
authorization_flow = data.authentik_flow.default-authorization-flow.id
client_type = "confidential"
sub_mode = "user_username"
signing_key = data.authentik_certificate_key_pair.ca.id
property_mappings = data.authentik_scope_mapping.oauth2.ids
redirect_uris = [
"https://${local.dns-name}/apps/user_oidc/code"
]
}
resource "kubernetes_secret_v1" "oauth2-client-secret" {
metadata {
name = "${var.component}-${var.instance}-secret"
namespace = var.namespace
}
data = {
client-secret = authentik_provider_oauth2.oauth2.client_secret
}
}

View File

@@ -1,27 +1,7 @@
locals {
onlyoffice-labels = merge(local.common-labels, {
"app.kubernetes.io/component" = "onlyoffice"
})
dns-onlyoffice = "onlyoffice.${local.dns-name}"
onlyoffice-middlewares = ["${var.instance}-https"]
onlyoffice-service = {
"name" = "${var.instance}-onlyoffice"
"port" = {
"number" = 80
}
}
onlyoffice-rules = [ for v in [local.dns-onlyoffice] : {
"host" = "${v}"
"http" = {
"paths" = [{
"backend" = {
"service" = local.onlyoffice-service
}
"path" = "/"
"pathType" = "Prefix"
}]
}
}]
onlyoffice-labels = merge(local.common-labels, {
"app.kubernetes.io/component" = "onlyoffice"
})
}
resource "kubectl_manifest" "onlyoffice_deploy" {
@@ -81,63 +61,3 @@ resource "kubectl_manifest" "onlyoffice_deploy" {
protocol: TCP
EOF
}
resource "kubectl_manifest" "onlyoffice_svc" {
count = var.apps.onlyoffice ? 1 : 0
yaml_body = <<-EOF
apiVersion: v1
kind: Service
metadata:
name: "${var.instance}-onlyoffice"
namespace: "${var.namespace}"
labels: ${jsonencode(local.onlyoffice-labels)}
spec:
type: ClusterIP
ports:
- port: 80
targetPort: http
protocol: TCP
name: http
selector: ${jsonencode(local.onlyoffice-labels)}
EOF
}
resource "kubectl_manifest" "onlyoffice_certificate" {
count = var.apps.onlyoffice ? 1 : 0
yaml_body = <<-EOF
apiVersion: "cert-manager.io/v1"
kind: "Certificate"
metadata:
name: "${var.instance}-onlyoffice"
namespace: "${var.namespace}"
labels: ${jsonencode(local.onlyoffice-labels)}
spec:
secretName: "${var.instance}-onlyoffice-cert"
dnsNames: [${jsonencode(local.dns-onlyoffice)}]
issuerRef:
name: "${var.issuer}"
kind: "ClusterIssuer"
group: "cert-manager.io"
EOF
}
resource "kubectl_manifest" "onlyoffice_ing" {
count = var.apps.onlyoffice ? 1 : 0
yaml_body = <<-EOF
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: "${var.instance}-onlyoffice"
namespace: "${var.namespace}"
labels: ${jsonencode(local.onlyoffice-labels)}
annotations:
"traefik.ingress.kubernetes.io/router.middlewares": "${join(",", [for m in local.onlyoffice-middlewares : format("%s-%s@kubernetescrd", var.namespace, m)])}"
spec:
ingressClassName: "${var.ingress-class}"
rules: ${jsonencode(local.onlyoffice-rules)}
tls:
- hosts: [${local.dns-onlyoffice}]
secretName: "${var.instance}-onlyoffice-cert"
EOF
}

View File

@@ -0,0 +1,134 @@
locals {
dns-name = "${var.sub-domain}.${var.domain-name}"
dns-collabora = "collabora.${local.dns-name}"
dns-onlyoffice = "onlyoffice.${local.dns-name}"
dns-names = [local.dns-name]
app-name = var.component == var.instance ? var.instance : format("%s-%s", var.component, var.instance)
icon = "apps/theming/favicon"
service = {
"name" = "${var.component}"
"port" = {
"number" = 80
}
}
collabora-service = {
"name" = "${var.instance}-collabora"
"port" = {
"number" = 80
}
}
onlyoffice-service = {
"name" = "${var.instance}-onlyoffice"
"port" = {
"number" = 80
}
}
}
module "ingress" {
source = "/dist/modules/ingress"
component = ""
instance = var.instance
namespace = var.namespace
issuer = var.issuer
ingress-class = var.ingress-class
labels = local.common-labels
dns-names = local.dns-names
middlewares = ["${var.instance}-sslenforce", "${var.instance}-redirectdav", "${var.instance}-redirectindex"]
service = local.service
providers = {
kubectl = kubectl
}
}
module "application" {
source = "/dist/modules/application"
component = var.component
instance = var.instance
app-group = var.app-group
sub-domain = var.sub-domain
domain-name = var.domain-name
icon = local.icon
protocol_provider = module.oauth2.provider-id
providers = {
authentik = authentik
}
}
module "oauth2" {
source = "/dist/modules/oauth2"
component = var.component
instance = var.instance
namespace = var.namespace
labels = local.common-labels
dns-name = local.dns-name
redirect-path = "apps/user_oidc/code"
providers = {
kubernetes = kubernetes
kubectl = kubectl
authentik = authentik
}
}
module "collabora-service" {
count = var.apps.collabora ? 1 : 0
source = "/dist/modules/service"
component = "collabora"
instance = var.instance
namespace = var.namespace
labels = local.collabora-labels
target = "http"
port = local.collabora-service.port.number
providers = {
kubectl = kubectl
}
}
module "collabora-ingress" {
count = var.apps.collabora ? 1 : 0
source = "/dist/modules/ingress"
component = "collabora"
instance = var.instance
namespace = var.namespace
issuer = var.issuer
ingress-class = var.ingress-class
labels = local.collabora-labels
dns-names = [local.dns-collabora]
middlewares = []
service = local.service
providers = {
kubectl = kubectl
}
}
module "onlyoffice-service" {
count = var.apps.onlyoffice ? 1 : 0
source = "/dist/modules/service"
component = "onlyoffice"
instance = var.instance
namespace = var.namespace
labels = local.onlyoffice-labels
target = "http"
port = local.onlyoffice-service.port.number
providers = {
kubectl = kubectl
}
}
module "onlyoffice-ingress" {
count = var.apps.onlyoffice ? 1 : 0
source = "/dist/modules/ingress"
component = "onlyoffice"
instance = var.instance
namespace = var.namespace
issuer = var.issuer
ingress-class = var.ingress-class
labels = local.onlyoffice-labels
dns-names = [local.dns-onlyoffice]
middlewares = []
service = local.service
providers = {
kubectl = kubectl
}
}

View File

@@ -5,7 +5,7 @@ metadata:
name: nextcloud-config
labels:
app.kubernetes.io/name: nextcloud
helm.sh/chart: nextcloud-4.3.1
helm.sh/chart: nextcloud-4.3.5
app.kubernetes.io/instance: nextcloud
app.kubernetes.io/managed-by: Helm
data:

View File

@@ -5,7 +5,7 @@ metadata:
name: nextcloud-nginxconfig
labels:
app.kubernetes.io/name: nextcloud
helm.sh/chart: nextcloud-4.3.1
helm.sh/chart: nextcloud-4.3.5
app.kubernetes.io/instance: nextcloud
app.kubernetes.io/managed-by: Helm
data:

View File

@@ -5,7 +5,7 @@ metadata:
name: nextcloud-nextcloud
labels:
app.kubernetes.io/name: nextcloud
helm.sh/chart: nextcloud-4.3.1
helm.sh/chart: nextcloud-4.3.5
app.kubernetes.io/instance: nextcloud
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: app

View File

@@ -5,7 +5,7 @@ metadata:
name: nextcloud-metrics
labels:
app.kubernetes.io/name: nextcloud
helm.sh/chart: nextcloud-4.3.1
helm.sh/chart: nextcloud-4.3.5
app.kubernetes.io/instance: nextcloud
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: metrics

View File

@@ -5,7 +5,7 @@ metadata:
name: nextcloud
labels:
app.kubernetes.io/name: nextcloud
helm.sh/chart: nextcloud-4.3.1
helm.sh/chart: nextcloud-4.3.5
app.kubernetes.io/instance: nextcloud
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: app