This commit is contained in:
2023-10-08 15:51:41 +02:00
parent 2110aed366
commit 6613284e61
8 changed files with 714 additions and 100 deletions

View File

@@ -0,0 +1,45 @@
locals {
annotations = {
"vynil.solidite.fr/meta" = var.component
"vynil.solidite.fr/name" = "${var.domain}-devspaces"
"vynil.solidite.fr/domain" = var.domain-name
"vynil.solidite.fr/issuer" = var.issuer
"vynil.solidite.fr/ingress" = var.ingress-class
}
global = {
"domain" = var.namespace
"domain-name" = var.domain-name
"issuer" = var.issuer
"ingress-class" = var.ingress-class
"backups" = var.backups
"app-group" = var.app-group
}
dbgate = { for k, v in var.apps.dbgate : k => v if k!="enable" }
}
resource "kubernetes_namespace_v1" "apps-ns" {
count = var.apps.dbgate.enable ? 1 : 0
metadata {
annotations = local.annotations
labels = merge(local.common-labels, local.annotations)
name = "${var.namespace}-devapps"
}
}
resource "kubectl_manifest" "dbgate" {
count = var.apps.dbgate.enable ? 1 : 0
depends_on = [kubernetes_namespace_v1.apps-ns]
yaml_body = <<-EOF
apiVersion: "vynil.solidite.fr/v1"
kind: "Install"
metadata:
name: "dbgate"
namespace: "${var.namespace}-devapps"
labels: ${jsonencode(local.common-labels)}
spec:
distrib: "${var.distributions.domain}"
category: "apps"
component: "dbgate"
options: ${jsonencode(merge(local.global, local.dbgate))}
EOF
}

View File

@@ -0,0 +1,279 @@
---
apiVersion: vinyl.solidite.fr/v1beta1
kind: Component
category: meta
metadata:
name: domain-devspaces
description: null
options:
apps:
default:
dbgate:
enable: false
superset:
enable: false
yaade:
enable: false
examples:
- dbgate:
enable: false
superset:
enable: false
yaade:
enable: false
type: object
properties:
dbgate:
type: object
properties:
enable:
type: boolean
default: false
default:
enable: false
superset:
type: object
properties:
enable:
type: boolean
default: false
default:
enable: false
yaade:
type: object
properties:
enable:
type: boolean
default: false
default:
enable: false
issuer:
default: letsencrypt-prod
examples:
- letsencrypt-prod
type: string
backups:
default:
enable: false
endpoint: ''
secret-name: backup-settings
key-id-key: s3-id
secret-key: s3-secret
examples:
- enable: false
endpoint: ''
secret-name: backup-settings
key-id-key: s3-id
secret-key: s3-secret
type: object
properties:
enable:
type: boolean
default: false
endpoint:
type: string
default: ''
key-id-key:
type: string
default: s3-id
secret-key:
type: string
default: s3-secret
secret-name:
type: string
default: backup-settings
external-databases:
default: []
items:
type: object
properties:
name:
type: string
default: ''
namespace:
type: string
default: ''
engine:
type: string
default: postgres
enum:
- postgres
- mongo
- redis
- maria
- rabbit
secret:
type: object
default:
name: default
namespace: default
user-key: username
pass-key: password
properties:
name:
type: string
default: default
namespace:
type: string
default: default
user-key:
type: string
default: username
pass-key:
type: string
default: password
examples:
- []
type: array
storage-classes:
default:
FilesystemReadWriteMany: ''
FilesystemReadWriteOnce: ''
BlockReadWriteMany: ''
BlockReadWriteOnce: ''
examples:
- FilesystemReadWriteMany: ''
FilesystemReadWriteOnce: ''
BlockReadWriteMany: ''
BlockReadWriteOnce: ''
type: object
properties:
BlockReadWriteMany:
type: string
default: ''
BlockReadWriteOnce:
type: string
default: ''
FilesystemReadWriteMany:
type: string
default: ''
FilesystemReadWriteOnce:
type: string
default: ''
stations:
default: []
items:
type: object
properties:
name:
type: string
default: ''
organisations:
default: []
type: array
items:
type: string
examples:
- []
type: array
distributions:
default:
domain: domain
core: core
examples:
- domain: domain
core: core
type: object
properties:
core:
type: string
default: core
domain:
type: string
default: domain
organisations:
default: []
items:
type: object
properties:
name:
type: string
default: ''
datasets:
default: []
type: array
items:
type: object
properties:
name:
default: ''
type: string
engine:
default: pg
type: string
examples:
- []
type: array
ingress-class:
default: traefik
examples:
- traefik
type: string
images:
default:
codeserver:
registry: docker.io
repository: sebt3/code-server
tag: 4.15
pullPolicy: IfNotPresent
properties:
codeserver:
properties:
pullPolicy:
enum:
- Always
- Never
- IfNotPresent
type: string
default: IfNotPresent
registry:
type: string
default: docker.io
repository:
type: string
default: sebt3/code-server
tag:
type: number
default: 4.15
type: object
default:
registry: docker.io
repository: sebt3/code-server
tag: 4.15
pullPolicy: IfNotPresent
examples:
- codeserver:
registry: docker.io
repository: sebt3/code-server
tag: 4.15
pullPolicy: IfNotPresent
type: object
domain:
default: your-company
examples:
- your-company
type: string
app-group:
default: dev
examples:
- dev
type: string
stations-sub-domain:
default: code
examples:
- code
type: string
domain-name:
default: your_company.com
examples:
- your_company.com
type: string
dependencies: []
providers:
kubernetes: true
authentik: null
kubectl: true
postgresql: null
restapi: null
http: null
tfaddtype: null

View File

@@ -0,0 +1,29 @@
locals {
sorted-organisation-names = reverse(distinct(sort([for org in var.organisations: org.name])))
sorted-organisations = flatten([
for name in local.sorted-organisation-names: [
for org in var.organisations: org if org.name == name
]
])
}
resource "kubectl_manifest" "organisations" {
count = length(local.sorted-organisations)
depends_on = [kubernetes_namespace_v1.ns]
yaml_body = <<-EOF
apiVersion: "vynil.solidite.fr/v1"
kind: "Install"
metadata:
name: "${local.sorted-organisations[count.index].name}"
namespace: "${var.namespace}"
labels: ${jsonencode(local.common-labels)}
spec:
distrib: "${var.distributions.domain}"
category: "share"
component: "organisation"
options: ${jsonencode(merge(
local.global,
{ for k, v in local.sorted-organisations[count.index] : k => v if !contains(["name","organisations"], k) }
))}
EOF
}

View File

@@ -0,0 +1,73 @@
locals {
sorted-station-names = reverse(distinct(sort([
for station in var.stations: station.name
])))
sorted-stations = flatten([
for name in local.sorted-station-names: [
for station in var.stations:
station if station.name == name
]
])
// le tableau de toutes les BDs requises dans toutes les devstations (aka de toutes les orga dont la devstation depend) triées par station/orga/ds
sorted-datasets = flatten([
for station in local.sorted-stations: flatten([
for name in distinct(sort(station.organisations)):
for org in local.sorted-organisations: flatten([
for dsname in reverse(distinct(sort([for d in org.datasets: d.name]))):
for ds in org.datasets:
merge(ds, {
"name" = "${org.name}-${ds.name}"
"namespace" = "${var.domain}-devspaces-${station.name}"
"organisation" = organisation
"usage" = "station"
"station" = station
}) if ds.name = dsname
]) if org.name == name
])
])
}
resource "kubernetes_namespace_v1" "dev-ns" {
count = length(local.sorted-stations)
metadata {
annotations = local.annotations
labels = merge(local.common-labels, local.annotations)
name = "${var.domain}-devspaces-${local.sorted-stations[count.index].name}"
}
}
resource "kubectl_manifest" "devstations" {
count = length(local.sorted-stations)
depends_on = [kubernetes_namespace_v1.dev-ns]
yaml_body = <<-EOF
apiVersion: "vynil.solidite.fr/v1"
kind: "Install"
metadata:
name: "${local.sorted-stations[count.index].name}"
namespace: "${var.domain}-devspaces-${local.sorted-stations[count.index].name}"
labels: ${jsonencode(local.common-labels)}
spec:
distrib: "${var.distributions.domain}"
category: "share"
component: "code-server"
options: ${jsonencode(merge(local.global, { for k, v in local.sorted-stations[count.index] : k => v if !contains(["name"], k) }))}
EOF
}
resource "kubectl_manifest" "datasets" {
count = length(local.sorted-datasets)
depends_on = [kubernetes_namespace_v1.dev-ns]
yaml_body = <<-EOF
apiVersion: "vynil.solidite.fr/v1"
kind: "Install"
metadata:
name: "${local.sorted-datasets[count.index].name}"
namespace: "${local.sorted-datasets[count.index].name}"
labels: ${jsonencode(local.common-labels)}
spec:
distrib: "${var.distributions.domain}"
category: "share"
component: "dataset-${local.sorted-datasets[count.index].engine}"
options: ${jsonencode(merge(local.global, { for k, v in local.sorted-datasets[count.index] : k => v if !contains(["name", "namespace", "engine", "organisation", "station", "usage"], k) }))}
EOF
}

View File

@@ -6,48 +6,6 @@ metadata:
name: domain
description: null
options:
issuer:
default: letsencrypt-prod
examples:
- letsencrypt-prod
type: string
ingress-class:
default: traefik
examples:
- traefik
type: string
devspaces:
default:
enable: false
examples:
- enable: false
properties:
enable:
default: false
type: boolean
type: object
apps:
default:
enable: false
nextcloud:
enable: true
examples:
- enable: false
nextcloud:
enable: true
properties:
enable:
default: false
type: boolean
nextcloud:
default:
enable: true
properties:
enable:
default: true
type: boolean
type: object
type: object
distributions:
default:
core: core
@@ -63,27 +21,15 @@ options:
default: domain
type: string
type: object
ci:
auth:
default:
enable: false
gitea:
enable: true
enable: true
examples:
- enable: false
gitea:
enable: true
- enable: true
properties:
enable:
default: false
default: true
type: boolean
gitea:
default:
enable: true
properties:
enable:
default: true
type: boolean
type: object
type: object
erp:
default:
@@ -107,26 +53,6 @@ options:
default: false
type: boolean
type: object
mail:
default:
enable: false
examples:
- enable: false
properties:
enable:
default: false
type: boolean
type: object
auth:
default:
enable: true
examples:
- enable: true
properties:
enable:
default: true
type: boolean
type: object
infra:
default:
enable: false
@@ -149,11 +75,73 @@ options:
type: boolean
type: object
type: object
storage-classes:
default:
BlockReadWriteMany: ''
BlockReadWriteOnce: ''
FilesystemReadWriteMany: ''
FilesystemReadWriteOnce: ''
examples:
- BlockReadWriteMany: ''
BlockReadWriteOnce: ''
FilesystemReadWriteMany: ''
FilesystemReadWriteOnce: ''
properties:
BlockReadWriteMany:
default: ''
type: string
BlockReadWriteOnce:
default: ''
type: string
FilesystemReadWriteMany:
default: ''
type: string
FilesystemReadWriteOnce:
default: ''
type: string
type: object
domain-name:
default: your_company.com
examples:
- your_company.com
type: string
ci:
default:
enable: false
gitea:
enable: true
examples:
- enable: false
gitea:
enable: true
properties:
enable:
default: false
type: boolean
gitea:
default:
enable: true
properties:
enable:
default: true
type: boolean
type: object
type: object
devspaces:
default:
enable: false
examples:
- enable: false
properties:
enable:
default: false
type: boolean
type: object
issuer:
default: letsencrypt-prod
examples:
- letsencrypt-prod
type: string
backups:
default:
enable: false
@@ -184,30 +172,42 @@ options:
default: backup-settings
type: string
type: object
storage-classes:
default:
BlockReadWriteMany: ''
BlockReadWriteOnce: ''
FilesystemReadWriteMany: ''
FilesystemReadWriteOnce: ''
ingress-class:
default: traefik
examples:
- BlockReadWriteMany: ''
BlockReadWriteOnce: ''
FilesystemReadWriteMany: ''
FilesystemReadWriteOnce: ''
- traefik
type: string
apps:
default:
enable: false
nextcloud:
enable: true
examples:
- enable: false
nextcloud:
enable: true
properties:
BlockReadWriteMany:
default: ''
type: string
BlockReadWriteOnce:
default: ''
type: string
FilesystemReadWriteMany:
default: ''
type: string
FilesystemReadWriteOnce:
default: ''
type: string
enable:
default: false
type: boolean
nextcloud:
default:
enable: true
properties:
enable:
default: true
type: boolean
type: object
type: object
mail:
default:
enable: false
examples:
- enable: false
properties:
enable:
default: false
type: boolean
type: object
dependencies: []
providers:

View File

@@ -21,6 +21,7 @@ locals {
erp = { for k, v in var.erp : k => v if k!="enable" }
apps = { for k, v in var.apps : k => v if k!="enable" }
mail = { for k, v in var.mail : k => v if k!="enable" }
devspaces = { for k, v in var.devspaces : k => v if k!="enable" }
# Force install authentik and it's modules when any are needed
use-ldap = (var.ci.enable && var.ci.gitea.enable) || (var.erp.enable && var.erp.dolibarr.enable)
@@ -150,3 +151,19 @@ resource "kubectl_manifest" "mail" {
options: ${jsonencode(merge(local.global, local.mail))}
EOF
}
resource "kubectl_manifest" "devspaces" {
count = var.mail.enable ? 1 : 0
yaml_body = <<-EOF
apiVersion: "vynil.solidite.fr/v1"
kind: "Install"
metadata:
name: "devspaces"
namespace: "${var.namespace}"
labels: ${jsonencode(local.common-labels)}
spec:
distrib: "${var.distributions.domain}"
category: "meta"
component: "domain-devspaces"
options: ${jsonencode(merge(local.global, local.devspaces))}
EOF
}

View File

@@ -0,0 +1,113 @@
---
apiVersion: vinyl.solidite.fr/v1beta1
kind: Component
category: share
metadata:
name: organisation
description: null
options:
backups:
default:
enable: false
endpoint: ''
key-id-key: s3-id
secret-key: s3-secret
secret-name: backup-settings
examples:
- enable: false
endpoint: ''
key-id-key: s3-id
secret-key: s3-secret
secret-name: backup-settings
properties:
enable:
default: false
type: boolean
endpoint:
default: ''
type: string
key-id-key:
default: s3-id
type: string
secret-key:
default: s3-secret
type: string
secret-name:
default: backup-settings
type: string
type: object
datasets:
default: []
items:
properties:
engine:
default: pg
type: string
name:
default: ''
type: string
type: object
type: array
domain-name:
default: your_company.com
examples:
- your_company.com
type: string
domain:
default: your-company
examples:
- your-company
type: string
ingress-class:
default: traefik
examples:
- traefik
type: string
app-group:
default: dev
examples:
- dev
type: string
distributions:
default:
core: core
domain: domain
examples:
- core: core
domain: domain
properties:
core:
default: core
type: string
domain:
default: domain
type: string
type: object
issuer:
default: letsencrypt-prod
examples:
- letsencrypt-prod
type: string
haveGitea:
default: false
examples:
- false
type: boolean
stages:
default: []
items:
properties:
name:
default: prod
type: string
type: object
type: array
dependencies: []
providers:
kubernetes: true
authentik: null
kubectl: true
postgresql: null
restapi: null
http: null
tfaddtype: null

View File

@@ -0,0 +1,58 @@
locals {
annotations = {
"vynil.solidite.fr/name" = "${var.component}"
"vynil.solidite.fr/domain" = var.domain-name
"vynil.solidite.fr/issuer" = var.issuer
"vynil.solidite.fr/ingress" = var.ingress-class
}
global = {
"domain" = var.namespace
"domain-name" = var.domain-name
"issuer" = var.issuer
"ingress-class" = var.ingress-class
"backups" = var.backups
"app-group" = var.app-group
}
sorted-stage-name = reverse(distinct(sort([for s in var.stages: s.name])))
sorted-dataset-name = reverse(distinct(sort([for d in var.datasets: d.name])))
sorted-stages = flatten([
for name in local.sorted-stage-name: [
for s in var.stages:
merge({s, {"namespace" = "${var.domain}-${var.instance}-${name}"}}) if s.name == name
]
])
sorted-datasets = flatten([
for stage in local.sorted-stage-name: flatten([
for name in local.sorted-dataset-name: [
for ds in var.datasets:
merge(ds,{"namespace" = "${var.domain}-${var.instance}-${stage}"}) if ds.name == name
]
])
])
}
resource "kubernetes_namespace_v1" "ns" {
count = length(local.sorted-stages)
metadata {
annotations = local.annotations
labels = merge(local.common-labels, local.annotations)
name = local.sorted-stages[count.index].namespace
}
}
resource "kubectl_manifest" "datasets" {
count = length(local.sorted-datasets)
depends_on = [kubernetes_namespace_v1.ns]
yaml_body = <<-EOF
apiVersion: "vynil.solidite.fr/v1"
kind: "Install"
metadata:
name: "${local.sorted-datasets[count.index].name}"
namespace: "${local.sorted-datasets[count.index].namespace}"
labels: ${jsonencode(local.common-labels)}
spec:
distrib: "${var.distributions.domain}"
category: "share"
component: "dataset-${local.sorted-datasets[count.index].engine}"
options: ${jsonencode(merge(local.global, { for k, v in local.sorted-datasets[count.index] : k => v if !contains(["name","namespace","engine"], k) }))}
EOF
}