From 0011b17cfffea8154b5d34fa28fbbf6454a2e448 Mon Sep 17 00:00:00 2001 From: Faraaz Khan Date: Tue, 8 May 2018 10:49:52 -0500 Subject: [PATCH] [stable/neo4j] Update Neo4j to 3.3.4 (#5172) * update neo4j chart * updates neo4j to 3.3.4 * Adds pod disruption budget * Removes privileged security context * Adds delete hook annotation to test pod * Reorganizes tests so they pass on clusters with rbac enabled, example: gke-1.9.6 * require explicit agreement to neo4j license * switch to using default instead of required See: https://github.com/kubernetes/helm/issues/2347 * print error when license is not accepted --- stable/neo4j/Chart.yaml | 4 +- stable/neo4j/README.md | 9 ++- stable/neo4j/ci/ci-values.yaml | 2 + stable/neo4j/templates/NOTES.txt | 10 ++- stable/neo4j/templates/core-statefulset.yaml | 4 +- .../neo4j/templates/poddisruptionbudget.yaml | 17 ++++ stable/neo4j/templates/tests/test-config.yaml | 78 +++++++------------ .../templates/tests/test-neo4j-cluster.yaml | 3 + stable/neo4j/test.sh | 37 +++++++++ stable/neo4j/values.yaml | 6 +- 10 files changed, 114 insertions(+), 56 deletions(-) create mode 100644 stable/neo4j/ci/ci-values.yaml create mode 100644 stable/neo4j/templates/poddisruptionbudget.yaml create mode 100644 stable/neo4j/test.sh diff --git a/stable/neo4j/Chart.yaml b/stable/neo4j/Chart.yaml index a81175015c..a64722c23b 100644 --- a/stable/neo4j/Chart.yaml +++ b/stable/neo4j/Chart.yaml @@ -1,7 +1,7 @@ name: neo4j home: https://www.neo4j.com -version: 0.7.1 -appVersion: 3.2.3 +version: 0.7.2 +appVersion: 3.3.4 description: Neo4j is the world's leading graph database icon: http://info.neo4j.com/rs/773-GON-065/images/neo4j_logo.png sources: diff --git a/stable/neo4j/README.md b/stable/neo4j/README.md index 0c65ca63a1..36f3cc1362 100644 --- a/stable/neo4j/README.md +++ b/stable/neo4j/README.md @@ -20,15 +20,19 @@ deployment on a [Kubernetes](http://kubernetes.io) cluster using the * Kubernetes 1.6+ with Beta APIs enabled * PV provisioner support in the underlying infrastructure +* Requires the following variables + You must add `acceptLicenseAgreement` in the values.yaml file and set it to `yes` or include `--set acceptLicenseAgreement=yes` in the command line of helm install to accept the license. ## Installing the Chart To install the chart with the release name `neo4j-helm`: ```bash -$ helm install --name neo4j-helm stable/neo4j --set neo4jPassword=mySecretPassword +$ helm install --name neo4j-helm stable/neo4j --set acceptLicenseAgreement=yes --set neo4jPassword=mySecretPassword ``` +You must explicitly accept the neo4j license agreement for the installation to be successful. + The command deploys Neo4j on the Kubernetes cluster in the default configuration but with the password set to `mySecretPassword`. The [configuration](#configuration) section lists the parameters that can be @@ -57,6 +61,7 @@ their default values. | `image` | Neo4j image | `neo4j` | | `imageTag` | Neo4j version | `{VERSION}` | | `imagePullPolicy` | Image pull policy | `IfNotPresent` | +| `podDisruptionBudget` | Pod disruption budget | `{}` | | `authEnabled` | Is login/password required? | `true` | | `core.numberOfServers` | Number of machines in CORE mode | `3` | | `core.sideCarContainers` | Sidecar containers to add to the core pod. Example use case is a sidecar which identifies and labels the leader when using the http API | `{}` | @@ -91,3 +96,5 @@ $ helm install --name neo4j-helm -f values.yaml stable/neo4j ``` > **Tip**: You can use the default [values.yaml](values.yaml) + +Once you have all 3 pods in running, you can run the "test.sh" script in this directory, which will verify the role attached to each pod and also test recovery of a failed/deleted pod. This script requires that the $RELEASE_NAME environment variable be set, in order to access the pods, if you have specified a custom `namespace` or `replicas` value when installing you can set those via `RELEASE_NAMESPACE` and `CORE_REPLICAS` environment variables for this script. diff --git a/stable/neo4j/ci/ci-values.yaml b/stable/neo4j/ci/ci-values.yaml new file mode 100644 index 0000000000..a5ad456544 --- /dev/null +++ b/stable/neo4j/ci/ci-values.yaml @@ -0,0 +1,2 @@ +--- +acceptLicenseAgreement: "yes" diff --git a/stable/neo4j/templates/NOTES.txt b/stable/neo4j/templates/NOTES.txt index ed3619263c..d02b996eec 100644 --- a/stable/neo4j/templates/NOTES.txt +++ b/stable/neo4j/templates/NOTES.txt @@ -1,3 +1,8 @@ +{{- if and (ne "yes" .Values.acceptLicenseAgreement) (contains "enterprise" .Values.imageTag)}} +#### ERROR: You did not accept the Neo4j Enterprise License. #### +#### ERROR: Please set acceptLicenseAgreement to yes. #### +################################################################### +{{- else }} We'll need to wait a few seconds for the Neo4j cluster to form. We need to see this line in all of our pods' logs: @@ -13,7 +18,7 @@ kubectl run -it --rm cypher-shell \ --image=neo4j:3.2.3-enterprise \ --restart=Never \ --namespace {{ .Release.Namespace }} \ - --command -- ./bin/cypher-shell -u neo4j -p --a {{ printf "%s-%s" .Release.Name .Values.name | trunc 56 }}.default.svc.cluster.local "call dbms.cluster.overview()" + --command -- ./bin/cypher-shell -u neo4j -p --a {{ printf "%s-%s" .Release.Name .Values.name | trunc 56 }}.{{ printf "%s" .Release.Namespace }}.svc.cluster.local "call dbms.cluster.overview()" This will print out the addresses of the members of the cluster. @@ -22,4 +27,5 @@ You'll need to substitute with the password you set when installing t If you didn't set a password, one will be auto generated. You can find the base64 encoded version of the password by running the following command: -kubectl get secrets {{ template "neo4j.secrets.fullname" . }} -o yaml \ No newline at end of file +kubectl get secrets {{ template "neo4j.secrets.fullname" . }} -o yaml +{{- end}} diff --git a/stable/neo4j/templates/core-statefulset.yaml b/stable/neo4j/templates/core-statefulset.yaml index 138f138a80..d63e3eb69c 100644 --- a/stable/neo4j/templates/core-statefulset.yaml +++ b/stable/neo4j/templates/core-statefulset.yaml @@ -1,4 +1,4 @@ -apiVersion: "apps/v1beta1" +apiVersion: "apps/v1beta2" kind: StatefulSet metadata: name: "{{ template "neo4j.core.fullname" . }}" @@ -24,6 +24,8 @@ spec: image: "{{ .Values.image }}:{{ .Values.imageTag }}" imagePullPolicy: "{{ .Values.imagePullPolicy }}" env: + - name: NEO4J_ACCEPT_LICENSE_AGREEMENT + value: "{{ .Values.acceptLicenseAgreement }}" - name: NEO4J_dbms_mode value: CORE - name: NUMBER_OF_CORES diff --git a/stable/neo4j/templates/poddisruptionbudget.yaml b/stable/neo4j/templates/poddisruptionbudget.yaml new file mode 100644 index 0000000000..64eb8837c5 --- /dev/null +++ b/stable/neo4j/templates/poddisruptionbudget.yaml @@ -0,0 +1,17 @@ +{{- if .Values.podDisruptionBudget -}} +apiVersion: policy/v1beta1 +kind: PodDisruptionBudget +metadata: + labels: + app: {{ template "neo4j.name" . }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + name: {{ template "neo4j.fullname" . }} +spec: + selector: + matchLabels: + app: {{ template "neo4j.name" . }} + release: {{ .Release.Name | quote }} +{{ toYaml .Values.podDisruptionBudget | indent 2 }} +{{- end -}} diff --git a/stable/neo4j/templates/tests/test-config.yaml b/stable/neo4j/templates/tests/test-config.yaml index 1f33917b4f..3dd0e3889b 100644 --- a/stable/neo4j/templates/tests/test-config.yaml +++ b/stable/neo4j/templates/tests/test-config.yaml @@ -11,61 +11,41 @@ data: run.sh: |- @test "Testing Neo4j cluster has quorum" { echo "checking if the cluster is up" - check_machine() { - name=$1 - end="$((SECONDS+90))" + path="data" + for id in $(seq 0 $((CORE_REPLICAS - 1))); do + host="${STATEFULSET_NAME}-core-$id.${STATEFULSET_NAME}.${NAMESPACE}.svc.cluster.local" + auth="neo4j:${NEO4J_SECRETS_PASSWORD}" + url="http://${auth}@${host}:7474/db/${path}" + attempts=10 + attempt=0 while true; do - echo "testing http://neo4j:${NEO4J_SECRETS_PASSWORD}@$name:7474/db/data" - out=`wget http://neo4j:${NEO4J_SECRETS_PASSWORD}@$name:7474/db/data -O - 2>&1` - echo "out: $out" - wget http://neo4j:${NEO4J_SECRETS_PASSWORD}@$name:7474/db/data -O - 2>&1 - response_code=$? - echo "response: $response_code" - [[ "0" = "$response_code" ]] && break - [[ "${SECONDS}" -ge "${end}" ]] && exit 1 - sleep 1 + attempt=$[$attempt + 1] + echo "Try $attempt: Connecting to $host:7474/db/${path}" + run wget ${url} -qO- 2>&1 + echo "Exit code: $status" + [ $status -eq 0 ] && break + [ "${attempt}" -ge "${attempts}" ] && exit 1 + sleep 5 done - } - - for id in {0..2}; do - name="${STATEFULSET_NAME}-core-$id.${STATEFULSET_NAME}.${NAMESPACE}.svc.cluster.local" - echo "checking $name" - run check_machine $name - echo $status - echo $output - [ "$status" -eq 0 ] done } - @test "Testing we can get the cluster role of each server" { - check_role() { - name=$1 - end="$((SECONDS+90))" + @test "Testing Neo4j core servers are available" { + echo "checking if nodes are available" + path="manage/server/core/available" + for id in $(seq 0 $((CORE_REPLICAS - 1))); do + host="${STATEFULSET_NAME}-core-$id.${STATEFULSET_NAME}.${NAMESPACE}.svc.cluster.local" + auth="neo4j:${NEO4J_SECRETS_PASSWORD}" + url="http://${auth}@${host}:7474/db/${path}" + attempts=10 + attempt=0 while true; do - echo "checking cluster role: $name" - kubectl exec $name -- bin/cypher-shell -u neo4j -p ${NEO4J_SECRETS_PASSWORD} "call dbms.cluster.role()" - response_code=$? - echo "response: $response_code" - [[ "0" = "$response_code" ]] && break - [[ "${SECONDS}" -ge "${end}" ]] && exit 1 - sleep 1 + attempt=$[$attempt + 1] + echo "Try $attempt: Connecting to $host:7474/db/${path}" + response=$(wget ${url} -qO- 2>&1) + [ "$response" = "true" ] && break + [ "${attempt}" -ge "${attempts}" ] && exit 1 + sleep 5 done - } - - for id in {0..2}; do - name="${STATEFULSET_NAME}-core-$id" - echo "checking role of $name" - run check_role $name - echo $status - echo $output - [ "$status" -eq 0 ] done - - # kill a machine and make sure it comes back again - machine_to_kill="${STATEFULSET_NAME}-core-0" - kubectl delete pod ${machine_to_kill} - run check_role ${machine_to_kill} - echo $status - echo $output - [ "$status" -eq 0 ] } diff --git a/stable/neo4j/templates/tests/test-neo4j-cluster.yaml b/stable/neo4j/templates/tests/test-neo4j-cluster.yaml index c2156b11cb..ee6cdab605 100644 --- a/stable/neo4j/templates/tests/test-neo4j-cluster.yaml +++ b/stable/neo4j/templates/tests/test-neo4j-cluster.yaml @@ -9,6 +9,7 @@ metadata: app: {{ template "neo4j.name" . }} annotations: "helm.sh/hook": test-success + "helm.sh/hook-delete-policy": "before-hook-creation,hook-succeeded" spec: containers: - name: {{ .Release.Name }}-ui-test @@ -16,6 +17,8 @@ spec: env: - name: "STATEFULSET_NAME" value: "{{ template "neo4j.fullname" . }}" + - name: "CORE_REPLICAS" + value: "{{ .Values.core.numberOfServers }}" - name: "NAMESPACE" value: {{ .Release.Namespace }} - name: NEO4J_SECRETS_PASSWORD diff --git a/stable/neo4j/test.sh b/stable/neo4j/test.sh new file mode 100644 index 0000000000..47293e975c --- /dev/null +++ b/stable/neo4j/test.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +NS="${RELEASE_NAMESPACE:-default}" +STATEFULSET_NAME="${RELEASE_NAME:-neo4j}-neo4j" +NEO4J_SECRETS_PASSWORD=$(kubectl get secret -n ${NS} ${RELEASE_NAME}-neo4j-secrets -o jsonpath='{.data.neo4j-password}' | base64 --decode) +CORE_REPLICAS=${REPLICAS:-3} + +echo "Testing we can get the cluster role of each server in statefulset ${STATEFULSET_NAME} in namespace: ${NS}" + +check_role() { + name=$1 + end="$((SECONDS+120))" + while true; do + echo "checking cluster role: ${name}" + kubectl exec ${name} -n ${NS} -- bin/cypher-shell -u neo4j -p ${NEO4J_SECRETS_PASSWORD} "call dbms.cluster.role()" 2>/dev/null + response_code=$? + [[ "0" = "$response_code" ]] && break + [[ "${SECONDS}" -ge "${end}" ]] && exit 1 + echo "waiting for connection to pod: ${name}" + sleep 5 + done +} + +for num in $(seq $CORE_REPLICAS); do + id=$(expr $num - 1) + name="${STATEFULSET_NAME}-core-$id" + echo "checking role of $name" + check_role $name +done + +# kill a machine and make sure it comes back again +machine_to_kill="${STATEFULSET_NAME}-core-0" +echo "Testing recovery after failed/deleted pod" +echo "Deleting pod: ${machine_to_kill}" +kubectl delete pod ${machine_to_kill} -n ${NS} +check_role ${machine_to_kill} +echo "Pod recovered successfully!" diff --git a/stable/neo4j/values.yaml b/stable/neo4j/values.yaml index 161040412e..efbebd73ed 100644 --- a/stable/neo4j/values.yaml +++ b/stable/neo4j/values.yaml @@ -7,9 +7,13 @@ name: "neo4j" # Specs for the Neo4j docker image image: "neo4j" -imageTag: "3.2.3-enterprise" +imageTag: "3.3.4-enterprise" imagePullPolicy: "IfNotPresent" # imagePullSecret: registry-secret +acceptLicenseAgreement: "no" +podDisruptionBudget: {} + # minAvailable: 2 + # maxUnavailable: 1 # Use password authentication authEnabled: true