From a1a7579d3dbff1f0da03cc2278ea31dafa082d9f Mon Sep 17 00:00:00 2001 From: Alex Chapellon Date: Wed, 9 Aug 2023 10:55:23 +0200 Subject: [PATCH] OPSEXP-1862: offer repository subsystem configuration (#95) --- .pre-commit-config.yaml | 6 +- charts/alfresco-repository/Chart.yaml | 2 +- charts/alfresco-repository/README.md | 91 +++++++++++++++++-- charts/alfresco-repository/README.md.gotmpl | 19 ++++ charts/alfresco-repository/docs/subsystems.md | 75 +++++++++++++++ .../templates/deployment.yaml | 27 ++++-- .../tests/deployment_test.yaml | 26 +++++- charts/alfresco-repository/values.yaml | 14 ++- charts/alfresco-sync-service/Chart.lock | 7 +- charts/alfresco-sync-service/Chart.yaml | 5 +- charts/alfresco-sync-service/README.md | 3 +- 11 files changed, 234 insertions(+), 41 deletions(-) create mode 100644 charts/alfresco-repository/README.md.gotmpl create mode 100644 charts/alfresco-repository/docs/subsystems.md diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6c00fe5e..32a7ac11 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -12,7 +12,7 @@ repos: hooks: - id: helm-docs - repo: https://github.com/bridgecrewio/checkov.git - rev: 2.3.130 + rev: 2.3.358 hooks: - id: checkov files: charts/.*\.yaml$ @@ -21,7 +21,7 @@ repos: - --quiet - --compact - repo: https://github.com/jtyr/kubeconform-helm - rev: v0.1.12 + rev: v0.1.15 hooks: - id: kubeconform-helm alias: kubeconform-helm-min @@ -32,7 +32,7 @@ repos: - --exclude-charts=alfresco-common,alfresco-sync-service - --values-dir=ci - repo: https://github.com/jtyr/kubeconform-helm - rev: v0.1.12 + rev: v0.1.15 hooks: - id: kubeconform-helm name: "Kubeconform Helm - current k8s version" diff --git a/charts/alfresco-repository/Chart.yaml b/charts/alfresco-repository/Chart.yaml index 2430d1ce..e503dd08 100644 --- a/charts/alfresco-repository/Chart.yaml +++ b/charts/alfresco-repository/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 name: alfresco-repository description: Alfresco content repository Helm chart type: application -version: 0.1.0-alpha.5 +version: 0.1.0-alpha.6 appVersion: 23.1.0-A21 dependencies: - name: alfresco-common diff --git a/charts/alfresco-repository/README.md b/charts/alfresco-repository/README.md index 60b151b7..da844eb9 100644 --- a/charts/alfresco-repository/README.md +++ b/charts/alfresco-repository/README.md @@ -1,6 +1,6 @@ # alfresco-repository -![Version: 0.1.0-alpha.5](https://img.shields.io/badge/Version-0.1.0--alpha.5-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 23.1.0-A21](https://img.shields.io/badge/AppVersion-23.1.0--A21-informational?style=flat-square) +![Version: 0.1.0-alpha.6](https://img.shields.io/badge/Version-0.1.0--alpha.6-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 23.1.0-A21](https://img.shields.io/badge/AppVersion-23.1.0--A21-informational?style=flat-square) Alfresco content repository Helm chart @@ -11,6 +11,82 @@ Alfresco content repository Helm chart | https://alfresco.github.io/alfresco-helm-charts/ | alfresco-common | 2.1.0-alpha.4 | | oci://registry-1.docker.io/bitnamicharts | postgresql | 12.5.6 | +## Configuring Alfresco subsystems + +This chart offers a simple mechanism to configure Alfresco Subsystems. + +The way it's done is pretty simple, one just need to provide a secret which +contains all the configuration files for the subsystems. The secret needs to be +added to the list of `.Values.configuration.repository.existingSecrets`: + +```yaml +configuration: + repository: + existingSecrets: + - name: ldap1 + purpose: subsystems:Authentication:ldap +``` + +For the above configuration to work there are some rules to follow: + +* `name` must match both the secret name and the subsystem instance name (in + case the subsystem name must be referenced somewhere else, e.g. in + `authentication.chain`) +* `purpose` must be of the form: `subsystems:subsystemName:subsystemType` +* The secret must contain all necessary files to configure the subsystem. + Usually a bean definition XML file and properties file. (see example below) + +### Examples: ContentStore configuration + +Creating the subsystem's secret: + +Place all the configuration files in a folder on your local system. Sample +files can be extracted from the S3 AMP file. For more details on the content of +the files check out the [Alfresco S3 connector +doc](https://docs.alfresco.com/aws-s3/latest/config/#content-store-subsystems#). + +```bash +mkdir s3-config +unzip -d s3-config ~/Downloads/alfresco-s3-connector-5.1.0.amp config/alfresco/subsystems/ContentStore/S3/ +tree s3-config +s3-config/ + ├── s3-contentstore-context.xml + └── s3-contentstore.properties +... +``` + +> By default subsystem Beans may include other XML files from upper level +> directories. This is not possible with as kubernetes secrets are projected +> down from a single directory (mount point). If your subsystem config does +> this kind of inclusion you'll need to amend the Bean to not use `import` +> statement or import from the current directory. + +Create the secret using `kubectl` + +```shell +kubectl create secret generic S3 --from-file=s3-config/ +``` + +Pass the following `configuration.repository.existingSecrets` together with the +property to set the new contentstore subsystem as the default contentstore: + +```yaml +configuration: + repository: + existingSecrets: + - name: repository-secrets + key: license.lic + purpose: acs-license + - name: S3 + purpose: subsystems:ContentStore:S3 +environment: + CATALINA_OPTS: >- + -Dfilecontentstore.subsystem.name=S3 +``` + +> As a list, `configuration.repository/existingSecrets` cannot be merged so you +> would need to re-define the license secret to have it deployed. + ## Values | Key | Type | Default | Description | @@ -38,7 +114,7 @@ Alfresco content repository Helm chart | configuration.messageBroker.url | string | `nil` | Message Broker URL | | configuration.messageBroker.username | string | `nil` | Username to authenticate to the message broker | | configuration.repository.existingConfigMap | string | `nil` | a configmap containing the "alfresco-global.properties" key populated with actual Alfresco repository properties | -| configuration.repository.existingSecrets | list | `[{"key":"license.lic","name":"repository-secrets","purpose":"acs-license"}]` | A list of secrets to make available to the repo as env vars. It's also used to pass the Alfresco license which will be mounted as a file when the secret as the `purpose` value set to `acs-license`. Other secrets will be used as env variables. | +| configuration.repository.existingSecrets | list | `[{"key":"license.lic","name":"repository-secrets","purpose":"acs-license"}]` | A list of secrets to make available to the repository as env vars. This list can contain special secrets marked with predifined `purpose`: `acs-license` to pass license as a secret or subsystems:*:* to configure an Alfresco subsystem. See [Configuring Alfresco Subsystem](#configuring-alfresco-subsystems) for more details. | | configuration.search.existingConfigMap.keys.flavor | string | `"SEARCH_FLAVOR"` | | | configuration.search.existingConfigMap.keys.url | string | `"SEARCH_URL"` | Key within the configmap holding the search service URL. | | configuration.search.existingConfigMap.name | string | `nil` | Optional configmap containing the search service URL | @@ -65,13 +141,10 @@ Alfresco content repository Helm chart | image.repository | string | `"quay.io/alfresco/alfresco-content-repository"` | | | image.tag | string | `"23.1.0-A21"` | | | imagePullSecrets | list | `[]` | | -| ingress.annotations."nginx.ingress.kubernetes.io/affinity" | string | `"cookie"` | | -| ingress.annotations."nginx.ingress.kubernetes.io/proxy-body-size" | string | `"5g"` | | -| ingress.annotations."nginx.ingress.kubernetes.io/session-cookie-hash" | string | `"sha1"` | | -| ingress.annotations."nginx.ingress.kubernetes.io/session-cookie-name" | string | `"alfrescoRepo"` | | -| ingress.enabled | bool | `true` | | +| ingress.annotations | object | `{"nginx.ingress.kubernetes.io/affinity":"cookie","nginx.ingress.kubernetes.io/proxy-body-size":"5g","nginx.ingress.kubernetes.io/session-cookie-hash":"sha1","nginx.ingress.kubernetes.io/session-cookie-name":"alfrescoRepo"}` | provide annotations for nginx ingress (no toher ingress is supported at that point) | +| ingress.enabled | bool | `true` | Toggle ingress | | ingress.hosts[0].paths[0].path | string | `"/"` | | -| ingress.hosts[0].paths[0].pathType | string | `"ImplementationSpecific"` | | +| ingress.hosts[0].paths[0].pathType | string | `"Prefix"` | | | ingress.tls | list | `[]` | | | livenessProbe.httpGet.path | string | `"/alfresco/api/-default-/public/alfresco/versions/1/probes/-live-"` | | | livenessProbe.httpGet.port | string | `"http"` | | @@ -118,5 +191,3 @@ Alfresco content repository Helm chart | terminationGracePeriod | int | `60` | How long to wait for tomcat to complete shutdown before killing it | | tolerations | list | `[]` | | ----------------------------------------------- -Autogenerated from chart metadata using [helm-docs v1.11.0](https://github.com/norwoodj/helm-docs/releases/v1.11.0) diff --git a/charts/alfresco-repository/README.md.gotmpl b/charts/alfresco-repository/README.md.gotmpl new file mode 100644 index 00000000..009bb727 --- /dev/null +++ b/charts/alfresco-repository/README.md.gotmpl @@ -0,0 +1,19 @@ +{{ template "chart.header" . }} +{{ template "chart.deprecationWarning" . }} + +{{ template "chart.badgesSection" . }} + +{{ template "chart.description" . }} + +{{ template "chart.homepageLine" . }} + +{{ template "chart.maintainersSection" . }} + +{{ template "chart.sourcesSection" . }} + +{{ template "chart.requirementsSection" . }} + +{{ .Files.Get "docs/subsystems.md" }} + +{{ template "chart.valuesSection" . }} + diff --git a/charts/alfresco-repository/docs/subsystems.md b/charts/alfresco-repository/docs/subsystems.md new file mode 100644 index 00000000..faa75d66 --- /dev/null +++ b/charts/alfresco-repository/docs/subsystems.md @@ -0,0 +1,75 @@ +## Configuring Alfresco subsystems + +This chart offers a simple mechanism to configure Alfresco Subsystems. + +The way it's done is pretty simple, one just need to provide a secret which +contains all the configuration files for the subsystems. The secret needs to be +added to the list of `.Values.configuration.repository.existingSecrets`: + +```yaml +configuration: + repository: + existingSecrets: + - name: ldap1 + purpose: subsystems:Authentication:ldap +``` + +For the above configuration to work there are some rules to follow: + +* `name` must match both the secret name and the subsystem instance name (in + case the subsystem name must be referenced somewhere else, e.g. in + `authentication.chain`) +* `purpose` must be of the form: `subsystems:subsystemName:subsystemType` +* The secret must contain all necessary files to configure the subsystem. + Usually a bean definition XML file and properties file. (see example below) + +### Examples: ContentStore configuration + +Creating the subsystem's secret: + +Place all the configuration files in a folder on your local system. Sample +files can be extracted from the S3 AMP file. For more details on the content of +the files check out the [Alfresco S3 connector +doc](https://docs.alfresco.com/aws-s3/latest/config/#content-store-subsystems#). + +```bash +mkdir s3-config +unzip -d s3-config ~/Downloads/alfresco-s3-connector-5.1.0.amp config/alfresco/subsystems/ContentStore/S3/ +tree s3-config +s3-config/ + ├── s3-contentstore-context.xml + └── s3-contentstore.properties +... +``` + +> By default subsystem Beans may include other XML files from upper level +> directories. This is not possible with as kubernetes secrets are projected +> down from a single directory (mount point). If your subsystem config does +> this kind of inclusion you'll need to amend the Bean to not use `import` +> statement or import from the current directory. + +Create the secret using `kubectl` + +```shell +kubectl create secret generic S3 --from-file=s3-config/ +``` + +Pass the following `configuration.repository.existingSecrets` together with the +property to set the new contentstore subsystem as the default contentstore: + +```yaml +configuration: + repository: + existingSecrets: + - name: repository-secrets + key: license.lic + purpose: acs-license + - name: S3 + purpose: subsystems:ContentStore:S3 +environment: + CATALINA_OPTS: >- + -Dfilecontentstore.subsystem.name=S3 +``` + +> As a list, `configuration.repository/existingSecrets` cannot be merged so you +> would need to re-define the license secret to have it deployed. diff --git a/charts/alfresco-repository/templates/deployment.yaml b/charts/alfresco-repository/templates/deployment.yaml index 65fc0b40..e835e186 100644 --- a/charts/alfresco-repository/templates/deployment.yaml +++ b/charts/alfresco-repository/templates/deployment.yaml @@ -91,11 +91,11 @@ spec: name: {{ $dbsecret }} key: {{ .Values.configuration.db.existingSecret.keys.password }} {{- range .Values.configuration.repository.existingSecrets }} - {{- if not (eq "acs-license" .purpose) }} - {{- $repoSecretsKeyRef := dict "name" .name "key" .key }} - {{- $repoSecretsEnv:= dict "name" .key "valueFrom" (dict "secretKeyRef" $repoSecretsKeyRef) }} - {{- list $repoSecretsEnv | toYaml | nindent 12 }} - {{- end }} + {{- if not (or (eq "acs-license" .purpose) (hasPrefix "subsystems:" (.purpose | default ""))) }} + {{- $repoSecretsKeyRef := dict "name" .name "key" .key }} + {{- $repoSecretsEnv:= dict "name" .key "valueFrom" (dict "secretKeyRef" $repoSecretsKeyRef) }} + {{- list $repoSecretsEnv | toYaml | nindent 12 }} + {{- end }} {{- end }} - name: ELASTICSEARCH_USERNAME valueFrom: @@ -172,6 +172,10 @@ spec: - name: acs-license mountPath: /usr/local/tomcat/shared/classes/alfresco/extension/license readOnly: true + {{- else if and (hasPrefix "subsystems:" (.purpose | default "")) (eq (splitList ":" (.purpose | default "") | len) 3) }} + - name: {{ .name }} + mountPath: /usr/local/tomcat/shared/classes/alfresco/extension/{{ splitList ":" (.purpose | default "") | join "/" }}/{{ .name }} + readOnly: true {{- end }} {{- end }} {{- if .Values.extraVolumeMounts }} @@ -192,11 +196,14 @@ spec: path: alfresco-global.properties {{- end }} {{- range .Values.configuration.repository.existingSecrets }} - {{- if eq "acs-license" .purpose }} - {{- $licitems := list (dict "key" .key "path" "license.lic") }} - {{- $licvol := dict "name" "acs-license" "secret" (dict "secretName" .name "defaultMode" 0400 "optional" true "items" $licitems ) }} - {{- list $licvol | toYaml | nindent 8 }} - {{- end }} + {{- if eq "acs-license" .purpose }} + {{- $licitems := list (dict "key" .key "path" "license.lic") }} + {{- $licvol := dict "name" "acs-license" "secret" (dict "secretName" .name "defaultMode" 0400 "optional" true "items" $licitems ) }} + {{- list $licvol | toYaml | nindent 8 }} + {{- else if and (hasPrefix "subsystems:" (.purpose | default "")) (eq (splitList ":" (.purpose | default "") | len) 3) }} + {{- $subsysvol := dict "name" .name "secret" (dict "secretName" .name "defaultMode" 0400) }} + {{- list $subsysvol | toYaml | nindent 8 }} + {{- end }} {{- end }} {{- if .Values.extraVolumes }} {{- tpl (.Values.extraVolumes | toYaml) . | nindent 8 }} diff --git a/charts/alfresco-repository/tests/deployment_test.yaml b/charts/alfresco-repository/tests/deployment_test.yaml index 5984be30..5e6928a2 100644 --- a/charts/alfresco-repository/tests/deployment_test.yaml +++ b/charts/alfresco-repository/tests/deployment_test.yaml @@ -122,7 +122,16 @@ tests: fsType: ext4 template: deployment.yaml - - it: should have default license volume + - it: should have custom secrets for license and subsytems + set: + configuration: + repository: + existingSecrets: + - name: repository-secrets + purpose: acs-license + key: license.lic + - name: myAzureAD + purpose: subsystems:Authentication:ldap-ad asserts: - contains: path: spec.template.spec.volumes @@ -143,6 +152,21 @@ tests: mountPath: /usr/local/tomcat/shared/classes/alfresco/extension/license readOnly: true template: deployment.yaml + - contains: + path: spec.template.spec.volumes + content: + name: myAzureAD + secret: + secretName: myAzureAD + defaultMode: 0400 + template: deployment.yaml + - contains: + path: spec.template.spec.containers[0].volumeMounts + content: + name: myAzureAD + mountPath: /usr/local/tomcat/shared/classes/alfresco/extension/subsystems/Authentication/ldap-ad/myAzureAD + readOnly: true + template: deployment.yaml - it: should not have any license volume but vars instead set: configuration: diff --git a/charts/alfresco-repository/values.yaml b/charts/alfresco-repository/values.yaml index c719f520..92034122 100644 --- a/charts/alfresco-repository/values.yaml +++ b/charts/alfresco-repository/values.yaml @@ -24,10 +24,11 @@ configuration: # -- a configmap containing the "alfresco-global.properties" key populated # with actual Alfresco repository properties existingConfigMap: null - # -- A list of secrets to make available to the repo as env vars. It's also - # used to pass the Alfresco license which will be mounted as a file when - # the secret as the `purpose` value set to `acs-license`. Other secrets - # will be used as env variables. + # -- A list of secrets to make available to the repository as env vars. + # This list can contain special secrets marked with predifined `purpose`: + # `acs-license` to pass license as a secret or subsystems:*:* to configure + # an Alfresco subsystem. See [Configuring Alfresco + # Subsystem](#configuring-alfresco-subsystems) for more details. existingSecrets: - name: repository-secrets key: license.lic @@ -166,7 +167,10 @@ service: port: 80 ingress: + # -- Toggle ingress enabled: true + # -- provide annotations for nginx ingress (no toher ingress is supported at + # that point) annotations: nginx.ingress.kubernetes.io/proxy-body-size: 5g nginx.ingress.kubernetes.io/affinity: "cookie" @@ -175,7 +179,7 @@ ingress: hosts: - paths: - path: / - pathType: ImplementationSpecific + pathType: Prefix tls: [] # - secretName: chart-example-tls # hosts: diff --git a/charts/alfresco-sync-service/Chart.lock b/charts/alfresco-sync-service/Chart.lock index fe06c76e..e981ba5b 100644 --- a/charts/alfresco-sync-service/Chart.lock +++ b/charts/alfresco-sync-service/Chart.lock @@ -1,7 +1,4 @@ dependencies: -- name: common - repository: oci://registry-1.docker.io/bitnamicharts - version: 2.6.0 - name: alfresco-common repository: https://alfresco.github.io/alfresco-helm-charts/ version: 2.0.0 @@ -11,5 +8,5 @@ dependencies: - name: postgresql repository: oci://registry-1.docker.io/bitnamicharts version: 12.5.6 -digest: sha256:0b170e8034f115b475b6e93c52d0b57b07eb23b60d4c1324c540886422e053f2 -generated: "2023-07-24T15:36:54.518253+05:30" +digest: sha256:8e8a94621abb15ef020b09684259eb3d14d7b998b8d0faccadbb1103c5037089 +generated: "2023-08-08T19:50:13.609905+02:00" diff --git a/charts/alfresco-sync-service/Chart.yaml b/charts/alfresco-sync-service/Chart.yaml index 88b0d8cb..5697fd0d 100644 --- a/charts/alfresco-sync-service/Chart.yaml +++ b/charts/alfresco-sync-service/Chart.yaml @@ -8,13 +8,10 @@ keywords: name: alfresco-sync-service sources: - https://github.com/Alfresco/acs-deployment -version: 4.2.1 +version: 4.2.2 appVersion: "3.10.0" icon: https://avatars0.githubusercontent.com/u/391127?s=200&v=4 dependencies: - - name: common - repository: oci://registry-1.docker.io/bitnamicharts - version: 2.x.x - name: alfresco-common version: 2.0.0 repository: https://alfresco.github.io/alfresco-helm-charts/ diff --git a/charts/alfresco-sync-service/README.md b/charts/alfresco-sync-service/README.md index 3aeb9b60..2b80f4a6 100644 --- a/charts/alfresco-sync-service/README.md +++ b/charts/alfresco-sync-service/README.md @@ -1,6 +1,6 @@ # alfresco-sync-service -![Version: 4.2.1](https://img.shields.io/badge/Version-4.2.1-informational?style=flat-square) ![AppVersion: 3.10.0](https://img.shields.io/badge/AppVersion-3.10.0-informational?style=flat-square) +![Version: 4.2.2](https://img.shields.io/badge/Version-4.2.2-informational?style=flat-square) ![AppVersion: 3.10.0](https://img.shields.io/badge/AppVersion-3.10.0-informational?style=flat-square) Alfresco Sync Service @@ -14,7 +14,6 @@ Alfresco Sync Service |------------|------|---------| | https://alfresco.github.io/alfresco-helm-charts/ | activemq | 3.1.0 | | https://alfresco.github.io/alfresco-helm-charts/ | alfresco-common | 2.0.0 | -| oci://registry-1.docker.io/bitnamicharts | common | 2.x.x | | oci://registry-1.docker.io/bitnamicharts | postgresql | 12.5.6 | ## Values