From 6613284e615e674274738380b3b6a1b71cf8d656 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Huss?= Date: Sun, 8 Oct 2023 15:51:41 +0200 Subject: [PATCH] fix --- meta/domain-devspaces/apps.tf | 45 ++++ meta/domain-devspaces/index.yaml | 279 +++++++++++++++++++++++++ meta/domain-devspaces/organisations.tf | 29 +++ meta/domain-devspaces/stations.tf | 73 +++++++ meta/domain/index.yaml | 200 +++++++++--------- meta/domain/installs.tf | 17 ++ share/organisation/index.yaml | 113 ++++++++++ share/organisation/stages.tf | 58 +++++ 8 files changed, 714 insertions(+), 100 deletions(-) create mode 100644 meta/domain-devspaces/apps.tf create mode 100644 meta/domain-devspaces/index.yaml create mode 100644 meta/domain-devspaces/organisations.tf create mode 100644 meta/domain-devspaces/stations.tf create mode 100644 share/organisation/index.yaml create mode 100644 share/organisation/stages.tf diff --git a/meta/domain-devspaces/apps.tf b/meta/domain-devspaces/apps.tf new file mode 100644 index 0000000..7c74f2f --- /dev/null +++ b/meta/domain-devspaces/apps.tf @@ -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 +} diff --git a/meta/domain-devspaces/index.yaml b/meta/domain-devspaces/index.yaml new file mode 100644 index 0000000..9457f39 --- /dev/null +++ b/meta/domain-devspaces/index.yaml @@ -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 diff --git a/meta/domain-devspaces/organisations.tf b/meta/domain-devspaces/organisations.tf new file mode 100644 index 0000000..b8a620b --- /dev/null +++ b/meta/domain-devspaces/organisations.tf @@ -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 +} diff --git a/meta/domain-devspaces/stations.tf b/meta/domain-devspaces/stations.tf new file mode 100644 index 0000000..d08cb76 --- /dev/null +++ b/meta/domain-devspaces/stations.tf @@ -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 +} diff --git a/meta/domain/index.yaml b/meta/domain/index.yaml index 4d31963..d344d0f 100644 --- a/meta/domain/index.yaml +++ b/meta/domain/index.yaml @@ -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: diff --git a/meta/domain/installs.tf b/meta/domain/installs.tf index 9f072ec..4fd0b19 100644 --- a/meta/domain/installs.tf +++ b/meta/domain/installs.tf @@ -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 +} diff --git a/share/organisation/index.yaml b/share/organisation/index.yaml new file mode 100644 index 0000000..dbb0bbb --- /dev/null +++ b/share/organisation/index.yaml @@ -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 diff --git a/share/organisation/stages.tf b/share/organisation/stages.tf new file mode 100644 index 0000000..a33b2d3 --- /dev/null +++ b/share/organisation/stages.tf @@ -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 +}