mirror of
https://github.com/arangodb/kube-arangodb.git
synced 2024-12-14 11:57:37 +00:00
481 lines
18 KiB
Go
481 lines
18 KiB
Go
//
|
|
// DISCLAIMER
|
|
//
|
|
// Copyright 2016-2022 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.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
//
|
|
// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
|
//
|
|
|
|
package deployment
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"github.com/arangodb/kube-arangodb/pkg/util/errors"
|
|
|
|
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
|
|
"github.com/arangodb/kube-arangodb/pkg/util"
|
|
"github.com/arangodb/kube-arangodb/pkg/util/constants"
|
|
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
|
|
|
|
"github.com/arangodb/kube-arangodb/pkg/apis/shared"
|
|
"github.com/stretchr/testify/require"
|
|
core "k8s.io/api/core/v1"
|
|
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
)
|
|
|
|
func TestEnsurePod_Sync_Error(t *testing.T) {
|
|
testCases := []testCaseStruct{
|
|
{
|
|
Name: "Sync Pod does not work for enterprise image",
|
|
ArangoDeployment: &api.ArangoDeployment{
|
|
Spec: api.DeploymentSpec{
|
|
Image: util.NewString(testImage),
|
|
},
|
|
},
|
|
Helper: func(t *testing.T, deployment *Deployment, testCase *testCaseStruct) {
|
|
deployment.status.last = api.DeploymentStatus{
|
|
Members: api.DeploymentStatusMembers{
|
|
SyncMasters: api.MemberStatusList{
|
|
firstSyncMaster,
|
|
},
|
|
},
|
|
Images: createTestImages(false),
|
|
}
|
|
},
|
|
ExpectedError: errors.New("Image '" + testImage + "' does not contain an Enterprise version of ArangoDB"),
|
|
},
|
|
{
|
|
Name: "Sync Pod cannot get master JWT secret",
|
|
ArangoDeployment: &api.ArangoDeployment{
|
|
Spec: api.DeploymentSpec{
|
|
Image: util.NewString(testImage),
|
|
},
|
|
},
|
|
Helper: func(t *testing.T, deployment *Deployment, testCase *testCaseStruct) {
|
|
deployment.status.last = api.DeploymentStatus{
|
|
Members: api.DeploymentStatusMembers{
|
|
SyncMasters: api.MemberStatusList{
|
|
firstSyncMaster,
|
|
},
|
|
},
|
|
Images: createTestImages(true),
|
|
}
|
|
},
|
|
ExpectedError: errors.New("Master JWT secret validation failed: secrets \"" +
|
|
testDeploymentName + "-sync-jwt\" not found"),
|
|
},
|
|
{
|
|
Name: "Sync Pod cannot get monitoring token secret",
|
|
ArangoDeployment: &api.ArangoDeployment{
|
|
Spec: api.DeploymentSpec{
|
|
Image: util.NewString(testImage),
|
|
Sync: api.SyncSpec{
|
|
Enabled: util.NewBool(true),
|
|
},
|
|
},
|
|
},
|
|
Helper: func(t *testing.T, deployment *Deployment, testCase *testCaseStruct) {
|
|
deployment.status.last = api.DeploymentStatus{
|
|
Members: api.DeploymentStatusMembers{
|
|
SyncMasters: api.MemberStatusList{
|
|
firstSyncMaster,
|
|
},
|
|
},
|
|
Images: createTestImages(true),
|
|
}
|
|
|
|
secretName := testCase.ArangoDeployment.Spec.Sync.Monitoring.GetTokenSecretName()
|
|
err := deployment.SecretsModInterface().Delete(context.Background(), secretName, meta.DeleteOptions{})
|
|
require.NoError(t, err)
|
|
},
|
|
ExpectedError: errors.New("Monitoring token secret validation failed: secrets \"" +
|
|
testDeploymentName + "-sync-mt\" not found"),
|
|
},
|
|
}
|
|
|
|
runTestCases(t, testCases...)
|
|
}
|
|
|
|
func TestEnsurePod_Sync_Master(t *testing.T) {
|
|
testCases := []testCaseStruct{
|
|
{
|
|
Name: "Sync Master Pod cannot create TLS keyfile secret",
|
|
ArangoDeployment: &api.ArangoDeployment{
|
|
Spec: api.DeploymentSpec{
|
|
Image: util.NewString(testImage),
|
|
Sync: api.SyncSpec{
|
|
Enabled: util.NewBool(true),
|
|
},
|
|
},
|
|
},
|
|
Helper: func(t *testing.T, deployment *Deployment, testCase *testCaseStruct) {
|
|
deployment.status.last = api.DeploymentStatus{
|
|
Members: api.DeploymentStatusMembers{
|
|
SyncMasters: api.MemberStatusList{
|
|
firstSyncMaster,
|
|
},
|
|
},
|
|
Images: createTestImages(true),
|
|
}
|
|
|
|
secretName := testCase.ArangoDeployment.Spec.Sync.TLS.GetCASecretName()
|
|
err := deployment.SecretsModInterface().Delete(context.Background(), secretName, meta.DeleteOptions{})
|
|
require.NoError(t, err)
|
|
},
|
|
ExpectedError: errors.New("Failed to create TLS keyfile secret: secrets \"" +
|
|
testDeploymentName + "-sync-ca\" not found"),
|
|
},
|
|
{
|
|
Name: "Sync Master Pod cannot get cluster JWT secret",
|
|
ArangoDeployment: &api.ArangoDeployment{
|
|
Spec: api.DeploymentSpec{
|
|
Image: util.NewString(testImage),
|
|
Authentication: authenticationSpec,
|
|
Sync: api.SyncSpec{
|
|
Enabled: util.NewBool(true),
|
|
},
|
|
},
|
|
},
|
|
Helper: func(t *testing.T, deployment *Deployment, testCase *testCaseStruct) {
|
|
deployment.status.last = api.DeploymentStatus{
|
|
Members: api.DeploymentStatusMembers{
|
|
SyncMasters: api.MemberStatusList{
|
|
firstSyncMaster,
|
|
},
|
|
},
|
|
Images: createTestImages(true),
|
|
}
|
|
|
|
secretName := testCase.ArangoDeployment.Spec.Authentication.GetJWTSecretName()
|
|
err := deployment.SecretsModInterface().Delete(context.Background(), secretName, meta.DeleteOptions{})
|
|
require.NoError(t, err)
|
|
},
|
|
ExpectedError: errors.New("Cluster JWT secret validation failed: secrets \"" +
|
|
testJWTSecretName + "\" not found"),
|
|
},
|
|
{
|
|
Name: "Sync Master Pod cannot get authentication CA certificate",
|
|
ArangoDeployment: &api.ArangoDeployment{
|
|
Spec: api.DeploymentSpec{
|
|
Image: util.NewString(testImage),
|
|
Authentication: authenticationSpec,
|
|
Sync: api.SyncSpec{
|
|
Enabled: util.NewBool(true),
|
|
},
|
|
},
|
|
},
|
|
Helper: func(t *testing.T, deployment *Deployment, testCase *testCaseStruct) {
|
|
deployment.status.last = api.DeploymentStatus{
|
|
Members: api.DeploymentStatusMembers{
|
|
SyncMasters: api.MemberStatusList{
|
|
firstSyncMaster,
|
|
},
|
|
},
|
|
Images: createTestImages(true),
|
|
}
|
|
|
|
secretName := testCase.ArangoDeployment.Spec.Sync.Authentication.GetClientCASecretName()
|
|
err := deployment.SecretsModInterface().Delete(context.Background(), secretName, meta.DeleteOptions{})
|
|
require.NoError(t, err)
|
|
},
|
|
ExpectedError: errors.New("Client authentication CA certificate secret validation failed: " +
|
|
"secrets \"" + testDeploymentName + "-sync-client-auth-ca\" not found"),
|
|
},
|
|
{
|
|
DropInit: true,
|
|
Name: "Sync Master Pod with authentication, monitoring, tls, service account, node selector, " +
|
|
"liveness probe, priority class name, resource requirements",
|
|
ArangoDeployment: &api.ArangoDeployment{
|
|
Spec: api.DeploymentSpec{
|
|
Image: util.NewString(testImage),
|
|
Authentication: authenticationSpec,
|
|
Sync: api.SyncSpec{
|
|
Enabled: util.NewBool(true),
|
|
},
|
|
SyncMasters: api.ServerGroupSpec{
|
|
ServiceAccountName: util.NewString(testServiceAccountName),
|
|
NodeSelector: nodeSelectorTest,
|
|
PriorityClassName: testPriorityClassName,
|
|
Resources: resourcesUnfiltered,
|
|
},
|
|
},
|
|
},
|
|
Helper: func(t *testing.T, deployment *Deployment, testCase *testCaseStruct) {
|
|
deployment.status.last = api.DeploymentStatus{
|
|
Members: api.DeploymentStatusMembers{
|
|
SyncMasters: api.MemberStatusList{
|
|
firstSyncMaster,
|
|
},
|
|
},
|
|
Images: createTestImages(true),
|
|
}
|
|
|
|
testCase.createTestPodData(deployment, api.ServerGroupSyncMasters, firstSyncMaster)
|
|
|
|
name := testCase.ArangoDeployment.Spec.Sync.Monitoring.GetTokenSecretName()
|
|
auth, err := k8sutil.GetTokenSecret(context.Background(), deployment.GetCachedStatus().Secret().V1().Read(), name)
|
|
require.NoError(t, err)
|
|
|
|
testCase.ExpectedPod.Spec.Containers[0].LivenessProbe = createTestLivenessProbe(
|
|
"", true, "bearer "+auth, shared.ArangoSyncMasterPort)
|
|
},
|
|
ExpectedEvent: "member syncmaster is created",
|
|
ExpectedPod: core.Pod{
|
|
Spec: core.PodSpec{
|
|
Volumes: []core.Volume{
|
|
k8sutil.LifecycleVolume(),
|
|
createTestTLSVolume(api.ServerGroupSyncMastersString, firstSyncMaster.ID),
|
|
k8sutil.CreateVolumeWithSecret(shared.ClientAuthCAVolumeName, "test-sync-client-auth-ca"),
|
|
k8sutil.CreateVolumeWithSecret(shared.MasterJWTSecretVolumeName, "test-sync-jwt"),
|
|
k8sutil.CreateVolumeWithSecret(shared.ClusterJWTSecretVolumeName, testJWTSecretName),
|
|
},
|
|
InitContainers: []core.Container{
|
|
createTestLifecycleContainer(emptyResources),
|
|
},
|
|
Containers: []core.Container{
|
|
{
|
|
Name: shared.ServerContainerName,
|
|
Image: testImage,
|
|
Command: createTestCommandForSyncMaster(firstSyncMaster.ID, true, true, true),
|
|
Ports: createTestPorts(),
|
|
Env: []core.EnvVar{
|
|
k8sutil.CreateEnvSecretKeySelector(constants.EnvArangoSyncMonitoringToken,
|
|
testDeploymentName+"-sync-mt", 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"),
|
|
},
|
|
ImagePullPolicy: core.PullIfNotPresent,
|
|
Lifecycle: createTestLifecycle(api.ServerGroupSyncMasters),
|
|
Resources: resourcesUnfiltered,
|
|
SecurityContext: securityContext.NewSecurityContext(),
|
|
VolumeMounts: []core.VolumeMount{
|
|
k8sutil.LifecycleVolumeMount(),
|
|
k8sutil.TlsKeyfileVolumeMount(),
|
|
k8sutil.ClientAuthCACertificateVolumeMount(),
|
|
k8sutil.MasterJWTVolumeMount(),
|
|
k8sutil.ClusterJWTVolumeMount(),
|
|
},
|
|
},
|
|
},
|
|
PriorityClassName: testPriorityClassName,
|
|
RestartPolicy: core.RestartPolicyNever,
|
|
ServiceAccountName: testServiceAccountName,
|
|
NodeSelector: nodeSelectorTest,
|
|
TerminationGracePeriodSeconds: &defaultSyncMasterTerminationTimeout,
|
|
Hostname: testDeploymentName + "-" + api.ServerGroupSyncMastersString + "-" +
|
|
firstSyncMaster.ID,
|
|
Subdomain: testDeploymentName + "-int",
|
|
Affinity: k8sutil.CreateAffinity(testDeploymentName, api.ServerGroupSyncMastersString,
|
|
false, ""),
|
|
},
|
|
},
|
|
},
|
|
{
|
|
DropInit: true,
|
|
Name: "Sync Master Pod with lifecycle, license, monitoring without authentication and alpine",
|
|
config: Config{
|
|
OperatorImage: testImageOperator,
|
|
},
|
|
ArangoDeployment: &api.ArangoDeployment{
|
|
Spec: api.DeploymentSpec{
|
|
Image: util.NewString(testImage),
|
|
Authentication: noAuthentication,
|
|
Environment: api.NewEnvironment(api.EnvironmentProduction),
|
|
Sync: api.SyncSpec{
|
|
Enabled: util.NewBool(true),
|
|
},
|
|
License: api.LicenseSpec{
|
|
SecretName: util.NewString(testLicense),
|
|
},
|
|
},
|
|
},
|
|
Helper: func(t *testing.T, deployment *Deployment, testCase *testCaseStruct) {
|
|
deployment.status.last = api.DeploymentStatus{
|
|
Members: api.DeploymentStatusMembers{
|
|
SyncMasters: api.MemberStatusList{
|
|
firstSyncMaster,
|
|
},
|
|
},
|
|
Images: createTestImages(true),
|
|
}
|
|
|
|
testCase.createTestPodData(deployment, api.ServerGroupSyncMasters, firstSyncMaster)
|
|
name := testCase.ArangoDeployment.Spec.Sync.Monitoring.GetTokenSecretName()
|
|
auth, err := k8sutil.GetTokenSecret(context.Background(), deployment.GetCachedStatus().Secret().V1().Read(), name)
|
|
require.NoError(t, err)
|
|
|
|
testCase.ExpectedPod.Spec.Containers[0].LivenessProbe = createTestLivenessProbe(
|
|
"", true, "bearer "+auth, shared.ArangoSyncMasterPort)
|
|
},
|
|
ExpectedEvent: "member syncmaster is created",
|
|
ExpectedPod: core.Pod{
|
|
Spec: core.PodSpec{
|
|
Volumes: []core.Volume{
|
|
k8sutil.LifecycleVolume(),
|
|
createTestTLSVolume(api.ServerGroupSyncMastersString, firstSyncMaster.ID),
|
|
k8sutil.CreateVolumeWithSecret(shared.ClientAuthCAVolumeName,
|
|
testDeploymentName+"-sync-client-auth-ca"),
|
|
k8sutil.CreateVolumeWithSecret(shared.MasterJWTSecretVolumeName,
|
|
testDeploymentName+"-sync-jwt"),
|
|
},
|
|
InitContainers: []core.Container{
|
|
createTestLifecycleContainer(emptyResources),
|
|
},
|
|
Containers: []core.Container{
|
|
{
|
|
Name: shared.ServerContainerName,
|
|
Image: testImage,
|
|
Command: createTestCommandForSyncMaster(firstSyncMaster.ID, true, false, true),
|
|
Ports: createTestPorts(),
|
|
Env: []core.EnvVar{
|
|
k8sutil.CreateEnvSecretKeySelector(constants.EnvArangoSyncMonitoringToken,
|
|
testDeploymentName+"-sync-mt", constants.SecretKeyToken),
|
|
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"),
|
|
},
|
|
Resources: emptyResources,
|
|
ImagePullPolicy: core.PullIfNotPresent,
|
|
Lifecycle: createTestLifecycle(api.ServerGroupSyncMasters),
|
|
SecurityContext: securityContext.NewSecurityContext(),
|
|
VolumeMounts: []core.VolumeMount{
|
|
k8sutil.LifecycleVolumeMount(),
|
|
k8sutil.TlsKeyfileVolumeMount(),
|
|
k8sutil.ClientAuthCACertificateVolumeMount(),
|
|
k8sutil.MasterJWTVolumeMount(),
|
|
},
|
|
},
|
|
},
|
|
RestartPolicy: core.RestartPolicyNever,
|
|
TerminationGracePeriodSeconds: &defaultSyncMasterTerminationTimeout,
|
|
Hostname: testDeploymentName + "-" + api.ServerGroupSyncMastersString + "-" +
|
|
firstSyncMaster.ID,
|
|
Subdomain: testDeploymentName + "-int",
|
|
Affinity: k8sutil.CreateAffinity(testDeploymentName, api.ServerGroupSyncMastersString,
|
|
true, ""),
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
runTestCases(t, testCases...)
|
|
}
|
|
|
|
func TestEnsurePod_Sync_Worker(t *testing.T) {
|
|
testCases := []testCaseStruct{
|
|
{
|
|
DropInit: true,
|
|
Name: "Sync Worker Pod with monitoring, service account, node selector, lifecycle, license " +
|
|
"liveness probe, priority class name, resource requirements without alpine",
|
|
config: Config{
|
|
OperatorImage: testImageOperator,
|
|
},
|
|
ArangoDeployment: &api.ArangoDeployment{
|
|
Spec: api.DeploymentSpec{
|
|
Image: util.NewString(testImage),
|
|
Authentication: noAuthentication,
|
|
Sync: api.SyncSpec{
|
|
Enabled: util.NewBool(true),
|
|
},
|
|
SyncWorkers: api.ServerGroupSpec{
|
|
ServiceAccountName: util.NewString(testServiceAccountName),
|
|
NodeSelector: nodeSelectorTest,
|
|
PriorityClassName: testPriorityClassName,
|
|
Resources: resourcesUnfiltered,
|
|
},
|
|
License: api.LicenseSpec{
|
|
SecretName: util.NewString(testLicense),
|
|
},
|
|
},
|
|
},
|
|
Helper: func(t *testing.T, deployment *Deployment, testCase *testCaseStruct) {
|
|
deployment.status.last = api.DeploymentStatus{
|
|
Members: api.DeploymentStatusMembers{
|
|
SyncWorkers: api.MemberStatusList{
|
|
firstSyncWorker,
|
|
},
|
|
},
|
|
Images: createTestImages(true),
|
|
}
|
|
|
|
testCase.createTestPodData(deployment, api.ServerGroupSyncWorkers, firstSyncWorker)
|
|
|
|
name := testCase.ArangoDeployment.Spec.Sync.Monitoring.GetTokenSecretName()
|
|
auth, err := k8sutil.GetTokenSecret(context.Background(), deployment.GetCachedStatus().Secret().V1().Read(), name)
|
|
require.NoError(t, err)
|
|
|
|
testCase.ExpectedPod.Spec.Containers[0].LivenessProbe = createTestLivenessProbe(
|
|
"", true, "bearer "+auth, shared.ArangoSyncWorkerPort)
|
|
},
|
|
ExpectedEvent: "member syncworker is created",
|
|
ExpectedPod: core.Pod{
|
|
Spec: core.PodSpec{
|
|
Volumes: []core.Volume{
|
|
k8sutil.LifecycleVolume(),
|
|
k8sutil.CreateVolumeWithSecret(shared.MasterJWTSecretVolumeName, testDeploymentName+"-sync-jwt"),
|
|
},
|
|
InitContainers: []core.Container{
|
|
createTestLifecycleContainer(emptyResources),
|
|
},
|
|
Containers: []core.Container{
|
|
{
|
|
Name: shared.ServerContainerName,
|
|
Image: testImage,
|
|
Command: createTestCommandForSyncWorker(firstSyncWorker.ID, true, true),
|
|
Ports: createTestPorts(),
|
|
Env: []core.EnvVar{
|
|
k8sutil.CreateEnvSecretKeySelector(constants.EnvArangoSyncMonitoringToken,
|
|
testDeploymentName+"-sync-mt", constants.SecretKeyToken),
|
|
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"),
|
|
},
|
|
ImagePullPolicy: core.PullIfNotPresent,
|
|
Lifecycle: createTestLifecycle(api.ServerGroupSyncMasters),
|
|
Resources: k8sutil.ExtractPodResourceRequirement(resourcesUnfiltered),
|
|
SecurityContext: securityContext.NewSecurityContext(),
|
|
VolumeMounts: []core.VolumeMount{
|
|
k8sutil.LifecycleVolumeMount(),
|
|
k8sutil.MasterJWTVolumeMount(),
|
|
},
|
|
},
|
|
},
|
|
PriorityClassName: testPriorityClassName,
|
|
RestartPolicy: core.RestartPolicyNever,
|
|
ServiceAccountName: testServiceAccountName,
|
|
NodeSelector: nodeSelectorTest,
|
|
TerminationGracePeriodSeconds: &defaultSyncWorkerTerminationTimeout,
|
|
Hostname: testDeploymentName + "-" + api.ServerGroupSyncWorkersString + "-" +
|
|
firstSyncWorker.ID,
|
|
Subdomain: testDeploymentName + "-int",
|
|
Affinity: k8sutil.CreateAffinity(testDeploymentName, api.ServerGroupSyncWorkersString,
|
|
false, api.ServerGroupDBServersString),
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
runTestCases(t, testCases...)
|
|
}
|