diff --git a/charts/alfresco-share/Chart.yaml b/charts/alfresco-share/Chart.yaml index 1486a8fb..44cdbe10 100644 --- a/charts/alfresco-share/Chart.yaml +++ b/charts/alfresco-share/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 name: alfresco-share description: Alfresco Share Helm chart for Kubernetes type: application -version: 0.3.0 +version: 0.4.0 appVersion: 23.1.1 dependencies: - repository: https://alfresco.github.io/alfresco-helm-charts diff --git a/charts/alfresco-share/README.md b/charts/alfresco-share/README.md index b113f5da..30ba9c72 100644 --- a/charts/alfresco-share/README.md +++ b/charts/alfresco-share/README.md @@ -1,6 +1,6 @@ # alfresco-share -![Version: 0.3.0](https://img.shields.io/badge/Version-0.3.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 23.1.1](https://img.shields.io/badge/AppVersion-23.1.1-informational?style=flat-square) +![Version: 0.4.0](https://img.shields.io/badge/Version-0.4.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 23.1.1](https://img.shields.io/badge/AppVersion-23.1.1-informational?style=flat-square) Alfresco Share Helm chart for Kubernetes @@ -27,6 +27,7 @@ Checkout [alfresco-content-services chart's doc](https://github.com/Alfresco/acs | fullnameOverride | string | `""` | Define a fully static name | | global.alfrescoRegistryPullSecrets | string | `"quay-registry-secret"` | If a private image registry a secret can be defined and passed to kubernetes, see: https://github.com/Alfresco/acs-deployment/blob/a924ad6670911f64f1bba680682d266dd4ea27fb/docs/helm/eks-deployment.md#docker-registry-secret | | global.known_urls | string | `nil` | a fallback for .Values.known_urls that can be shared between charts | +| hazelcast.port | int | `5701` | Port used to expose the Hazelcast service when replicaCount > 1 | | image.port | int | `8080` | Internal port where the pod is listening. Should only be changed is you use a custom image which uses a different port. | | image.pullPolicy | string | `"IfNotPresent"` | | | image.repository | string | `"quay.io/alfresco/alfresco-share"` | | @@ -38,6 +39,7 @@ Checkout [alfresco-content-services chart's doc](https://github.com/Alfresco/acs | ingress.annotations."nginx.ingress.kubernetes.io/session-cookie-max-age" | string | `"604800"` | | | ingress.annotations."nginx.ingress.kubernetes.io/session-cookie-name" | string | `"alfrescoShare"` | | | ingress.annotations."nginx.ingress.kubernetes.io/session-cookie-path" | string | `"/share"` | | +| ingress.className | string | `"nginx"` | | | ingress.enabled | bool | `true` | | | ingress.hosts[0].paths[0].path | string | `"/share"` | | | ingress.hosts[0].paths[0].pathType | string | `"ImplementationSpecific"` | | @@ -46,6 +48,7 @@ Checkout [alfresco-content-services chart's doc](https://github.com/Alfresco/acs | livenessProbe.initialDelaySeconds | int | `15` | | | livenessProbe.periodSeconds | int | `20` | | | livenessProbe.timeoutSeconds | int | `5` | | +| managedApplicationContext.enabled | bool | `true` | Automatically inject a custom application context file which for now only enables hazelcast clustering when more than one replica is configured. Should be disabled when providing a custom application context file. | | nameOverride | string | `""` | Define a partially static name | | nodeSelector | object | `{}` | | | podAnnotations | object | `{}` | | @@ -54,6 +57,7 @@ Checkout [alfresco-content-services chart's doc](https://github.com/Alfresco/acs | readinessProbe.initialDelaySeconds | int | `15` | | | readinessProbe.periodSeconds | int | `30` | | | readinessProbe.timeoutSeconds | int | `5` | | +| replicaCount | int | `1` | Define the number of replicas to run. Multiple replicas are only supported on Share 23.1.1 and later | | repository.existingConfigMap.keys.host | string | `"REPO_HOST"` | name of the key in the configMap where to find the repository service host | | repository.existingConfigMap.keys.port | string | `"REPO_PORT"` | name of the key in the configMap where to find the repository service port | | repository.existingConfigMap.name | string | `nil` | a pre-existing configmap which provides expected configuration for Share | diff --git a/charts/alfresco-share/ci/default-values.yaml b/charts/alfresco-share/ci/default-values.yaml new file mode 100644 index 00000000..0cb20bb2 --- /dev/null +++ b/charts/alfresco-share/ci/default-values.yaml @@ -0,0 +1,4 @@ +tags: + ci: true + +replicaCount: 2 diff --git a/charts/alfresco-share/templates/_helpers-name.tpl b/charts/alfresco-share/templates/_helpers-name.tpl new file mode 100644 index 00000000..b54e1005 --- /dev/null +++ b/charts/alfresco-share/templates/_helpers-name.tpl @@ -0,0 +1,19 @@ +{{- define "alfresco-share.custom-application-context.name" -}} +{{- $scope := (dict "Values" (dict "nameOverride" "share-custom-application-context" ) "Chart" .Chart "Release" .Release) }} +{{- include "alfresco-share.fullname" $scope }} +{{- end }} + +{{- define "alfresco-share.service-hz.name" -}} +{{- $scope := (dict "Values" (dict "nameOverride" "share-hz" ) "Chart" .Chart "Release" .Release) }} +{{- include "alfresco-share.fullname" $scope }} +{{- end }} + +{{- define "alfresco-share.cluster-role-hz.name" -}} +{{- $scope := (dict "Values" (dict "nameOverride" "share-hazelcast-cluster-role" ) "Chart" .Chart "Release" .Release) }} +{{- include "alfresco-share.fullname" $scope }} +{{- end }} + +{{- define "alfresco-share.cluster-role-binding-hz.name" -}} +{{- $scope := (dict "Values" (dict "nameOverride" "share-hazelcast-cluster-role-binding" ) "Chart" .Chart "Release" .Release) }} +{{- include "alfresco-share.fullname" $scope }} +{{- end }} diff --git a/charts/alfresco-share/templates/configmap-custom-application-context.yaml b/charts/alfresco-share/templates/configmap-custom-application-context.yaml new file mode 100644 index 00000000..ab74bd81 --- /dev/null +++ b/charts/alfresco-share/templates/configmap-custom-application-context.yaml @@ -0,0 +1,33 @@ +{{- if and (gt (int .Values.replicaCount) 1) .Values.managedApplicationContext.enabled -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "alfresco-share.custom-application-context.name" . }} + labels: + {{- include "alfresco-share.labels" . | nindent 4 }} +data: + custom-slingshot-application-context.xml: |- + + + + + + + + + + + + + + + slingshot-topic + + +{{- end -}} diff --git a/charts/alfresco-share/templates/deployment.yaml b/charts/alfresco-share/templates/deployment.yaml index 9e571384..9a043e00 100644 --- a/charts/alfresco-share/templates/deployment.yaml +++ b/charts/alfresco-share/templates/deployment.yaml @@ -10,7 +10,7 @@ metadata: checkov.io/skip2: CKV_K8S_23=Requires APPS-1832 checkov.io/skip3: CKV_K8S_40=Requires APPS-1832 spec: - replicas: 1 + replicas: {{ .Values.replicaCount }} selector: matchLabels: {{- include "alfresco-share.selectorLabels" . | nindent 6 }} @@ -49,6 +49,11 @@ spec: - name: http containerPort: {{ .Values.image.port }} protocol: TCP + {{- if gt (int .Values.replicaCount) 1 }} + - name: hz + containerPort: {{ .Values.hazelcast.port }} + protocol: TCP + {{- end }} resources: {{- toYaml .Values.resources | nindent 12 }} {{- $repo_details_cm := coalesce .Values.repository.existingConfigMap.name (include "alfresco-share.fullname" .) }} @@ -77,7 +82,14 @@ spec: value: {{ $value }} {{- end }} volumeMounts: - {{- toYaml .Values.extraVolumeMounts | nindent 12 }} + {{- if and (gt (int .Values.replicaCount) 1) .Values.managedApplicationContext.enabled }} + - name: custom-application-context-volume + mountPath: /usr/local/tomcat/shared/classes/alfresco/web-extension/custom-slingshot-application-context.xml + subPath: custom-slingshot-application-context.xml + {{- end }} + {{- with .Values.extraVolumeMounts }} + {{- toYaml . | nindent 12 }} + {{- end }} readinessProbe: httpGet: path: /share @@ -98,7 +110,14 @@ spec: initContainers: {{- toYaml .Values.extraInitContainers | nindent 8 }} volumes: + {{- if and (gt (int .Values.replicaCount) 1) .Values.managedApplicationContext.enabled }} + - name: custom-application-context-volume + configMap: + name: {{ template "alfresco-share.custom-application-context.name" . }} + {{- end }} + {{- if .Values.extraVolumes }} {{- toYaml .Values.extraVolumes | nindent 8 }} + {{- end }} {{- with .Values.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }} diff --git a/charts/alfresco-share/templates/ingress.yaml b/charts/alfresco-share/templates/ingress.yaml index 60afc986..648e219f 100644 --- a/charts/alfresco-share/templates/ingress.yaml +++ b/charts/alfresco-share/templates/ingress.yaml @@ -1,23 +1,8 @@ {{- if .Values.ingress.enabled -}} -{{- $fullName := include "alfresco-share.fullname" . -}} -{{- $svcPort := .Values.service.port -}} -{{/* -We only support nginx ingress for now: https://alfresco.atlassian.net/browse/OPSEXP-131 -*/}} -{{- if not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }} - {{- $_ := unset .Values.ingress.annotations "kubernetes.io/ingress.class" }} - {{- $_ = set .Values.ingress.annotations "kubernetes.io/ingress.class" "nginx" }} -{{- end }} -{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}} apiVersion: networking.k8s.io/v1 -{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} -apiVersion: networking.k8s.io/v1beta1 -{{- else -}} -apiVersion: extensions/v1beta1 -{{- end }} kind: Ingress metadata: - name: {{ $fullName }} + name: {{ template "alfresco-share.fullname" . }} labels: {{- include "alfresco-share.labels" . | nindent 4 }} annotations: @@ -25,15 +10,10 @@ metadata: {{- include "alfresco-common.nginx.annotations" .Values }} {{- include "alfresco-common.nginx.secure.annotations" .Values }} spec: -{{/* -We only support nginx ingress for now: https://alfresco.atlassian.net/browse/OPSEXP-131 -*/}} - {{- if (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }} - ingressClassName: nginx - {{- end }} - {{- if .Values.ingress.tls }} + ingressClassName: {{ .Values.ingress.className }} + {{- with .Values.ingress.tls }} tls: - {{- range .Values.ingress.tls }} + {{- range . }} - hosts: {{- range .hosts }} - {{ . | quote }} @@ -48,19 +28,12 @@ We only support nginx ingress for now: https://alfresco.atlassian.net/browse/OPS paths: {{- range .paths }} - path: {{ .path }} - {{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }} pathType: {{ .pathType }} - {{- end }} backend: - {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }} service: - name: {{ $fullName }} + name: {{ template "alfresco-share.fullname" $ }} port: - number: {{ $svcPort }} - {{- else }} - serviceName: {{ $fullName }} - servicePort: {{ $svcPort }} - {{- end }} + number: {{ $.Values.service.port }} {{- end }} {{- end }} {{- end }} diff --git a/charts/alfresco-share/templates/rbac.yaml b/charts/alfresco-share/templates/rbac.yaml new file mode 100644 index 00000000..18d8499f --- /dev/null +++ b/charts/alfresco-share/templates/rbac.yaml @@ -0,0 +1,48 @@ +{{- if gt (int .Values.replicaCount) 1 -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "alfresco-share.cluster-role-hz.name" . }} +rules: + - apiGroups: + - "" + # Access to apps API is only required to support automatic cluster state management + # when persistence (hot-restart) is enabled. + - apps + resources: + - endpoints + - pods + - nodes + - services + # Access to statefulsets resource is only required to support automatic cluster state management + # when persistence (hot-restart) is enabled. + - statefulsets + verbs: + - get + - list + # Watching resources is only required to support automatic cluster state management + # when persistence (hot-restart) is enabled. + - watch + - apiGroups: + - "discovery.k8s.io" + resources: + - endpointslices + verbs: + - get + - list + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "alfresco-share.cluster-role-binding-hz.name" . }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "alfresco-share.cluster-role-hz.name" . }} +subjects: + - kind: ServiceAccount + name: {{ include "alfresco-share.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end -}} diff --git a/charts/alfresco-share/templates/service-hz.yaml b/charts/alfresco-share/templates/service-hz.yaml new file mode 100644 index 00000000..2efd398a --- /dev/null +++ b/charts/alfresco-share/templates/service-hz.yaml @@ -0,0 +1,15 @@ +{{- if gt (int .Values.replicaCount) 1 }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "alfresco-share.service-hz.name" . }} + labels: + {{- include "alfresco-share.selectorLabels" . | nindent 4 }} +spec: + type: {{ .Values.service.type }} + ports: + - name: hazelcast + port: {{ .Values.hazelcast.port }} + selector: + {{- include "alfresco-share.selectorLabels" . | nindent 4 }} +{{- end -}} diff --git a/charts/alfresco-share/tests/configmap-custom-application-context_test.yaml b/charts/alfresco-share/tests/configmap-custom-application-context_test.yaml new file mode 100644 index 00000000..2f78a40d --- /dev/null +++ b/charts/alfresco-share/tests/configmap-custom-application-context_test.yaml @@ -0,0 +1,18 @@ +--- +suite: test custom application context configmap +templates: + - configmap-custom-application-context.yaml +tests: + - it: should not render the configmap when replicaCount is 1 + asserts: + - hasDocuments: + count: 0 + - it: should render default contents when replicaCount is 2 + set: + replicaCount: 2 + asserts: + - equal: + path: metadata.name + value: RELEASE-NAME-share-custom-application-context + - isNotNullOrEmpty: + path: data["custom-slingshot-application-context.xml"] diff --git a/charts/alfresco-share/tests/cm_test.yaml b/charts/alfresco-share/tests/configmap_test.yaml similarity index 95% rename from charts/alfresco-share/tests/cm_test.yaml rename to charts/alfresco-share/tests/configmap_test.yaml index ae217694..b14ada16 100644 --- a/charts/alfresco-share/tests/cm_test.yaml +++ b/charts/alfresco-share/tests/configmap_test.yaml @@ -1,5 +1,5 @@ --- -suite: test Alfresco Share ingress +suite: test share configmap templates: - configmap.yaml tests: diff --git a/charts/alfresco-share/tests/deployment_test.yaml b/charts/alfresco-share/tests/deployment_test.yaml index e6500c26..ac6bb21b 100644 --- a/charts/alfresco-share/tests/deployment_test.yaml +++ b/charts/alfresco-share/tests/deployment_test.yaml @@ -1,5 +1,5 @@ --- -suite: test Alfresco Share deployment +suite: test share deployment templates: - deployment.yaml tests: @@ -14,6 +14,8 @@ tests: path: spec.template.spec.affinity - isNull: path: spec.template.spec.tolerations + - isEmpty: + path: spec.template.spec.volumes - it: should have customized metadata in place in deployment set: @@ -161,3 +163,29 @@ tests: limits: cpu: "4" memory: "2000Mi" + + - it: should render volumes when replicaCount more than 1 + set: + replicaCount: 2 + asserts: + - equal: + path: spec.replicas + value: 2 + - contains: + path: spec.template.spec.volumes + content: + name: custom-application-context-volume + configMap: + name: RELEASE-NAME-share-custom-application-context + - contains: + path: spec.template.spec.containers[0].volumeMounts + content: + mountPath: /usr/local/tomcat/shared/classes/alfresco/web-extension/custom-slingshot-application-context.xml + subPath: custom-slingshot-application-context.xml + name: custom-application-context-volume + - contains: + path: spec.template.spec.containers[0].ports + content: + containerPort: 5701 + name: hz + protocol: TCP diff --git a/charts/alfresco-share/tests/ingress_test.yaml b/charts/alfresco-share/tests/ingress_test.yaml index 41f57782..418515d1 100644 --- a/charts/alfresco-share/tests/ingress_test.yaml +++ b/charts/alfresco-share/tests/ingress_test.yaml @@ -1,5 +1,5 @@ --- -suite: test Alfresco Share ingress +suite: test share ingress templates: - ingress.yaml tests: @@ -17,22 +17,3 @@ tests: path: spec.ingressClassName value: nginx template: ingress.yaml - - - it: should sanitize ingress - capabilities: - majorVersion: 1 - minorVersion: 17 - set: - ingress: - annotations: - kubernetes.io/ingress.class: myfancyClass - nginx.ingress.kubernetes.io/server-snippet: listen 6666; - asserts: - - notMatchRegex: - path: metadata.annotations['nginx.ingress.kubernetes.io/server-snippet'] - pattern: listen 6666; - template: ingress.yaml - - equal: - path: metadata.annotations['kubernetes.io/ingress.class'] - value: nginx - template: ingress.yaml diff --git a/charts/alfresco-share/tests/rbac_test.yaml b/charts/alfresco-share/tests/rbac_test.yaml new file mode 100644 index 00000000..bec85a05 --- /dev/null +++ b/charts/alfresco-share/tests/rbac_test.yaml @@ -0,0 +1,18 @@ +--- +suite: test share rbac resources +templates: + - rbac.yaml +tests: + - it: should render expected manifests + set: + replicaCount: 2 + asserts: + - hasDocuments: + count: 2 + + - it: should render no manifests with replicaCount 1 + set: + replicaCount: 1 + asserts: + - hasDocuments: + count: 0 diff --git a/charts/alfresco-share/tests/service-hz_test.yaml b/charts/alfresco-share/tests/service-hz_test.yaml new file mode 100644 index 00000000..a1cbe001 --- /dev/null +++ b/charts/alfresco-share/tests/service-hz_test.yaml @@ -0,0 +1,17 @@ +--- +suite: test share hazelcast service +templates: + - service-hz.yaml +tests: + - it: should use the default service name + set: + replicaCount: 2 + asserts: + - equal: + path: metadata.name + value: RELEASE-NAME-share-hz + - equal: + path: spec.selector + value: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/name: alfresco-share diff --git a/charts/alfresco-share/tests/service_test.yaml b/charts/alfresco-share/tests/service_test.yaml new file mode 100644 index 00000000..d3cd8b50 --- /dev/null +++ b/charts/alfresco-share/tests/service_test.yaml @@ -0,0 +1,15 @@ +--- +suite: test share service +templates: + - service.yaml +tests: + - it: should use the default service name + asserts: + - equal: + path: metadata.name + value: RELEASE-NAME-alfresco-share + - equal: + path: spec.selector + value: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/name: alfresco-share diff --git a/charts/alfresco-share/values.yaml b/charts/alfresco-share/values.yaml index cb6027da..5b7afaf6 100644 --- a/charts/alfresco-share/values.yaml +++ b/charts/alfresco-share/values.yaml @@ -25,6 +25,8 @@ image: # -- Internal port where the pod is listening. Should only be changed is you # use a custom image which uses a different port. port: 8080 +# -- Define the number of replicas to run. Multiple replicas are only supported on Share 23.1.1 and later +replicaCount: 1 strategy: type: RollingUpdate rollingUpdate: @@ -59,6 +61,7 @@ service: port: 80 ingress: enabled: true + className: nginx annotations: nginx.ingress.kubernetes.io/proxy-body-size: 5g nginx.ingress.kubernetes.io/affinity: "cookie" @@ -110,3 +113,11 @@ global: alfrescoRegistryPullSecrets: quay-registry-secret # -- a fallback for .Values.known_urls that can be shared between charts known_urls: null +hazelcast: + # -- Port used to expose the Hazelcast service when replicaCount > 1 + port: 5701 +managedApplicationContext: + # -- Automatically inject a custom application context file which for now only + # enables hazelcast clustering when more than one replica is configured. + # Should be disabled when providing a custom application context file. + enabled: true