This commit is contained in:
2023-11-28 12:39:01 +01:00
parent 1a023a18e5
commit 76db355a8b
22 changed files with 1074 additions and 563 deletions

View File

@@ -6,26 +6,11 @@ metadata:
name: code-server
description: null
options:
ingress-class:
default: traefik
examples:
- traefik
type: string
sub-domain:
default: code
examples:
- code
type: string
app-group:
default: dev
examples:
- dev
type: string
no-editor:
default: false
examples:
- false
type: boolean
timezone:
default: Europe/Paris
examples:
@@ -70,21 +55,31 @@ options:
type: number
type: object
type: object
no-editor:
default: false
examples:
- false
type: boolean
domain-name:
default: your_company.com
examples:
- your_company.com
type: string
domain:
default: your-company
examples:
- your-company
type: string
issuer:
default: letsencrypt-prod
examples:
- letsencrypt-prod
type: string
sub-domain:
default: code
examples:
- code
type: string
ingress-class:
default: traefik
examples:
- traefik
type: string
admin:
default:
cluster: false
@@ -100,6 +95,11 @@ options:
default: false
type: boolean
type: object
domain:
default: your-company
examples:
- your-company
type: string
storage:
default:
accessMode: ReadWriteOnce

View File

@@ -6,39 +6,20 @@ metadata:
name: dbgate
description: null
options:
mongo:
default: []
sub-domain:
default: dbgate
examples:
- []
items:
properties:
dbname:
default: ''
type: string
name:
default: ''
type: string
namespace:
default: ''
type: string
secret:
properties:
key:
default: ''
type: string
name:
default: ''
type: string
type: object
username:
default: ''
type: string
type: object
type: array
domain:
default: your-company
- dbgate
type: string
issuer:
default: letsencrypt-prod
examples:
- your-company
- letsencrypt-prod
type: string
app-group:
default: dev
examples:
- dev
type: string
redis:
default: []
@@ -54,77 +35,6 @@ options:
type: string
type: object
type: array
app-group:
default: dev
examples:
- dev
type: string
storage:
default:
accessMode: ReadWriteOnce
size: 1Gi
type: Filesystem
examples:
- accessMode: ReadWriteOnce
size: 1Gi
type: Filesystem
properties:
accessMode:
default: ReadWriteOnce
enum:
- ReadWriteOnce
- ReadOnlyMany
- ReadWriteMany
type: string
size:
default: 1Gi
type: string
type:
default: Filesystem
enum:
- Filesystem
- Block
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
pg:
default: []
examples:
- []
items:
properties:
dbname:
default: ''
type: string
name:
default: ''
type: string
namespace:
default: ''
type: string
secret:
properties:
key:
default: ''
type: string
name:
default: ''
type: string
type: object
username:
default: ''
type: string
type: object
type: array
maria:
default: []
examples:
@@ -154,11 +64,6 @@ options:
type: string
type: object
type: array
ingress-class:
default: traefik
examples:
- traefik
type: string
images:
default:
dbgate:
@@ -198,10 +103,105 @@ options:
type: string
type: object
type: object
sub-domain:
default: dbgate
mongo:
default: []
examples:
- dbgate
- []
items:
properties:
dbname:
default: ''
type: string
name:
default: ''
type: string
namespace:
default: ''
type: string
secret:
properties:
key:
default: ''
type: string
name:
default: ''
type: string
type: object
username:
default: ''
type: string
type: object
type: array
storage:
default:
accessMode: ReadWriteOnce
size: 1Gi
type: Filesystem
examples:
- accessMode: ReadWriteOnce
size: 1Gi
type: Filesystem
properties:
accessMode:
default: ReadWriteOnce
enum:
- ReadWriteOnce
- ReadOnlyMany
- ReadWriteMany
type: string
size:
default: 1Gi
type: string
type:
default: Filesystem
enum:
- Filesystem
- Block
type: string
type: object
pg:
default: []
examples:
- []
items:
properties:
dbname:
default: ''
type: string
name:
default: ''
type: string
namespace:
default: ''
type: string
secret:
properties:
key:
default: ''
type: string
name:
default: ''
type: string
type: object
username:
default: ''
type: string
type: object
type: array
ingress-class:
default: traefik
examples:
- traefik
type: string
domain-name:
default: your_company.com
examples:
- your_company.com
type: string
domain:
default: your-company
examples:
- your-company
type: string
dependencies:
- dist: null

View File

@@ -6,16 +6,6 @@ metadata:
name: dolibarr
description: null
options:
app-group:
default: ''
examples:
- ''
type: string
issuer:
default: letsencrypt-prod
examples:
- letsencrypt-prod
type: string
redis:
default:
exporter:
@@ -49,11 +39,61 @@ options:
default: 2Gi
type: string
type: object
ingress-class:
default: traefik
sub-domain:
default: erp
examples:
- traefik
- erp
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
user-groups:
default:
- admin: true
name: dolibarr-admin
examples:
- - admin: true
name: dolibarr-admin
items:
properties:
admin:
type: boolean
name:
type: string
type: object
type: array
log-level:
default: 5
examples:
- 5
type: integer
parameters:
default:
MAIN_LANG_DEFAULT: auto
examples:
- MAIN_LANG_DEFAULT: auto
properties:
MAIN_LANG_DEFAULT:
default: auto
type: string
type: object
images:
default:
dolibarr:
@@ -119,16 +159,6 @@ options:
type: string
type: object
type: object
sub-domain:
default: erp
examples:
- erp
type: string
log-level:
default: 5
examples:
- 5
type: integer
backups:
default:
enable: false
@@ -235,6 +265,58 @@ options:
default: false
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
issuer:
default: letsencrypt-prod
examples:
- letsencrypt-prod
type: string
app-group:
default: ''
examples:
- ''
type: string
ingress-class:
default: traefik
examples:
- traefik
type: string
storage:
default:
accessMode: ReadWriteOnce
size: 10Gi
type: Filesystem
examples:
- accessMode: ReadWriteOnce
size: 10Gi
type: Filesystem
properties:
accessMode:
default: ReadWriteOnce
enum:
- ReadWriteOnce
- ReadOnlyMany
- ReadWriteMany
type: string
size:
default: 10Gi
type: string
type:
default: Filesystem
enum:
- Filesystem
- block
type: string
type: object
resources:
default:
limits:
@@ -276,44 +358,6 @@ options:
type: string
type: object
type: object
parameters:
default:
MAIN_LANG_DEFAULT: auto
examples:
- MAIN_LANG_DEFAULT: auto
properties:
MAIN_LANG_DEFAULT:
default: auto
type: string
type: object
modules:
default:
- societe
examples:
- - societe
items:
type: string
type: array
domain:
default: your-company
examples:
- your-company
type: string
user-groups:
default:
- admin: true
name: dolibarr-admin
examples:
- - admin: true
name: dolibarr-admin
items:
properties:
admin:
type: boolean
name:
type: string
type: object
type: array
postgres:
default:
replicas: 1
@@ -334,58 +378,14 @@ options:
default: '14'
type: string
type: object
storage:
modules:
default:
accessMode: ReadWriteOnce
size: 10Gi
type: Filesystem
- societe
examples:
- accessMode: ReadWriteOnce
size: 10Gi
type: Filesystem
properties:
accessMode:
default: ReadWriteOnce
enum:
- ReadWriteOnce
- ReadOnlyMany
- ReadWriteMany
type: string
size:
default: 10Gi
type: string
type:
default: Filesystem
enum:
- Filesystem
- block
type: string
type: object
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
domain-name:
default: your_company.com
examples:
- your_company.com
type: string
- - societe
items:
type: string
type: array
dependencies:
- dist: null
category: share

View File

@@ -27,7 +27,7 @@ spec:
metadata:
annotations:
checksum/config: ad2ce0a245d17a13676e98bfc6d1833351e36e913af45f98b89299cc83f3fc11
checksum/ldap_0: d9e7446d3ea8b10f29ff9cb1e1a885db73ccb22f3d1a9e054611607e1c168226
checksum/oauth_0: f0f765c091d516960342092cbf7ed9ed3ef8de0ca140d33f6eadbec60df69d3b
labels:
helm.sh/chart: gitea-9.5.0
app: gitea
@@ -127,16 +127,16 @@ spec:
value: /tmp/gitea
- name: HOME
value: /data/gitea/git
- name: GITEA_LDAP_BIND_DN_0
- name: GITEA_OAUTH_KEY_0
valueFrom:
secretKeyRef:
key: bindDn
name: gitea-ldap
- name: GITEA_LDAP_PASSWORD_0
key: key
name: gitea-oauth-secret
- name: GITEA_OAUTH_SECRET_0
valueFrom:
secretKeyRef:
key: bindPassword
name: gitea-ldap
key: secret
name: gitea-oauth-secret
- name: GITEA_ADMIN_USERNAME
valueFrom:
secretKeyRef:

View File

@@ -64,6 +64,18 @@ data "kustomization_overlay" "data" {
image: "${var.images.gitea.registry}/${var.images.gitea.repository}:${var.images.gitea.tag}"
imagePullPolicy: IfNotPresent
env:
- name: VYNIL_OAUTH_DISCOVERY
value: "https://${data.kubernetes_ingress_v1.authentik.spec[0].rule[0].host}/application/o/${var.component}-${var.instance}/.well-known/openid-configuration"
- name: GITEA_OAUTH_KEY_0
valueFrom:
secretKeyRef:
name: "${var.component}-${var.instance}-id"
key: client-id
- name: GITEA_OAUTH_SECRET_0
valueFrom:
secretKeyRef:
name: "${var.component}-${var.instance}-secret"
key: client-secret
- name: LDAP_USER_SEARCH_BASE
valueFrom:
secretKeyRef:

View File

@@ -9,71 +9,16 @@ metadata:
A painless self-hosted Git service.
Gitea is a community managed lightweight code hosting solution written in Go. It is published under the MIT license.
options:
domain-name:
default: your_company.com
examples:
- your_company.com
type: string
domain:
default: your-company
examples:
- your-company
type: string
issuer:
default: letsencrypt-prod
examples:
- letsencrypt-prod
type: string
sub-domain:
default: git
examples:
- git
type: string
load-balancer:
default:
ip: ''
examples:
- ip: ''
properties:
ip:
default: ''
type: string
type: object
release:
default: 8.3.0
examples:
- 8.3.0
type: string
timezone:
default: Europe/Paris
examples:
- Europe/Paris
type: string
disable-registration:
default: true
examples:
- true
type: boolean
push-create:
default:
org: 'true'
private: 'false'
user: 'true'
examples:
- org: 'true'
private: 'false'
user: 'true'
properties:
org:
default: 'true'
type: string
private:
default: 'false'
type: string
user:
default: 'true'
type: string
type: object
replicas:
default: 1
examples:
- 1
type: integer
backups:
default:
enable: false
@@ -180,21 +125,51 @@ options:
default: false
type: boolean
type: object
replicas:
default: 1
examples:
- 1
type: integer
admin:
default:
email: git-admin@git.your_company.com
name: gitea_admin
examples:
- email: git-admin@git.your_company.com
name: gitea_admin
properties:
email:
default: git-admin@git.your_company.com
type: string
name:
default: gitea_admin
type: string
type: object
issuer:
default: letsencrypt-prod
examples:
- letsencrypt-prod
type: string
ingress-class:
default: traefik
examples:
- traefik
type: string
sub-domain:
default: git
examples:
- git
type: string
disable-registration:
default: true
examples:
- true
type: boolean
default-branch:
default: main
examples:
- main
type: string
domain-name:
default: your_company.com
examples:
- your_company.com
type: string
app-group:
default: dev
examples:
- dev
type: string
webhook:
default:
allowed-hosts: private
@@ -210,6 +185,21 @@ options:
default: false
type: boolean
type: object
timezone:
default: Europe/Paris
examples:
- Europe/Paris
type: string
theme:
default: gitea-modern
examples:
- gitea-modern
type: string
ssh-sub-domain:
default: git
examples:
- git
type: string
postgres:
default:
replicas: 1
@@ -230,21 +220,88 @@ options:
default: '14'
type: string
type: object
admin:
push-create:
default:
email: git-admin@git.your_company.com
name: gitea_admin
org: 'true'
private: 'false'
user: 'true'
examples:
- email: git-admin@git.your_company.com
name: gitea_admin
- org: 'true'
private: 'false'
user: 'true'
properties:
email:
default: git-admin@git.your_company.com
org:
default: 'true'
type: string
name:
default: gitea_admin
private:
default: 'false'
type: string
user:
default: 'true'
type: string
type: object
volume:
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
redis:
default:
exporter:
enabled: true
image: quay.io/opstree/redis-exporter:v1.44.0
image: quay.io/opstree/redis:v7.0.12
storage: 2Gi
examples:
- exporter:
enabled: true
image: quay.io/opstree/redis-exporter:v1.44.0
image: quay.io/opstree/redis:v7.0.12
storage: 2Gi
properties:
exporter:
default:
enabled: true
image: quay.io/opstree/redis-exporter:v1.44.0
properties:
enabled:
default: true
type: boolean
image:
default: quay.io/opstree/redis-exporter:v1.44.0
type: string
type: object
image:
default: quay.io/opstree/redis:v7.0.12
type: string
storage:
default: 2Gi
type: string
type: object
ssh-port:
default: 2222
examples:
- 2222
type: integer
app-group:
default: dev
examples:
- dev
type: string
images:
default:
gitea:
@@ -284,73 +341,21 @@ options:
type: string
type: object
type: object
redis:
default:
exporter:
enabled: true
image: quay.io/opstree/redis-exporter:v1.44.0
image: quay.io/opstree/redis:v7.0.12
storage: 2Gi
release:
default: 8.3.0
examples:
- exporter:
enabled: true
image: quay.io/opstree/redis-exporter:v1.44.0
image: quay.io/opstree/redis:v7.0.12
storage: 2Gi
- 8.3.0
type: string
load-balancer:
default:
ip: ''
examples:
- ip: ''
properties:
exporter:
default:
enabled: true
image: quay.io/opstree/redis-exporter:v1.44.0
properties:
enabled:
default: true
type: boolean
image:
default: quay.io/opstree/redis-exporter:v1.44.0
type: string
type: object
image:
default: quay.io/opstree/redis:v7.0.12
type: string
storage:
default: 2Gi
ip:
default: ''
type: string
type: object
ingress-class:
default: traefik
examples:
- traefik
type: string
theme:
default: gitea-modern
examples:
- gitea-modern
type: string
volume:
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
ssh-port:
default: 2222
examples:
- 2222
type: integer
dependencies:
- dist: null
category: share

View File

@@ -1,75 +0,0 @@
locals {
dns-names = ["${var.sub-domain}.${var.domain-name}"]
middlewares = ["${var.instance}-https"]
service = {
"name" = "gitea-http"
"port" = {
"number" = 3000
}
}
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

@@ -20,7 +20,7 @@ CONN_STR=redis://:@${var.instance}-${var.component}-redis-headless.${var.namespa
TYPE=redis
EOF
session = <<-EOF
PROVIDER=db
PROVIDER=redis
PROVIDER_CONFIG=redis://:@${var.instance}-${var.component}-redis-headless.${var.namespace}.svc.cluster.local:6379/0?pool_size=100&idle_timeout=180s&
EOF
indexer = <<-EOF
@@ -49,8 +49,9 @@ HTTP_PORT=3000
PROTOCOL=http
ROOT_URL=https://${var.sub-domain}.${var.domain-name}
SSH_DOMAIN=${var.sub-domain}.${var.domain-name}
SSH_LISTEN_PORT=${var.ssh-port}
SSH_LISTEN_PORT=2222
SSH_PORT=${var.ssh-port}
SSH_DOMAIN=${var.ssh-sub-domain}.${var.domain-name}
START_SSH_SERVER=true
EOF
ui = <<-EOF

View File

@@ -13,28 +13,28 @@ locals {
ldap-outpost-prividers = jsondecode(data.http.get_ldap_outpost.response_body).results[0].providers
ldap-outpost-pk = jsondecode(data.http.get_ldap_outpost.response_body).results[0].pk
}
resource "kubectl_manifest" "gitea_ldap" {
ignore_fields = ["metadata.annotations"]
yaml_body = <<-EOF
apiVersion: "secretgenerator.mittwald.de/v1alpha1"
kind: "StringSecret"
metadata:
name: "${var.component}-ldap"
namespace: "${var.namespace}"
labels: ${jsonencode(local.common-labels)}
spec:
forceRegenerate: false
data:
bindDn: "cn=${var.component}-ldapsearch,${local.base-user-dn}"
user-search-base: "${local.base-user-dn}"
user-filter: "(&(|(memberof=cn=${format("admin-%s", local.app-name)},${local.base-group-dn})(memberof=cn=${local.main-group},${local.base-group-dn}))(|(cn=%[1]s)(mail=%[1]s)))"
admin-filter: "(memberof=cn=${format("admin-%s", local.app-name)},${local.base-group-dn})"
endpoint: "ak-outpost-ldap.${var.domain}-auth.svc"
fields:
- fieldName: "bindPassword"
length: "32"
EOF
}
# resource "kubectl_manifest" "gitea_ldap" {
# ignore_fields = ["metadata.annotations"]
# yaml_body = <<-EOF
# apiVersion: "secretgenerator.mittwald.de/v1alpha1"
# kind: "StringSecret"
# metadata:
# name: "${var.component}-ldap"
# namespace: "${var.namespace}"
# labels: ${jsonencode(local.common-labels)}
# spec:
# forceRegenerate: false
# data:
# bindDn: "cn=${var.component}-ldapsearch,${local.base-user-dn}"
# user-search-base: "${local.base-user-dn}"
# user-filter: "(&(|(memberof=cn=${format("admin-%s", local.app-name)},${local.base-group-dn})(memberof=cn=${local.main-group},${local.base-group-dn}))(|(cn=%[1]s)(mail=%[1]s)))"
# admin-filter: "(memberof=cn=${format("admin-%s", local.app-name)},${local.base-group-dn})"
# endpoint: "ak-outpost-ldap.${var.domain}-auth.svc"
# fields:
# - fieldName: "bindPassword"
# length: "32"
# EOF
# }
data "kubernetes_secret_v1" "gitea_ldap_password" {
depends_on = [kubectl_manifest.gitea_ldap]
metadata {
@@ -43,16 +43,16 @@ data "kubernetes_secret_v1" "gitea_ldap_password" {
}
}
resource "authentik_user" "gitea_ldapsearch" {
username = "${var.component}-ldapsearch"
name = "${var.component}-ldapsearch"
}
# resource "authentik_user" "gitea_ldapsearch" {
# username = "${var.component}-ldapsearch"
# name = "${var.component}-ldapsearch"
# }
resource "authentik_group" "gitea_ldapsearch" {
name = "${var.component}-ldapsearch"
users = [authentik_user.gitea_ldapsearch.id]
is_superuser = true
}
# resource "authentik_group" "gitea_ldapsearch" {
# name = "${var.component}-ldapsearch"
# users = [authentik_user.gitea_ldapsearch.id]
# is_superuser = true
# }
data "http" "gitea_ldapsearch_password" {
@@ -73,61 +73,61 @@ data "authentik_flow" "ldap-authentication-flow" {
slug = "ldap-authentication-flow"
}
resource "authentik_provider_ldap" "gitea_provider_ldap" {
name = "gitea-ldap-provider"
base_dn = local.base-dn
search_group = authentik_group.gitea_ldapsearch.id
bind_flow = data.authentik_flow.ldap-authentication-flow.id
}
# resource "authentik_provider_ldap" "gitea_provider_ldap" {
# name = "gitea-ldap-provider"
# base_dn = local.base-dn
# search_group = authentik_group.gitea_ldapsearch.id
# bind_flow = data.authentik_flow.ldap-authentication-flow.id
# }
resource "authentik_application" "gitea_application" {
name = "${var.instance}"
slug = "${var.component}-${var.instance}-ldap"
group = var.app-group
protocol_provider = authentik_provider_ldap.gitea_provider_ldap.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, "assets/img/logo.svg")
}
# resource "authentik_application" "gitea_application" {
# name = "${var.instance}"
# slug = "${var.component}-${var.instance}-ldap"
# group = var.app-group
# protocol_provider = authentik_provider_ldap.gitea_provider_ldap.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, "assets/img/logo.svg")
# }
resource "authentik_group" "gitea_users" {
name = local.main-group
attributes = jsonencode({"${local.app-name}" = true})
}
# resource "authentik_group" "gitea_users" {
# name = local.main-group
# attributes = jsonencode({"${local.app-name}" = true})
# }
data "authentik_group" "vynil-admin" {
depends_on = [authentik_group.gitea_users] # fake dependency so it is not evaluated at plan stage
name = "vynil-ldap-admins"
}
resource "authentik_group" "gitea_admin" {
name = format("admin-%s", local.app-name)
parent = authentik_group.gitea_users.id
attributes = jsonencode({"${local.app-name}" = true})
}
# resource "authentik_group" "gitea_admin" {
# name = format("admin-%s", local.app-name)
# parent = authentik_group.gitea_users.id
# attributes = jsonencode({"${local.app-name}" = true})
# }
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_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" "gitea_access_users" {
target = authentik_application.gitea_application.uuid
policy = authentik_policy_expression.policy.id
order = 0
}
resource "authentik_policy_binding" "gitea_access_vynil" {
target = authentik_application.gitea_application.uuid
group = data.authentik_group.vynil-admin.id
order = 1
}
resource "authentik_policy_binding" "gitea_access_ldap" {
target = authentik_application.gitea_application.uuid
group = authentik_group.gitea_ldapsearch.id
order = 2
}
# resource "authentik_policy_binding" "gitea_access_users" {
# target = authentik_application.gitea_application.uuid
# policy = authentik_policy_expression.policy.id
# order = 0
# }
# resource "authentik_policy_binding" "gitea_access_vynil" {
# target = authentik_application.gitea_application.uuid
# group = data.authentik_group.vynil-admin.id
# order = 1
# }
# resource "authentik_policy_binding" "gitea_access_ldap" {
# target = authentik_application.gitea_application.uuid
# group = authentik_group.gitea_ldapsearch.id
# order = 2
# }
data "http" "get_ldap_outpost" {
depends_on = [authentik_group.gitea_users] # fake dependency so it is not evaluated at plan stage
@@ -152,11 +152,11 @@ provider "restapi" {
id_attribute = "name"
}
resource "restapi_object" "ldap_outpost_binding" {
path = "/outposts/instances/${local.ldap-outpost-pk}/"
data = jsonencode({
name = "ldap"
providers = contains(local.ldap-outpost-prividers, authentik_provider_ldap.gitea_provider_ldap.id) ? local.ldap-outpost-prividers : concat(local.ldap-outpost-prividers, [authentik_provider_ldap.gitea_provider_ldap.id])
})
}
# resource "restapi_object" "ldap_outpost_binding" {
# path = "/outposts/instances/${local.ldap-outpost-pk}/"
# data = jsonencode({
# name = "ldap"
# providers = contains(local.ldap-outpost-prividers, authentik_provider_ldap.gitea_provider_ldap.id) ? local.ldap-outpost-prividers : concat(local.ldap-outpost-prividers, [authentik_provider_ldap.gitea_provider_ldap.id])
# })
# }

View File

@@ -0,0 +1,73 @@
locals {
dns-name = "${var.sub-domain}.${var.domain-name}"
dns-names = [local.dns-name]
app-name = var.component == var.instance ? var.instance : format("%s-%s", var.component, var.instance)
icon = "logo192.png"
request_headers = {
"Content-Type" = "application/json"
Authorization = "Bearer ${data.kubernetes_secret_v1.authentik.data["AUTHENTIK_BOOTSTRAP_TOKEN"]}"
}
service = {
"name" = "gitea-http"
"port" = {
"number" = 3000
}
}
}
# module "service" {
# source = "/dist/modules/service"
# component = var.component
# instance = var.instance
# namespace = var.namespace
# labels = local.common-labels
# target = "http"
# port = local.service.port.number
# providers = {
# kubectl = kubectl
# }
# }
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 = []
service = local.service
providers = {
kubectl = kubectl
}
}
module "application" {
source = "/dist/modules/application"
component = var.component
instance = var.instance
app-group = var.app-group
dns-name = local.dns-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 = ""
providers = {
kubernetes = kubernetes
kubectl = kubectl
authentik = authentik
}
}

View File

@@ -63,24 +63,24 @@ stringData:
configure_admin_user
function configure_ldap() {
local LDAP_NAME='vynil'
local GITEA_AUTH_ID=$(gitea admin auth list --vertical-bars | grep -E "\|${LDAP_NAME}\s+\|" | grep -iE '\|LDAP \(via BindDN\)\s+\|' | awk -F " " "{print \$1}")
if [[ -z "${GITEA_AUTH_ID}" ]]; then
echo "No ldap configuration found with name "${LDAP_NAME}". Installing it now..."
gitea admin auth add-ldap --admin-filter "${LDAP_ADMIN_FILTER}" --avatar-attribute 'jpegPhoto' --bind-dn "${GITEA_LDAP_BIND_DN_0}" --bind-password "${GITEA_LDAP_PASSWORD_0}" --email-attribute 'mail' --firstname-attribute 'givenname' --host "${LDAP_HOST}" --name 'vynil' --port 389 --security-protocol 'unencrypted' --surname-attribute 'name' --user-filter "${LDAP_USER_FILTER}" --user-search-base "${LDAP_USER_SEARCH_BASE}" --username-attribute 'cn'
echo '...installed.'
else
echo "Existing ldap configuration with name "${LDAP_NAME}": '${GITEA_AUTH_ID}'. Running update to sync settings..."
gitea admin auth update-ldap --id "${GITEA_AUTH_ID}" --admin-filter "${LDAP_ADMIN_FILTER}" --avatar-attribute 'jpegPhoto' --bind-dn "${GITEA_LDAP_BIND_DN_0}" --bind-password "${GITEA_LDAP_PASSWORD_0}" --email-attribute 'mail' --firstname-attribute 'givenname' --host "${LDAP_HOST}" --name 'vynil' --port 389 --security-protocol 'unencrypted' --surname-attribute 'name' --user-filter "${LDAP_USER_FILTER}" --user-search-base "${LDAP_USER_SEARCH_BASE}" --username-attribute 'cn'
echo '...sync settings done.'
fi
echo 'no ldap configuration... skipping.'
}
configure_ldap
function configure_oauth() {
echo 'no oauth configuration... skipping.'
local OAUTH_NAME='vynil'
local AUTH_ID=$(gitea admin auth list --vertical-bars | grep -E "\|${OAUTH_NAME}\s+\|" | grep -iE '\|OAuth2\s+\|' | awk -F " " "{print \$1}")
if [[ -z "${AUTH_ID}" ]]; then
echo "No oauth configuration found with name '${OAUTH_NAME}'. Installing it now..."
gitea admin auth add-oauth --auto-discover-url "${VYNIL_OAUTH_DISCOVERY}" --key "${GITEA_OAUTH_KEY_0}" --name "vynil" --provider "openidConnect" --secret "${GITEA_OAUTH_SECRET_0}"
echo '...installed.'
else
echo "Existing oauth configuration with name '${OAUTH_NAME}': '${AUTH_ID}'. Running update to sync settings..."
gitea admin auth update-oauth --id "${AUTH_ID}" --auto-discover-url "${VYNIL_OAUTH_DISCOVERY}" --key "${GITEA_OAUTH_KEY_0}" --name "vynil" --provider "openidConnect" --secret "${GITEA_OAUTH_SECRET_0}"
echo '...sync settings done.'
fi
}
configure_oauth

View File

@@ -0,0 +1,247 @@
# Source: sonarqube/templates/sonarqube-sts.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: sonar-sonarqube
labels:
app: sonarqube
chart: sonarqube-10.2.1_800
release: sonar
heritage: Helm
app.kubernetes.io/name: sonarqube-sonar-sonarqube
app.kubernetes.io/instance: sonar
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/part-of: sonarqube
app.kubernetes.io/component: sonar-sonarqube
app.kubernetes.io/version: "10.2.1-community"
spec:
replicas: 1
serviceName: sonar-sonarqube
selector:
matchLabels:
app: sonarqube
release: sonar
template:
metadata:
labels:
app: sonarqube
release: sonar
annotations:
checksum/init-sysctl: cee36a3c219877f5e5283c33ac42dd45ab515536473d11327c3fb16451fcf389
checksum/init-fs: e91ea63db7f365c895f20cd1aa88f5ddbfcc2673527e33ba18b7f0dcb21d8699
checksum/plugins: 81e69508572a0af41c9f523d7e3fa65c76d7808be29b9313b6d627230c64837f
checksum/config: 62f22fcd909503d99971789b55a68daa5265a47a2d16a30943a6b01c8510978f
checksum/secret: 6bc1c9a02ff03ca932d573bccf2803e0b3a46df7466f4cdff80a3716fab6c5f2
checksum/prometheus-config: f7ab66f106b162963a4b644166c9755dd34eca76f8bbe57e4d11ce61e7e055af
checksum/prometheus-ce-config: 767e03641f6a1999c70f373b40fc2a348a36697cfc75a97d245021e68d30606a
spec:
securityContext:
fsGroup: 1000
initContainers:
- name: "wait-for-db"
image: busybox:1.32
imagePullPolicy: IfNotPresent
resources:
{}
command: ["/bin/sh", "-c", "for i in $(seq 1 200); do nc -z -w3 sonar-postgresql 5432 && exit 0 || sleep 2; done; exit 1"]
- name: init-sysctl
image: busybox:1.32
imagePullPolicy: IfNotPresent
securityContext:
privileged: true
resources:
{}
command: ["sh",
"-e",
"/tmp/scripts/init_sysctl.sh"]
volumeMounts:
- name: init-sysctl
mountPath: /tmp/scripts/
- name: inject-prometheus-exporter
image: curlimages/curl:8.2.0
imagePullPolicy: IfNotPresent
securityContext:
runAsGroup: 1000
runAsUser: 1000
resources:
{}
command: ["/bin/sh","-c"]
args: ["curl -s 'https://repo1.maven.org/maven2/io/prometheus/jmx/jmx_prometheus_javaagent/0.17.2/jmx_prometheus_javaagent-0.17.2.jar' --output /data/jmx_prometheus_javaagent.jar -v"]
volumeMounts:
- mountPath: /data
name: sonarqube
subPath: data
env:
- name: http_proxy
value:
- name: https_proxy
value:
- name: no_proxy
value:
- name: install-plugins
image: curlimages/curl:8.2.0
imagePullPolicy: IfNotPresent
command: ["sh",
"-e",
"/tmp/scripts/install_plugins.sh"]
volumeMounts:
- mountPath: /opt/sonarqube/extensions/plugins
name: sonarqube
subPath: extensions/plugins
- name: install-plugins
mountPath: /tmp/scripts/
securityContext:
runAsGroup: 1000
runAsUser: 1000
resources:
{}
env:
- name: http_proxy
value:
- name: https_proxy
value:
- name: no_proxy
value:
containers:
- name: sonarqube
image: "sonarqube:10.2.1-community"
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 9000
protocol: TCP
- name: monitoring-web
containerPort: 8000
protocol: TCP
- name: monitoring-ce
containerPort: 8001
protocol: TCP
resources:
limits:
cpu: 800m
memory: 4Gi
requests:
cpu: 400m
memory: 2Gi
env:
- name: SONAR_HELM_CHART_VERSION
value: 10.2.1_800
- name: SONAR_WEB_JAVAOPTS
value: "-javaagent:/opt/sonarqube/data/jmx_prometheus_javaagent.jar=8000:/opt/sonarqube/conf/prometheus-config.yaml"
- name: SONAR_WEB_CONTEXT
value: /
- name: SONAR_CE_JAVAOPTS
value: "-javaagent:/opt/sonarqube/data/jmx_prometheus_javaagent.jar=8001:/opt/sonarqube/conf/prometheus-ce-config.yaml"
- name: SONAR_JDBC_PASSWORD
valueFrom:
secretKeyRef:
name: sonar-postgresql
key: postgresql-password
- name: SONAR_WEB_SYSTEMPASSCODE
valueFrom:
secretKeyRef:
name: sonar-sonarqube-monitoring-passcode
key: SONAR_WEB_SYSTEMPASSCODE
envFrom:
- configMapRef:
name: sonar-sonarqube-jdbc-config
livenessProbe:
exec:
command:
- sh
- -c
- |
host="$(hostname -i || echo '127.0.0.1')"
wget --no-proxy --quiet -O /dev/null --timeout=1 --header="X-Sonar-Passcode: $SONAR_WEB_SYSTEMPASSCODE" "http://${host}:9000/api/system/liveness"
initialDelaySeconds: 60
periodSeconds: 30
failureThreshold: 6
timeoutSeconds: 1
readinessProbe:
exec:
command:
- sh
- -c
- |
#!/bin/bash
# A Sonarqube container is considered ready if the status is UP, DB_MIGRATION_NEEDED or DB_MIGRATION_RUNNING
# status about migration are added to prevent the node to be kill while sonarqube is upgrading the database.
host="$(hostname -i || echo '127.0.0.1')"
if wget --no-proxy -qO- http://${host}:9000/api/system/status | grep -q -e '"status":"UP"' -e '"status":"DB_MIGRATION_NEEDED"' -e '"status":"DB_MIGRATION_RUNNING"'; then
exit 0
fi
exit 1
initialDelaySeconds: 60
periodSeconds: 30
failureThreshold: 6
timeoutSeconds: 1
startupProbe:
httpGet:
scheme: HTTP
path: /api/system/status
port: http
initialDelaySeconds: 30
periodSeconds: 10
failureThreshold: 24
timeoutSeconds: 1
securityContext:
runAsUser: 1000
volumeMounts:
- mountPath: /opt/sonarqube/data
name: sonarqube
subPath: data
- mountPath: /opt/sonarqube/extensions/plugins
name: sonarqube
subPath: extensions/plugins
- mountPath: /opt/sonarqube/temp
name: sonarqube
subPath: temp
- mountPath: /opt/sonarqube/logs
name: sonarqube
subPath: logs
- mountPath: /tmp
name: tmp-dir
- mountPath: /opt/sonarqube/conf/prometheus-config.yaml
subPath: prometheus-config.yaml
name: prometheus-config
- mountPath: /opt/sonarqube/conf/prometheus-ce-config.yaml
subPath: prometheus-ce-config.yaml
name: prometheus-ce-config
serviceAccountName: default
volumes:
- name: init-sysctl
configMap:
name: sonar-sonarqube-init-sysctl
items:
- key: init_sysctl.sh
path: init_sysctl.sh
- name: init-fs
configMap:
name: sonar-sonarqube-init-fs
items:
- key: init_fs.sh
path: init_fs.sh
- name: install-plugins
configMap:
name: sonar-sonarqube-install-plugins
items:
- key: install_plugins.sh
path: install_plugins.sh
- name: prometheus-config
configMap:
name: sonar-sonarqube-prometheus-config
items:
- key: prometheus-config.yaml
path: prometheus-config.yaml
- name: prometheus-ce-config
configMap:
name: sonar-sonarqube-prometheus-ce-config
items:
- key: prometheus-ce-config.yaml
path: prometheus-ce-config.yaml
- name: sonarqube
emptyDir:
{}
- name : tmp-dir
emptyDir:
{}

100
apps/sonar/index.yaml Normal file
View File

@@ -0,0 +1,100 @@
---
apiVersion: vinyl.solidite.fr/v1beta1
kind: Component
category: apps
metadata:
name: sonar
description: null
options:
ingress-class:
default: traefik
examples:
- traefik
type: string
sub-domain:
default: sonar
examples:
- sonar
type: string
images:
default:
sonar:
pullPolicy: IfNotPresent
registry: docker.io
repository: to-be/defined
tag: v1.0.0
examples:
- sonar:
pullPolicy: IfNotPresent
registry: docker.io
repository: to-be/defined
tag: v1.0.0
properties:
sonar:
default:
pullPolicy: IfNotPresent
registry: docker.io
repository: to-be/defined
tag: v1.0.0
properties:
pullPolicy:
default: IfNotPresent
enum:
- Always
- Never
- IfNotPresent
type: string
registry:
default: docker.io
type: string
repository:
default: to-be/defined
type: string
tag:
default: v1.0.0
type: string
type: object
type: object
plugins:
default:
- https://github.com/vaulttec/sonar-auth-oidc/releases/download/v2.1.1/sonar-auth-oidc-plugin-2.1.1.jar
- https://github.com/jycr/sonar-l10n-fr/releases/download/9.9.0/sonar-l10n-fr-plugin-9.9.0.jar
- https://github.com/sbaudoin/sonar-yaml/releases/download/v1.7.0/sonar-yaml-plugin-1.7.0.jar
- https://github.com/sbaudoin/sonar-shellcheck/releases/download/v2.5.0/sonar-shellcheck-plugin-2.5.0.jar
- https://github.com/cnescatlab/sonar-hadolint-plugin/releases/download/1.1.0/sonar-hadolint-plugin-1.1.0.jar
- https://github.com/sbaudoin/sonar-ansible/releases/download/v2.5.1/sonar-ansible-extras-plugin-2.5.1.jar
examples:
- - https://github.com/vaulttec/sonar-auth-oidc/releases/download/v2.1.1/sonar-auth-oidc-plugin-2.1.1.jar
- https://github.com/jycr/sonar-l10n-fr/releases/download/9.9.0/sonar-l10n-fr-plugin-9.9.0.jar
- https://github.com/sbaudoin/sonar-yaml/releases/download/v1.7.0/sonar-yaml-plugin-1.7.0.jar
- https://github.com/sbaudoin/sonar-shellcheck/releases/download/v2.5.0/sonar-shellcheck-plugin-2.5.0.jar
- https://github.com/cnescatlab/sonar-hadolint-plugin/releases/download/1.1.0/sonar-hadolint-plugin-1.1.0.jar
- https://github.com/sbaudoin/sonar-ansible/releases/download/v2.5.1/sonar-ansible-extras-plugin-2.5.1.jar
items:
type: string
type: array
domain:
default: your-company
examples:
- your-company
type: string
domain-name:
default: your_company.com
examples:
- your_company.com
type: string
issuer:
default: letsencrypt-prod
examples:
- letsencrypt-prod
type: string
dependencies: []
providers:
kubernetes: true
authentik: true
kubectl: true
postgresql: null
restapi: null
http: null
gitea: null
tfaddtype: null

View File

@@ -0,0 +1,12 @@
# Source: sonarqube/templates/config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: sonar-sonarqube-config
labels:
app: sonarqube
chart: sonarqube-10.2.1_800
release: sonar
heritage: Helm
data:
sonar.properties: |

View File

@@ -0,0 +1,12 @@
# Source: sonarqube/templates/init-fs.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: sonar-sonarqube-init-fs
labels:
app: sonarqube
chart: sonarqube-10.2.1_800
release: sonar
heritage: Helm
data:
init_fs.sh: |-

View File

@@ -0,0 +1,30 @@
# Source: sonarqube/templates/init-sysctl.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: sonar-sonarqube-init-sysctl
labels:
app: sonarqube
chart: sonarqube-10.2.1_800
release: sonar
heritage: Helm
data:
init_sysctl.sh: |-
if [[ "$(sysctl -n vm.max_map_count)" -lt 524288 ]]; then
sysctl -w vm.max_map_count=524288
fi
if [[ "$(sysctl -n fs.file-max)" -lt 131072 ]]; then
sysctl -w fs.file-max=131072
fi
if [[ "$(ulimit -n)" != "unlimited" ]]; then
if [[ "$(ulimit -n)" -lt 131072 ]]; then
echo "ulimit -n 131072"
ulimit -n 131072
fi
fi
if [[ "$(ulimit -u)" != "unlimited" ]]; then
if [[ "$(ulimit -u)" -lt 8192 ]]; then
echo "ulimit -u 8192"
ulimit -u 8192
fi
fi

View File

@@ -0,0 +1,20 @@
# Source: sonarqube/templates/install-plugins.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: sonar-sonarqube-install-plugins
labels:
app: sonarqube
chart: sonarqube-10.2.1_800
release: sonar
heritage: Helm
data:
install_plugins.sh: |-
rm -f /opt/sonarqube/extensions/plugins/*
cd /opt/sonarqube/extensions/plugins
curl -fsSLO "https://github.com/vaulttec/sonar-auth-oidc/releases/download/v2.1.1/sonar-auth-oidc-plugin-2.1.1.jar"
curl -fsSLO "https://github.com/jycr/sonar-l10n-fr/releases/download/9.9.0/sonar-l10n-fr-plugin-9.9.0.jar"
curl -fsSLO "https://github.com/sbaudoin/sonar-yaml/releases/download/v1.7.0/sonar-yaml-plugin-1.7.0.jar"
curl -fsSLO "https://github.com/sbaudoin/sonar-shellcheck/releases/download/v2.5.0/sonar-shellcheck-plugin-2.5.0.jar"
curl -fsSLO "https://github.com/cnescatlab/sonar-hadolint-plugin/releases/download/1.1.0/sonar-hadolint-plugin-1.1.0.jar"
curl -fsSLO "https://github.com/sbaudoin/sonar-ansible/releases/download/v2.5.1/sonar-ansible-extras-plugin-2.5.1.jar"

View File

@@ -0,0 +1,13 @@
# Source: sonarqube/templates/jdbc-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: sonar-sonarqube-jdbc-config
labels:
app: sonarqube
chart: sonarqube-10.2.1_800
release: sonar
heritage: Helm
data:
SONAR_JDBC_USERNAME: "sonarUser"
SONAR_JDBC_URL: "jdbc:postgresql://sonar-postgresql:5432/sonarDB"

View File

@@ -0,0 +1,14 @@
# Source: sonarqube/templates/prometheus-ce-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: sonar-sonarqube-prometheus-ce-config
labels:
app: sonarqube
chart: sonarqube-10.2.1_800
release: sonar
heritage: Helm
data:
prometheus-ce-config.yaml: |-
rules:
- pattern: .*

View File

@@ -0,0 +1,14 @@
# Source: sonarqube/templates/prometheus-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: sonar-sonarqube-prometheus-config
labels:
app: sonarqube
chart: sonarqube-10.2.1_800
release: sonar
heritage: Helm
data:
prometheus-config.yaml: |-
rules:
- pattern: .*

View File

@@ -0,0 +1,12 @@
apiVersion: v1
kind: Secret
metadata:
name: sonar-sonarqube-monitoring-passcode
labels:
app: sonarqube
chart: sonarqube-10.2.1_800
release: sonar
heritage: Helm
type: Opaque
data:
SONAR_WEB_SYSTEMPASSCODE: "ZGVmaW5lX2l0"

View File

@@ -0,0 +1,21 @@
# Source: sonarqube/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: sonar-sonarqube
labels:
app: sonarqube
chart: sonarqube-10.2.1_800
release: sonar
heritage: Helm
spec:
type: ClusterIP
ports:
- port: 9000
targetPort: http
protocol: TCP
name: http
selector:
app: sonarqube
release: sonar