From de59f4c81e05addbf258cfd76ff20057d51fa8d7 Mon Sep 17 00:00:00 2001 From: Tomasz Mielech Date: Tue, 7 Sep 2021 12:51:32 +0200 Subject: [PATCH 1/6] always use internal metrics exporter --- README.md | 1 + pkg/deployment/features/features.go | 15 ++++++++++++++- pkg/deployment/features/local.go | 16 +++++++++++++--- pkg/deployment/features/metrics.go | 7 +++++++ 4 files changed, 35 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 9c41cafc9..4007c7826 100644 --- a/README.md +++ b/README.md @@ -95,6 +95,7 @@ Feature-wise production readiness table: | Operator Maintenance Management Support | 1.2.0 | >= 3.6.0 | Community, Enterprise | Production | True | --deployment.feature.maintenance | N/A | | Operator Internal Metrics Exporter | 1.1.9 | >= 3.6.0 | Community, Enterprise | Alpha | False | --deployment.feature.metrics-exporter | N/A | | Operator Internal Metrics Exporter | 1.2.0 | >= 3.6.0 | Community, Enterprise | Production | True | --deployment.feature.metrics-exporter | N/A | +| Operator Internal Metrics Exporter | 1.2.3 | >= 3.6.0 | Community, Enterprise | Production | True | --deployment.feature.metrics-exporter | It is always enabled | | Operator Ephemeral Volumes | 1.2.2 | >= 3.7.0 | Community, Enterprise | Alpha | False | --deployment.feature.ephemeral-volumes | N/A | ## Release notes for 0.3.16 diff --git a/pkg/deployment/features/features.go b/pkg/deployment/features/features.go index cb5ae6e91..12f64e68b 100644 --- a/pkg/deployment/features/features.go +++ b/pkg/deployment/features/features.go @@ -1,7 +1,7 @@ // // DISCLAIMER // -// Copyright 2020 ArangoDB GmbH, Cologne, Germany +// Copyright 2020-2021 ArangoDB GmbH, Cologne, Germany // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ // Copyright holder is ArangoDB GmbH, Cologne, Germany // // Author Adam Janikowski +// Author Tomasz Mielech // package features @@ -34,6 +35,7 @@ type Feature interface { EnabledByDefault() bool Enabled() bool EnabledPointer() *bool + Deprecated() (bool, string) Supported(v driver.Version, enterprise bool) bool } @@ -41,6 +43,8 @@ type feature struct { name, description string version driver.Version enterpriseRequired, enabledByDefault, enabled bool + deprecated string + constValue *bool } func (f feature) Supported(v driver.Version, enterprise bool) bool { @@ -48,6 +52,10 @@ func (f feature) Supported(v driver.Version, enterprise bool) bool { } func (f feature) Enabled() bool { + if f.constValue != nil { + return *f.constValue + } + return f.enabled } @@ -74,3 +82,8 @@ func (f feature) Name() string { func (f feature) Description() string { return f.description } + +// Deprecated returns true if the feature is deprecated and the reason why it is deprecated. +func (f feature) Deprecated() (bool, string) { + return len(f.deprecated) > 0, f.deprecated +} diff --git a/pkg/deployment/features/local.go b/pkg/deployment/features/local.go index 927341401..284816af9 100644 --- a/pkg/deployment/features/local.go +++ b/pkg/deployment/features/local.go @@ -1,7 +1,7 @@ // // DISCLAIMER // -// Copyright 2020 ArangoDB GmbH, Cologne, Germany +// Copyright 2020-2021 ArangoDB GmbH, Cologne, Germany // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ // Copyright holder is ArangoDB GmbH, Cologne, Germany // // Author Adam Janikowski +// Author Tomasz Mielech // package features @@ -80,11 +81,16 @@ func Init(cmd *cobra.Command) { } } - f.BoolVar(feature.EnabledPointer(), fmt.Sprintf("deployment.feature.%s", feature.Name()), feature.EnabledByDefault(), z) + featureName := fmt.Sprintf("deployment.feature.%s", feature.Name()) + if ok, reason := feature.Deprecated(); ok { + f.MarkDeprecated(featureName, reason) + } + + f.BoolVar(feature.EnabledPointer(), featureName, feature.EnabledByDefault(), z) } } -func cmdRun(cmd *cobra.Command, args []string) { +func cmdRun(_ *cobra.Command, _ []string) { featuresLock.Lock() defer featuresLock.Unlock() @@ -106,6 +112,10 @@ func cmdRun(cmd *cobra.Command, args []string) { println("ArangoDB Edition Required: Community, Enterprise") } + if ok, reason := feature.Deprecated(); ok { + println(fmt.Sprintf("Deprecated: %s", reason)) + } + println() } } diff --git a/pkg/deployment/features/metrics.go b/pkg/deployment/features/metrics.go index 2a69727dd..756638de4 100644 --- a/pkg/deployment/features/metrics.go +++ b/pkg/deployment/features/metrics.go @@ -18,10 +18,15 @@ // Copyright holder is ArangoDB GmbH, Cologne, Germany // // Author Adam Janikowski +// Author Tomasz Mielech // package features +import ( + "github.com/arangodb/kube-arangodb/pkg/util" +) + func init() { registerFeature(metricsExporter) } @@ -32,6 +37,8 @@ var metricsExporter = &feature{ version: "3.6.0", enterpriseRequired: false, enabledByDefault: true, + deprecated: "It is always set to True", + constValue: util.NewBool(true), } func MetricsExporter() Feature { From b5061cb582e06de673149e761e5fa72789509bc9 Mon Sep 17 00:00:00 2001 From: Tomasz Mielech Date: Tue, 7 Sep 2021 15:24:00 +0200 Subject: [PATCH 2/6] fix some unit tests --- pkg/deployment/deployment_core_test.go | 506 ++++++++++-------- pkg/deployment/deployment_definitions_test.go | 2 +- 2 files changed, 275 insertions(+), 233 deletions(-) diff --git a/pkg/deployment/deployment_core_test.go b/pkg/deployment/deployment_core_test.go index 026a2994c..793935b09 100644 --- a/pkg/deployment/deployment_core_test.go +++ b/pkg/deployment/deployment_core_test.go @@ -1,7 +1,7 @@ // // DISCLAIMER // -// Copyright 2020 ArangoDB GmbH, Cologne, Germany +// Copyright 2020-2021 ArangoDB GmbH, Cologne, Germany // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -23,18 +23,17 @@ package deployment import ( + "os" + "path/filepath" "testing" - "github.com/arangodb/kube-arangodb/pkg/util/constants" - - "github.com/arangodb/kube-arangodb/pkg/util/k8sutil" - "github.com/stretchr/testify/require" - - "github.com/arangodb/kube-arangodb/pkg/util" + core "k8s.io/api/core/v1" api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1" - core "k8s.io/api/core/v1" + "github.com/arangodb/kube-arangodb/pkg/util" + "github.com/arangodb/kube-arangodb/pkg/util/constants" + "github.com/arangodb/kube-arangodb/pkg/util/k8sutil" ) func TestEnsurePod_ArangoDB_Core(t *testing.T) { @@ -893,7 +892,7 @@ func TestEnsurePod_ArangoDB_Core(t *testing.T) { }, }, { - Name: "Agent Pod can not have metrics exporter", + Name: "Agent Pod can not have metrics exporter", // TODO ArangoDeployment: &api.ArangoDeployment{ Spec: api.DeploymentSpec{ Image: util.NewString(testImage), @@ -913,12 +912,14 @@ func TestEnsurePod_ArangoDB_Core(t *testing.T) { } testCase.createTestPodData(deployment, api.ServerGroupAgents, firstAgentStatus) + testCase.ExpectedPod.ObjectMeta.Labels[k8sutil.LabelKeyArangoExporter] = testYes }, ExpectedEvent: "member agent is created", ExpectedPod: core.Pod{ Spec: core.PodSpec{ Volumes: []core.Volume{ k8sutil.CreateVolumeEmptyDir(k8sutil.ArangodVolumeName), + k8sutil.CreateVolumeWithSecret(k8sutil.ExporterJWTVolumeName, testExporterToken), }, Containers: []core.Container{ { @@ -934,6 +935,7 @@ func TestEnsurePod_ArangoDB_Core(t *testing.T) { ImagePullPolicy: core.PullIfNotPresent, SecurityContext: securityContext.NewSecurityContext(), }, + testArangodbInternalExporterContainer(emptyResources), }, RestartPolicy: core.RestartPolicyNever, TerminationGracePeriodSeconds: &defaultAgentTerminationTimeout, @@ -945,7 +947,7 @@ func TestEnsurePod_ArangoDB_Core(t *testing.T) { }, }, { - Name: "DBserver Pod with metrics exporter", + Name: "DBserver Pod with internal metrics exporter", ArangoDeployment: &api.ArangoDeployment{ Spec: api.DeploymentSpec{ Image: util.NewString(testImage), @@ -988,7 +990,7 @@ func TestEnsurePod_ArangoDB_Core(t *testing.T) { ImagePullPolicy: core.PullIfNotPresent, SecurityContext: securityContext.NewSecurityContext(), }, - testCreateExporterContainer(false, emptyResources), + testArangodbInternalExporterContainer(emptyResources), }, RestartPolicy: core.RestartPolicyNever, TerminationGracePeriodSeconds: &defaultDBServerTerminationTimeout, @@ -1008,7 +1010,7 @@ func TestEnsurePod_ArangoDB_Core(t *testing.T) { TLS: noTLS, Metrics: api.MetricsSpec{ Enabled: util.NewBool(true), - Image: util.NewString(testExporterImage), + Image: util.NewString(testImage), Authentication: api.MetricsAuthenticationSpec{ JWTTokenSecretName: util.NewString(testExporterToken), }, @@ -1050,7 +1052,7 @@ func TestEnsurePod_ArangoDB_Core(t *testing.T) { ImagePullPolicy: core.PullIfNotPresent, SecurityContext: securityContext.NewSecurityContext(), }, - testCreateExporterContainer(false, k8sutil.ExtractPodResourceRequirement(resourcesUnfiltered)), + testArangodbInternalExporterContainer(k8sutil.ExtractPodResourceRequirement(resourcesUnfiltered)), }, RestartPolicy: core.RestartPolicyNever, TerminationGracePeriodSeconds: &defaultDBServerTerminationTimeout, @@ -1123,7 +1125,7 @@ func TestEnsurePod_ArangoDB_Core(t *testing.T) { ImagePullPolicy: core.PullIfNotPresent, SecurityContext: securityContext.NewSecurityContext(), }, - testCreateExporterContainer(false, emptyResources), + testArangodbInternalExporterContainer(emptyResources), }, RestartPolicy: core.RestartPolicyNever, TerminationGracePeriodSeconds: &defaultDBServerTerminationTimeout, @@ -1195,7 +1197,7 @@ func TestEnsurePod_ArangoDB_Core(t *testing.T) { ImagePullPolicy: core.PullIfNotPresent, SecurityContext: securityContext.NewSecurityContext(), }, - testCreateExporterContainer(false, emptyResources), + testArangodbInternalExporterContainer(emptyResources), }, RestartPolicy: core.RestartPolicyNever, TerminationGracePeriodSeconds: &defaultDBServerTerminationTimeout, @@ -1206,232 +1208,272 @@ func TestEnsurePod_ArangoDB_Core(t *testing.T) { }, }, }, - { - Name: "DBserver Pod with metrics exporter, lifecycle, tls, authentication, license, rocksDB encryption, secured liveness", - ArangoDeployment: &api.ArangoDeployment{ - Spec: api.DeploymentSpec{ - Image: util.NewString(testImage), - Authentication: authenticationSpec, - TLS: tlsSpec, - Metrics: metricsSpec, - RocksDB: rocksDBSpec, - Environment: api.NewEnvironment(api.EnvironmentProduction), - License: api.LicenseSpec{ - SecretName: util.NewString(testLicense), - }, - }, - }, - Helper: func(t *testing.T, deployment *Deployment, testCase *testCaseStruct) { - deployment.status.last = api.DeploymentStatus{ - Members: api.DeploymentStatusMembers{ - DBServers: api.MemberStatusList{ - firstDBServerStatus, - }, - }, - Images: createTestImages(false), - } + //{ + // Name: "DBserver Pod with metrics exporter, lifecycle, tls, authentication, license, rocksDB encryption, secured liveness", + // ArangoDeployment: &api.ArangoDeployment{ + // Spec: api.DeploymentSpec{ + // Image: util.NewString(testImage), + // Authentication: authenticationSpec, + // TLS: tlsSpec, + // Metrics: metricsSpec, + // RocksDB: rocksDBSpec, + // Environment: api.NewEnvironment(api.EnvironmentProduction), + // License: api.LicenseSpec{ + // SecretName: util.NewString(testLicense), + // }, + // }, + // }, + // Helper: func(t *testing.T, deployment *Deployment, testCase *testCaseStruct) { + // deployment.status.last = api.DeploymentStatus{ + // Members: api.DeploymentStatusMembers{ + // DBServers: api.MemberStatusList{ + // firstDBServerStatus, + // }, + // }, + // Images: createTestImages(false), + // } + // + // testCase.createTestPodData(deployment, api.ServerGroupDBServers, firstDBServerStatus) + // testCase.ExpectedPod.ObjectMeta.Labels[k8sutil.LabelKeyArangoExporter] = testYes + // + // secrets := deployment.GetKubeCli().CoreV1().Secrets(testNamespace) + // key := make([]byte, 32) + // k8sutil.CreateEncryptionKeySecret(secrets, testRocksDBEncryptionKey, key) + // + // authorization, err := createTestToken(deployment, testCase, []string{"/_api/version"}) + // require.NoError(t, err) + // + // testCase.ExpectedPod.Spec.Containers[0].LivenessProbe = createTestLivenessProbe(httpProbe, true, + // authorization, k8sutil.ArangoPort) + // }, + // config: Config{ + // LifecycleImage: testImageLifecycle, + // }, + // ExpectedEvent: "member dbserver is created", + // ExpectedPod: core.Pod{ + // Spec: core.PodSpec{ + // Volumes: []core.Volume{ + // k8sutil.CreateVolumeEmptyDir(k8sutil.ArangodVolumeName), + // createTestTLSVolume(api.ServerGroupDBServersString, firstDBServerStatus.ID), + // k8sutil.CreateVolumeWithSecret(k8sutil.RocksdbEncryptionVolumeName, testRocksDBEncryptionKey), + // k8sutil.CreateVolumeWithSecret(k8sutil.ExporterJWTVolumeName, testExporterToken), + // k8sutil.CreateVolumeWithSecret(k8sutil.ClusterJWTSecretVolumeName, testJWTSecretName), + // k8sutil.LifecycleVolume(), + // }, + // InitContainers: []core.Container{ + // createTestLifecycleContainer(emptyResources), + // }, + // Containers: []core.Container{ + // { + // Name: k8sutil.ServerContainerName, + // Image: testImage, + // Command: createTestCommandForDBServer(firstDBServerStatus.ID, true, true, true), + // Env: []core.EnvVar{ + // k8sutil.CreateEnvSecretKeySelector(constants.EnvArangoLicenseKey, + // testLicense, constants.SecretKeyToken), + // k8sutil.CreateEnvFieldPath(constants.EnvOperatorPodName, "metadata.name"), + // k8sutil.CreateEnvFieldPath(constants.EnvOperatorPodNamespace, "metadata.namespace"), + // k8sutil.CreateEnvFieldPath(constants.EnvOperatorNodeName, "spec.nodeName"), + // k8sutil.CreateEnvFieldPath(constants.EnvOperatorNodeNameArango, "spec.nodeName"), + // }, + // Ports: createTestPorts(), + // Lifecycle: createTestLifecycle(), + // LivenessProbe: createTestLivenessProbe(httpProbe, false, "", k8sutil.ArangoPort), + // ImagePullPolicy: core.PullIfNotPresent, + // SecurityContext: securityContext.NewSecurityContext(), + // VolumeMounts: []core.VolumeMount{ + // k8sutil.ArangodVolumeMount(), + // k8sutil.LifecycleVolumeMount(), + // k8sutil.TlsKeyfileVolumeMount(), + // k8sutil.RocksdbEncryptionVolumeMount(), + // k8sutil.ClusterJWTVolumeMount(), + // }, + // Resources: emptyResources, + // }, + // func() core.Container { + // c := testCreateExporterContainer(true, emptyResources) + // c.VolumeMounts = append(c.VolumeMounts, k8sutil.TlsKeyfileVolumeMount()) + // return c + // }(), + // }, + // RestartPolicy: core.RestartPolicyNever, + // TerminationGracePeriodSeconds: &defaultDBServerTerminationTimeout, + // Hostname: testDeploymentName + "-" + api.ServerGroupDBServersString + "-" + firstDBServerStatus.ID, + // Subdomain: testDeploymentName + "-int", + // Affinity: k8sutil.CreateAffinity(testDeploymentName, api.ServerGroupDBServersString, + // true, ""), + // }, + // }, + //}, + //{ + // Name: "Coordinator Pod with TLS and authentication and readiness and liveness", + // ArangoDeployment: &api.ArangoDeployment{ + // Spec: api.DeploymentSpec{ + // Image: util.NewString(testImage), + // Authentication: authenticationSpec, + // Environment: api.NewEnvironment(api.EnvironmentProduction), + // TLS: api.TLSSpec{ + // CASecretName: util.NewString(testCASecretName), + // }, + // }, + // }, + // Helper: func(t *testing.T, deployment *Deployment, testCase *testCaseStruct) { + // deployment.status.last = api.DeploymentStatus{ + // Members: api.DeploymentStatusMembers{ + // Coordinators: api.MemberStatusList{ + // firstCoordinatorStatus, + // }, + // }, + // Images: createTestImages(false), + // } + // + // testCase.createTestPodData(deployment, api.ServerGroupCoordinators, firstCoordinatorStatus) + // + // auth, err := createTestToken(deployment, testCase, []string{"/_admin/server/availability"}) + // require.NoError(t, err) + // + // testCase.ExpectedPod.Spec.Containers[0].ReadinessProbe = createTestReadinessProbe(httpProbe, true, auth) + // }, + // ExpectedEvent: "member coordinator is created", + // ExpectedPod: core.Pod{ + // Spec: core.PodSpec{ + // Volumes: []core.Volume{ + // k8sutil.CreateVolumeEmptyDir(k8sutil.ArangodVolumeName), + // createTestTLSVolume(api.ServerGroupCoordinatorsString, firstCoordinatorStatus.ID), + // k8sutil.CreateVolumeWithSecret(k8sutil.ClusterJWTSecretVolumeName, testJWTSecretName), + // }, + // Containers: []core.Container{ + // { + // Name: k8sutil.ServerContainerName, + // Image: testImage, + // Command: createTestCommandForCoordinator(firstCoordinatorStatus.ID, true, true), + // Ports: createTestPorts(), + // ImagePullPolicy: core.PullIfNotPresent, + // Resources: emptyResources, + // SecurityContext: securityContext.NewSecurityContext(), + // VolumeMounts: []core.VolumeMount{ + // k8sutil.ArangodVolumeMount(), + // k8sutil.TlsKeyfileVolumeMount(), + // k8sutil.ClusterJWTVolumeMount(), + // }, + // }, + // }, + // RestartPolicy: core.RestartPolicyNever, + // TerminationGracePeriodSeconds: &defaultCoordinatorTerminationTimeout, + // Hostname: testDeploymentName + "-" + api.ServerGroupCoordinatorsString + "-" + firstCoordinatorStatus.ID, + // Subdomain: testDeploymentName + "-int", + // Affinity: k8sutil.CreateAffinity(testDeploymentName, api.ServerGroupCoordinatorsString, + // true, ""), + // }, + // }, + //}, + //{ + // Name: "Single Pod with TLS and authentication and readiness and readiness", + // ArangoDeployment: &api.ArangoDeployment{ + // Spec: api.DeploymentSpec{ + // Image: util.NewString(testImage), + // Authentication: authenticationSpec, + // TLS: api.TLSSpec{ + // CASecretName: util.NewString(testCASecretName), + // }, + // }, + // }, + // Helper: func(t *testing.T, deployment *Deployment, testCase *testCaseStruct) { + // deployment.status.last = api.DeploymentStatus{ + // Members: api.DeploymentStatusMembers{ + // Single: api.MemberStatusList{ + // singleStatus, + // }, + // }, + // Images: createTestImages(false), + // } + // + // testCase.createTestPodData(deployment, api.ServerGroupSingle, singleStatus) + // + // authLiveness, err := createTestToken(deployment, testCase, []string{"/_api/version"}) + // require.NoError(t, err) + // + // authReadiness, err := createTestToken(deployment, testCase, []string{"/_admin/server/availability"}) + // require.NoError(t, err) + // + // testCase.ExpectedPod.Spec.Containers[0].LivenessProbe = createTestLivenessProbe(httpProbe, true, + // authLiveness, 0) + // testCase.ExpectedPod.Spec.Containers[0].ReadinessProbe = createTestReadinessProbe(httpProbe, true, authReadiness) + // }, + // ExpectedEvent: "member single is created", + // ExpectedPod: core.Pod{ + // Spec: core.PodSpec{ + // Volumes: []core.Volume{ + // k8sutil.CreateVolumeEmptyDir(k8sutil.ArangodVolumeName), + // createTestTLSVolume(api.ServerGroupSingleString, singleStatus.ID), + // k8sutil.CreateVolumeWithSecret(k8sutil.ClusterJWTSecretVolumeName, testJWTSecretName), + // }, + // Containers: []core.Container{ + // { + // Name: k8sutil.ServerContainerName, + // Image: testImage, + // Command: createTestCommandForSingleMode(true, true), + // Ports: createTestPorts(), + // ImagePullPolicy: core.PullIfNotPresent, + // SecurityContext: securityContext.NewSecurityContext(), + // VolumeMounts: []core.VolumeMount{ + // k8sutil.ArangodVolumeMount(), + // k8sutil.TlsKeyfileVolumeMount(), + // k8sutil.ClusterJWTVolumeMount(), + // }, + // Resources: emptyResources, + // }, + // }, + // RestartPolicy: core.RestartPolicyNever, + // TerminationGracePeriodSeconds: &defaultSingleTerminationTimeout, + // Hostname: testDeploymentName + "-" + api.ServerGroupSingleString + "-" + singleStatus.ID, + // Subdomain: testDeploymentName + "-int", + // Affinity: k8sutil.CreateAffinity(testDeploymentName, api.ServerGroupSingleString, + // false, ""), + // }, + // }, + //}, + } - testCase.createTestPodData(deployment, api.ServerGroupDBServers, firstDBServerStatus) - testCase.ExpectedPod.ObjectMeta.Labels[k8sutil.LabelKeyArangoExporter] = testYes + runTestCases(t, testCases...) +} - secrets := deployment.GetKubeCli().CoreV1().Secrets(testNamespace) - key := make([]byte, 32) - k8sutil.CreateEncryptionKeySecret(secrets, testRocksDBEncryptionKey, key) +func testArangodbInternalExporterContainer(resources core.ResourceRequirements) core.Container { + binaryPath, err := os.Executable() + if err != nil { + return core.Container{} + } + exePath := filepath.Join(k8sutil.LifecycleVolumeMountDir, filepath.Base(binaryPath)) - authorization, err := createTestToken(deployment, testCase, []string{"/_api/version"}) - require.NoError(t, err) + args := []string{ + "--arangodb.endpoint=http://localhost:8529/_admin/metrics", + "--arangodb.jwt-file=/secrets/exporter/jwt/token", + } - testCase.ExpectedPod.Spec.Containers[0].LivenessProbe = createTestLivenessProbe(httpProbe, true, - authorization, k8sutil.ArangoPort) - }, - config: Config{ - LifecycleImage: testImageLifecycle, - }, - ExpectedEvent: "member dbserver is created", - ExpectedPod: core.Pod{ - Spec: core.PodSpec{ - Volumes: []core.Volume{ - k8sutil.CreateVolumeEmptyDir(k8sutil.ArangodVolumeName), - createTestTLSVolume(api.ServerGroupDBServersString, firstDBServerStatus.ID), - k8sutil.CreateVolumeWithSecret(k8sutil.RocksdbEncryptionVolumeName, testRocksDBEncryptionKey), - k8sutil.CreateVolumeWithSecret(k8sutil.ExporterJWTVolumeName, testExporterToken), - k8sutil.CreateVolumeWithSecret(k8sutil.ClusterJWTSecretVolumeName, testJWTSecretName), - k8sutil.LifecycleVolume(), - }, - InitContainers: []core.Container{ - createTestLifecycleContainer(emptyResources), - }, - Containers: []core.Container{ - { - Name: k8sutil.ServerContainerName, - Image: testImage, - Command: createTestCommandForDBServer(firstDBServerStatus.ID, true, true, true), - Env: []core.EnvVar{ - k8sutil.CreateEnvSecretKeySelector(constants.EnvArangoLicenseKey, - testLicense, constants.SecretKeyToken), - k8sutil.CreateEnvFieldPath(constants.EnvOperatorPodName, "metadata.name"), - k8sutil.CreateEnvFieldPath(constants.EnvOperatorPodNamespace, "metadata.namespace"), - k8sutil.CreateEnvFieldPath(constants.EnvOperatorNodeName, "spec.nodeName"), - k8sutil.CreateEnvFieldPath(constants.EnvOperatorNodeNameArango, "spec.nodeName"), - }, - Ports: createTestPorts(), - Lifecycle: createTestLifecycle(), - LivenessProbe: createTestLivenessProbe(httpProbe, false, "", k8sutil.ArangoPort), - ImagePullPolicy: core.PullIfNotPresent, - SecurityContext: securityContext.NewSecurityContext(), - VolumeMounts: []core.VolumeMount{ - k8sutil.ArangodVolumeMount(), - k8sutil.LifecycleVolumeMount(), - k8sutil.TlsKeyfileVolumeMount(), - k8sutil.RocksdbEncryptionVolumeMount(), - k8sutil.ClusterJWTVolumeMount(), - }, - Resources: emptyResources, - }, - func() core.Container { - c := testCreateExporterContainer(true, emptyResources) - c.VolumeMounts = append(c.VolumeMounts, k8sutil.TlsKeyfileVolumeMount()) - return c - }(), - }, - RestartPolicy: core.RestartPolicyNever, - TerminationGracePeriodSeconds: &defaultDBServerTerminationTimeout, - Hostname: testDeploymentName + "-" + api.ServerGroupDBServersString + "-" + firstDBServerStatus.ID, - Subdomain: testDeploymentName + "-int", - Affinity: k8sutil.CreateAffinity(testDeploymentName, api.ServerGroupDBServersString, - true, ""), - }, + return core.Container{ + Name: k8sutil.ExporterContainerName, + Image: testImage, + Command: append([]string{exePath, "exporter"}, args...), + Ports: []core.ContainerPort{ + { + Name: "exporter", + ContainerPort: k8sutil.ArangoExporterPort, + Protocol: core.ProtocolTCP, }, }, - { - Name: "Coordinator Pod with TLS and authentication and readiness and liveness", - ArangoDeployment: &api.ArangoDeployment{ - Spec: api.DeploymentSpec{ - Image: util.NewString(testImage), - Authentication: authenticationSpec, - Environment: api.NewEnvironment(api.EnvironmentProduction), - TLS: api.TLSSpec{ - CASecretName: util.NewString(testCASecretName), - }, - }, - }, - Helper: func(t *testing.T, deployment *Deployment, testCase *testCaseStruct) { - deployment.status.last = api.DeploymentStatus{ - Members: api.DeploymentStatusMembers{ - Coordinators: api.MemberStatusList{ - firstCoordinatorStatus, - }, - }, - Images: createTestImages(false), - } - - testCase.createTestPodData(deployment, api.ServerGroupCoordinators, firstCoordinatorStatus) - - auth, err := createTestToken(deployment, testCase, []string{"/_admin/server/availability"}) - require.NoError(t, err) - - testCase.ExpectedPod.Spec.Containers[0].ReadinessProbe = createTestReadinessProbe(httpProbe, true, auth) - }, - ExpectedEvent: "member coordinator is created", - ExpectedPod: core.Pod{ - Spec: core.PodSpec{ - Volumes: []core.Volume{ - k8sutil.CreateVolumeEmptyDir(k8sutil.ArangodVolumeName), - createTestTLSVolume(api.ServerGroupCoordinatorsString, firstCoordinatorStatus.ID), - k8sutil.CreateVolumeWithSecret(k8sutil.ClusterJWTSecretVolumeName, testJWTSecretName), - }, - Containers: []core.Container{ - { - Name: k8sutil.ServerContainerName, - Image: testImage, - Command: createTestCommandForCoordinator(firstCoordinatorStatus.ID, true, true), - Ports: createTestPorts(), - ImagePullPolicy: core.PullIfNotPresent, - Resources: emptyResources, - SecurityContext: securityContext.NewSecurityContext(), - VolumeMounts: []core.VolumeMount{ - k8sutil.ArangodVolumeMount(), - k8sutil.TlsKeyfileVolumeMount(), - k8sutil.ClusterJWTVolumeMount(), - }, - }, - }, - RestartPolicy: core.RestartPolicyNever, - TerminationGracePeriodSeconds: &defaultCoordinatorTerminationTimeout, - Hostname: testDeploymentName + "-" + api.ServerGroupCoordinatorsString + "-" + firstCoordinatorStatus.ID, - Subdomain: testDeploymentName + "-int", - Affinity: k8sutil.CreateAffinity(testDeploymentName, api.ServerGroupCoordinatorsString, - true, ""), + LivenessProbe: createTestExporterLivenessProbe(false), + Resources: resources, + ImagePullPolicy: core.PullIfNotPresent, + SecurityContext: &core.SecurityContext{ + Capabilities: &core.Capabilities{ + Drop: []core.Capability{ + "ALL", }, }, }, - { - Name: "Single Pod with TLS and authentication and readiness and readiness", - ArangoDeployment: &api.ArangoDeployment{ - Spec: api.DeploymentSpec{ - Image: util.NewString(testImage), - Authentication: authenticationSpec, - TLS: api.TLSSpec{ - CASecretName: util.NewString(testCASecretName), - }, - }, - }, - Helper: func(t *testing.T, deployment *Deployment, testCase *testCaseStruct) { - deployment.status.last = api.DeploymentStatus{ - Members: api.DeploymentStatusMembers{ - Single: api.MemberStatusList{ - singleStatus, - }, - }, - Images: createTestImages(false), - } - - testCase.createTestPodData(deployment, api.ServerGroupSingle, singleStatus) - - authLiveness, err := createTestToken(deployment, testCase, []string{"/_api/version"}) - require.NoError(t, err) - - authReadiness, err := createTestToken(deployment, testCase, []string{"/_admin/server/availability"}) - require.NoError(t, err) - - testCase.ExpectedPod.Spec.Containers[0].LivenessProbe = createTestLivenessProbe(httpProbe, true, - authLiveness, 0) - testCase.ExpectedPod.Spec.Containers[0].ReadinessProbe = createTestReadinessProbe(httpProbe, true, authReadiness) - }, - ExpectedEvent: "member single is created", - ExpectedPod: core.Pod{ - Spec: core.PodSpec{ - Volumes: []core.Volume{ - k8sutil.CreateVolumeEmptyDir(k8sutil.ArangodVolumeName), - createTestTLSVolume(api.ServerGroupSingleString, singleStatus.ID), - k8sutil.CreateVolumeWithSecret(k8sutil.ClusterJWTSecretVolumeName, testJWTSecretName), - }, - Containers: []core.Container{ - { - Name: k8sutil.ServerContainerName, - Image: testImage, - Command: createTestCommandForSingleMode(true, true), - Ports: createTestPorts(), - ImagePullPolicy: core.PullIfNotPresent, - SecurityContext: securityContext.NewSecurityContext(), - VolumeMounts: []core.VolumeMount{ - k8sutil.ArangodVolumeMount(), - k8sutil.TlsKeyfileVolumeMount(), - k8sutil.ClusterJWTVolumeMount(), - }, - Resources: emptyResources, - }, - }, - RestartPolicy: core.RestartPolicyNever, - TerminationGracePeriodSeconds: &defaultSingleTerminationTimeout, - Hostname: testDeploymentName + "-" + api.ServerGroupSingleString + "-" + singleStatus.ID, - Subdomain: testDeploymentName + "-int", - Affinity: k8sutil.CreateAffinity(testDeploymentName, api.ServerGroupSingleString, - false, ""), - }, - }, + VolumeMounts: []core.VolumeMount{ + k8sutil.LifecycleVolumeMount(), + k8sutil.ExporterJWTVolumeMount(), }, } - - runTestCases(t, testCases...) } diff --git a/pkg/deployment/deployment_definitions_test.go b/pkg/deployment/deployment_definitions_test.go index fa4a82d2f..7f130c39a 100644 --- a/pkg/deployment/deployment_definitions_test.go +++ b/pkg/deployment/deployment_definitions_test.go @@ -96,7 +96,7 @@ var ( metricsSpec = api.MetricsSpec{ Enabled: util.NewBool(true), - Image: util.NewString(testExporterImage), + Image: util.NewString(testImage), Authentication: api.MetricsAuthenticationSpec{ JWTTokenSecretName: util.NewString(testExporterToken), }, From cf644fa85ebf282f7e2c3eeaeb158984ef40a244 Mon Sep 17 00:00:00 2001 From: Tomasz Mielech Date: Tue, 7 Sep 2021 20:37:16 +0200 Subject: [PATCH 3/6] fix unit tests --- pkg/deployment/deployment_core_test.go | 490 ++++++++++--------- pkg/deployment/deployment_encryption_test.go | 16 +- pkg/deployment/deployment_metrics_test.go | 298 +---------- pkg/deployment/deployment_suite_test.go | 26 - 4 files changed, 272 insertions(+), 558 deletions(-) diff --git a/pkg/deployment/deployment_core_test.go b/pkg/deployment/deployment_core_test.go index 793935b09..f49456758 100644 --- a/pkg/deployment/deployment_core_test.go +++ b/pkg/deployment/deployment_core_test.go @@ -23,6 +23,7 @@ package deployment import ( + "fmt" "os" "path/filepath" "testing" @@ -935,7 +936,7 @@ func TestEnsurePod_ArangoDB_Core(t *testing.T) { ImagePullPolicy: core.PullIfNotPresent, SecurityContext: securityContext.NewSecurityContext(), }, - testArangodbInternalExporterContainer(emptyResources), + testArangodbInternalExporterContainer(false, emptyResources), }, RestartPolicy: core.RestartPolicyNever, TerminationGracePeriodSeconds: &defaultAgentTerminationTimeout, @@ -990,7 +991,7 @@ func TestEnsurePod_ArangoDB_Core(t *testing.T) { ImagePullPolicy: core.PullIfNotPresent, SecurityContext: securityContext.NewSecurityContext(), }, - testArangodbInternalExporterContainer(emptyResources), + testArangodbInternalExporterContainer(false, emptyResources), }, RestartPolicy: core.RestartPolicyNever, TerminationGracePeriodSeconds: &defaultDBServerTerminationTimeout, @@ -1052,7 +1053,7 @@ func TestEnsurePod_ArangoDB_Core(t *testing.T) { ImagePullPolicy: core.PullIfNotPresent, SecurityContext: securityContext.NewSecurityContext(), }, - testArangodbInternalExporterContainer(k8sutil.ExtractPodResourceRequirement(resourcesUnfiltered)), + testArangodbInternalExporterContainer(false, k8sutil.ExtractPodResourceRequirement(resourcesUnfiltered)), }, RestartPolicy: core.RestartPolicyNever, TerminationGracePeriodSeconds: &defaultDBServerTerminationTimeout, @@ -1125,7 +1126,7 @@ func TestEnsurePod_ArangoDB_Core(t *testing.T) { ImagePullPolicy: core.PullIfNotPresent, SecurityContext: securityContext.NewSecurityContext(), }, - testArangodbInternalExporterContainer(emptyResources), + testArangodbInternalExporterContainer(false, emptyResources), }, RestartPolicy: core.RestartPolicyNever, TerminationGracePeriodSeconds: &defaultDBServerTerminationTimeout, @@ -1197,7 +1198,7 @@ func TestEnsurePod_ArangoDB_Core(t *testing.T) { ImagePullPolicy: core.PullIfNotPresent, SecurityContext: securityContext.NewSecurityContext(), }, - testArangodbInternalExporterContainer(emptyResources), + testArangodbInternalExporterContainer(false, emptyResources), }, RestartPolicy: core.RestartPolicyNever, TerminationGracePeriodSeconds: &defaultDBServerTerminationTimeout, @@ -1208,246 +1209,263 @@ func TestEnsurePod_ArangoDB_Core(t *testing.T) { }, }, }, - //{ - // Name: "DBserver Pod with metrics exporter, lifecycle, tls, authentication, license, rocksDB encryption, secured liveness", - // ArangoDeployment: &api.ArangoDeployment{ - // Spec: api.DeploymentSpec{ - // Image: util.NewString(testImage), - // Authentication: authenticationSpec, - // TLS: tlsSpec, - // Metrics: metricsSpec, - // RocksDB: rocksDBSpec, - // Environment: api.NewEnvironment(api.EnvironmentProduction), - // License: api.LicenseSpec{ - // SecretName: util.NewString(testLicense), - // }, - // }, - // }, - // Helper: func(t *testing.T, deployment *Deployment, testCase *testCaseStruct) { - // deployment.status.last = api.DeploymentStatus{ - // Members: api.DeploymentStatusMembers{ - // DBServers: api.MemberStatusList{ - // firstDBServerStatus, - // }, - // }, - // Images: createTestImages(false), - // } - // - // testCase.createTestPodData(deployment, api.ServerGroupDBServers, firstDBServerStatus) - // testCase.ExpectedPod.ObjectMeta.Labels[k8sutil.LabelKeyArangoExporter] = testYes - // - // secrets := deployment.GetKubeCli().CoreV1().Secrets(testNamespace) - // key := make([]byte, 32) - // k8sutil.CreateEncryptionKeySecret(secrets, testRocksDBEncryptionKey, key) - // - // authorization, err := createTestToken(deployment, testCase, []string{"/_api/version"}) - // require.NoError(t, err) - // - // testCase.ExpectedPod.Spec.Containers[0].LivenessProbe = createTestLivenessProbe(httpProbe, true, - // authorization, k8sutil.ArangoPort) - // }, - // config: Config{ - // LifecycleImage: testImageLifecycle, - // }, - // ExpectedEvent: "member dbserver is created", - // ExpectedPod: core.Pod{ - // Spec: core.PodSpec{ - // Volumes: []core.Volume{ - // k8sutil.CreateVolumeEmptyDir(k8sutil.ArangodVolumeName), - // createTestTLSVolume(api.ServerGroupDBServersString, firstDBServerStatus.ID), - // k8sutil.CreateVolumeWithSecret(k8sutil.RocksdbEncryptionVolumeName, testRocksDBEncryptionKey), - // k8sutil.CreateVolumeWithSecret(k8sutil.ExporterJWTVolumeName, testExporterToken), - // k8sutil.CreateVolumeWithSecret(k8sutil.ClusterJWTSecretVolumeName, testJWTSecretName), - // k8sutil.LifecycleVolume(), - // }, - // InitContainers: []core.Container{ - // createTestLifecycleContainer(emptyResources), - // }, - // Containers: []core.Container{ - // { - // Name: k8sutil.ServerContainerName, - // Image: testImage, - // Command: createTestCommandForDBServer(firstDBServerStatus.ID, true, true, true), - // Env: []core.EnvVar{ - // k8sutil.CreateEnvSecretKeySelector(constants.EnvArangoLicenseKey, - // testLicense, constants.SecretKeyToken), - // k8sutil.CreateEnvFieldPath(constants.EnvOperatorPodName, "metadata.name"), - // k8sutil.CreateEnvFieldPath(constants.EnvOperatorPodNamespace, "metadata.namespace"), - // k8sutil.CreateEnvFieldPath(constants.EnvOperatorNodeName, "spec.nodeName"), - // k8sutil.CreateEnvFieldPath(constants.EnvOperatorNodeNameArango, "spec.nodeName"), - // }, - // Ports: createTestPorts(), - // Lifecycle: createTestLifecycle(), - // LivenessProbe: createTestLivenessProbe(httpProbe, false, "", k8sutil.ArangoPort), - // ImagePullPolicy: core.PullIfNotPresent, - // SecurityContext: securityContext.NewSecurityContext(), - // VolumeMounts: []core.VolumeMount{ - // k8sutil.ArangodVolumeMount(), - // k8sutil.LifecycleVolumeMount(), - // k8sutil.TlsKeyfileVolumeMount(), - // k8sutil.RocksdbEncryptionVolumeMount(), - // k8sutil.ClusterJWTVolumeMount(), - // }, - // Resources: emptyResources, - // }, - // func() core.Container { - // c := testCreateExporterContainer(true, emptyResources) - // c.VolumeMounts = append(c.VolumeMounts, k8sutil.TlsKeyfileVolumeMount()) - // return c - // }(), - // }, - // RestartPolicy: core.RestartPolicyNever, - // TerminationGracePeriodSeconds: &defaultDBServerTerminationTimeout, - // Hostname: testDeploymentName + "-" + api.ServerGroupDBServersString + "-" + firstDBServerStatus.ID, - // Subdomain: testDeploymentName + "-int", - // Affinity: k8sutil.CreateAffinity(testDeploymentName, api.ServerGroupDBServersString, - // true, ""), - // }, - // }, - //}, - //{ - // Name: "Coordinator Pod with TLS and authentication and readiness and liveness", - // ArangoDeployment: &api.ArangoDeployment{ - // Spec: api.DeploymentSpec{ - // Image: util.NewString(testImage), - // Authentication: authenticationSpec, - // Environment: api.NewEnvironment(api.EnvironmentProduction), - // TLS: api.TLSSpec{ - // CASecretName: util.NewString(testCASecretName), - // }, - // }, - // }, - // Helper: func(t *testing.T, deployment *Deployment, testCase *testCaseStruct) { - // deployment.status.last = api.DeploymentStatus{ - // Members: api.DeploymentStatusMembers{ - // Coordinators: api.MemberStatusList{ - // firstCoordinatorStatus, - // }, - // }, - // Images: createTestImages(false), - // } - // - // testCase.createTestPodData(deployment, api.ServerGroupCoordinators, firstCoordinatorStatus) - // - // auth, err := createTestToken(deployment, testCase, []string{"/_admin/server/availability"}) - // require.NoError(t, err) - // - // testCase.ExpectedPod.Spec.Containers[0].ReadinessProbe = createTestReadinessProbe(httpProbe, true, auth) - // }, - // ExpectedEvent: "member coordinator is created", - // ExpectedPod: core.Pod{ - // Spec: core.PodSpec{ - // Volumes: []core.Volume{ - // k8sutil.CreateVolumeEmptyDir(k8sutil.ArangodVolumeName), - // createTestTLSVolume(api.ServerGroupCoordinatorsString, firstCoordinatorStatus.ID), - // k8sutil.CreateVolumeWithSecret(k8sutil.ClusterJWTSecretVolumeName, testJWTSecretName), - // }, - // Containers: []core.Container{ - // { - // Name: k8sutil.ServerContainerName, - // Image: testImage, - // Command: createTestCommandForCoordinator(firstCoordinatorStatus.ID, true, true), - // Ports: createTestPorts(), - // ImagePullPolicy: core.PullIfNotPresent, - // Resources: emptyResources, - // SecurityContext: securityContext.NewSecurityContext(), - // VolumeMounts: []core.VolumeMount{ - // k8sutil.ArangodVolumeMount(), - // k8sutil.TlsKeyfileVolumeMount(), - // k8sutil.ClusterJWTVolumeMount(), - // }, - // }, - // }, - // RestartPolicy: core.RestartPolicyNever, - // TerminationGracePeriodSeconds: &defaultCoordinatorTerminationTimeout, - // Hostname: testDeploymentName + "-" + api.ServerGroupCoordinatorsString + "-" + firstCoordinatorStatus.ID, - // Subdomain: testDeploymentName + "-int", - // Affinity: k8sutil.CreateAffinity(testDeploymentName, api.ServerGroupCoordinatorsString, - // true, ""), - // }, - // }, - //}, - //{ - // Name: "Single Pod with TLS and authentication and readiness and readiness", - // ArangoDeployment: &api.ArangoDeployment{ - // Spec: api.DeploymentSpec{ - // Image: util.NewString(testImage), - // Authentication: authenticationSpec, - // TLS: api.TLSSpec{ - // CASecretName: util.NewString(testCASecretName), - // }, - // }, - // }, - // Helper: func(t *testing.T, deployment *Deployment, testCase *testCaseStruct) { - // deployment.status.last = api.DeploymentStatus{ - // Members: api.DeploymentStatusMembers{ - // Single: api.MemberStatusList{ - // singleStatus, - // }, - // }, - // Images: createTestImages(false), - // } - // - // testCase.createTestPodData(deployment, api.ServerGroupSingle, singleStatus) - // - // authLiveness, err := createTestToken(deployment, testCase, []string{"/_api/version"}) - // require.NoError(t, err) - // - // authReadiness, err := createTestToken(deployment, testCase, []string{"/_admin/server/availability"}) - // require.NoError(t, err) - // - // testCase.ExpectedPod.Spec.Containers[0].LivenessProbe = createTestLivenessProbe(httpProbe, true, - // authLiveness, 0) - // testCase.ExpectedPod.Spec.Containers[0].ReadinessProbe = createTestReadinessProbe(httpProbe, true, authReadiness) - // }, - // ExpectedEvent: "member single is created", - // ExpectedPod: core.Pod{ - // Spec: core.PodSpec{ - // Volumes: []core.Volume{ - // k8sutil.CreateVolumeEmptyDir(k8sutil.ArangodVolumeName), - // createTestTLSVolume(api.ServerGroupSingleString, singleStatus.ID), - // k8sutil.CreateVolumeWithSecret(k8sutil.ClusterJWTSecretVolumeName, testJWTSecretName), - // }, - // Containers: []core.Container{ - // { - // Name: k8sutil.ServerContainerName, - // Image: testImage, - // Command: createTestCommandForSingleMode(true, true), - // Ports: createTestPorts(), - // ImagePullPolicy: core.PullIfNotPresent, - // SecurityContext: securityContext.NewSecurityContext(), - // VolumeMounts: []core.VolumeMount{ - // k8sutil.ArangodVolumeMount(), - // k8sutil.TlsKeyfileVolumeMount(), - // k8sutil.ClusterJWTVolumeMount(), - // }, - // Resources: emptyResources, - // }, - // }, - // RestartPolicy: core.RestartPolicyNever, - // TerminationGracePeriodSeconds: &defaultSingleTerminationTimeout, - // Hostname: testDeploymentName + "-" + api.ServerGroupSingleString + "-" + singleStatus.ID, - // Subdomain: testDeploymentName + "-int", - // Affinity: k8sutil.CreateAffinity(testDeploymentName, api.ServerGroupSingleString, - // false, ""), - // }, - // }, - //}, + { + Name: "DBserver Pod with metrics exporter, lifecycle, tls, authentication, license, rocksDB encryption, secured liveness", + ArangoDeployment: &api.ArangoDeployment{ + Spec: api.DeploymentSpec{ + Image: util.NewString(testImage), + Authentication: authenticationSpec, + TLS: tlsSpec, + Metrics: metricsSpec, + RocksDB: rocksDBSpec, + Environment: api.NewEnvironment(api.EnvironmentProduction), + License: api.LicenseSpec{ + SecretName: util.NewString(testLicense), + }, + }, + }, + Helper: func(t *testing.T, deployment *Deployment, testCase *testCaseStruct) { + deployment.status.last = api.DeploymentStatus{ + Members: api.DeploymentStatusMembers{ + DBServers: api.MemberStatusList{ + firstDBServerStatus, + }, + }, + Images: createTestImages(false), + } + + testCase.createTestPodData(deployment, api.ServerGroupDBServers, firstDBServerStatus) + testCase.ExpectedPod.ObjectMeta.Labels[k8sutil.LabelKeyArangoExporter] = testYes + + secrets := deployment.GetKubeCli().CoreV1().Secrets(testNamespace) + key := make([]byte, 32) + k8sutil.CreateEncryptionKeySecret(secrets, testRocksDBEncryptionKey, key) + + authorization, err := createTestToken(deployment, testCase, []string{"/_api/version"}) + require.NoError(t, err) + + testCase.ExpectedPod.Spec.Containers[0].LivenessProbe = createTestLivenessProbe(httpProbe, true, + authorization, k8sutil.ArangoPort) + }, + config: Config{ + LifecycleImage: testImageLifecycle, + }, + ExpectedEvent: "member dbserver is created", + ExpectedPod: core.Pod{ + Spec: core.PodSpec{ + Volumes: []core.Volume{ + k8sutil.CreateVolumeEmptyDir(k8sutil.ArangodVolumeName), + createTestTLSVolume(api.ServerGroupDBServersString, firstDBServerStatus.ID), + k8sutil.CreateVolumeWithSecret(k8sutil.RocksdbEncryptionVolumeName, testRocksDBEncryptionKey), + k8sutil.CreateVolumeWithSecret(k8sutil.ExporterJWTVolumeName, testExporterToken), + k8sutil.CreateVolumeWithSecret(k8sutil.ClusterJWTSecretVolumeName, testJWTSecretName), + k8sutil.LifecycleVolume(), + }, + InitContainers: []core.Container{ + createTestLifecycleContainer(emptyResources), + }, + Containers: []core.Container{ + { + Name: k8sutil.ServerContainerName, + Image: testImage, + Command: createTestCommandForDBServer(firstDBServerStatus.ID, true, true, true), + Env: []core.EnvVar{ + k8sutil.CreateEnvSecretKeySelector(constants.EnvArangoLicenseKey, + testLicense, constants.SecretKeyToken), + k8sutil.CreateEnvFieldPath(constants.EnvOperatorPodName, "metadata.name"), + k8sutil.CreateEnvFieldPath(constants.EnvOperatorPodNamespace, "metadata.namespace"), + k8sutil.CreateEnvFieldPath(constants.EnvOperatorNodeName, "spec.nodeName"), + k8sutil.CreateEnvFieldPath(constants.EnvOperatorNodeNameArango, "spec.nodeName"), + }, + Ports: createTestPorts(), + Lifecycle: createTestLifecycle(), + LivenessProbe: createTestLivenessProbe(httpProbe, false, "", k8sutil.ArangoPort), + ImagePullPolicy: core.PullIfNotPresent, + SecurityContext: securityContext.NewSecurityContext(), + VolumeMounts: []core.VolumeMount{ + k8sutil.ArangodVolumeMount(), + k8sutil.LifecycleVolumeMount(), + k8sutil.TlsKeyfileVolumeMount(), + k8sutil.RocksdbEncryptionVolumeMount(), + k8sutil.ClusterJWTVolumeMount(), + }, + Resources: emptyResources, + }, + func() core.Container { + c := testArangodbInternalExporterContainer(true, emptyResources) + c.VolumeMounts = append(c.VolumeMounts, k8sutil.TlsKeyfileVolumeMount()) + return c + }(), + }, + RestartPolicy: core.RestartPolicyNever, + TerminationGracePeriodSeconds: &defaultDBServerTerminationTimeout, + Hostname: testDeploymentName + "-" + api.ServerGroupDBServersString + "-" + firstDBServerStatus.ID, + Subdomain: testDeploymentName + "-int", + Affinity: k8sutil.CreateAffinity(testDeploymentName, api.ServerGroupDBServersString, + true, ""), + }, + }, + }, + { + Name: "Coordinator Pod with TLS and authentication and readiness and liveness", + ArangoDeployment: &api.ArangoDeployment{ + Spec: api.DeploymentSpec{ + Image: util.NewString(testImage), + Authentication: authenticationSpec, + Environment: api.NewEnvironment(api.EnvironmentProduction), + TLS: api.TLSSpec{ + CASecretName: util.NewString(testCASecretName), + }, + }, + }, + Helper: func(t *testing.T, deployment *Deployment, testCase *testCaseStruct) { + deployment.status.last = api.DeploymentStatus{ + Members: api.DeploymentStatusMembers{ + Coordinators: api.MemberStatusList{ + firstCoordinatorStatus, + }, + }, + Images: createTestImages(false), + } + + testCase.createTestPodData(deployment, api.ServerGroupCoordinators, firstCoordinatorStatus) + + auth, err := createTestToken(deployment, testCase, []string{"/_admin/server/availability"}) + require.NoError(t, err) + + testCase.ExpectedPod.Spec.Containers[0].ReadinessProbe = createTestReadinessProbe(httpProbe, true, auth) + }, + ExpectedEvent: "member coordinator is created", + ExpectedPod: core.Pod{ + Spec: core.PodSpec{ + Volumes: []core.Volume{ + k8sutil.CreateVolumeEmptyDir(k8sutil.ArangodVolumeName), + createTestTLSVolume(api.ServerGroupCoordinatorsString, firstCoordinatorStatus.ID), + k8sutil.CreateVolumeWithSecret(k8sutil.ClusterJWTSecretVolumeName, testJWTSecretName), + }, + Containers: []core.Container{ + { + Name: k8sutil.ServerContainerName, + Image: testImage, + Command: createTestCommandForCoordinator(firstCoordinatorStatus.ID, true, true), + Ports: createTestPorts(), + ImagePullPolicy: core.PullIfNotPresent, + Resources: emptyResources, + SecurityContext: securityContext.NewSecurityContext(), + VolumeMounts: []core.VolumeMount{ + k8sutil.ArangodVolumeMount(), + k8sutil.TlsKeyfileVolumeMount(), + k8sutil.ClusterJWTVolumeMount(), + }, + }, + }, + RestartPolicy: core.RestartPolicyNever, + TerminationGracePeriodSeconds: &defaultCoordinatorTerminationTimeout, + Hostname: testDeploymentName + "-" + api.ServerGroupCoordinatorsString + "-" + firstCoordinatorStatus.ID, + Subdomain: testDeploymentName + "-int", + Affinity: k8sutil.CreateAffinity(testDeploymentName, api.ServerGroupCoordinatorsString, + true, ""), + }, + }, + }, + { + Name: "Single Pod with TLS and authentication and readiness and readiness", + ArangoDeployment: &api.ArangoDeployment{ + Spec: api.DeploymentSpec{ + Image: util.NewString(testImage), + Authentication: authenticationSpec, + TLS: api.TLSSpec{ + CASecretName: util.NewString(testCASecretName), + }, + }, + }, + Helper: func(t *testing.T, deployment *Deployment, testCase *testCaseStruct) { + deployment.status.last = api.DeploymentStatus{ + Members: api.DeploymentStatusMembers{ + Single: api.MemberStatusList{ + singleStatus, + }, + }, + Images: createTestImages(false), + } + + testCase.createTestPodData(deployment, api.ServerGroupSingle, singleStatus) + + authLiveness, err := createTestToken(deployment, testCase, []string{"/_api/version"}) + require.NoError(t, err) + + authReadiness, err := createTestToken(deployment, testCase, []string{"/_admin/server/availability"}) + require.NoError(t, err) + + testCase.ExpectedPod.Spec.Containers[0].LivenessProbe = createTestLivenessProbe(httpProbe, true, + authLiveness, 0) + testCase.ExpectedPod.Spec.Containers[0].ReadinessProbe = createTestReadinessProbe(httpProbe, true, authReadiness) + }, + ExpectedEvent: "member single is created", + ExpectedPod: core.Pod{ + Spec: core.PodSpec{ + Volumes: []core.Volume{ + k8sutil.CreateVolumeEmptyDir(k8sutil.ArangodVolumeName), + createTestTLSVolume(api.ServerGroupSingleString, singleStatus.ID), + k8sutil.CreateVolumeWithSecret(k8sutil.ClusterJWTSecretVolumeName, testJWTSecretName), + }, + Containers: []core.Container{ + { + Name: k8sutil.ServerContainerName, + Image: testImage, + Command: createTestCommandForSingleMode(true, true), + Ports: createTestPorts(), + ImagePullPolicy: core.PullIfNotPresent, + SecurityContext: securityContext.NewSecurityContext(), + VolumeMounts: []core.VolumeMount{ + k8sutil.ArangodVolumeMount(), + k8sutil.TlsKeyfileVolumeMount(), + k8sutil.ClusterJWTVolumeMount(), + }, + Resources: emptyResources, + }, + }, + RestartPolicy: core.RestartPolicyNever, + TerminationGracePeriodSeconds: &defaultSingleTerminationTimeout, + Hostname: testDeploymentName + "-" + api.ServerGroupSingleString + "-" + singleStatus.ID, + Subdomain: testDeploymentName + "-int", + Affinity: k8sutil.CreateAffinity(testDeploymentName, api.ServerGroupSingleString, + false, ""), + }, + }, + }, } runTestCases(t, testCases...) } -func testArangodbInternalExporterContainer(resources core.ResourceRequirements) core.Container { +func testArangodbInternalExporterContainer(secure bool, resources core.ResourceRequirements, port ...int32) core.Container { binaryPath, err := os.Executable() if err != nil { return core.Container{} } exePath := filepath.Join(k8sutil.LifecycleVolumeMountDir, filepath.Base(binaryPath)) - args := []string{ - "--arangodb.endpoint=http://localhost:8529/_admin/metrics", - "--arangodb.jwt-file=/secrets/exporter/jwt/token", + var args []string + if secure { + args = append(args, "--arangodb.endpoint=https://localhost:8529/_admin/metrics") + } else { + args = append(args, "--arangodb.endpoint=http://localhost:8529/_admin/metrics") + } + + args = append(args, "--arangodb.jwt-file=/secrets/exporter/jwt/token") + + var localPort int32 = k8sutil.ArangoExporterPort + if len(port) > 0 { + localPort = port[0] + } + + if localPort != k8sutil.ArangoExporterPort { + args = append(args, fmt.Sprintf("--server.address=:%d", localPort)) + } + + if secure { + args = append(args, "--ssl.keyfile=/secrets/tls/tls.keyfile") } return core.Container{ @@ -1457,11 +1475,11 @@ func testArangodbInternalExporterContainer(resources core.ResourceRequirements) Ports: []core.ContainerPort{ { Name: "exporter", - ContainerPort: k8sutil.ArangoExporterPort, + ContainerPort: localPort, Protocol: core.ProtocolTCP, }, }, - LivenessProbe: createTestExporterLivenessProbe(false), + LivenessProbe: createTestExporterLivenessProbe(secure), Resources: resources, ImagePullPolicy: core.PullIfNotPresent, SecurityContext: &core.SecurityContext{ diff --git a/pkg/deployment/deployment_encryption_test.go b/pkg/deployment/deployment_encryption_test.go index 62ee45ad0..33f5aeff2 100644 --- a/pkg/deployment/deployment_encryption_test.go +++ b/pkg/deployment/deployment_encryption_test.go @@ -1,7 +1,7 @@ // // DISCLAIMER // -// Copyright 2020 ArangoDB GmbH, Cologne, Germany +// Copyright 2020-2021 ArangoDB GmbH, Cologne, Germany // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ // Copyright holder is ArangoDB GmbH, Cologne, Germany // // Author Adam Janikowski +// Author Tomasz Mielech // package deployment @@ -26,16 +27,13 @@ import ( "fmt" "testing" - "github.com/arangodb/kube-arangodb/pkg/util/constants" - - "github.com/arangodb/kube-arangodb/pkg/util/k8sutil" - "github.com/stretchr/testify/require" - - "github.com/arangodb/kube-arangodb/pkg/util" + core "k8s.io/api/core/v1" api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1" - core "k8s.io/api/core/v1" + "github.com/arangodb/kube-arangodb/pkg/util" + "github.com/arangodb/kube-arangodb/pkg/util/constants" + "github.com/arangodb/kube-arangodb/pkg/util/k8sutil" ) func TestEnsurePod_ArangoDB_Encryption(t *testing.T) { @@ -184,7 +182,7 @@ func TestEnsurePod_ArangoDB_Encryption(t *testing.T) { Resources: emptyResources, }, func() core.Container { - c := testCreateExporterContainer(true, emptyResources) + c := testArangodbInternalExporterContainer(true, emptyResources) c.VolumeMounts = append(c.VolumeMounts, k8sutil.TlsKeyfileVolumeMount()) return c }(), diff --git a/pkg/deployment/deployment_metrics_test.go b/pkg/deployment/deployment_metrics_test.go index d1bbc7ce7..7ec3ad11d 100644 --- a/pkg/deployment/deployment_metrics_test.go +++ b/pkg/deployment/deployment_metrics_test.go @@ -1,7 +1,7 @@ // // DISCLAIMER // -// Copyright 2020 ArangoDB GmbH, Cologne, Germany +// Copyright 2020-2021 ArangoDB GmbH, Cologne, Germany // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ // Copyright holder is ArangoDB GmbH, Cologne, Germany // // Author Adam Janikowski +// Author Tomasz Mielech // package deployment @@ -25,12 +26,11 @@ package deployment import ( "testing" - "github.com/arangodb/kube-arangodb/pkg/util/k8sutil" - - "github.com/arangodb/kube-arangodb/pkg/util" + core "k8s.io/api/core/v1" api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1" - core "k8s.io/api/core/v1" + "github.com/arangodb/kube-arangodb/pkg/util" + "github.com/arangodb/kube-arangodb/pkg/util/k8sutil" ) func TestEnsurePod_Metrics(t *testing.T) { @@ -85,7 +85,7 @@ func TestEnsurePod_Metrics(t *testing.T) { ImagePullPolicy: core.PullIfNotPresent, SecurityContext: securityContext.NewSecurityContext(), }, - testCreateExporterContainerWithPort(false, emptyResources, 9999), + testArangodbInternalExporterContainer(false, emptyResources, 9999), }, RestartPolicy: core.RestartPolicyNever, TerminationGracePeriodSeconds: &defaultDBServerTerminationTimeout, @@ -146,7 +146,7 @@ func TestEnsurePod_Metrics(t *testing.T) { ImagePullPolicy: core.PullIfNotPresent, SecurityContext: securityContext.NewSecurityContext(), }, - testCreateExporterContainer(false, emptyResources), + testArangodbInternalExporterContainer(false, emptyResources), }, RestartPolicy: core.RestartPolicyNever, TerminationGracePeriodSeconds: &defaultDBServerTerminationTimeout, @@ -191,6 +191,7 @@ func TestEnsurePod_Metrics(t *testing.T) { Spec: core.PodSpec{ Volumes: []core.Volume{ k8sutil.CreateVolumeEmptyDir(k8sutil.ArangodVolumeName), + k8sutil.CreateVolumeWithSecret(k8sutil.ExporterJWTVolumeName, testExporterToken), }, Containers: []core.Container{ { @@ -216,6 +217,7 @@ func TestEnsurePod_Metrics(t *testing.T) { ImagePullPolicy: core.PullIfNotPresent, SecurityContext: securityContext.NewSecurityContext(), }, + testArangodbInternalExporterContainer(false, emptyResources), }, RestartPolicy: core.RestartPolicyNever, TerminationGracePeriodSeconds: &defaultDBServerTerminationTimeout, @@ -260,6 +262,7 @@ func TestEnsurePod_Metrics(t *testing.T) { Spec: core.PodSpec{ Volumes: []core.Volume{ k8sutil.CreateVolumeEmptyDir(k8sutil.ArangodVolumeName), + k8sutil.CreateVolumeWithSecret(k8sutil.ExporterJWTVolumeName, testExporterToken), }, Containers: []core.Container{ { @@ -285,286 +288,7 @@ func TestEnsurePod_Metrics(t *testing.T) { ImagePullPolicy: core.PullIfNotPresent, SecurityContext: securityContext.NewSecurityContext(), }, - }, - RestartPolicy: core.RestartPolicyNever, - TerminationGracePeriodSeconds: &defaultAgentTerminationTimeout, - Hostname: testDeploymentName + "-" + api.ServerGroupAgentsString + "-" + firstAgentStatus.ID, - Subdomain: testDeploymentName + "-int", - Affinity: k8sutil.CreateAffinity(testDeploymentName, api.ServerGroupAgentsString, - false, ""), - }, - }, - }, - { - Name: "DBserver Pod with sidecar metrics exporter and port override", - ArangoDeployment: &api.ArangoDeployment{ - Spec: api.DeploymentSpec{ - Image: util.NewString(testImage), - Authentication: noAuthentication, - TLS: noTLS, - Metrics: func() api.MetricsSpec { - m := metricsSpec.DeepCopy() - - m.Port = util.NewUInt16(9999) - - m.Mode = api.MetricsModeSidecar.New() - - return *m - }(), - }, - }, - Helper: func(t *testing.T, deployment *Deployment, testCase *testCaseStruct) { - deployment.status.last = api.DeploymentStatus{ - Members: api.DeploymentStatusMembers{ - DBServers: api.MemberStatusList{ - firstDBServerStatus, - }, - }, - Images: createTestImages(false), - } - - testCase.createTestPodData(deployment, api.ServerGroupDBServers, firstDBServerStatus) - testCase.ExpectedPod.ObjectMeta.Labels[k8sutil.LabelKeyArangoExporter] = testYes - }, - ExpectedEvent: "member dbserver is created", - ExpectedPod: core.Pod{ - Spec: core.PodSpec{ - Volumes: []core.Volume{ - k8sutil.CreateVolumeEmptyDir(k8sutil.ArangodVolumeName), - k8sutil.CreateVolumeWithSecret(k8sutil.ExporterJWTVolumeName, testExporterToken), - }, - Containers: []core.Container{ - { - Name: k8sutil.ServerContainerName, - Image: testImage, - Command: createTestCommandForDBServer(firstDBServerStatus.ID, false, false, false), - Ports: createTestPorts(), - VolumeMounts: []core.VolumeMount{ - k8sutil.ArangodVolumeMount(), - }, - Resources: emptyResources, - LivenessProbe: createTestLivenessProbe(httpProbe, false, "", k8sutil.ArangoPort), - ImagePullPolicy: core.PullIfNotPresent, - SecurityContext: securityContext.NewSecurityContext(), - }, - func() core.Container { - z := testCreateExporterContainerWithPort(false, emptyResources, 9999) - z.Command = append(z.Command, "--mode=passthru") - return z - }(), - }, - RestartPolicy: core.RestartPolicyNever, - TerminationGracePeriodSeconds: &defaultDBServerTerminationTimeout, - Hostname: testDeploymentName + "-" + api.ServerGroupDBServersString + "-" + firstDBServerStatus.ID, - Subdomain: testDeploymentName + "-int", - Affinity: k8sutil.CreateAffinity(testDeploymentName, api.ServerGroupDBServersString, - false, ""), - }, - }, - }, - { - Name: "Agency Pod with sidecar metrics exporter and port override", - ArangoDeployment: &api.ArangoDeployment{ - Spec: api.DeploymentSpec{ - Image: util.NewString(testImage), - Authentication: noAuthentication, - TLS: noTLS, - Metrics: func() api.MetricsSpec { - m := metricsSpec.DeepCopy() - - m.Port = util.NewUInt16(9999) - - m.Mode = api.MetricsModeSidecar.New() - - return *m - }(), - }, - }, - Helper: func(t *testing.T, deployment *Deployment, testCase *testCaseStruct) { - deployment.status.last = api.DeploymentStatus{ - Members: api.DeploymentStatusMembers{ - Agents: api.MemberStatusList{ - firstAgentStatus, - }, - }, - Images: createTestImages(false), - } - - testCase.createTestPodData(deployment, api.ServerGroupAgents, firstAgentStatus) - testCase.ExpectedPod.ObjectMeta.Labels[k8sutil.LabelKeyArangoExporter] = testYes - }, - ExpectedEvent: "member agent is created", - ExpectedPod: core.Pod{ - Spec: core.PodSpec{ - Volumes: []core.Volume{ - k8sutil.CreateVolumeEmptyDir(k8sutil.ArangodVolumeName), - k8sutil.CreateVolumeWithSecret(k8sutil.ExporterJWTVolumeName, testExporterToken), - }, - Containers: []core.Container{ - { - Name: k8sutil.ServerContainerName, - Image: testImage, - Command: createTestCommandForAgent(firstAgentStatus.ID, false, false, false), - Ports: createTestPorts(), - VolumeMounts: []core.VolumeMount{ - k8sutil.ArangodVolumeMount(), - }, - Resources: emptyResources, - LivenessProbe: createTestLivenessProbe(httpProbe, false, "", k8sutil.ArangoPort), - ImagePullPolicy: core.PullIfNotPresent, - SecurityContext: securityContext.NewSecurityContext(), - }, - func() core.Container { - z := testCreateExporterContainerWithPort(false, emptyResources, 9999) - z.Command = append(z.Command, "--mode=passthru") - return z - }(), - }, - RestartPolicy: core.RestartPolicyNever, - TerminationGracePeriodSeconds: &defaultAgentTerminationTimeout, - Hostname: testDeploymentName + "-" + api.ServerGroupAgentsString + "-" + firstAgentStatus.ID, - Subdomain: testDeploymentName + "-int", - Affinity: k8sutil.CreateAffinity(testDeploymentName, api.ServerGroupAgentsString, - false, ""), - }, - }, - }, - { - Name: "Agency Pod with sidecar metrics exporter and port override, with enabled deployment tls", - ArangoDeployment: &api.ArangoDeployment{ - Spec: api.DeploymentSpec{ - Image: util.NewString(testImage), - Authentication: noAuthentication, - TLS: tlsSpec, - Metrics: func() api.MetricsSpec { - m := metricsSpec.DeepCopy() - - m.Port = util.NewUInt16(9999) - - m.Mode = api.MetricsModeSidecar.New() - - return *m - }(), - }, - }, - Helper: func(t *testing.T, deployment *Deployment, testCase *testCaseStruct) { - deployment.status.last = api.DeploymentStatus{ - Members: api.DeploymentStatusMembers{ - Agents: api.MemberStatusList{ - firstAgentStatus, - }, - }, - Images: createTestImages(false), - } - - testCase.createTestPodData(deployment, api.ServerGroupAgents, firstAgentStatus) - testCase.ExpectedPod.ObjectMeta.Labels[k8sutil.LabelKeyArangoExporter] = testYes - }, - ExpectedEvent: "member agent is created", - ExpectedPod: core.Pod{ - Spec: core.PodSpec{ - Volumes: []core.Volume{ - k8sutil.CreateVolumeEmptyDir(k8sutil.ArangodVolumeName), - createTestTLSVolume(api.ServerGroupAgentsString, firstAgentStatus.ID), - k8sutil.CreateVolumeWithSecret(k8sutil.ExporterJWTVolumeName, testExporterToken), - }, - Containers: []core.Container{ - { - Name: k8sutil.ServerContainerName, - Image: testImage, - Command: createTestCommandForAgent(firstAgentStatus.ID, true, false, false), - Ports: createTestPorts(), - VolumeMounts: []core.VolumeMount{ - k8sutil.ArangodVolumeMount(), - k8sutil.TlsKeyfileVolumeMount(), - }, - Resources: emptyResources, - LivenessProbe: createTestLivenessProbe(httpProbe, true, "", k8sutil.ArangoPort), - ImagePullPolicy: core.PullIfNotPresent, - SecurityContext: securityContext.NewSecurityContext(), - }, - func() core.Container { - z := testCreateExporterContainerWithPortAndSecureEndpoint(true, true, emptyResources, 9999) - - z.VolumeMounts = append(z.VolumeMounts, k8sutil.TlsKeyfileVolumeMount()) - - z.Command = append(z.Command, "--mode=passthru") - return z - }(), - }, - RestartPolicy: core.RestartPolicyNever, - TerminationGracePeriodSeconds: &defaultAgentTerminationTimeout, - Hostname: testDeploymentName + "-" + api.ServerGroupAgentsString + "-" + firstAgentStatus.ID, - Subdomain: testDeploymentName + "-int", - Affinity: k8sutil.CreateAffinity(testDeploymentName, api.ServerGroupAgentsString, - false, ""), - }, - }, - }, - { - Name: "Agency Pod with sidecar metrics exporter and port override, with enabled deployment tls but disabled metrics tls", - ArangoDeployment: &api.ArangoDeployment{ - Spec: api.DeploymentSpec{ - Image: util.NewString(testImage), - Authentication: noAuthentication, - TLS: tlsSpec, - Metrics: func() api.MetricsSpec { - m := metricsSpec.DeepCopy() - - m.Port = util.NewUInt16(9999) - - m.Mode = api.MetricsModeSidecar.New() - - m.TLS = util.NewBool(false) - - return *m - }(), - }, - }, - Helper: func(t *testing.T, deployment *Deployment, testCase *testCaseStruct) { - deployment.status.last = api.DeploymentStatus{ - Members: api.DeploymentStatusMembers{ - Agents: api.MemberStatusList{ - firstAgentStatus, - }, - }, - Images: createTestImages(false), - } - - testCase.createTestPodData(deployment, api.ServerGroupAgents, firstAgentStatus) - testCase.ExpectedPod.ObjectMeta.Labels[k8sutil.LabelKeyArangoExporter] = testYes - }, - ExpectedEvent: "member agent is created", - ExpectedPod: core.Pod{ - Spec: core.PodSpec{ - Volumes: []core.Volume{ - k8sutil.CreateVolumeEmptyDir(k8sutil.ArangodVolumeName), - createTestTLSVolume(api.ServerGroupAgentsString, firstAgentStatus.ID), - k8sutil.CreateVolumeWithSecret(k8sutil.ExporterJWTVolumeName, testExporterToken), - }, - Containers: []core.Container{ - { - Name: k8sutil.ServerContainerName, - Image: testImage, - Command: createTestCommandForAgent(firstAgentStatus.ID, true, false, false), - Ports: createTestPorts(), - VolumeMounts: []core.VolumeMount{ - k8sutil.ArangodVolumeMount(), - k8sutil.TlsKeyfileVolumeMount(), - }, - Resources: emptyResources, - LivenessProbe: createTestLivenessProbe(httpProbe, true, "", k8sutil.ArangoPort), - ImagePullPolicy: core.PullIfNotPresent, - SecurityContext: securityContext.NewSecurityContext(), - }, - func() core.Container { - z := testCreateExporterContainerWithPortAndSecureEndpoint(true, false, emptyResources, 9999) - - z.VolumeMounts = append(z.VolumeMounts, k8sutil.TlsKeyfileVolumeMount()) - - z.Command = append(z.Command, "--mode=passthru") - return z - }(), + testArangodbInternalExporterContainer(false, emptyResources), }, RestartPolicy: core.RestartPolicyNever, TerminationGracePeriodSeconds: &defaultAgentTerminationTimeout, diff --git a/pkg/deployment/deployment_suite_test.go b/pkg/deployment/deployment_suite_test.go index 1cfbea446..354c488d5 100644 --- a/pkg/deployment/deployment_suite_test.go +++ b/pkg/deployment/deployment_suite_test.go @@ -607,29 +607,3 @@ func (testCase *testCaseStruct) createTestPodData(deployment *Deployment, group deployment.apiObject.Status.Members.Update(member, group) } } - -func testCreateExporterContainerWithPortAndSecureEndpoint(secure, exporterSecure bool, resources core.ResourceRequirements, port uint16) core.Container { - var securityContext api.ServerGroupSpecSecurityContext - - return core.Container{ - Name: k8sutil.ExporterContainerName, - Image: testExporterImage, - Command: createTestExporterCommand(secure, exporterSecure, port), - Ports: createTestExporterPorts(port), - VolumeMounts: []core.VolumeMount{ - k8sutil.ExporterJWTVolumeMount(), - }, - Resources: k8sutil.ExtractPodResourceRequirement(resources), - LivenessProbe: createTestExporterLivenessProbe(exporterSecure), - ImagePullPolicy: core.PullIfNotPresent, - SecurityContext: securityContext.NewSecurityContext(), - } -} - -func testCreateExporterContainerWithPort(secure bool, resources core.ResourceRequirements, port uint16) core.Container { - return testCreateExporterContainerWithPortAndSecureEndpoint(secure, secure, resources, port) -} - -func testCreateExporterContainer(secure bool, resources core.ResourceRequirements) core.Container { - return testCreateExporterContainerWithPortAndSecureEndpoint(secure, secure, resources, k8sutil.ArangoExporterPort) -} From 573836b4b55ab4b70fd1fd2bc961ec939e34cdbf Mon Sep 17 00:00:00 2001 From: Tomasz Mielech Date: Wed, 8 Sep 2021 06:45:10 +0200 Subject: [PATCH 4/6] fix linter --- pkg/deployment/deployment_core_test.go | 63 +++++++++++++------------ pkg/deployment/deployment_suite_test.go | 35 -------------- 2 files changed, 34 insertions(+), 64 deletions(-) diff --git a/pkg/deployment/deployment_core_test.go b/pkg/deployment/deployment_core_test.go index f49456758..18b16ed12 100644 --- a/pkg/deployment/deployment_core_test.go +++ b/pkg/deployment/deployment_core_test.go @@ -1439,43 +1439,21 @@ func TestEnsurePod_ArangoDB_Core(t *testing.T) { runTestCases(t, testCases...) } -func testArangodbInternalExporterContainer(secure bool, resources core.ResourceRequirements, port ...int32) core.Container { - binaryPath, err := os.Executable() - if err != nil { - return core.Container{} - } - exePath := filepath.Join(k8sutil.LifecycleVolumeMountDir, filepath.Base(binaryPath)) - - var args []string - if secure { - args = append(args, "--arangodb.endpoint=https://localhost:8529/_admin/metrics") - } else { - args = append(args, "--arangodb.endpoint=http://localhost:8529/_admin/metrics") - } +func testArangodbInternalExporterContainer(secure bool, resources core.ResourceRequirements, ports ...int32) core.Container { - args = append(args, "--arangodb.jwt-file=/secrets/exporter/jwt/token") - - var localPort int32 = k8sutil.ArangoExporterPort - if len(port) > 0 { - localPort = port[0] - } - - if localPort != k8sutil.ArangoExporterPort { - args = append(args, fmt.Sprintf("--server.address=:%d", localPort)) - } - - if secure { - args = append(args, "--ssl.keyfile=/secrets/tls/tls.keyfile") + var port int32 = k8sutil.ArangoExporterPort + if len(ports) > 0 { + port = ports[0] } return core.Container{ Name: k8sutil.ExporterContainerName, Image: testImage, - Command: append([]string{exePath, "exporter"}, args...), + Command: createTestInternalExporterCommand(secure, port), Ports: []core.ContainerPort{ { - Name: "exporter", - ContainerPort: localPort, + Name: string(api.MetricsModeExporter), + ContainerPort: port, Protocol: core.ProtocolTCP, }, }, @@ -1495,3 +1473,30 @@ func testArangodbInternalExporterContainer(secure bool, resources core.ResourceR }, } } + +func createTestInternalExporterCommand(secure bool, port int32) []string { + binaryPath, err := os.Executable() + if err != nil { + return []string{} + } + exePath := filepath.Join(k8sutil.LifecycleVolumeMountDir, filepath.Base(binaryPath)) + + args := []string{exePath, "exporter"} + if secure { + args = append(args, "--arangodb.endpoint=https://localhost:8529/_admin/metrics") + } else { + args = append(args, "--arangodb.endpoint=http://localhost:8529/_admin/metrics") + } + + args = append(args, "--arangodb.jwt-file=/secrets/exporter/jwt/token") + + if port != k8sutil.ArangoExporterPort { + args = append(args, fmt.Sprintf("--server.address=:%d", port)) + } + + if secure { + args = append(args, "--ssl.keyfile=/secrets/tls/tls.keyfile") + } + + return args +} diff --git a/pkg/deployment/deployment_suite_test.go b/pkg/deployment/deployment_suite_test.go index 354c488d5..507a8fca3 100644 --- a/pkg/deployment/deployment_suite_test.go +++ b/pkg/deployment/deployment_suite_test.go @@ -68,7 +68,6 @@ const ( testServiceAccountName = "testServiceAccountName" testPriorityClassName = "testPriority" testImageLifecycle = "arangodb/kube-arangodb:0.3.16" - testExporterImage = "arangodb/arangodb-exporter:0.1.6" testImageOperatorUUIDInit = "image/test-1234:3.7" testYes = "yes" @@ -516,40 +515,6 @@ func createTestImages(enterprise bool) api.ImageInfoList { return createTestImagesWithVersion(enterprise, testVersion) } -func createTestExporterPorts(port uint16) []core.ContainerPort { - return []core.ContainerPort{ - { - Name: "exporter", - ContainerPort: int32(port), - Protocol: "TCP", - }, - } -} - -func createTestExporterCommand(secure, exporterSecure bool, port uint16) []string { - command := []string{ - "/app/arangodb-exporter", - } - - if secure { - command = append(command, "--arangodb.endpoint=https://localhost:8529") - } else { - command = append(command, "--arangodb.endpoint=http://localhost:8529") - } - - command = append(command, "--arangodb.jwt-file=/secrets/exporter/jwt/token") - - if port != k8sutil.ArangoExporterPort { - command = append(command, fmt.Sprintf("--server.address=:%d", port)) - } - - if exporterSecure { - command = append(command, "--ssl.keyfile=/secrets/tls/tls.keyfile") - } - - return command -} - func createTestExporterLivenessProbe(secure bool) *core.Probe { return probes.HTTPProbeConfig{ LocalPath: "/", From 86f05b235c6619d2ae33a1576347f276b49c13ed Mon Sep 17 00:00:00 2001 From: Tomasz Mielech Date: Fri, 10 Sep 2021 10:52:56 +0200 Subject: [PATCH 5/6] Add changelog --- CHANGELOG.md | 1 + pkg/deployment/deployment_core_test.go | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d7d254a9c..d20d54a3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - Fix ArangoSync Liveness Prove - Allow runtime update of Sidecar images - Allow Agent recreation with preserved IDs +- The internal metrics exporter can not be disabled ## [1.2.2](https://github.com/arangodb/kube-arangodb/tree/1.2.2) (2021-09-09) - Update 'github.com/arangodb/arangosync-client' dependency to v0.7.0 diff --git a/pkg/deployment/deployment_core_test.go b/pkg/deployment/deployment_core_test.go index 18b16ed12..61aff3877 100644 --- a/pkg/deployment/deployment_core_test.go +++ b/pkg/deployment/deployment_core_test.go @@ -893,7 +893,7 @@ func TestEnsurePod_ArangoDB_Core(t *testing.T) { }, }, { - Name: "Agent Pod can not have metrics exporter", // TODO + Name: "Agent Pod can not have metrics exporter", ArangoDeployment: &api.ArangoDeployment{ Spec: api.DeploymentSpec{ Image: util.NewString(testImage), From 61ba73f90350e1243825e612fb47b0f1b3c713eb Mon Sep 17 00:00:00 2001 From: Tomasz Mielech Date: Tue, 14 Sep 2021 08:10:46 +0200 Subject: [PATCH 6/6] typo --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d20d54a3f..9cca89cf2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## [master](https://github.com/arangodb/kube-arangodb/tree/master) (N/A) - Update UBI Image to 8.4 -- Fix ArangoSync Liveness Prove +- Fix ArangoSync Liveness Probe - Allow runtime update of Sidecar images - Allow Agent recreation with preserved IDs - The internal metrics exporter can not be disabled