Skip to content

Commit

Permalink
[controller] continuously reconcile configmaps (#118)
Browse files Browse the repository at this point in the history
Now that we have a default template for configmaps that we construct for
users, we should continuously reconcile it. This will allow us to roll
out new config for M3DB over time and know that users' clusters will
pick up our changes.

This logic doesn't trigger if the user has a custom configmap.
  • Loading branch information
schallert authored Apr 8, 2019
1 parent 4531661 commit 72037d8
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 7 deletions.
45 changes: 42 additions & 3 deletions pkg/controller/add_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,17 @@ package controller
import (
"errors"
"fmt"
"reflect"

myspec "github.com/m3db/m3db-operator/pkg/apis/m3dboperator/v1alpha1"
"github.com/m3db/m3db-operator/pkg/k8sops"
"github.com/m3db/m3db-operator/pkg/util/eventer"

corev1 "k8s.io/api/core/v1"
kerrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"go.uber.org/zap"
)

var (
Expand Down Expand Up @@ -75,14 +79,49 @@ func (c *Controller) ensureConfigMap(cluster *myspec.M3DBCluster) error {
return nil
}

cm, err := k8sops.GenerateDefaultConfigMap(cluster)
wantCM, err := k8sops.GenerateDefaultConfigMap(cluster)
if err != nil {
return err
}

_, err = c.kubeClient.CoreV1().ConfigMaps(cluster.Namespace).Create(cm)
if kerrors.IsAlreadyExists(err) {
cmClient := c.kubeClient.CoreV1().ConfigMaps(cluster.Namespace)

// Check if there is a configmap that exists. If so, overwrite it with the
// current templated out config. Otherwise, create one.
cm, err := cmClient.Get(wantCM.Name, metav1.GetOptions{})
if err != nil {
if !kerrors.IsNotFound(err) {
return err
}

// If the config doesn't exist, create it.
_, err := cmClient.Create(wantCM)
return err
}

// Make a copy of the configmap to not corrupt cache.
cm = cm.DeepCopy()

// Found an existing config map, check if we need to update its contents.
if reflect.DeepEqual(cm.Data, wantCM.Data) {
c.logger.Debug("config maps equal, nothing to do",
zap.String("namespace", cluster.Namespace),
zap.String("cluster", cluster.Name),
)
return nil
}

cm.Data = wantCM.Data
_, err = cmClient.Update(cm)
if err != nil {
c.logger.Error("error updating configmap", zap.Error(err))
} else {
c.logger.Info("updated configmap data",
zap.String("namespace", cluster.Namespace),
zap.String("cluster", cluster.Name),
zap.String("configmap", cm.Name),
)
}

return err
}
30 changes: 26 additions & 4 deletions pkg/controller/add_cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import (
"github.com/stretchr/testify/require"
)

func registerValidConfigMap() error {
func registerValidConfigMap(content string) error {
sw := &strings.Builder{}
zw := zip.NewWriter(sw)

Expand All @@ -42,7 +42,7 @@ func registerValidConfigMap() error {
if err != nil {
return err
}
_, err = fw.Write([]byte("my_config_data"))
_, err = fw.Write([]byte(content))
if err != nil {
return err
}
Expand Down Expand Up @@ -79,10 +79,9 @@ func TestEnsureConfigMap(t *testing.T) {
deps := newTestDeps(t, &testOpts{})
defer deps.cleanup()

require.NoError(t, registerValidConfigMap())
require.NoError(t, registerValidConfigMap("my_config_data"))

controller := deps.newController()

err := controller.ensureConfigMap(cluster)
assert.NoError(t, err)

Expand All @@ -97,3 +96,26 @@ func TestEnsureConfigMap(t *testing.T) {
err = controller.ensureConfigMap(cluster)
assert.Equal(t, errEmptyConfigMap, err)
}

func TestEnsureConfigMap_Update(t *testing.T) {
cluster := getFixture("cluster-simple.yaml", t)
deps := newTestDeps(t, &testOpts{})
defer deps.cleanup()

require.NoError(t, registerValidConfigMap("my_config_data"))

controller := deps.newController()

err := controller.ensureConfigMap(cluster)
assert.NoError(t, err)

// Change configmap data, expect to see changes reflected.
require.NoError(t, registerValidConfigMap("new_config_data"))

err = controller.ensureConfigMap(cluster)
assert.NoError(t, err)

cm, err := deps.kubeClient.CoreV1().ConfigMaps(cluster.Namespace).Get("m3db-config-map-cluster-simple", metav1.GetOptions{})
require.NoError(t, err)
assert.Equal(t, "new_config_data", cm.Data["m3.yml"])
}

0 comments on commit 72037d8

Please sign in to comment.