From c1ae7e6377c6c2fb5e98be0ab833884c440f584e Mon Sep 17 00:00:00 2001 From: John Sanda Date: Tue, 27 Apr 2021 00:14:51 -0400 Subject: [PATCH 1/3] remove reaper sidecar integration --- .../v1beta1/cassandradatacenter_types.go | 7 - operator/pkg/images/images.go | 6 - .../construct_podtemplatespec.go | 17 -- .../construct_podtemplatespec_test.go | 73 +----- operator/pkg/reconciliation/constructor.go | 44 ---- .../pkg/reconciliation/reconcile_racks.go | 9 +- .../pkg/reconciliation/reconcile_reaper.go | 209 ------------------ .../reconciliation/reconcile_reaper_test.go | 153 ------------- .../enable_reaper/enable_reaper_suite_test.go | 108 --------- 9 files changed, 3 insertions(+), 623 deletions(-) delete mode 100644 operator/pkg/reconciliation/reconcile_reaper.go delete mode 100644 operator/pkg/reconciliation/reconcile_reaper_test.go delete mode 100644 tests/enable_reaper/enable_reaper_suite_test.go diff --git a/operator/pkg/apis/cassandra/v1beta1/cassandradatacenter_types.go b/operator/pkg/apis/cassandra/v1beta1/cassandradatacenter_types.go index 33e831be2..3b4f4ccf5 100644 --- a/operator/pkg/apis/cassandra/v1beta1/cassandradatacenter_types.go +++ b/operator/pkg/apis/cassandra/v1beta1/cassandradatacenter_types.go @@ -457,13 +457,6 @@ func (dc *CassandraDatacenter) GetRackLabels(rackName string) map[string]string return labels } -func (dc *CassandraDatacenter) IsReaperEnabled() bool { - if dc.Spec.Reaper != nil && dc.Spec.Reaper.Enabled && dc.Spec.ServerType == "cassandra" { - return true - } - return false -} - func (status *CassandraDatacenterStatus) GetConditionStatus(conditionType DatacenterConditionType) corev1.ConditionStatus { for _, condition := range status.Conditions { if condition.Type == conditionType { diff --git a/operator/pkg/images/images.go b/operator/pkg/images/images.go index 6ec782f9d..98395ead6 100644 --- a/operator/pkg/images/images.go +++ b/operator/pkg/images/images.go @@ -69,7 +69,6 @@ const ( UBIConfigBuilder BusyBox - Reaper BaseImageOS SystemLoggerImage @@ -104,7 +103,6 @@ var imageLookupMap map[Image]string = map[Image]string{ UBIConfigBuilder: "datastax/cass-config-builder:1.0.3-ubi7", BusyBox: "busybox:1.32.0-uclibc", - Reaper: "thelastpickle/cassandra-reaper:2.0.5", SystemLoggerImage: "k8ssandra/system-logger:latest", } @@ -271,10 +269,6 @@ func GetConfigBuilderImage() string { } } -func GetReaperImage() string { - return GetImage(Reaper) -} - func GetSystemLoggerImage() string { return GetImage(SystemLoggerImage) } diff --git a/operator/pkg/reconciliation/construct_podtemplatespec.go b/operator/pkg/reconciliation/construct_podtemplatespec.go index a4d49a9fe..79f652492 100644 --- a/operator/pkg/reconciliation/construct_podtemplatespec.go +++ b/operator/pkg/reconciliation/construct_podtemplatespec.go @@ -328,11 +328,9 @@ func buildContainers(dc *api.CassandraDatacenter, baseTemplate *corev1.PodTempla cassContainer := &corev1.Container{} loggerContainer := &corev1.Container{} - reaperContainer := &corev1.Container{} foundCass := false foundLogger := false - foundReaper := false for i, c := range baseTemplate.Spec.Containers { if c.Name == CassandraContainerName { foundCass = true @@ -340,9 +338,6 @@ func buildContainers(dc *api.CassandraDatacenter, baseTemplate *corev1.PodTempla } else if c.Name == SystemLoggerContainerName { foundLogger = true loggerContainer = &baseTemplate.Spec.Containers[i] - } else if c.Name == ReaperContainerName { - foundReaper = true - reaperContainer = &baseTemplate.Spec.Containers[i] } } @@ -462,12 +457,6 @@ func buildContainers(dc *api.CassandraDatacenter, baseTemplate *corev1.PodTempla loggerContainer.Resources = *getResourcesOrDefault(&dc.Spec.SystemLoggerResources, &DefaultsLoggerContainer) - // Reaper Container - - if dc.IsReaperEnabled() { - buildReaperContainer(dc, reaperContainer) - } - // Note that append() can make copies of each element, // so we call it after modifying any existing elements. @@ -481,12 +470,6 @@ func buildContainers(dc *api.CassandraDatacenter, baseTemplate *corev1.PodTempla } } - if dc.IsReaperEnabled() { - if !foundReaper { - baseTemplate.Spec.Containers = append(baseTemplate.Spec.Containers, *reaperContainer) - } - } - return nil } diff --git a/operator/pkg/reconciliation/construct_podtemplatespec_test.go b/operator/pkg/reconciliation/construct_podtemplatespec_test.go index 3b83b0bb1..f9d57c0db 100644 --- a/operator/pkg/reconciliation/construct_podtemplatespec_test.go +++ b/operator/pkg/reconciliation/construct_podtemplatespec_test.go @@ -203,72 +203,12 @@ func TestCassandraDatacenter_buildContainers_systemlogger_resources_set_when_not } } -func TestCassandraDatacenter_buildContainers_reaper_resources(t *testing.T) { - dc := &api.CassandraDatacenter{ - Spec: api.CassandraDatacenterSpec{ - ClusterName: "bob", - ServerType: "cassandra", - ServerVersion: "3.11.7", - Reaper: &api.ReaperConfig{ - Enabled: true, - Resources: corev1.ResourceRequirements{ - Limits: corev1.ResourceList{ - "cpu": *resource.NewMilliQuantity(1, resource.DecimalSI), - "memory": *resource.NewScaledQuantity(1, resource.Giga), - }, - Requests: corev1.ResourceList{ - "cpu": *resource.NewMilliQuantity(1, resource.DecimalSI), - "memory": *resource.NewScaledQuantity(1, resource.Giga), - }, - }, - }, - }, - } - - podTemplateSpec := &corev1.PodTemplateSpec{} - err := buildContainers(dc, podTemplateSpec) - containers := podTemplateSpec.Spec.Containers - assert.NotNil(t, containers, "Unexpected containers containers received") - assert.Nil(t, err, "Unexpected error encountered") - - assert.Len(t, containers, 3, "Unexpected number of containers containers returned") - assert.Equal(t, containers[2].Resources, dc.Spec.Reaper.Resources, - "reaper container resources have unexpected values.") -} - -func TestCassandraDatacenter_buildContainers_reaper_resources_set_when_not_specified(t *testing.T) { - dc := &api.CassandraDatacenter{ - Spec: api.CassandraDatacenterSpec{ - ClusterName: "bob", - ServerType: "cassandra", - ServerVersion: "3.11.7", - Reaper: &api.ReaperConfig{ - Enabled: true, - }, - }, - } - - podTemplateSpec := &corev1.PodTemplateSpec{} - err := buildContainers(dc, podTemplateSpec) - containers := podTemplateSpec.Spec.Containers - assert.NotNil(t, containers, "Unexpected containers containers received") - assert.Nil(t, err, "Unexpected error encountered") - - assert.Len(t, containers, 3, "Unexpected number of containers containers returned") - if !reflect.DeepEqual(containers[2].Resources, DefaultsReaperContainer) { - t.Error("reaper container resources are not set to the default values.") - } -} - func TestCassandraDatacenter_buildContainers_use_cassandra_settings(t *testing.T) { dc := &api.CassandraDatacenter{ Spec: api.CassandraDatacenterSpec{ ClusterName: "bob", ServerType: "cassandra", ServerVersion: "3.11.7", - Reaper: &api.ReaperConfig{ - Enabled: true, - }, }, } @@ -290,10 +230,7 @@ func TestCassandraDatacenter_buildContainers_use_cassandra_settings(t *testing.T assert.NotNil(t, containers, "Unexpected containers containers received") assert.Nil(t, err, "Unexpected error encountered") - assert.Len(t, containers, 3, "Unexpected number of containers containers returned") - if !reflect.DeepEqual(containers[2].Resources, DefaultsReaperContainer) { - t.Error("reaper container resources are not set to the default values.") - } + assert.Len(t, containers, 2, "Unexpected number of containers containers returned") if !reflect.DeepEqual(containers[0].Env[0].Name, "k1") { t.Errorf("Unexpected env vars allocated for the cassandra container: %v", containers[0].Env) @@ -306,9 +243,6 @@ func TestCassandraDatacenter_buildContainers_override_other_containers(t *testin ClusterName: "bob", ServerType: "cassandra", ServerVersion: "3.11.7", - Reaper: &api.ReaperConfig{ - Enabled: true, - }, }, } @@ -333,10 +267,7 @@ func TestCassandraDatacenter_buildContainers_override_other_containers(t *testin assert.NotNil(t, containers, "Unexpected containers containers received") assert.Nil(t, err, "Unexpected error encountered") - assert.Len(t, containers, 3, "Unexpected number of containers containers returned") - if !reflect.DeepEqual(containers[2].Resources, DefaultsReaperContainer) { - t.Error("reaper container resources are not set to the default values.") - } + assert.Len(t, containers, 2, "Unexpected number of containers containers returned") if !reflect.DeepEqual(containers[0].VolumeMounts, []corev1.VolumeMount{ diff --git a/operator/pkg/reconciliation/constructor.go b/operator/pkg/reconciliation/constructor.go index c766f41b1..79d553b0d 100644 --- a/operator/pkg/reconciliation/constructor.go +++ b/operator/pkg/reconciliation/constructor.go @@ -10,8 +10,6 @@ import ( "github.com/k8ssandra/cass-operator/operator/pkg/oplabels" "github.com/k8ssandra/cass-operator/operator/pkg/utils" - batchv1 "k8s.io/api/batch/v1" - corev1 "k8s.io/api/core/v1" policyv1beta1 "k8s.io/api/policy/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" @@ -65,45 +63,3 @@ func setOperatorProgressStatus(rc *ReconciliationContext, newState api.ProgressS return nil } - -func buildInitReaperSchemaJob(dc *api.CassandraDatacenter) *batchv1.Job { - return &batchv1.Job{ - TypeMeta: metav1.TypeMeta{ - Kind: "Job", - APIVersion: "batch/v1", - }, - ObjectMeta: metav1.ObjectMeta{ - Namespace: dc.Namespace, - Name: getReaperSchemaInitJobName(dc), - Labels: dc.GetDatacenterLabels(), - }, - Spec: batchv1.JobSpec{ - Template: corev1.PodTemplateSpec{ - Spec: corev1.PodSpec{ - RestartPolicy: corev1.RestartPolicyOnFailure, - Containers: []corev1.Container{ - { - Name: getReaperSchemaInitJobName(dc), - Image: ReaperSchemaInitJobImage, - ImagePullPolicy: corev1.PullIfNotPresent, - Env: []corev1.EnvVar{ - { - Name: "KEYSPACE", - Value: ReaperKeyspace, - }, - { - Name: "CONTACT_POINTS", - Value: dc.GetSeedServiceName(), - }, - { - Name: "REPLICATION", - Value: getReaperReplication(dc), - }, - }, - }, - }, - }, - }, - }, - } -} diff --git a/operator/pkg/reconciliation/reconcile_racks.go b/operator/pkg/reconciliation/reconcile_racks.go index d554f03ee..f9eaea083 100644 --- a/operator/pkg/reconciliation/reconcile_racks.go +++ b/operator/pkg/reconciliation/reconcile_racks.go @@ -26,8 +26,8 @@ import ( "github.com/k8ssandra/cass-operator/operator/pkg/events" "github.com/k8ssandra/cass-operator/operator/pkg/httphelper" "github.com/k8ssandra/cass-operator/operator/pkg/oplabels" - "github.com/k8ssandra/cass-operator/operator/pkg/utils" "github.com/k8ssandra/cass-operator/operator/pkg/psp" + "github.com/k8ssandra/cass-operator/operator/pkg/utils" ) var ( @@ -2318,13 +2318,6 @@ func (rc *ReconciliationContext) ReconcileAllRacks() (reconcile.Result, error) { return recResult.Output() } - if recResult := rc.CheckReaperService(); recResult.Completed() { - return recResult.Output() - } - - if recResult := rc.CheckReaperSchemaInitialized(); recResult.Completed() { - return recResult.Output() - } if recResult := rc.CheckRollingRestart(); recResult.Completed() { return recResult.Output() diff --git a/operator/pkg/reconciliation/reconcile_reaper.go b/operator/pkg/reconciliation/reconcile_reaper.go deleted file mode 100644 index 80a6eee32..000000000 --- a/operator/pkg/reconciliation/reconcile_reaper.go +++ /dev/null @@ -1,209 +0,0 @@ -// Copyright DataStax, Inc. -// Please see the included license file for details. - -package reconciliation - -import ( - "fmt" - "math" - "strconv" - - v1batch "k8s.io/api/batch/v1" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/intstr" - - "github.com/k8ssandra/cass-operator/operator/internal/result" - api "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1" - "github.com/k8ssandra/cass-operator/operator/pkg/images" -) - -const ( - ReaperUIPort = 7080 - ReaperAdminPort = 7081 - ReaperDefaultPullPolicy = corev1.PullIfNotPresent - ReaperContainerName = "reaper" - ReaperHealthCheckPath = "/healthcheck" - ReaperKeyspace = "reaper_db" - ReaperSchemaInitJob = "ReaperSchemaInitJob" - // This code currently lives at https://github.com/jsanda/create_keyspace. - ReaperSchemaInitJobImage = "jsanda/reaper-init-keyspace:latest" -) - -// We are passing in container by reference because the user may have already provided a -// reaper container with desired settings in CassandraDatacenter.Spec.PodTemplateSpec. -// Therefore we will simply fill-in any missing defaults inside of buildReaperContainer. -// TODO: provide more unit testing for building reaper containers. -func buildReaperContainer(dc *api.CassandraDatacenter, container *corev1.Container) { - - ports := []corev1.ContainerPort{ - {Name: "ui", ContainerPort: ReaperUIPort, Protocol: "TCP"}, - {Name: "admin", ContainerPort: ReaperAdminPort, Protocol: "TCP"}, - } - - container.Name = ReaperContainerName - container.Image = getReaperImage(dc) - container.ImagePullPolicy = getReaperPullPolicy(dc) - - container.Ports = combinePortSlices(ports, container.Ports) - - if container.LivenessProbe == nil { - container.LivenessProbe = probe(ReaperAdminPort, ReaperHealthCheckPath, int(60*dc.Spec.Size), 10) - } - - if container.ReadinessProbe == nil { - container.ReadinessProbe = probe(ReaperAdminPort, ReaperHealthCheckPath, 30, 15) - } - - envDefaults := []corev1.EnvVar{ - {Name: "REAPER_STORAGE_TYPE", Value: "cassandra"}, - {Name: "REAPER_ENABLE_DYNAMIC_SEED_LIST", Value: "false"}, - {Name: "REAPER_DATACENTER_AVAILABILITY", Value: "SIDECAR"}, - {Name: "REAPER_SERVER_APP_PORT", Value: strconv.Itoa(ReaperUIPort)}, - {Name: "REAPER_SERVER_ADMIN_PORT", Value: strconv.Itoa(ReaperAdminPort)}, - {Name: "REAPER_CASS_CLUSTER_NAME", Value: dc.ClusterName}, - {Name: "REAPER_CASS_CONTACT_POINTS", Value: fmt.Sprintf("[%s]", dc.GetSeedServiceName())}, - {Name: "REAPER_AUTH_ENABLED", Value: "false"}, - {Name: "REAPER_JMX_AUTH_USERNAME", Value: ""}, - {Name: "REAPER_JMX_AUTH_PASSWORD", Value: ""}, - } - - container.Env = combineEnvSlices(envDefaults, container.Env) - - container.Resources = *getResourcesOrDefault(&dc.Spec.Reaper.Resources, &DefaultsReaperContainer) -} - -func getReaperImage(dc *api.CassandraDatacenter) string { - if len(dc.Spec.Reaper.Image) == 0 { - return images.GetReaperImage() - } - return dc.Spec.Reaper.Image -} - -func getReaperPullPolicy(dc *api.CassandraDatacenter) corev1.PullPolicy { - if len(dc.Spec.Reaper.ImagePullPolicy) == 0 { - return ReaperDefaultPullPolicy - } - return dc.Spec.Reaper.ImagePullPolicy -} - -func (rc *ReconciliationContext) CheckReaperSchemaInitialized() result.ReconcileResult { - // Using a job eventually get replaced with calls to the mgmt api once it has support for - // creating keyspaces and tables. - - rc.ReqLogger.Info("reconcile_reaper::CheckReaperSchemaInitialized") - - if rc.Datacenter.Spec.Reaper == nil || !rc.Datacenter.Spec.Reaper.Enabled { - return result.Continue() - } - - jobName := getReaperSchemaInitJobName(rc.Datacenter) - schemaJob := &v1batch.Job{} - - err := rc.Client.Get(rc.Ctx, types.NamespacedName{Namespace: rc.Datacenter.Namespace, Name: jobName}, schemaJob) - if err != nil && errors.IsNotFound(err) { - // Create the job - schemaJob := buildInitReaperSchemaJob(rc.Datacenter) - rc.ReqLogger.Info("creating Reaper schema init job", ReaperSchemaInitJob, schemaJob.Name) - if err := setControllerReference(rc.Datacenter, schemaJob, rc.Scheme); err != nil { - rc.ReqLogger.Error(err, "failed to set owner reference", ReaperSchemaInitJob, schemaJob.Name) - return result.Error(err) - } - if err := rc.Client.Create(rc.Ctx, schemaJob); err != nil { - rc.ReqLogger.Error(err, "failed to create job", ReaperSchemaInitJob, schemaJob.Name) - return result.Error(err) - } else { - return result.RequeueSoon(2) - } - } else if err != nil { - return result.Error(err) - } else if jobFinished(schemaJob) { - return result.Continue() - } else { - return result.RequeueSoon(2) - } -} - -func getReaperSchemaInitJobName(dc *api.CassandraDatacenter) string { - return fmt.Sprintf("%s-reaper-init-schema", dc.Spec.ClusterName) -} - -func getReaperReplication(dc *api.CassandraDatacenter) string { - replicationFactor := int(math.Min(float64(dc.Spec.Size), 3)) - return fmt.Sprintf("{'class': 'NetworkTopologyStrategy', '%s': %d}", dc.Name, replicationFactor) -} - -func jobFinished(job *v1batch.Job) bool { - for _, c := range job.Status.Conditions { - if (c.Type == v1batch.JobComplete || c.Type == v1batch.JobFailed) && c.Status == corev1.ConditionTrue { - return true - } - } - return false -} - -func (rc *ReconciliationContext) CheckReaperService() result.ReconcileResult { - rc.ReqLogger.Info("reconcile_reaper::CheckReaperService") - - serviceName := getReaperServiceName(rc.Datacenter) - service := &corev1.Service{} - - err := rc.Client.Get(rc.Ctx, types.NamespacedName{Namespace: rc.Datacenter.Namespace, Name: serviceName}, service) - if err != nil && errors.IsNotFound(err) { - if rc.Datacenter.Spec.Reaper != nil && rc.Datacenter.Spec.Reaper.Enabled { - // Create the service - service = newReaperService(rc.Datacenter) - rc.ReqLogger.Info("creating Reaper service") - if err := setControllerReference(rc.Datacenter, service, rc.Scheme); err != nil { - rc.ReqLogger.Error(err, "failed to set owner reference", "ReaperService", serviceName) - return result.Error(err) - } - if err := rc.Client.Create(rc.Ctx, service); err != nil { - rc.ReqLogger.Error(err, "failed to create Reaper service") - return result.Error(err) - } - return result.Continue() - } - } else if err != nil { - return result.Error(err) - } else if rc.Datacenter.Spec.Reaper == nil || !rc.Datacenter.Spec.Reaper.Enabled { - if err := rc.Client.Delete(rc.Ctx, service); err != nil { - rc.ReqLogger.Error(err, "failed to delete Reaper service", "ReaperService", serviceName) - } - } - return result.Continue() -} - -func getReaperServiceName(dc *api.CassandraDatacenter) string { - return fmt.Sprintf("%s-reaper-service", dc.Spec.ClusterName) -} - -func newReaperService(dc *api.CassandraDatacenter) *corev1.Service { - return &corev1.Service{ - TypeMeta: metav1.TypeMeta{ - Kind: "Service", - APIVersion: "v1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: getReaperServiceName(dc), - Namespace: dc.Namespace, - Labels: dc.GetDatacenterLabels(), - }, - Spec: corev1.ServiceSpec{ - Ports: []corev1.ServicePort{ - { - Port: ReaperUIPort, - Name: "ui", - Protocol: corev1.ProtocolTCP, - TargetPort: intstr.IntOrString{ - Type: intstr.String, - StrVal: "ui", - }, - }, - }, - Selector: dc.GetDatacenterLabels(), - }, - } -} diff --git a/operator/pkg/reconciliation/reconcile_reaper_test.go b/operator/pkg/reconciliation/reconcile_reaper_test.go deleted file mode 100644 index 5a8f9e4d4..000000000 --- a/operator/pkg/reconciliation/reconcile_reaper_test.go +++ /dev/null @@ -1,153 +0,0 @@ -package reconciliation - -import ( - "testing" - - api "github.com/k8ssandra/cass-operator/operator/pkg/apis/cassandra/v1beta1" - "github.com/stretchr/testify/assert" - v1batch "k8s.io/api/batch/v1" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client/fake" -) - -func TestReconcileReaper_buildInitReaperSchemaJob(t *testing.T) { - dc := newCassandraDatacenter() - job := buildInitReaperSchemaJob(dc) - - assert.Equal(t, getReaperSchemaInitJobName(dc), job.Name) - assert.Equal(t, dc.GetDatacenterLabels(), job.Labels) - - assert.Equal(t, 1, len(job.Spec.Template.Spec.Containers)) - container := job.Spec.Template.Spec.Containers[0] - - assert.Equal(t, ReaperSchemaInitJobImage, container.Image) - - expectedEnvVars := []corev1.EnvVar{ - {Name: "KEYSPACE", Value: ReaperKeyspace}, - {Name: "CONTACT_POINTS", Value: dc.GetSeedServiceName()}, - {Name: "REPLICATION", Value: "{'class': 'NetworkTopologyStrategy', 'ReaperSchemaJobTest': 3}"}, - } - assert.ElementsMatch(t, expectedEnvVars, container.Env) -} - -func TestReconcileReaper_newReaperService(t *testing.T) { - dc := newCassandraDatacenter() - service := newReaperService(dc) - - assert.Equal(t, getReaperServiceName(dc), service.Name) - assert.Equal(t, dc.GetDatacenterLabels(), service.Labels) - assert.Equal(t, 1, len(service.Spec.Ports)) - - port := service.Spec.Ports[0] - assert.Equal(t, int32(ReaperUIPort), port.Port) - assert.Equal(t, dc.GetDatacenterLabels(), service.Spec.Selector) -} - -func TestReconcileReaper_CheckReaperSchemaInitialized(t *testing.T) { - rc, _, cleanupMockScr := setupTest() - rc.Datacenter.Spec.Reaper = &api.ReaperConfig{Enabled: true} - defer cleanupMockScr() - - trackObjects := []runtime.Object{rc.Datacenter} - - rc.Client = fake.NewFakeClient(trackObjects...) - - reconcileResult := rc.CheckReaperSchemaInitialized() - assert.True(t, reconcileResult.Completed()) - - result, err := reconcileResult.Output() - - assert.NoError(t, err) - assert.True(t, result.Requeue, "should requeue request") - - job := &v1batch.Job{} - jobName := getReaperSchemaInitJobName(rc.Datacenter) - err = rc.Client.Get(rc.Ctx, types.NamespacedName{Namespace: rc.Datacenter.Namespace, Name: jobName}, job) - - assert.NoErrorf(t, err, "failed to get job %s", jobName) -} - -func TestReconcileReaper_CheckReaperSchemaNotInitialized(t *testing.T) { - rc, _, cleanupMockScr := setupTest() - defer cleanupMockScr() - - trackObjects := []runtime.Object{rc.Datacenter} - - rc.Client = fake.NewFakeClient(trackObjects...) - - reconcileResult := rc.CheckReaperSchemaInitialized() - assert.False(t, reconcileResult.Completed()) - - job := &v1batch.Job{} - jobName := getReaperSchemaInitJobName(rc.Datacenter) - err := rc.Client.Get(rc.Ctx, types.NamespacedName{Namespace: rc.Datacenter.Namespace, Name: jobName}, job) - - assert.True(t, errors.IsNotFound(err), "did not expect to find job %s", jobName) -} - -func TestReconcileReaper_CheckReaperService(t *testing.T) { - rc, _, cleanupMockScr := setupTest() - defer cleanupMockScr() - - rc.Datacenter.Spec.Reaper = &api.ReaperConfig{Enabled: true} - - trackObjects := []runtime.Object{rc.Datacenter} - - rc.Client = fake.NewFakeClient(trackObjects...) - - reconcileResult := rc.CheckReaperService() - assert.False(t, reconcileResult.Completed()) - - service := &corev1.Service{} - serviceName := getReaperServiceName(rc.Datacenter) - err := rc.Client.Get(rc.Ctx, types.NamespacedName{Namespace: rc.Datacenter.Namespace, Name: serviceName}, service) - - assert.NoErrorf(t, err, "failed to get service %s", serviceName) -} - -func TestReconcileReaper_CheckReaperServiceReaperDisabled(t *testing.T) { - rc, _, cleanupMockScr := setupTest() - defer cleanupMockScr() - - serviceName := getReaperServiceName(rc.Datacenter) - service := &corev1.Service{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: rc.Datacenter.Namespace, - Name: serviceName, - }, - } - - trackObjects := []runtime.Object{rc.Datacenter, service} - - rc.Client = fake.NewFakeClient(trackObjects...) - - reconcileResult := rc.CheckReaperService() - assert.False(t, reconcileResult.Completed()) - - err := rc.Client.Get(rc.Ctx, types.NamespacedName{Namespace: rc.Datacenter.Namespace, Name: serviceName}, service) - - assert.True(t, errors.IsNotFound(err), "did not expect to find service %s", serviceName) -} - -func newCassandraDatacenter() *api.CassandraDatacenter { - return &api.CassandraDatacenter{ - ObjectMeta: metav1.ObjectMeta{ - Name: "ReaperSchemaJobTest", - Namespace: "reaper", - Labels: map[string]string{ - api.DatacenterLabel: "ReaperSchemaJobTest", - api.ClusterLabel: "reaper", - }, - }, - Spec: api.CassandraDatacenterSpec{ - Size: 6, - ClusterName: "reaper", - ServerType: "Cassandra", - ServerVersion: "3.11.7", - }, - } -} diff --git a/tests/enable_reaper/enable_reaper_suite_test.go b/tests/enable_reaper/enable_reaper_suite_test.go deleted file mode 100644 index adc84d1d5..000000000 --- a/tests/enable_reaper/enable_reaper_suite_test.go +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright DataStax, Inc. -// Please see the included license file for details. - -package enable_reaper - -import ( - "fmt" - "testing" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - - corev1 "k8s.io/api/core/v1" - - ginkgo_util "github.com/k8ssandra/cass-operator/mage/ginkgo" - "github.com/k8ssandra/cass-operator/mage/kubectl" -) - -var ( - testName = "Enable Reaper" - namespace = "test-enable-reaper" - dcName = "dc1" - dcYaml = "../testdata/oss-three-rack-three-node-dc.yaml" - operatorYaml = "../testdata/operator.yaml" - dcResource = fmt.Sprintf("CassandraDatacenter/%s", dcName) - dcLabel = fmt.Sprintf("cassandra.datastax.com/datacenter=%s", dcName) - ns = ginkgo_util.NewWrapper(testName, namespace) -) - -func TestLifecycle(t *testing.T) { - AfterSuite(func() { - logPath := fmt.Sprintf("%s/aftersuite", ns.LogDir) - kubectl.DumpAllLogs(logPath).ExecV() - fmt.Printf("\n\tPost-run logs dumped at: %s\n\n", logPath) - ns.Terminate() - }) - - RegisterFailHandler(Fail) - RunSpecs(t, testName) -} - -var _ = Describe(testName, func() { - Context("when in a new cluster", func() { - Specify("the operator can scale up and enable Reaper and then disable Reaper", func() { - By("creating a namespace") - err := kubectl.CreateNamespace(namespace).ExecV() - Expect(err).ToNot(HaveOccurred()) - - step := "setting up cass-operator resources via helm chart" - ns.HelmInstall("../../charts/cass-operator-chart") - - ns.WaitForOperatorReady() - - step = "creating a datacenter resource with 3 racks/3 nodes" - k := kubectl.ApplyFiles(dcYaml) - ns.ExecAndLog(step, k) - - ns.WaitForSuperUserUpserted(dcName, 600) - - step = "check recorded host IDs" - nodeStatusesHostIds := ns.GetNodeStatusesHostIds(dcName) - Expect(len(nodeStatusesHostIds), 3) - - ns.WaitForDatacenterReady(dcName) - ns.WaitForDatacenterCondition(dcName, "Ready", string(corev1.ConditionTrue)) - ns.WaitForDatacenterCondition(dcName, "Initialized", string(corev1.ConditionTrue)) - - step = "enable Reaper" - json := `{"spec": {"reaper": {"enabled": true}}}` - k = kubectl.PatchMerge(dcResource, json) - ns.ExecAndLog(step, k) - - ns.WaitForDatacenterOperatorProgress(dcName, "Updating", 120) - ns.WaitForDatacenterOperatorProgress(dcName, "Ready", 1200) - - step = "check that Reaper container is deployed" - json = `jsonpath={.items[*].spec.containers[?(@.name=="reaper")].name}` - k = kubectl.Get("pods"). - FormatOutput(json) - ns.WaitForOutputAndLog(step, k, "reaper reaper reaper", 20) - - step = "disable Reaper" - json = `{"spec": {"reaper": {"enabled": false}}}` - k = kubectl.PatchMerge(dcResource, json) - ns.ExecAndLog(step, k) - - ns.WaitForDatacenterOperatorProgress(dcName, "Updating", 120) - ns.WaitForDatacenterOperatorProgress(dcName, "Ready", 1200) - - step = "check that Reaper container is not deployed" - json = `jsonpath={.items[*].spec.containers[?(@.name=="reaper")]}` - k = kubectl.Get("pods"). - FormatOutput(json) - ns.WaitForOutputAndLog(step, k, "", 20) - - step = "deleting the dc" - k = kubectl.DeleteFromFiles(dcYaml) - ns.ExecAndLog(step, k) - - step = "checking that the dc no longer exists" - json = "jsonpath={.items}" - k = kubectl.Get("CassandraDatacenter"). - WithLabel(dcLabel). - FormatOutput(json) - ns.WaitForOutputAndLog(step, k, "[]", 300) - }) - }) -}) From 479dafdad04f1d62d2fc11ef09899ff47eb2c05b Mon Sep 17 00:00:00 2001 From: John Sanda Date: Tue, 27 Apr 2021 10:33:03 -0400 Subject: [PATCH 2/3] add deprecation doc --- .../pkg/apis/cassandra/v1beta1/cassandradatacenter_types.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/operator/pkg/apis/cassandra/v1beta1/cassandradatacenter_types.go b/operator/pkg/apis/cassandra/v1beta1/cassandradatacenter_types.go index 3b4f4ccf5..9deb8efd9 100644 --- a/operator/pkg/apis/cassandra/v1beta1/cassandradatacenter_types.go +++ b/operator/pkg/apis/cassandra/v1beta1/cassandradatacenter_types.go @@ -174,6 +174,11 @@ type CassandraDatacenterSpec struct { AdditionalSeeds []string `json:"additionalSeeds,omitempty"` + // Deprecated: Reaper's sidecar mode has too many problems in Kubernetes for it to + // usable. In order for it to work reliably, changes in Reaper would be needed. See + // https://github.com/thelastpickle/cassandra-reaper/issues/956 for details. Because + // those changes were not implemented in Reaper and because Reaper support was instead + // added through k8ssandra, this field will be removed in the 1.8.0 release. Reaper *ReaperConfig `json:"reaper,omitempty"` // Configuration for disabling the simple log tailing sidecar container. Our default is to have it enabled. From f249c230e3429486a3d858fe38eeffcb2d1d1828 Mon Sep 17 00:00:00 2001 From: John Sanda Date: Wed, 28 Apr 2021 00:22:31 -0400 Subject: [PATCH 3/3] update CRD --- .../templates/customresourcedefinition.yaml | 6 ++++++ .../cassandra.datastax.com_cassandradatacenters_crd.yaml | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/charts/cass-operator-chart/templates/customresourcedefinition.yaml b/charts/cass-operator-chart/templates/customresourcedefinition.yaml index 044529a9a..c3aa671c6 100644 --- a/charts/cass-operator-chart/templates/customresourcedefinition.yaml +++ b/charts/cass-operator-chart/templates/customresourcedefinition.yaml @@ -6024,6 +6024,12 @@ spec: type: object type: array reaper: + description: 'Deprecated: Reaper''s sidecar mode has too many problems + in Kubernetes for it to usable. In order for it to work reliably, + changes in Reaper would be needed. See https://github.com/thelastpickle/cassandra-reaper/issues/956 + for details. Because those changes were not implemented in Reaper + and because Reaper support was instead added through k8ssandra, this + field will be removed in the 1.8.0 release.' properties: enabled: type: boolean diff --git a/operator/deploy/crds/cassandra.datastax.com_cassandradatacenters_crd.yaml b/operator/deploy/crds/cassandra.datastax.com_cassandradatacenters_crd.yaml index 0f4aa7f04..47dc1d94b 100644 --- a/operator/deploy/crds/cassandra.datastax.com_cassandradatacenters_crd.yaml +++ b/operator/deploy/crds/cassandra.datastax.com_cassandradatacenters_crd.yaml @@ -6036,6 +6036,12 @@ spec: type: object type: array reaper: + description: 'Deprecated: Reaper''s sidecar mode has too many problems + in Kubernetes for it to usable. In order for it to work reliably, + changes in Reaper would be needed. See https://github.com/thelastpickle/cassandra-reaper/issues/956 + for details. Because those changes were not implemented in Reaper + and because Reaper support was instead added through k8ssandra, this + field will be removed in the 1.8.0 release.' properties: enabled: type: boolean