diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 5008ddfc..00000000 Binary files a/.DS_Store and /dev/null differ diff --git a/.gitignore b/.gitignore index d335323b..37c9c7f4 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ temp/ devenv.local .idea/ .kube/ +.DS_Store *.test diff --git a/build/gcloud-create-gke-cluster-tc b/build/gcloud-create-gke-cluster-tc index 24fc1c8f..59095491 100755 --- a/build/gcloud-create-gke-cluster-tc +++ b/build/gcloud-create-gke-cluster-tc @@ -21,4 +21,7 @@ CLOUDSDK_CONTAINER_CLUSTER="${cluster_name_prefix}-$(date +%s)-helm" export CLOUDSDK_CONTAINER_CLUSTER="$(echo "${CLOUDSDK_CONTAINER_CLUSTER}" | sed 's/\./-/g' )" echo "##teamcity[setParameter name='env.CLOUDSDK_CONTAINER_CLUSTER' value='$CLOUDSDK_CONTAINER_CLUSTER']" +#token to be used in imagePullSecret +GCR_ACCESS_TOKEN="$(gcloud auth print-access-token)" +echo "##teamcity[setParameter name='env.IPS_PASS' value='${GCR_ACCESS_TOKEN}']" gcloud-create-gke-cluster diff --git a/build/gcloud-push-docker-image b/build/gcloud-push-docker-image index 30f18c34..2378e7a7 100755 --- a/build/gcloud-push-docker-image +++ b/build/gcloud-push-docker-image @@ -27,6 +27,5 @@ function push_to_gcr { echo "##teamcity[setParameter name='env.NEO4J_DOCKER_IMG_${EDITION}' value='${NEO4J_DOCKER_IMG}']" docker rmi "${NEO4J_DOCKER_IMG}" "${DOCKER_IMG}" } - push_to_gcr "$(ls | grep "neo4j-enterprise-")" "ENTERPRISE" -push_to_gcr "$(ls | grep "neo4j-community-")" "COMMUNITY" \ No newline at end of file +push_to_gcr "$(ls | grep "neo4j-community-")" "COMMUNITY" diff --git a/demo-backup.sh b/demo-backup.sh deleted file mode 100644 index e69de29b..00000000 diff --git a/devenv b/devenv index f5fa8e17..b9731814 100644 --- a/devenv +++ b/devenv @@ -8,6 +8,11 @@ if [ -f ./devenv.local ]; then export CLOUDSDK_CONTAINER_CLUSTER export PACKAGE_SIGNING_KEY export PACKAGE_SIGNING_KEYRING + export IPS_USERNAME + export IPS_PASS + export IPS_EMAIL + export NEO4J_DOCKER_IMG + else echo "Couldn't find ./devenv.local." fi diff --git a/index_public.yaml b/index_public.yaml deleted file mode 100644 index 0d3fa4ec..00000000 --- a/index_public.yaml +++ /dev/null @@ -1,278 +0,0 @@ -apiVersion: v1 -generated: 2022-01-28T12:15:12.380915000+00:00 -entries: - neo4j-standalone: - - created: 2022-01-14T11:00:24.393724000+00:00 - description: Neo4j Standalone 4.4.3 - digest: daee86bd26d38da7e6538a958642bac1b7a79c1038899c0dff2adbf00bdc0ff7 - home: https://github.com/neo4j/helm-charts - name: neo4j-standalone - sources: - - https://github.com/neo4j/helm-charts/tree/4.4/neo4j-standalone - urls: - - https://github.com/neo4j/helm-charts/releases/download/4.4.3/neo4j-standalone-4.4.3.tgz - version: 4.4.3 - - created: 2021-12-20T11:00:14.293713000+00:00 - description: Neo4j Standalone 4.4.2 - digest: 3cd77afe5d19d84a62c2b3cc553a01bb9653ba1d4118abe6e97fca48be1b887e - home: https://github.com/neo4j/helm-charts - name: neo4j-standalone - sources: - - https://github.com/neo4j/helm-charts/tree/4.4/neo4j-standalone - urls: - - https://github.com/neo4j/helm-charts/releases/download/4.4.2/neo4j-standalone-4.4.2.tgz - version: 4.4.2 - - created: 2021-12-15T11:00:13.392713000+00:00 - description: Neo4j Standalone 4.4.1 - digest: 463eaad4052a6e155667913294b8af0e1023755738997113c83e0d11fa94af38 - home: https://github.com/neo4j/helm-charts - name: neo4j-standalone - sources: - - https://github.com/neo4j/helm-charts/tree/4.4/neo4j-standalone - urls: - - https://github.com/neo4j/helm-charts/releases/download/4.4.1/neo4j-standalone-4.4.1.tgz - version: 4.4.1 - - created: 2021-12-14T11:00:24.393724000+00:00 - description: Neo4j Standalone 4.4.0 - digest: 837be4c3a1aaab21ce574a4323a994a35692e63d14e2f628a60c3032039bb289 - home: https://github.com/neo4j/helm-charts - name: neo4j-standalone - sources: - - https://github.com/neo4j/helm-charts/tree/4.4/neo4j-standalone - urls: - - https://github.com/neo4j/helm-charts/releases/download/4.4.0/neo4j-standalone-4.4.0.tgz - version: 4.4.0 - - created: 2021-12-17T11:00:13.392713000+00:00 - description: Neo4j Standalone 4.3.9 - digest: 4fb1595f037dc81a22000f3bf6c36bbac2a14d7453ca874c406fbddea349aae2 - home: https://github.com/neo4j/helm-charts - name: neo4j-standalone - sources: - - https://github.com/neo4j/helm-charts/tree/4.3/neo4j-standalone - urls: - - https://github.com/neo4j/helm-charts/releases/download/4.3.9/neo4j-standalone-4.3.9.tgz - version: 4.3.9 - - created: 2021-12-15T11:00:24.393724000+00:00 - description: Neo4j Standalone 4.3.8 - digest: e8f78f78be3b266ca99d0fbe2122785c6e5e4a65783bf26054753eac73722d48 - home: https://github.com/neo4j/helm-charts - name: neo4j-standalone - sources: - - https://github.com/neo4j/helm-charts/tree/4.3/neo4j-standalone - urls: - - https://github.com/neo4j/helm-charts/releases/download/4.3.8/neo4j-standalone-4.3.8.tgz - version: 4.3.8 - - created: 2021-12-14T11:00:24.393724000+00:00 - description: Neo4j Standalone 4.3.7 - digest: 902faf91c0c62b606b4bf366975f96ef688f191f78032a577e800e41566c8534 - home: https://github.com/neo4j/helm-charts - name: neo4j-standalone - sources: - - https://github.com/neo4j/helm-charts/tree/4.3/neo4j-standalone - urls: - - https://github.com/neo4j/helm-charts/releases/download/4.3.7/neo4j-standalone-4.3.7.tgz - version: 4.3.7 - - created: 2021-12-13T11:00:24.393724000+00:00 - description: Neo4j Standalone 4.3.6 - digest: 50c1824c4815f2623fa8f1abd61eac2a2eb5f80ef496f376242959297936c386 - home: https://github.com/neo4j/helm-charts - name: neo4j-standalone - sources: - - https://github.com/neo4j/helm-charts/tree/4.3/neo4j-standalone - urls: - - https://github.com/neo4j/helm-charts/releases/download/4.3.6/neo4j-standalone-4.3.6.tgz - version: 4.3.6 - - created: 2021-10-13T11:00:24.393724000+00:00 - description: Neo4j Standalone 4.3.5 - digest: f353369999df9e4827052fd277beabd7f00709058d2409f20cd8a9fad3663894 - home: https://github.com/neo4j/helm-charts - name: neo4j-standalone - sources: - - https://github.com/neo4j/helm-charts/tree/4.3/neo4j-standalone - urls: - - https://github.com/neo4j/helm-charts/releases/download/4.3.5/neo4j-standalone-4.3.5.tgz - version: 4.3.5 - - created: 2022-01-14T11:00:24.393724000+00:00 - description: Neo4j Standalone 4.3.3 - digest: 69f9768a09033aafce25cc167bc8a2bff51c939692a42ce3a72c03e78bed3eaa - home: https://github.com/neo4j/helm-charts - name: neo4j-standalone - sources: - - https://github.com/neo4j/helm-charts/tree/4.3/neo4j-standalone - urls: - - https://github.com/neo4j/helm-charts/releases/download/4.3.3/neo4j-standalone-4.3.3.tgz - version: 4.3.3 - - created: 2021-08-12T11:00:24.393724000+00:00 - description: Neo4j Standalone 4.3.2 - digest: 18f04ee3e4fe9083b0fef442881245c8e01c9f057183a496dffeb2cf4c8b51bf - home: https://github.com/neo4j/helm-charts - name: neo4j-standalone - sources: - - https://github.com/neo4j/helm-charts/tree/4.3/neo4j-standalone - urls: - - https://github.com/neo4j/helm-charts/releases/download/4.3.2/neo4j-standalone-4.3.2.tgz - version: 4.3.2 - neo4j-cluster-core: - - created: 2022-01-14T11:00:24.393724000+00:00 - description: Neo4j Cluster Core 4.4.3 - digest: 0512147642c38f6c1f608144598715cb0ecae0af661b57a070e8a56aaa5192dc - home: https://github.com/neo4j/helm-charts - name: neo4j-cluster-core - sources: - - https://github.com/neo4j/helm-charts/tree/4.4/neo4j-cluster-core - urls: - - https://github.com/neo4j/helm-charts/releases/download/4.4.3/neo4j-cluster-core-4.4.3.tgz - version: 4.4.3 - - created: 2021-12-20T11:00:14.293713000+00:00 - description: Neo4j Cluster Core 4.4.2 - digest: f01ef8f97a892b4a86d8139f1b088d12b0f8c6ad124e81e10eaba77c6bb6cebc - home: https://github.com/neo4j/helm-charts - name: neo4j-cluster-core - sources: - - https://github.com/neo4j/helm-charts/tree/4.4/neo4j-cluster-core - urls: - - https://github.com/neo4j/helm-charts/releases/download/4.4.2/neo4j-cluster-core-4.4.2.tgz - version: 4.4.2 - - created: 2021-12-15T11:00:13.392713000+00:00 - description: Neo4j Cluster Core 4.4.1 - digest: 22a79ae4f5648735c2842d032a7073f6f5b33a00625b4a13815f98a1fa80d2b9 - home: https://github.com/neo4j/helm-charts - name: neo4j-cluster-core - sources: - - https://github.com/neo4j/helm-charts/tree/4.4/neo4j-cluster-core - urls: - - https://github.com/neo4j/helm-charts/releases/download/4.4.1/neo4j-cluster-core-4.4.1.tgz - version: 4.4.1 - - created: 2021-12-14T11:00:24.393724000+00:00 - description: Neo4j Cluster Core 4.4.0 - digest: 90803c044253bdc51012f3e6cf0f7ce5a0510e7eff6acc034a685994ef49643f - home: https://github.com/neo4j/helm-charts - name: neo4j-cluster-core - sources: - - https://github.com/neo4j/helm-charts/tree/4.4/neo4j-cluster-core - urls: - - https://github.com/neo4j/helm-charts/releases/download/4.4.0/neo4j-cluster-core-4.4.0.tgz - version: 4.4.0 - neo4j-cluster-read-replica: - - created: 2022-01-14T11:00:24.393724000+00:00 - description: Neo4j Cluster Read Replica 4.4.3 - digest: 2d348805e448139d539b881789898f30b8deffa5a6f4f52068b4c244a0a681eb - home: https://github.com/neo4j/helm-charts - name: neo4j-cluster-read-replica - sources: - - https://github.com/neo4j/helm-charts/tree/4.4/neo4j-cluster-read-replica - urls: - - https://github.com/neo4j/helm-charts/releases/download/4.4.3/neo4j-cluster-read-replica-4.4.3.tgz - version: 4.4.3 - - created: 2021-12-20T11:00:14.293713000+00:00 - description: Neo4j Cluster Read Replica 4.4.2 - digest: f4e8bf5d77fe30c9133dfdb4dbaa218f45b9b9bc8b9884f6e94033c03f6c2645 - home: https://github.com/neo4j/helm-charts - name: neo4j-cluster-read-replica - sources: - - https://github.com/neo4j/helm-charts/tree/4.4/neo4j-cluster-read-replica - urls: - - https://github.com/neo4j/helm-charts/releases/download/4.4.2/neo4j-cluster-read-replica-4.4.2.tgz - version: 4.4.2 - - created: 2021-12-15T11:00:13.392713000+00:00 - description: Neo4j Cluster Read Replica 4.4.1 - digest: baafae1186532bd58a3d3e21cca2fe192f941d9918904cbc576700241ccd1c5c - home: https://github.com/neo4j/helm-charts - name: neo4j-cluster-read-replica - sources: - - https://github.com/neo4j/helm-charts/tree/4.4/neo4j-cluster-read-replica - urls: - - https://github.com/neo4j/helm-charts/releases/download/4.4.1/neo4j-cluster-read-replica-4.4.1.tgz - version: 4.4.1 - - created: 2021-12-14T11:00:24.393724000+00:00 - description: Neo4j Cluster Read Replica 4.4.0 - digest: b041a12541f9706c2372ac2c8697d46c3ad4d90df323514f6c4fe561818edc03 - home: https://github.com/neo4j/helm-charts - name: neo4j-cluster-read-replica - sources: - - https://github.com/neo4j/helm-charts/tree/4.4/neo4j-cluster-read-replica - urls: - - https://github.com/neo4j/helm-charts/releases/download/4.4.0/neo4j-cluster-read-replica-4.4.0.tgz - version: 4.4.0 - neo4j-cluster-loadbalancer: - - created: 2022-01-14T11:00:24.393724000+00:00 - description: Neo4j Cluster LoadBalancer 4.4.3 - digest: 69a331184aca58c2a8c5b81a8baa39486da65f0f9b816c515669346f7f5c0f8d - home: https://github.com/neo4j/helm-charts - name: neo4j-cluster-loadbalancer - sources: - - https://github.com/neo4j/helm-charts/tree/4.4/neo4j-cluster-loadbalancer - urls: - - https://github.com/neo4j/helm-charts/releases/download/4.4.3/neo4j-cluster-loadbalancer-4.4.3.tgz - version: 4.4.3 - - created: 2021-12-20T11:00:14.293713000+00:00 - description: Neo4j Cluster LoadBalancer 4.4.2 - digest: c2aa0376b47a621a1afeaa6c5ab2a85d17a7d3a21088e1bac88cc3d272e5e6c2 - home: https://github.com/neo4j/helm-charts - name: neo4j-cluster-loadbalancer - sources: - - https://github.com/neo4j/helm-charts/tree/4.4/neo4j-cluster-loadbalancer - urls: - - https://github.com/neo4j/helm-charts/releases/download/4.4.2/neo4j-cluster-loadbalancer-4.4.2.tgz - version: 4.4.2 - - created: 2021-12-15T11:00:13.392713000+00:00 - description: Neo4j Cluster LoadBalancer 4.4.1 - digest: 91bb7d58cd31fe5f5365cc7581f1325ac84a83a84ad15dbbc0b79534c2d7f7e8 - home: https://github.com/neo4j/helm-charts - name: neo4j-cluster-loadbalancer - sources: - - https://github.com/neo4j/helm-charts/tree/4.4/neo4j-cluster-loadbalancer - urls: - - https://github.com/neo4j/helm-charts/releases/download/4.4.1/neo4j-cluster-loadbalancer-4.4.1.tgz - version: 4.4.1 - - created: 2021-12-14T11:00:24.393724000+00:00 - description: Neo4j Cluster LoadBalancer 4.4.0 - digest: 0ca3ef1102a9c44e316f4832e624d8bb69a7957f82285eb27c164c1d65923c38 - home: https://github.com/neo4j/helm-charts - name: neo4j-cluster-loadbalancer - sources: - - https://github.com/neo4j/helm-charts/tree/4.4/neo4j-cluster-loadbalancer - urls: - - https://github.com/neo4j/helm-charts/releases/download/4.4.0/neo4j-cluster-loadbalancer-4.4.0.tgz - version: 4.4.0 - neo4j-cluster-headless-service: - - created: 2022-01-14T11:00:24.393724000+00:00 - description: Neo4j Cluster Headless Service 4.4.3 - digest: 52e71db8e48c50808e9c8b1bbc36eda80307d58e77db0d657261d510d832d8ee - home: https://github.com/neo4j/helm-charts - name: neo4j-cluster-headless-service - sources: - - https://github.com/neo4j/helm-charts/tree/4.4/neo4j-cluster-headless-service - urls: - - https://github.com/neo4j/helm-charts/releases/download/4.4.3/neo4j-cluster-headless-service-4.4.3.tgz - version: 4.4.3 - - created: 2021-12-20T11:00:14.293713000+00:00 - description: Neo4j Cluster Headless Service 4.4.2 - digest: 525e87b175c1ff41441cf80785259cf999f37573e7fea5a598eef8f26084404c - home: https://github.com/neo4j/helm-charts - name: neo4j-cluster-headless-service - sources: - - https://github.com/neo4j/helm-charts/tree/4.4/neo4j-cluster-headless-service - urls: - - https://github.com/neo4j/helm-charts/releases/download/4.4.2/neo4j-cluster-headless-service-4.4.2.tgz - version: 4.4.2 - - created: 2021-12-15T11:00:13.392713000+00:00 - description: Neo4j Cluster Headless Service 4.4.1 - digest: 0ad4af85c83ccd8f2d1ff4391f968d34661607bd9f241015ef7612f5a7dad081 - home: https://github.com/neo4j/helm-charts - name: neo4j-cluster-headless-service - sources: - - https://github.com/neo4j/helm-charts/tree/4.4/neo4j-cluster-headless-service - urls: - - https://github.com/neo4j/helm-charts/releases/download/4.4.1/neo4j-cluster-headless-service-4.4.1.tgz - version: 4.4.1 - - created: 2022-01-14T11:00:24.393724000+00:00 - description: Neo4j Cluster Headless Service 4.4.0 - digest: 7786b8a841f5488377dbf6b65a1827af971e17923716f83635fb6bbe91aeed38 - home: https://github.com/neo4j/helm-charts - name: neo4j-cluster-headless-service - sources: - - https://github.com/neo4j/helm-charts/tree/4.4/neo4j-cluster-headless-service - urls: - - https://github.com/neo4j/helm-charts/releases/download/4.4.0/neo4j-cluster-headless-service-4.4.0.tgz - version: 4.4.0 diff --git a/internal/integration_tests/cluster_test.go b/internal/integration_tests/cluster_test.go index ceaddf85..e6219088 100644 --- a/internal/integration_tests/cluster_test.go +++ b/internal/integration_tests/cluster_test.go @@ -12,6 +12,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "os/exec" + "strings" "testing" ) @@ -26,7 +27,8 @@ type helmComponent interface { } type clusterCore struct { - name model.ReleaseName + name model.ReleaseName + extraHelmInstallArgs []string } func (c clusterCore) Name() model.ReleaseName { @@ -36,12 +38,13 @@ func (c clusterCore) Name() model.ReleaseName { func (c clusterCore) Install(t *testing.T) parallelResult { var err error var cleanup Closeable - cleanup, err = InstallNeo4jInGcloud(t, gcloud.CurrentZone(), gcloud.CurrentProject(), c.name, model.ClusterCoreHelmChart) + cleanup, err = InstallNeo4jInGcloud(t, gcloud.CurrentZone(), gcloud.CurrentProject(), c.name, model.ClusterCoreHelmChart, c.extraHelmInstallArgs...) return parallelResult{cleanup, err} } type clusterReadReplica struct { - name model.ReleaseName + name model.ReleaseName + extraHelmInstallArgs []string } func (c clusterReadReplica) Name() model.ReleaseName { @@ -51,12 +54,13 @@ func (c clusterReadReplica) Name() model.ReleaseName { func (c clusterReadReplica) Install(t *testing.T) parallelResult { var err error var cleanup Closeable - cleanup, err = InstallNeo4jInGcloud(t, gcloud.CurrentZone(), gcloud.CurrentProject(), c.name, model.ClusterReadReplicaHelmChart) + cleanup, err = InstallNeo4jInGcloud(t, gcloud.CurrentZone(), gcloud.CurrentProject(), c.name, model.ClusterReadReplicaHelmChart, c.extraHelmInstallArgs...) return parallelResult{cleanup, err} } type clusterLoadBalancer struct { - name model.ReleaseName + name model.ReleaseName + extraHelmInstallArgs []string } func (c clusterLoadBalancer) Name() model.ReleaseName { @@ -66,13 +70,16 @@ func (c clusterLoadBalancer) Name() model.ReleaseName { func (c clusterLoadBalancer) Install(t *testing.T) parallelResult { var err error var cleanup Closeable - cleanup = func() error { return run(t, "helm", model.LoadBalancerHelmCommand("uninstall", c.name)...) } - err = run(t, "helm", model.LoadBalancerHelmCommand("install", c.name)...) + cleanup = func() error { + return run(t, "helm", model.LoadBalancerHelmCommand("uninstall", c.name, c.extraHelmInstallArgs...)...) + } + err = run(t, "helm", model.LoadBalancerHelmCommand("install", c.name, c.extraHelmInstallArgs...)...) return parallelResult{cleanup, err} } type clusterHeadLessService struct { - name model.ReleaseName + name model.ReleaseName + extraHelmInstallArgs []string } func (c clusterHeadLessService) Name() model.ReleaseName { @@ -82,13 +89,15 @@ func (c clusterHeadLessService) Name() model.ReleaseName { func (c clusterHeadLessService) Install(t *testing.T) parallelResult { var err error var cleanup Closeable - cleanup = func() error { return run(t, "helm", model.HeadlessServiceHelmCommand("uninstall", c.name)...) } - err = run(t, "helm", model.HeadlessServiceHelmCommand("install", c.name)...) + cleanup = func() error { + return run(t, "helm", model.HeadlessServiceHelmCommand("uninstall", c.name, c.extraHelmInstallArgs...)...) + } + err = run(t, "helm", model.HeadlessServiceHelmCommand("install", c.name, c.extraHelmInstallArgs...)...) return parallelResult{cleanup, err} } //clusterTests contains all the tests related to cluster -func clusterTests(loadBalancerName model.ReleaseName, core model.ReleaseName) ([]SubTest, error) { +func clusterTests(loadBalancerName model.ReleaseName) ([]SubTest, error) { expectedConfiguration, err := (&model.Neo4jConfiguration{}).PopulateFromFile(Neo4jConfFile) if err != nil { return nil, err @@ -96,11 +105,20 @@ func clusterTests(loadBalancerName model.ReleaseName, core model.ReleaseName) ([ expectedConfiguration = addExpectedClusterConfiguration(expectedConfiguration) subTests := []SubTest{ + //TODO: This is to be enabled in 5.0 //{name: "Check Cluster Core Logs Format", test: func(t *testing.T) { // t.Parallel() // assert.NoError(t, CheckLogsFormat(t, core), "Cluster core logs format should be in JSON") //}}, + {name: "ImagePullSecret tests", test: func(t *testing.T) { + t.Parallel() + assert.NoError(t, ImagePullSecretTests(t, loadBalancerName), "Perform ImagePullSecret Tests") + }}, + {name: "Check Cluster Password failure", test: func(t *testing.T) { + t.Parallel() + assert.NoError(t, CheckClusterCorePasswordFailure(t), "Cluster core installation should not succeed with incorrect password") + }}, {name: "Check K8s", test: func(t *testing.T) { assert.NoError(t, CheckK8s(t, loadBalancerName), "Neo4j Config check should succeed") }}, @@ -110,15 +128,8 @@ func clusterTests(loadBalancerName model.ReleaseName, core model.ReleaseName) ([ {name: "Count Nodes", test: func(t *testing.T) { assert.NoError(t, CheckNodeCount(t, loadBalancerName), "Count Nodes should succeed") }}, - {name: "Check Cluster Password failure", test: func(t *testing.T) { - t.Parallel() - assert.NoError(t, CheckClusterCorePasswordFailure(t), "Cluster core installation should not succeed with incorrect password") - }}, - {name: "Create Database customers", test: func(t *testing.T) { - assert.NoError(t, CreateDatabase(t, loadBalancerName, "customers"), "Creates customer database") - }}, - {name: "Check Database customers exists", test: func(t *testing.T) { - assert.NoError(t, CheckDataBaseExists(t, loadBalancerName, "customers"), "Checks if customer database exists or not") + {name: "Database Creation Tests", test: func(t *testing.T) { + assert.NoError(t, DatabaseCreationTests(t, loadBalancerName, "customers"), "Creates \"customer\" database and checks for its existence") }}, } return subTests, nil @@ -142,6 +153,62 @@ func clusterTests(loadBalancerName model.ReleaseName, core model.ReleaseName) ([ // return nil //} +//ImagePullSecretTests runs tests related to imagePullSecret feature +func ImagePullSecretTests(t *testing.T, name model.ReleaseName) error { + t.Run("Check cluster core has imagePullSecret image", func(t *testing.T) { + t.Parallel() + assert.NoError(t, CheckCoreImageName(t, name), "Core-1 image name should match with customImage") + }) + t.Run("Check imagePullSecret \"demo\" is created", func(t *testing.T) { + t.Parallel() + assert.NoError(t, CheckImagePullSecret(t, name), "ImagePullSecret named \"demo\" should be present") + }) + return nil +} + +//DatabaseCreationTests creates a database against a cluster and checks if its created or not +func DatabaseCreationTests(t *testing.T, loadBalancerName model.ReleaseName, dataBaseName string) error { + t.Run("Create Database customers", func(t *testing.T) { + assert.NoError(t, CreateDatabase(t, loadBalancerName, dataBaseName), "Creates database") + }) + t.Run("Check Database customers exists", func(t *testing.T) { + assert.NoError(t, CheckDataBaseExists(t, loadBalancerName, dataBaseName), "Checks if database exists or not") + }) + return nil +} + +//CheckImagePullSecret checks whether a secret of type docker-registry is created or not +func CheckCoreImageName(t *testing.T, releaseName model.ReleaseName) error { + + pods, err := getAllPods(releaseName.Namespace()) + if !assert.NoError(t, err) { + return err + } + for _, pod := range pods.Items { + if strings.Contains(pod.Name, "core-1") { + container := pod.Spec.Containers[0] + if !assert.Equal(t, container.Image, model.ImagePullSecretCustomImageName) { + return fmt.Errorf("container image %s not matching with imagePullSecet customImage %s", container.Image, model.ImagePullSecretCustomImageName) + } + break + } + } + return nil +} + +//CheckImagePullSecret checks whether a secret of type docker-registry is created or not +func CheckImagePullSecret(t *testing.T, releaseName model.ReleaseName) error { + + secret, err := getSpecificSecret(releaseName.Namespace(), "demo") + if !assert.NoError(t, err) { + return fmt.Errorf("No secret found for the provided imagePullSecret \n %v", err) + } + if !assert.Equal(t, secret.Name, "demo") { + return fmt.Errorf("imagePullSecret name %s does not match with demo", secret.Name) + } + return nil +} + //headLessServiceTests contains all the tests related to headless service func headLessServiceTests(headlessService model.ReleaseName) []SubTest { return []SubTest{ @@ -205,7 +272,7 @@ func readReplicaTests(readReplica1Name model.ReleaseName, readReplica2Name model func CheckClusterCorePasswordFailure(t *testing.T) error { //creating a sample cluster core definition (which is not supposed to get installed) clusterReleaseName := model.NewReleaseName("cluster-" + TestRunIdentifier) - core := clusterCore{model.NewCoreReleaseName(clusterReleaseName, 4)} + core := clusterCore{model.NewCoreReleaseName(clusterReleaseName, 4), nil} releaseName := core.Name() diskName := releaseName.DiskName() // we are not using the customized run() func here since we need to assert the error received on stdout @@ -284,7 +351,6 @@ func CheckK8s(t *testing.T, name model.ReleaseName) error { t.Parallel() assert.NoError(t, CheckLoadBalancerService(t, name, 5)) }) - return nil } @@ -454,13 +520,14 @@ func TestInstallNeo4jClusterInGcloud(t *testing.T) { t.Parallel() clusterReleaseName := model.NewReleaseName("cluster-" + TestRunIdentifier) - loadBalancer := clusterLoadBalancer{model.NewLoadBalancerReleaseName(clusterReleaseName)} - headlessService := clusterHeadLessService{model.NewHeadlessServiceReleaseName(clusterReleaseName)} - readReplica1 := clusterReadReplica{model.NewReadReplicaReleaseName(clusterReleaseName, 1)} - readReplica2 := clusterReadReplica{model.NewReadReplicaReleaseName(clusterReleaseName, 2)} - core1 := clusterCore{model.NewCoreReleaseName(clusterReleaseName, 1)} - core2 := clusterCore{model.NewCoreReleaseName(clusterReleaseName, 2)} - core3 := clusterCore{model.NewCoreReleaseName(clusterReleaseName, 3)} + loadBalancer := clusterLoadBalancer{model.NewLoadBalancerReleaseName(clusterReleaseName), nil} + headlessService := clusterHeadLessService{model.NewHeadlessServiceReleaseName(clusterReleaseName), nil} + readReplica1 := clusterReadReplica{model.NewReadReplicaReleaseName(clusterReleaseName, 1), model.ImagePullSecretArgs} + readReplica2 := clusterReadReplica{model.NewReadReplicaReleaseName(clusterReleaseName, 2), nil} + + core1 := clusterCore{model.NewCoreReleaseName(clusterReleaseName, 1), model.ImagePullSecretArgs} + core2 := clusterCore{model.NewCoreReleaseName(clusterReleaseName, 2), nil} + core3 := clusterCore{model.NewCoreReleaseName(clusterReleaseName, 3), nil} cores := []clusterCore{core1, core2, core3} readReplicas := []clusterReadReplica{readReplica1, readReplica2} @@ -518,7 +585,7 @@ func TestInstallNeo4jClusterInGcloud(t *testing.T) { t.Logf("Succeeded with setup of '%s'", t.Name()) - subTests, err := clusterTests(loadBalancer.Name(), core1.Name()) + subTests, err := clusterTests(loadBalancer.Name()) if !assert.NoError(t, err) { return } diff --git a/internal/integration_tests/k8s_client_test.go b/internal/integration_tests/k8s_client_test.go index 4519968c..2c8bc2d9 100755 --- a/internal/integration_tests/k8s_client_test.go +++ b/internal/integration_tests/k8s_client_test.go @@ -200,6 +200,14 @@ func getAllServices(namespace model.Namespace) (*coreV1.ServiceList, error) { return Clientset.CoreV1().Services(string(namespace)).List(context.TODO(), v1.ListOptions{}) } +func getAllSecrets(namespace model.Namespace) (*coreV1.SecretList, error) { + return Clientset.CoreV1().Secrets(string(namespace)).List(context.TODO(), v1.ListOptions{}) +} + +func getSpecificSecret(namespace model.Namespace, secretName string) (*coreV1.Secret, error) { + return Clientset.CoreV1().Secrets(string(namespace)).Get(context.TODO(), secretName, v1.GetOptions{}) +} + func RunAsNonRoot(t *testing.T, releaseName model.ReleaseName) error { pods, err := Clientset.CoreV1().Pods(string(releaseName.Namespace())).List(context.TODO(), v1.ListOptions{}) if err != nil { diff --git a/internal/model/default_values.go b/internal/model/default_values.go index db859311..d81f33d0 100644 --- a/internal/model/default_values.go +++ b/internal/model/default_values.go @@ -3,10 +3,50 @@ package model import ( "fmt" . "github.com/neo4j/helm-charts/internal/helpers" + "k8s.io/utils/env" + "log" + "os" ) var DefaultPassword = fmt.Sprintf("defaulthelmpassword%da", RandomIntBetween(100000, 999999999)) +var ImagePullSecretUsername, + ImagePullSecretPass, + ImagePullSecretCustomImageName, + ImagePullSecretEmail string + +var ImagePullSecretArgs []string + +func init() { + setWorkingDir() + os.Setenv("KUBECONFIG", ".kube/config") + ImagePullSecretUsername = env.GetString("IPS_USERNAME", "") + if ImagePullSecretUsername == "" { + log.Panic("Please set IPS_USERNAME env variable !!") + } + ImagePullSecretPass = env.GetString("IPS_PASS", "") + if ImagePullSecretPass == "" { + log.Panic("Please set IPS_PASS env variable !!") + } + ImagePullSecretEmail = env.GetString("IPS_EMAIL", "") + if ImagePullSecretEmail == "" { + log.Panic("Please set IPS_EMAIL env variable !!") + } + ImagePullSecretCustomImageName = env.GetString("NEO4J_DOCKER_IMG", "") + if ImagePullSecretCustomImageName == "" { + log.Panic("Please set NEO4J_DOCKER_IMG env variable !!") + } + ImagePullSecretArgs = []string{ + "--set", fmt.Sprintf("image.customImage=%s", ImagePullSecretCustomImageName), + "--set", "image.imagePullSecrets[0]=demo", + "--set", "image.imageCredentials[0].registry=eu.gcr.io", + "--set", "image.imageCredentials[0].name=demo", + "--set", fmt.Sprintf("image.imageCredentials[0].username=%s", ImagePullSecretUsername), + "--set", fmt.Sprintf("image.imageCredentials[0].password=%s", ImagePullSecretPass), + "--set", fmt.Sprintf("image.imageCredentials[0].email=%s", ImagePullSecretEmail), + } +} + const StorageSize = "10Gi" const cpuRequests = "500m" const memoryRequests = "2Gi" diff --git a/internal/model/helm.go b/internal/model/helm.go index 22a3abd4..4b51aea0 100644 --- a/internal/model/helm.go +++ b/internal/model/helm.go @@ -57,12 +57,6 @@ func setWorkingDir() { panic("unable to set current dir correctly") } -func init() { - setWorkingDir() - - os.Setenv("KUBECONFIG", ".kube/config") -} - var DefaultHelmTemplateReleaseName = releaseName("my-release") var Neo4jEdition = strings.ToLower(env.GetString("NEO4J_EDITION", "enterprise")) diff --git a/internal/resources/imagePullSecret/duplicateImageCreds.yaml b/internal/resources/imagePullSecret/duplicateImageCreds.yaml new file mode 100644 index 00000000..cd2f74f4 --- /dev/null +++ b/internal/resources/imagePullSecret/duplicateImageCreds.yaml @@ -0,0 +1,12 @@ +image: + imageCredentials: + - registry: "https://index.docker.io/v1/" + username: "sample1" + password: "samplepass" + email: "sample1@gmail.com" + name: "sample1" + - registry: "https://index.docker.io/v1/" + username: "sample2" + password: "samplepass" + email: "sample2@gmail.com" + name: "sample1" diff --git a/internal/resources/imagePullSecret/emptyImageCreds.yaml b/internal/resources/imagePullSecret/emptyImageCreds.yaml new file mode 100644 index 00000000..1f2ee182 --- /dev/null +++ b/internal/resources/imagePullSecret/emptyImageCreds.yaml @@ -0,0 +1,22 @@ +image: + imageCredentials: + - registry: "https://index.docker.io/v1/" + username: "" + password: "samplepass" + email: "sample@gmail.com" + name: "sample1" + - registry: "https://index.docker.io/v1/" + username: "demo" + password: "" + email: "demo@gmail.com" + name: "sample2" + - registry: "https://index.docker.io/v1/" + username: "demo1" + password: "demo2 " + email: "" + name: "sample3" + - registry: "https://index.docker.io/v1/" + username: "sample4" + password: "samplepass" + email: "sample@gmail.com" + name: "" diff --git a/internal/resources/imagePullSecret/emptyImagePullSecrets.yaml b/internal/resources/imagePullSecret/emptyImagePullSecrets.yaml new file mode 100644 index 00000000..5db0cbc5 --- /dev/null +++ b/internal/resources/imagePullSecret/emptyImagePullSecrets.yaml @@ -0,0 +1,17 @@ +image: + imagePullSecrets: + - "secret1" + - " " + - "secret2" + - "" + imageCredentials: + - registry: "https://index.docker.io/v1/" + username: "sampleuser" + password: "samplepass" + email: "sample@gmail.com" + name: "secret1" + - registry: "https://index.docker.io/v1/" + username: "demo" + password: "demo" + email: "demo@gmail.com" + name: "secret2" diff --git a/internal/resources/imagePullSecret/missingImageCreds.yaml b/internal/resources/imagePullSecret/missingImageCreds.yaml new file mode 100644 index 00000000..3fd73181 --- /dev/null +++ b/internal/resources/imagePullSecret/missingImageCreds.yaml @@ -0,0 +1,9 @@ +image: + imagePullSecrets: + - "secret1" + imageCredentials: + - registry: "https://index.docker.io/v1/" + username: "sampleuser" + password: "samplepass" + email: "sample@gmail.com" + name: "sample" diff --git a/internal/resources/resources.go b/internal/resources/resources.go index 45d4f69c..004cf8c0 100644 --- a/internal/resources/resources.go +++ b/internal/resources/resources.go @@ -25,6 +25,10 @@ var ChmodInitContainer = newYamlFile("chmodInitContainer.yaml") var ChmodInitContainerAndCustomInitContainer = newYamlFile("chmodInitContainerAndCustomInitContainer.yaml") var ReadReplicaUpstreamStrategy = newYamlFile("read_replica_upstream_selection_strategy.yaml") var ExcludeLoadBalancer = newYamlFile("excludeLoadBalancer.yaml") +var EmptyImageCredentials = newYamlFile("imagePullSecret/emptyImageCreds.yaml") +var DuplicateImageCredentials = newYamlFile("imagePullSecret/duplicateImageCreds.yaml") +var MissingImageCredentials = newYamlFile("imagePullSecret/missingImageCreds.yaml") +var EmptyImagePullSecrets = newYamlFile("imagePullSecret/emptyImagePullSecrets.yaml") type YamlFile interface { Path() string diff --git a/internal/unit_tests/helm_template_primaries_test.go b/internal/unit_tests/helm_template_primaries_test.go index cfb1bd47..299815ec 100644 --- a/internal/unit_tests/helm_template_primaries_test.go +++ b/internal/unit_tests/helm_template_primaries_test.go @@ -560,6 +560,101 @@ func TestExtraLabels(t *testing.T) { })) } +func TestEmptyImageCredentials(t *testing.T) { + t.Parallel() + + forEachPrimaryChart(t, andEachSupportedEdition(func(t *testing.T, chart model.Neo4jHelmChart, edition string) { + _, err := model.HelmTemplate(t, chart, useDataModeAndAcceptLicense, resources.EmptyImageCredentials.HelmArgs()...) + if !assert.Error(t, err) { + return + } + if !assert.Contains(t, err.Error(), "Username field cannot be empty") { + return + } + if !assert.Contains(t, err.Error(), "Password field cannot be empty") { + return + } + if !assert.Contains(t, err.Error(), "Email field cannot be empty") { + return + } + if !assert.Contains(t, err.Error(), "name field cannot be empty") { + return + } + })) +} + +func TestDuplicateImageCredentials(t *testing.T) { + t.Parallel() + + forEachPrimaryChart(t, andEachSupportedEdition(func(t *testing.T, chart model.Neo4jHelmChart, edition string) { + _, err := model.HelmTemplate(t, chart, useDataModeAndAcceptLicense, resources.DuplicateImageCredentials.HelmArgs()...) + if !assert.Error(t, err) { + return + } + if !assert.Contains(t, err.Error(), "Duplicate \"names\" found in imageCredentials list. Please remove duplicates") { + return + } + })) +} + +func TestMissingImageCredentials(t *testing.T) { + t.Parallel() + + forEachPrimaryChart(t, andEachSupportedEdition(func(t *testing.T, chart model.Neo4jHelmChart, edition string) { + _, err := model.HelmTemplate(t, chart, useDataModeAndAcceptLicense, resources.MissingImageCredentials.HelmArgs()...) + if !assert.Error(t, err) { + return + } + if !assert.Contains(t, err.Error(), "Missing imageCredential entry") { + return + } + })) +} + +//TestEmptyImagePullSecrets ensures empty imagePullSecret names or names with just spaces are not included in the cluster formation +func TestEmptyImagePullSecrets(t *testing.T) { + t.Parallel() + + forEachPrimaryChart(t, andEachSupportedEdition(func(t *testing.T, chart model.Neo4jHelmChart, edition string) { + manifest, err := model.HelmTemplate(t, chart, useDataModeAndAcceptLicense, resources.EmptyImagePullSecrets.HelmArgs()...) + if !assert.NoError(t, err) { + return + } + secrets := manifest.OfType(&v1.Secret{}) + secret1 := manifest.OfTypeWithName(&v1.Secret{}, "secret1").(*v1.Secret) + secret2 := manifest.OfTypeWithName(&v1.Secret{}, "secret2").(*v1.Secret) + + if !assert.NotEqual(t, len(secrets), 0) { + fmt.Errorf("No secrets found !!") + return + } + var secretCount int + for _, secret := range secrets { + if secret.(*v1.Secret).Type == "kubernetes.io/dockerconfigjson" { + secretCount++ + } + } + if !assert.Equal(t, secretCount, 2) { + fmt.Errorf("%d secrets of type \"kubernetes.io/dockerconfigjson\" found instead of 2 ", secretCount) + return + } + if !assert.NotNil(t, secret1) { + return + } + if !assert.NotNil(t, secret2) { + return + } + if !assert.Equal(t, secret1.Name, "secret1") { + fmt.Errorf(" secret name %s not matching with secret1", secret1.Name) + return + } + if !assert.Equal(t, secret2.Name, "secret2") { + fmt.Errorf(" secret name %s not matching with secret2", secret2.Name) + return + } + })) +} + func TestErrorIsThrownForInvalidMemoryResources(t *testing.T) { t.Parallel() diff --git a/neo4j-cluster-core/Chart.yaml b/neo4j-cluster-core/Chart.yaml index 099d5144..919a327a 100644 --- a/neo4j-cluster-core/Chart.yaml +++ b/neo4j-cluster-core/Chart.yaml @@ -1,8 +1,8 @@ apiVersion: v1 name: neo4j-cluster-core home: https://www.neo4j.com -version: 4.4.3 -appVersion: 4.4.3 +version: 4.4.4 +appVersion: 4.4.4 description: Neo4j is the world's leading graph database keywords: - graph diff --git a/neo4j-cluster-core/values.yaml b/neo4j-cluster-core/values.yaml index 7c03f661..caab2117 100644 --- a/neo4j-cluster-core/values.yaml +++ b/neo4j-cluster-core/values.yaml @@ -30,6 +30,9 @@ neo4j: cpu: "1000m" memory: "2Gi" + #add labels if required + labels: + # Volumes for Neo4j volumes: data: @@ -266,6 +269,21 @@ image: # set a customImage if you want to use your own docker image # customImage: my-image:my-tag + #imagePullSecrets list + # imagePullSecrets: + # - "demo" + + #imageCredentials list for which secret of type docker-registry will be created automatically using the details provided + # registry , username , password , email are compulsory field for an imageCredential , without any , helm chart will throw an error + # imageCredential name should be part of the imagePullSecrets list or else the respective imageCredential will be ignored and no secret creation will be done + # imageCredentials: + # - registry: "" + # username: "" + # password: "" + # email: "" + # name: "" + + # additional environment variables for the Neo4j Container env: {} diff --git a/neo4j-cluster-headless-service/Chart.yaml b/neo4j-cluster-headless-service/Chart.yaml index 476d3ed6..302e68b8 100644 --- a/neo4j-cluster-headless-service/Chart.yaml +++ b/neo4j-cluster-headless-service/Chart.yaml @@ -1,7 +1,7 @@ apiVersion: v1 name: neo4j-cluster-headless-service home: https://www.neo4j.com -version: 4.4.3 +version: 4.4.4 appVersion: "-" description: Neo4j is the world's leading graph database keywords: diff --git a/neo4j-cluster-loadbalancer/Chart.yaml b/neo4j-cluster-loadbalancer/Chart.yaml index 83172a07..c8c7506c 100644 --- a/neo4j-cluster-loadbalancer/Chart.yaml +++ b/neo4j-cluster-loadbalancer/Chart.yaml @@ -1,7 +1,7 @@ apiVersion: v1 name: neo4j-cluster-loadbalancer home: https://www.neo4j.com -version: 4.4.3 +version: 4.4.4 appVersion: "-" description: Neo4j is the world's leading graph database keywords: diff --git a/neo4j-cluster-read-replica/Chart.yaml b/neo4j-cluster-read-replica/Chart.yaml index c20c272f..db44c580 100644 --- a/neo4j-cluster-read-replica/Chart.yaml +++ b/neo4j-cluster-read-replica/Chart.yaml @@ -1,8 +1,8 @@ apiVersion: v1 name: neo4j-cluster-read-replica home: https://www.neo4j.com -version: 4.4.3 -appVersion: 4.4.3 +version: 4.4.4 +appVersion: 4.4.4 description: Neo4j is the world's leading graph database keywords: - graph diff --git a/neo4j-cluster-read-replica/values.yaml b/neo4j-cluster-read-replica/values.yaml index 6903049c..7d8c6b9d 100644 --- a/neo4j-cluster-read-replica/values.yaml +++ b/neo4j-cluster-read-replica/values.yaml @@ -30,6 +30,9 @@ neo4j: cpu: "1000m" memory: "2Gi" + #add labels if required + labels: + # Volumes for Neo4j volumes: data: @@ -265,6 +268,20 @@ image: # set a customImage if you want to use your own docker image # customImage: my-image:my-tag + #imagePullSecrets list +# imagePullSecrets: +# - "demo" + + #imageCredentials list for which secret of type docker-registry will be created automatically using the details provided + # registry , username , password , email are compulsory field for an imageCredential , without any , helm chart will throw an error + # imageCredential name should be part of the imagePullSecrets list or else the respective imageCredential will be ignored and no secret creation will be done +# imageCredentials: +# - registry: "" +# username: "" +# password: "" +# email: "" +# name: "" + # additional environment variables for the Neo4j Container env: {} diff --git a/neo4j-docker-desktop-pv/Chart.yaml b/neo4j-docker-desktop-pv/Chart.yaml index f0335719..1a5d4851 100644 --- a/neo4j-docker-desktop-pv/Chart.yaml +++ b/neo4j-docker-desktop-pv/Chart.yaml @@ -1,7 +1,7 @@ apiVersion: v1 name: neo4j-docker-desktop-pv home: https://www.neo4j.com -version: 4.4.3 +version: 4.4.4 appVersion: "-" description: Sets up persistent disks suitable for simple development tasks with Neo4j Helm when using Kubernetes provided by Docker Desktop keywords: diff --git a/neo4j-gcloud-pv/Chart.yaml b/neo4j-gcloud-pv/Chart.yaml index c9f1dc3d..1ea41986 100644 --- a/neo4j-gcloud-pv/Chart.yaml +++ b/neo4j-gcloud-pv/Chart.yaml @@ -1,7 +1,7 @@ apiVersion: v1 name: neo4j-gcloud-pv home: https://www.neo4j.com -version: 4.4.3 +version: 4.4.4 appVersion: "-" description: Sets up persistent disks suitable for simple development tasks with Neo4j Helm when using Kubernetes provided Google Kubernetes Engine keywords: diff --git a/neo4j-shared-templates/Chart.yaml b/neo4j-shared-templates/Chart.yaml index 576b86f8..920998f6 100644 --- a/neo4j-shared-templates/Chart.yaml +++ b/neo4j-shared-templates/Chart.yaml @@ -1,8 +1,8 @@ apiVersion: v1 name: neo4j-shared-templates home: https://www.neo4j.com -version: 4.4.3 -appVersion: 4.4.3 +version: 4.4.4 +appVersion: 4.4.4 description: Neo4j is the world's leading graph database keywords: - graph diff --git a/neo4j-shared-templates/templates/_imagePullSecret.tpl b/neo4j-shared-templates/templates/_imagePullSecret.tpl new file mode 100644 index 00000000..764d77ba --- /dev/null +++ b/neo4j-shared-templates/templates/_imagePullSecret.tpl @@ -0,0 +1,85 @@ +{{/* To see imagePullSecret registrys in the statefulset*/}} +{{- define "neo4j.imagePullSecrets" -}} + {{/* add imagePullSecrets only when the list of imagePullSecrets is not emtpy and does not have all the entries as empty */}} + {{- if and (not (empty .)) (ne (len ( . | join "" | trim)) 0) }} +imagePullSecrets: + {{- range $name := . -}} + {{/* do not allow empty imagePullSecret registries */}} + {{- if ne (len ($name | trim)) 0 }} + - name: "{{ $name }}" + {{- end -}} + {{- end -}} + {{- end -}} +{{- end -}} + +{{/* Generates the .dockerconfigjson value for the respective .Values.neo4j.image.imageCredentials */}} +{{- define "neo4j.imagePullSecret.dockerConfigJson" }} +{{- printf "{\"auths\":{\"%s\":{\"username\":\"%s\",\"password\":\"%s\",\"email\":\"%s\",\"auth\":\"%s\"}}}" .registry .username .password .email (printf "%s:%s" .username .password | b64enc) | b64enc }} +{{- end }} + +{{/* checks and throws error if registry ,username , email and name imageCredentials fields are empty */}} +{{- define "neo4j.imageCredentials.checkForEmptyFields" -}} + + {{- if .Values.image.imageCredentials -}} + {{- $errorList := list -}} + {{- range $index, $element := .Values.image.imageCredentials }} + + {{- if empty ($element.registry | trim) -}} + {{- $errorList = append $errorList (printf "Registry field cannot be empty for imageCredential \"%s\"" $element.name) -}} + {{- end -}} + + {{- if empty ($element.username | trim) -}} + {{- $errorList = append $errorList (printf "Username field cannot be empty for imageCredential \"%s\"" $element.name) -}} + {{- end -}} + + {{- if empty ($element.password | trim) -}} + {{- $errorList = append $errorList (printf "Password field cannot be empty for imageCredential \"%s\"" $element.name) -}} + {{- end -}} + + {{- if empty ($element.email | trim) -}} + {{- $errorList = append $errorList (printf "Email field cannot be empty for imageCredential \"%s\"" $element.name) -}} + {{- end -}} + + {{- if empty ($element.name | trim) -}} + {{- $errorList = append $errorList "name field cannot be empty for an imageCredential" -}} + {{- end -}} + + {{- end -}} + + {{- if not (empty $errorList) -}} + {{ fail (printf "%s" ($errorList | join "\n")) }} + {{- end -}} + + {{- end -}} +{{- end -}} + +{{/* checkForDuplicates throws an error if there are duplicate 'names' found in imageCredential list */}} +{{- define "neo4j.imageCredentials.checkForDuplicates" -}} + + {{- if .Values.image.imageCredentials -}} + + {{- $nameList := list -}} + + {{- range $index, $element := .Values.image.imageCredentials }} + {{- $nameList = append $nameList $element.name -}} + {{- end -}} + + {{- $nameList = $nameList | uniq -}} + + {{- if ne (len $nameList) (len .Values.image.imageCredentials) -}} + {{ fail (printf "Duplicate \"names\" found in imageCredentials list. Please remove duplicates") }} + {{- end -}} + + {{- end -}} +{{- end -}} + +{{/* getImageCredential returns an imageCredential for the given name */}} +{{- define "neo4j.imageCredentials.getImageCredential" -}} + + {{- $imagePullSecretName := .imagePullSecret -}} + {{- range $index, $element := .imageCredentials -}} + {{- if eq $element.name $imagePullSecretName -}} + {{- $element | toYaml -}} + {{- end -}} + {{- end -}} +{{- end -}} diff --git a/neo4j-shared-templates/templates/_labels.tpl b/neo4j-shared-templates/templates/_labels.tpl index 5473c039..e749aedd 100644 --- a/neo4j-shared-templates/templates/_labels.tpl +++ b/neo4j-shared-templates/templates/_labels.tpl @@ -1,7 +1,7 @@ {{- define "neo4j.labels" -}} -{{- with .labels }} +{{- with .labels -}} {{- range $name, $value := . }} "{{ $name }}": "{{ $value }}" -{{ end }} -{{- end }} {{- end -}} +{{- end -}} +{{- end }} diff --git a/neo4j-shared-templates/templates/_loadbalancer.tpl b/neo4j-shared-templates/templates/_loadbalancer.tpl index fd911491..2a7b9e1a 100644 --- a/neo4j-shared-templates/templates/_loadbalancer.tpl +++ b/neo4j-shared-templates/templates/_loadbalancer.tpl @@ -32,7 +32,7 @@ metadata: helm.neo4j.com/neo4j.name: "{{ template "neo4j.name" $ }}" app: "{{ template "neo4j.appName" . }}" helm.neo4j.com/service: "neo4j" - {{- include "neo4j.labels" .Values.neo4j | nindent 4 }} + {{- include "neo4j.labels" .Values.neo4j | indent 4 }} {{- with .Values.annotations }} annotations: {{ toYaml . | nindent 4 }} {{- end }} diff --git a/neo4j-standalone/Chart.yaml b/neo4j-standalone/Chart.yaml index 2c52d137..f1633632 100644 --- a/neo4j-standalone/Chart.yaml +++ b/neo4j-standalone/Chart.yaml @@ -1,8 +1,8 @@ apiVersion: v1 name: neo4j-standalone home: https://www.neo4j.com -version: 4.4.3 -appVersion: 4.4.3 +version: 4.4.4 +appVersion: 4.4.4 description: Neo4j is the world's leading graph database keywords: - graph diff --git a/neo4j-standalone/templates/NOTES.txt b/neo4j-standalone/templates/NOTES.txt index 5d7de989..5fbc52fd 100644 --- a/neo4j-standalone/templates/NOTES.txt +++ b/neo4j-standalone/templates/NOTES.txt @@ -1,3 +1,4 @@ + {{- define "neo4j.namespaceParameter" -}} {{ if ne "default" .Release.Namespace }} --namespace "{{.Release.Namespace}}"{{ end }} {{- end -}} diff --git a/neo4j-standalone/templates/neo4j-auth.yaml b/neo4j-standalone/templates/neo4j-auth.yaml index 5f87410a..bef251d5 100644 --- a/neo4j-standalone/templates/neo4j-auth.yaml +++ b/neo4j-standalone/templates/neo4j-auth.yaml @@ -52,10 +52,11 @@ metadata: namespace: "{{ .Release.Namespace }}" labels: app: "{{ template "neo4j.appName" . }}" - {{- include "neo4j.labels" $.Values.neo4j | nindent 4 }} + {{- include "neo4j.labels" $.Values.neo4j | indent 4 }} type: Opaque data: NEO4J_AUTH: "{{ $password }}" {{- end -}} {{- end -}} + diff --git a/neo4j-standalone/templates/neo4j-config.yaml b/neo4j-standalone/templates/neo4j-config.yaml index 95cc2540..53ff89fd 100644 --- a/neo4j-standalone/templates/neo4j-config.yaml +++ b/neo4j-standalone/templates/neo4j-config.yaml @@ -9,7 +9,7 @@ metadata: namespace: "{{ .Release.Namespace }}" labels: app: "{{ template "neo4j.appName" $ }}" - {{- include "neo4j.labels" $.Values.neo4j | nindent 4 }} + {{- include "neo4j.labels" $.Values.neo4j | indent 4 }} data: dbms.default_listen_address: "0.0.0.0" --- @@ -27,7 +27,7 @@ metadata: namespace: "{{ .Release.Namespace }}" labels: app: "{{ template "neo4j.appName" $ }}" - {{- include "neo4j.labels" $.Values.neo4j | nindent 4 }} + {{- include "neo4j.labels" $.Values.neo4j | indent 4 }} data: {{- /* imported config first */}} {{- with $configImport }} @@ -68,7 +68,7 @@ metadata: namespace: "{{ .Release.Namespace }}" labels: app: "{{ template "neo4j.appName" $ }}" - {{- include "neo4j.labels" $.Values.neo4j | nindent 4 }} + {{- include "neo4j.labels" $.Values.neo4j | indent 4 }} data: # Neo4j defaults diff --git a/neo4j-standalone/templates/neo4j-env.yaml b/neo4j-standalone/templates/neo4j-env.yaml index b8819418..73b7032a 100644 --- a/neo4j-standalone/templates/neo4j-env.yaml +++ b/neo4j-standalone/templates/neo4j-env.yaml @@ -5,7 +5,7 @@ metadata: namespace: "{{ .Release.Namespace }}" labels: app: "{{ template "neo4j.appName" $ }}" - {{- include "neo4j.labels" $.Values.neo4j | nindent 4 }} + {{- include "neo4j.labels" $.Values.neo4j | indent 4 }} data: # It should not be necessary for neo4j users/administrators to modify this configMap # Neo4j configuration is set in the {{ .Release.Name }}-user-config ConfigMap diff --git a/neo4j-standalone/templates/neo4j-imagePullSecret.yaml b/neo4j-standalone/templates/neo4j-imagePullSecret.yaml new file mode 100644 index 00000000..759b2e7e --- /dev/null +++ b/neo4j-standalone/templates/neo4j-imagePullSecret.yaml @@ -0,0 +1,35 @@ + +{{- template "neo4j.imageCredentials.checkForDuplicates" . -}} +{{- template "neo4j.imageCredentials.checkForEmptyFields" . -}} + +{{- range $index, $imagePullSecret := $.Values.image.imagePullSecrets -}} + {{/* This is to avoid empty or spaces in imagePullSecrets*/}} + {{- if ne (len ($imagePullSecret | trim)) 0 -}} + {{- $imagePullSecret = $imagePullSecret | trim -}} + {{- $secret := (lookup "v1" "Secret" $.Release.Namespace $imagePullSecret) -}} + {{- $secretExists := $secret | all -}} + {{- $imageCredentialElement := include "neo4j.imageCredentials.getImageCredential" (dict "imagePullSecret" $imagePullSecret "imageCredentials" $.Values.image.imageCredentials) | fromYaml -}} + + {{/* create secret only and only if does not exist in the cluster */}} + {{- if not $secretExists -}} + + {{/* throw error if there is no imageCredential entry for the respective imagePullSecret*/}} + {{- if empty $imageCredentialElement -}} + {{ fail (printf "No docker-registry secret exists for imagePullSecret \"%s\" in the cluster. \n Missing imageCredential entry for \"%s\"" $imagePullSecret $imagePullSecret) }} + {{- else }} +apiVersion: v1 +kind: Secret +metadata: + name: "{{ $imageCredentialElement.name }}" + namespace: "{{ $.Release.Namespace }}" + labels: + app: "{{ $.Values.neo4j.name | default $.Release.Name }}" + {{- include "neo4j.labels" $.Values.neo4j | indent 4 }} +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ include "neo4j.imagePullSecret.dockerConfigJson" $imageCredentialElement }} +--- + {{- end -}} + {{- end -}} + {{- end }} +{{- end -}} diff --git a/neo4j-standalone/templates/neo4j-service-account.yaml b/neo4j-standalone/templates/neo4j-service-account.yaml index 4a022e7c..bb705d36 100644 --- a/neo4j-standalone/templates/neo4j-service-account.yaml +++ b/neo4j-standalone/templates/neo4j-service-account.yaml @@ -6,7 +6,7 @@ metadata: name: {{ .Release.Name }} labels: app: "{{ template "neo4j.appName" $ }}" - {{- include "neo4j.labels" $.Values.neo4j | nindent 4 }} + {{- include "neo4j.labels" $.Values.neo4j | indent 4 }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role @@ -14,7 +14,7 @@ metadata: name: "{{ .Release.Name }}-service-reader" labels: app: "{{ template "neo4j.appName" $ }}" - {{- include "neo4j.labels" $.Values.neo4j | nindent 4 }} + {{- include "neo4j.labels" $.Values.neo4j | indent 4 }} rules: - apiGroups: [""] # "" indicates the core API group resources: ["services", "endpoints"] @@ -26,7 +26,7 @@ metadata: name: "{{ .Release.Name }}-service-binding" labels: app: "{{ template "neo4j.appName" $ }}" - {{- include "neo4j.labels" $.Values.neo4j | nindent 4 }} + {{- include "neo4j.labels" $.Values.neo4j | indent 4 }} subjects: - kind: ServiceAccount name: {{ .Release.Name }} diff --git a/neo4j-standalone/templates/neo4j-statefulset.yaml b/neo4j-standalone/templates/neo4j-statefulset.yaml index f8446eeb..f573477f 100644 --- a/neo4j-standalone/templates/neo4j-statefulset.yaml +++ b/neo4j-standalone/templates/neo4j-statefulset.yaml @@ -17,7 +17,7 @@ metadata: helm.neo4j.com/dbms.mode: "{{ index $.Values.config "dbms.mode" | default "SINGLE" | upper }}" app: "{{ template "neo4j.appName" . }}" helm.neo4j.com/instance: "{{ .Release.Name }}" - {{- include "neo4j.labels" $.Values.neo4j | nindent 4 }} + {{- include "neo4j.labels" $.Values.neo4j | indent 4 }} name: "{{ .Release.Name }}" namespace: "{{ .Release.Namespace }}" spec: @@ -37,7 +37,7 @@ spec: helm.neo4j.com/pod_category: "neo4j-instance" # used for anti affinity rules helm.neo4j.com/neo4j.loadbalancer: "{{ $.Values.podSpec.loadbalancer }}" helm.neo4j.com/instance: "{{ .Release.Name }}" - {{- include "neo4j.labels" $.Values.neo4j | nindent 8 }} + {{- include "neo4j.labels" $.Values.neo4j | indent 8 }} annotations: "checksum/{{ .Release.Name }}-config": {{ include (print $.Template.BasePath "/neo4j-config.yaml") . | sha256sum }} spec: @@ -77,6 +77,7 @@ spec: {{- end }} {{- end }} {{- end }} + {{- include "neo4j.imagePullSecrets" .Values.image.imagePullSecrets | indent 6 }} containers: - name: "neo4j" image: "{{ $neo4jImage }}" diff --git a/neo4j-standalone/templates/neo4j-svc.yaml b/neo4j-standalone/templates/neo4j-svc.yaml index 7d131bea..d1398a66 100644 --- a/neo4j-standalone/templates/neo4j-svc.yaml +++ b/neo4j-standalone/templates/neo4j-svc.yaml @@ -22,7 +22,7 @@ metadata: app: "{{ template "neo4j.appName" $ }}" helm.neo4j.com/instance: "{{ $.Release.Name }}" helm.neo4j.com/service: "default" - {{- include "neo4j.labels" $.Values.neo4j | nindent 4 }} + {{- include "neo4j.labels" $.Values.neo4j | indent 4 }} {{- with .Values.services.default.annotations }} annotations: {{ toYaml . | nindent 4 }} {{- end }} @@ -60,7 +60,7 @@ metadata: app: "{{ template "neo4j.appName" $ }}" helm.neo4j.com/instance: "{{ $.Release.Name }}" helm.neo4j.com/service: "admin" - {{- include "neo4j.labels" $.Values.neo4j | nindent 4 }} + {{- include "neo4j.labels" $.Values.neo4j | indent 4 }} {{- with .annotations }} annotations: {{ toYaml . | nindent 4 }} {{- end }} @@ -124,7 +124,7 @@ metadata: app: "{{ template "neo4j.appName" $ }}" helm.neo4j.com/dbms.mode: "{{ index $.Values.config "dbms.mode" | default "SINGLE" | upper }}" helm.neo4j.com/service: "internals" - {{- include "neo4j.labels" $.Values.neo4j | nindent 4 }} + {{- include "neo4j.labels" $.Values.neo4j | indent 4 }} {{- with .annotations }} annotations: {{ toYaml . | nindent 4 }} {{- end }} diff --git a/neo4j-standalone/values.yaml b/neo4j-standalone/values.yaml index c267218f..e5fcf617 100644 --- a/neo4j-standalone/values.yaml +++ b/neo4j-standalone/values.yaml @@ -29,6 +29,10 @@ neo4j: cpu: "1000m" memory: "2Gi" + #add labels if required + labels: + + # Volumes for Neo4j volumes: data: @@ -268,6 +272,21 @@ image: # set a customImage if you want to use your own docker image # customImage: my-image:my-tag + #imagePullSecrets list + # imagePullSecrets: + # - "demo" + + #imageCredentials list for which secret of type docker-registry will be created automatically using the details provided + # registry , username , password , email are compulsory field for an imageCredential , without any , helm chart will throw an error + # imageCredential name should be part of the imagePullSecrets list or else the respective imageCredential will be ignored and no secret creation will be done +# imageCredentials: +# - registry: "" +# username: "" +# password: "" +# email: "" +# name: "" + + # additional environment variables for the Neo4j Container env: {}