diff --git a/base-values/mycloud-core.yaml b/base-values/mycloud-core.yaml new file mode 100644 index 0000000..2315db3 --- /dev/null +++ b/base-values/mycloud-core.yaml @@ -0,0 +1,37 @@ +commons: + # -- needed, but could be set with componentCommons.helm.release.valuesFrom + # masterPassword: + + theme: + title: + logo: + favicon: + + persistence: + storageClass: + hostPath: + enabled: false + prefix: "/var/lib/mycloud" + + mail: + host: + username: + password: + from: + use_tls: false + use_ssl: false + +components: + mycloud-services: + enabled: true + # current namespace + namespace: + values: + databases: + authentik: + type: postgresql + + mycloud-authentik: + enabled: true + # current namespace + namespace: \ No newline at end of file diff --git a/mycloud-authentik/.helmignore b/mycloud-authentik/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/mycloud-authentik/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/mycloud-authentik/Chart.yaml b/mycloud-authentik/Chart.yaml new file mode 100644 index 0000000..f198fe3 --- /dev/null +++ b/mycloud-authentik/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +name: mycloud-authentik +description: A mycloud components using authentik (for central authentification using SSO) + +type: application +version: 0.1.0 diff --git a/mycloud-authentik/blueprints/flows-recovery-email-verification.yaml b/mycloud-authentik/blueprints/flows-recovery-email-verification.yaml new file mode 100644 index 0000000..1abc77e --- /dev/null +++ b/mycloud-authentik/blueprints/flows-recovery-email-verification.yaml @@ -0,0 +1,161 @@ +# https://raw.githubusercontent.com/goauthentik/authentik/583c5e3ba7acd88d31444c2faabf80040319286a/blueprints/example/flows-recovery-email-verification.yaml +version: 1 +metadata: + name: myCloud - Recovery with email verification +entries: + - identifiers: + slug: default-recovery-flow + id: flow + model: authentik_flows.flow + attrs: + name: Default recovery flow + title: Reset your password + designation: recovery + authentication: require_unauthenticated + - identifiers: + name: default-recovery-field-password + id: prompt-field-password + model: authentik_stages_prompt.prompt + attrs: + field_key: password + label: Password + type: password + required: true + placeholder: Password + order: 0 + placeholder_expression: false + - identifiers: + name: default-recovery-field-password-repeat + id: prompt-field-password-repeat + model: authentik_stages_prompt.prompt + attrs: + field_key: password_repeat + label: Password (repeat) + type: password + required: true + placeholder: Password (repeat) + order: 1 + placeholder_expression: false + - identifiers: + name: default-recovery-skip-if-restored + id: default-recovery-skip-if-restored + model: authentik_policies_expression.expressionpolicy + attrs: + expression: | + return bool(request.context.get('is_restored', True)) + - identifiers: + name: default-recovery-email + id: default-recovery-email + model: authentik_stages_email.emailstage + attrs: + use_global_settings: true + host: localhost + port: 25 + username: "" + use_tls: false + use_ssl: false + timeout: 10 + from_address: system@authentik.local + token_expiry: 30 + subject: authentik + template: email/password_reset.html + activate_user_on_success: true + - identifiers: + name: default-recovery-user-write + id: default-recovery-user-write + model: authentik_stages_user_write.userwritestage + attrs: + user_creation_mode: never_create + - identifiers: + name: default-recovery-identification + id: default-recovery-identification + model: authentik_stages_identification.identificationstage + attrs: + user_fields: + - email + - username + - identifiers: + name: default-recovery-user-login + id: default-recovery-user-login + model: authentik_stages_user_login.userloginstage + - identifiers: + name: Change your password + id: stages-prompt-password + model: authentik_stages_prompt.promptstage + attrs: + fields: + - !KeyOf prompt-field-password + - !KeyOf prompt-field-password-repeat + validation_policies: [] + - identifiers: + target: !KeyOf flow + stage: !KeyOf default-recovery-identification + order: 10 + model: authentik_flows.flowstagebinding + id: flow-binding-identification + attrs: + evaluate_on_plan: true + re_evaluate_policies: true + policy_engine_mode: any + invalid_response_action: retry + - identifiers: + target: !KeyOf flow + stage: !KeyOf default-recovery-email + order: 20 + model: authentik_flows.flowstagebinding + id: flow-binding-email + attrs: + evaluate_on_plan: true + re_evaluate_policies: true + policy_engine_mode: any + invalid_response_action: retry + - identifiers: + pk: 1219d06e-2c06-4c5b-a162-78e3959c6cf0 + target: !KeyOf flow + stage: !KeyOf stages-prompt-password + order: 30 + model: authentik_flows.flowstagebinding + attrs: + evaluate_on_plan: true + re_evaluate_policies: false + policy_engine_mode: any + invalid_response_action: retry + - identifiers: + target: !KeyOf flow + stage: !KeyOf default-recovery-user-write + order: 40 + model: authentik_flows.flowstagebinding + attrs: + evaluate_on_plan: true + re_evaluate_policies: false + policy_engine_mode: any + invalid_response_action: retry + - identifiers: + target: !KeyOf flow + stage: !KeyOf default-recovery-user-login + order: 100 + model: authentik_flows.flowstagebinding + attrs: + evaluate_on_plan: true + re_evaluate_policies: false + policy_engine_mode: any + invalid_response_action: retry + - identifiers: + policy: !KeyOf default-recovery-skip-if-restored + target: !KeyOf flow-binding-identification + order: 0 + model: authentik_policies.policybinding + attrs: + negate: false + enabled: true + timeout: 30 + - identifiers: + policy: !KeyOf default-recovery-skip-if-restored + target: !KeyOf flow-binding-email + order: 0 + state: absent + model: authentik_policies.policybinding + attrs: + negate: false + enabled: true + timeout: 30 diff --git a/mycloud-authentik/blueprints/tenant.gotmpl b/mycloud-authentik/blueprints/tenant.gotmpl new file mode 100644 index 0000000..5b49959 --- /dev/null +++ b/mycloud-authentik/blueprints/tenant.gotmpl @@ -0,0 +1,20 @@ +version: 1 +metadata: + name: myCloud - tenant +entries: + - model: authentik_tenants.tenant + identifiers: + domain: "authentik-default" + state: present + attrs: + {{- with .Values.commons.theme }} + branding_title: {{ .title }} + branding_logo: {{ .logo }} + branding_favicon: {{ .favicon }} + {{- end }} + {{- with .Values.theme.background }} + attributes: + settings: + theme: + background: {{ . | quote }} + {{- end }} diff --git a/mycloud-authentik/templates/configmap_blueprints.yaml b/mycloud-authentik/templates/configmap_blueprints.yaml new file mode 100644 index 0000000..2510bdf --- /dev/null +++ b/mycloud-authentik/templates/configmap_blueprints.yaml @@ -0,0 +1,11 @@ +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-provisioning-blueprints + labels: + goauthentik_blueprint: "1" +data: + tenant.yaml: | + {{- tpl (.Files.Get "blueprints/tenant.gotmpl") . | nindent 4 }} + {{- (.Files.Glob "blueprints/*.yaml").AsConfig | nindent 2 }} diff --git a/mycloud-authentik/templates/configmap_init_crd.yaml b/mycloud-authentik/templates/configmap_init_crd.yaml new file mode 100644 index 0000000..f82bbe4 --- /dev/null +++ b/mycloud-authentik/templates/configmap_init_crd.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-init + namespace: "{{ .Values.init.namespace }}" +data: + {{- if and + (.Capabilities.APIVersions.Has "monitoring.coreos.com/v1/PrometheusRule") + (.Capabilities.APIVersions.Has "monitoring.coreos.com/v1/ServiceMonitor") + }} + init: "-1" + {{- else }} + init: "{{ add1 .Values.init.version }}" + {{- end }} diff --git a/mycloud-authentik/templates/middleware-outposts.yaml b/mycloud-authentik/templates/middleware-outposts.yaml new file mode 100644 index 0000000..b763837 --- /dev/null +++ b/mycloud-authentik/templates/middleware-outposts.yaml @@ -0,0 +1,22 @@ +{{- if (.Capabilities.APIVersions.Has "traefik.containo.us/v1alpha1/Middleware") }} +apiVersion: traefik.containo.us/v1alpha1 +kind: Middleware +metadata: + name: {{ .Release.Name }}-outpost +spec: + forwardAuth: + address: http://{{ .Release.Name }}.{{ .Release.Namespace}}.svc/outpost.goauthentik.io/auth/traefik + trustForwardHeader: true + authResponseHeaders: + - X-authentik-username + - X-authentik-groups + - X-authentik-email + - X-authentik-name + - X-authentik-uid + - X-authentik-jwt + - X-authentik-meta-jwks + - X-authentik-meta-outpost + - X-authentik-meta-provider + - X-authentik-meta-app + - X-authentik-meta-version +{{- end }} diff --git a/mycloud-authentik/templates/release.yaml b/mycloud-authentik/templates/release.yaml new file mode 100644 index 0000000..4d381d6 --- /dev/null +++ b/mycloud-authentik/templates/release.yaml @@ -0,0 +1,128 @@ +--- +apiVersion: helm.toolkit.fluxcd.io/v2beta1 +kind: HelmRelease +metadata: + name: "{{ .Release.Name }}-hr" +spec: + chart: + spec: + sourceRef: + kind: HelmRepository + name: "authentik" + chart: "authentik" + interval: 10m + install: + {{- toYaml .Values.commons.helm.release.install | nindent 4 }} + test: + {{- toYaml .Values.commons.helm.release.test | nindent 4 }} + upgrade: + {{- toYaml .Values.commons.helm.release.upgrade | nindent 4 }} + interval: 10m + values: + authentik: + secret_key: {{ .Values.secret_key | default (derivePassword 1 "long" .Values.commons.masterPassword "authentik" "secret_key") | quote }} + avatars: "none" + postgresql: + host: {{ .Values.database.host | quote }} + name: {{ .Values.database.name | quote }} + user: {{ .Values.database.username | quote }} + password: {{ .Values.database.password | default (derivePassword 1 "long" .Values.commons.masterPassword "authentik" "database_password") | quote }} + email: + host: {{ .Values.commons.mail.host | quote }} + username: {{ .Values.commons.mail.username | quote }} + password: {{ .Values.commons.mail.password | quote }} + use_tls: {{ .Values.commons.mail.use_tls }} + use_ssl: {{ .Values.commons.mail.use_ssl }} + from: {{ .Values.mail.from | default (printf "[%s] %s <%s>" .Values.commons.theme.title "authentik" .Values.commons.mail.from) | quote }} + + redis: + enabled: true + architecture: replication + replica: + replicaCount: 1 + metrics: + enabled: true + serviceMonitor: + enabled: {{ (.Capabilities.APIVersions.Has "monitoring.coreos.com/v1/ServiceMonitor") }} + additionalLabels: + {{- toYaml .Values.commons.prometheus.monitor.labels | nindent 12 }} + prometheusRule: + # empty rules + enabled: false + # {{ (.Capabilities.APIVersions.Has "monitoring.coreos.com/v1/PrometheusRule") }} + additionalLabels: + {{- toYaml .Values.commons.prometheus.rules.labels | nindent 12 }} + rules: [] + + postgresql: + enabled: false + + prometheus: + serviceMonitor: + create: {{ (.Capabilities.APIVersions.Has "monitoring.coreos.com/v1/ServiceMonitor") }} + labels: + {{- toYaml .Values.commons.prometheus.monitor.labels | nindent 10 }} + rules: + create: {{ (.Capabilities.APIVersions.Has "monitoring.coreos.com/v1/PrometheusRule") }} + labels: + {{- toYaml .Values.commons.prometheus.rules.labels | nindent 10 }} + + {{- $host := .Values.ingress.host | default (printf "auth.%s" .Values.commons.ingress.domain) }} + ingress: + enabled: true + annotations: + {{- with .Values.commons.ingress.annotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ingress.annotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + hosts: + - host: "{{ $host }}" + paths: + - path: "/" + pathType: "Prefix" + {{- if .Values.commons.ingress.tls.enabled }} + tls: + {{- with .Values.commons.ingress.tls.override }} + {{- toYaml . | nindent 8 }} + {{- else }} + - secretName: "mycloud-authentik-cert" + hosts: + - "{{ $host }}" + {{- end }} + {{- end }} + + # + # https://github.com/goauthentik/helm/pull/146 + # + serviceAccount: + create: true + + additionalContainers: + - name: sidecar-blueprints + image: "ghcr.io/kiwigrid/k8s-sidecar:1.25.1" + env: + - name: "FOLDER" + value: "/blueprints/sidecar" + - name: "LABEL" + value: "goauthentik_blueprint" + - name: "LABEL_VALUE" + value: "1" + # - name: "NAMESPACE" + # value: "ALL" + - name: "RESOURCE" + value: "both" + - name: "UNIQUE_FILENAMES" + value: "true" + volumeMounts: + - name: sidecar-blueprints + mountPath: /blueprints/sidecar + + volumeMounts: + - name: sidecar-blueprints + mountPath: /blueprints/sidecar + + volumes: + - name: sidecar-blueprints + emptyDir: {} diff --git a/mycloud-authentik/templates/repo.yaml b/mycloud-authentik/templates/repo.yaml new file mode 100644 index 0000000..ebc4ac2 --- /dev/null +++ b/mycloud-authentik/templates/repo.yaml @@ -0,0 +1,8 @@ +--- +apiVersion: source.toolkit.fluxcd.io/v1beta2 +kind: HelmRepository +metadata: + name: authentik +spec: + url: https://charts.goauthentik.io + interval: 10m0s diff --git a/mycloud-authentik/templates/role-binding.yaml b/mycloud-authentik/templates/role-binding.yaml new file mode 100644 index 0000000..b153763 --- /dev/null +++ b/mycloud-authentik/templates/role-binding.yaml @@ -0,0 +1,11 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ .Release.Name }}-blueprint-sidecar +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ .Release.Name }}-blueprint-sidecar +subjects: + - kind: ServiceAccount + name: {{ .Release.Name }}-hr diff --git a/mycloud-authentik/templates/role.yaml b/mycloud-authentik/templates/role.yaml new file mode 100644 index 0000000..ace6715 --- /dev/null +++ b/mycloud-authentik/templates/role.yaml @@ -0,0 +1,9 @@ +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ .Release.Name }}-blueprint-sidecar +rules: +- apiGroups: [""] + resources: ["configmaps", "secrets"] + verbs: ["get", "watch", "list"] diff --git a/mycloud-authentik/values.yaml b/mycloud-authentik/values.yaml new file mode 100644 index 0000000..0869c56 --- /dev/null +++ b/mycloud-authentik/values.yaml @@ -0,0 +1,65 @@ +init: + version: 0 + namespace: "bases" + +commons: + masterPassword: "CHANGEME" + theme: + title: myCloud + logo: /static/dist/assets/icons/icon_left_brand.svg + favicon: /static/dist/assets/icons/icon.png + + mail: + host: + username: + password: + from: + use_tls: false + use_ssl: false + + helm: + release: + install: {} + test: {} + upgrade: {} + + ingress: + domain: "wrenix.eu" + annotations: + cert-manager.io/cluster-issuer: letsencrypt-prod + tls: + # -- tls on every ingress + enabled: true + # -- use own definition of tls (e.g. for own or wildcard certificate) + override: + + prometheus: + monitor: + labels: {} + rules: + labels: {} + + +# -- generated by .Values.commons.masterPassword +secret_key: + +ingress: + # -- default: auth.(Values.commons.ingress.domain) + host: + annotations: + +database: + # -- default is from mysql-services + host: mycloud-services-postgresql + name: authentik + username: authentik + # -- generated by .Values.commons.masterPassword (equal to mycloud-services) + password: + +mail: + # -- generade by Values.commons.mail.from + from: + # other settings are taken from commons + +theme: + background: diff --git a/mycloud-services/.helmignore b/mycloud-services/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/mycloud-services/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/mycloud-services/Chart.yaml b/mycloud-services/Chart.yaml new file mode 100644 index 0000000..023f40d --- /dev/null +++ b/mycloud-services/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v2 +name: mycloud-services +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "1.16.0" diff --git a/mycloud-services/templates/postgresql/release.yaml b/mycloud-services/templates/postgresql/release.yaml new file mode 100644 index 0000000..a9c29db --- /dev/null +++ b/mycloud-services/templates/postgresql/release.yaml @@ -0,0 +1,47 @@ +--- +apiVersion: helm.toolkit.fluxcd.io/v2beta1 +kind: HelmRelease +metadata: + name: mycloud-services-postgresql +spec: + chart: + spec: + sourceRef: + kind: GitRepository + name: "wrenix-helm-charts" + namespace: "flux-system" + chart: "./postgresql" + reconcileStrategy: "Revision" + interval: 10m + releaseName: mycloud-services-postgresql + install: + {{- toYaml .Values.commons.helm.release.install | nindent 4 }} + test: + {{- toYaml .Values.commons.helm.release.test | nindent 4 }} + upgrade: + {{- toYaml .Values.commons.helm.release.upgrade | nindent 4 }} + interval: 10m + valuesFrom: + - kind: Secret + name: mycloud-services-postgresql + values: + persistence: + size: {{ .Values.postgresql.persistence.size }} + {{- with .Values.postgresql.persistence.storageClass | default .Values.commons.persistence.storageClass }} + storageClass: {{ . }} + {{- end }} + {{- if .Values.commons.persistence.hostPath.enabled }} + hostPath: "{{ .Values.commons.persistence.hostPath.prefix }}/services/postgresql" + {{- end }} + + postgres: + password: {{ .Values.postgresql.password | default (derivePassword 1 "long" .Values.commons.masterPassword "services" "postgresql_password") | quote }} + + job: + databases: + {{- range $database, $config := .Values.databases }} + {{- if (eq $config.type "postgresql") }} + {{ $database }}: + owner: {{ $config.username | default $database }} + {{- end }} + {{- end }} diff --git a/mycloud-services/templates/postgresql/secrets.yaml b/mycloud-services/templates/postgresql/secrets.yaml new file mode 100644 index 0000000..d32329c --- /dev/null +++ b/mycloud-services/templates/postgresql/secrets.yaml @@ -0,0 +1,14 @@ +--- +apiVersion: v1 +kind: Secret +metadata: + name: mycloud-services-postgresql +stringData: + values.yaml: | + job: + users: + {{- range $database, $config := .Values.databases }} + {{- if (eq $config.type "postgresql") }} + {{ $config.username | default $database }}: {{ $config.password | default (derivePassword 1 "long" $.Values.commons.masterPassword $database "database_password") | quote }} + {{- end }} + {{- end }} diff --git a/mycloud-services/values.yaml b/mycloud-services/values.yaml new file mode 100644 index 0000000..79a9ac8 --- /dev/null +++ b/mycloud-services/values.yaml @@ -0,0 +1,31 @@ +commons: + masterPassword: "CHANGEME" + + persistence: + storageClass: + hostPath: + enabled: false + prefix: "/var/lib/mycloud" + + helm: + release: + install: {} + test: {} + upgrade: {} + +postgresql: + persistence: + storageClass: + size: "10G" + # -- root + password: + +# -- create databases +databases: + example: + # -- database type (current only "postgresql" is supported) + type: none + # -- username default like database + username: example-password + # -- if not set generated by .Values.commons.masterPassword and databasename + password: \ No newline at end of file