Skip to content

Commit

Permalink
Inline manifestsSaver into the Calico component
Browse files Browse the repository at this point in the history
Adjust the tests to use temporary directories and let them call all the
lifecycle methods.

Signed-off-by: Tom Wieczorek <[email protected]>
  • Loading branch information
twz123 committed Oct 2, 2024
1 parent 716f601 commit cb8ea7b
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 52 deletions.
11 changes: 1 addition & 10 deletions cmd/controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -455,16 +455,7 @@ func (c *command) start(ctx context.Context) error {

if !slices.Contains(c.DisableComponents, constant.NetworkProviderComponentName) {
logrus.Infof("Creating network reconcilers")

calicoSaver, err := controller.NewManifestsSaver("calico", c.K0sVars.DataDir)
if err != nil {
return fmt.Errorf("failed to create calico manifests saver: %w", err)
}
calicoInitSaver, err := controller.NewManifestsSaver("calico_init", c.K0sVars.DataDir)
if err != nil {
return fmt.Errorf("failed to create calico_init manifests saver: %w", err)
}
clusterComponents.Add(ctx, controller.NewCalico(c.K0sVars, calicoInitSaver, calicoSaver))
clusterComponents.Add(ctx, controller.NewCalico(c.K0sVars))
if !slices.Contains(c.DisableComponents, constant.WindowsNodeComponentName) {
clusterComponents.Add(ctx, controller.NewWindowsStackComponent(c.K0sVars, adminClientFactory))
}
Expand Down
32 changes: 19 additions & 13 deletions pkg/component/controller/calico.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package controller
import (
"bytes"
"context"
"errors"
"fmt"
"io/fs"
"path"
Expand All @@ -36,6 +37,8 @@ import (

"github.com/sirupsen/logrus"

"github.com/k0sproject/k0s/internal/pkg/dir"
"github.com/k0sproject/k0s/internal/pkg/file"
"github.com/k0sproject/k0s/internal/pkg/templatewriter"
)

Expand All @@ -49,8 +52,6 @@ var calicoCRDOnce sync.Once
type Calico struct {
log logrus.FieldLogger

crdSaver manifestsSaver
saver manifestsSaver
prevConfig calicoConfig
k0sVars *config.CfgVars
}
Expand Down Expand Up @@ -88,24 +89,25 @@ type calicoConfig struct {
}

// NewCalico creates new Calico reconciler component
func NewCalico(k0sVars *config.CfgVars, crdSaver manifestsSaver, manifestsSaver manifestsSaver) *Calico {
func NewCalico(k0sVars *config.CfgVars) *Calico {
return &Calico{
log: logrus.WithFields(logrus.Fields{"component": "calico"}),

crdSaver: crdSaver,
saver: manifestsSaver,
prevConfig: calicoConfig{},
k0sVars: k0sVars,
}
}

// Init does nothing
func (c *Calico) Init(_ context.Context) error {
return nil
// Init implements [manager.Component].
func (c *Calico) Init(context.Context) error {
return errors.Join(
dir.Init(filepath.Join(c.k0sVars.ManifestsDir, "calico_init"), constant.ManifestsDirMode),
dir.Init(filepath.Join(c.k0sVars.ManifestsDir, "calico"), constant.ManifestsDirMode),
)
}

// Run nothing really running, all logic based on reactive reconcile
func (c *Calico) Start(_ context.Context) error {
// Start implements [manager.Component].
func (c *Calico) Start(context.Context) error {
return nil
}

Expand Down Expand Up @@ -138,7 +140,9 @@ func (c *Calico) dumpCRDs() error {
return fmt.Errorf("failed to write calico crd manifests %s: %w", manifestName, err)
}

if err := c.crdSaver.Save(manifestName, output.Bytes()); err != nil {
if err := file.AtomicWithTarget(filepath.Join(c.k0sVars.ManifestsDir, "calico_init", manifestName)).
WithPermissions(constant.CertMode).
Write(output.Bytes()); err != nil {
return fmt.Errorf("failed to save calico crd manifest %s: %w", manifestName, err)
}
}
Expand Down Expand Up @@ -184,7 +188,9 @@ func (c *Calico) processConfigChanges(newConfig calicoConfig) error {
Data: newConfig,
}
tryAndLog(manifestName, tw.WriteToBuffer(output))
tryAndLog(manifestName, c.saver.Save(manifestName, output.Bytes()))
tryAndLog(manifestName, file.AtomicWithTarget(filepath.Join(c.k0sVars.ManifestsDir, "calico", manifestName)).
WithPermissions(constant.CertMode).
Write(output.Bytes()))
}
}

Expand Down Expand Up @@ -227,7 +233,7 @@ func (c *Calico) getConfig(clusterConfig *v1beta1.ClusterConfig) (calicoConfig,
return config, nil
}

// Stop stops the calico reconciler
// Stop implements [manager.Component].
func (c *Calico) Stop() error {
return nil
}
Expand Down
65 changes: 36 additions & 29 deletions pkg/component/controller/calico_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,15 @@ limitations under the License.
package controller

import (
"context"
"os"
"path/filepath"
"testing"

"github.com/k0sproject/k0s/pkg/apis/k0s/v1beta1"
"github.com/k0sproject/k0s/pkg/config"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"sigs.k8s.io/yaml"
)
Expand All @@ -34,54 +38,61 @@ func (i inMemorySaver) Save(dst string, content []byte) error {
}

func TestCalicoManifests(t *testing.T) {
k0sVars, err := config.NewCfgVars(nil, t.TempDir())
require.NoError(t, err)
newTestInstance := func(t *testing.T) *Calico {
k0sVars, err := config.NewCfgVars(nil, t.TempDir())
require.NoError(t, err)
calico := NewCalico(k0sVars)
require.NoError(t, calico.Init(context.TODO()))
require.NoError(t, calico.Start(context.TODO()))
t.Cleanup(func() { assert.NoError(t, calico.Stop()) })
return calico
}

clusterConfig := v1beta1.DefaultClusterConfig()
clusterConfig.Spec.Network.Calico = v1beta1.DefaultCalico()
clusterConfig.Spec.Network.Provider = "calico"
clusterConfig.Spec.Network.KubeRouter = nil

t.Run("must_write_only_non_crd_on_change", func(t *testing.T) {
saver := inMemorySaver{}
crdSaver := inMemorySaver{}
calico := NewCalico(k0sVars, crdSaver, saver)
calico := newTestInstance(t)

_ = calico.processConfigChanges(calicoConfig{})
assert.NoError(t, calico.processConfigChanges(calicoConfig{}))

for k := range saver {
require.NotContains(t, k, "calico-crd")
if entries, err := os.ReadDir(filepath.Join(calico.k0sVars.ManifestsDir, "calico")); assert.NoError(t, err) {
assert.NotEmpty(t, entries)
for _, entry := range entries {
assert.NotContains(t, entry.Name(), "calico-crd")
}
}
if entries, err := os.ReadDir(filepath.Join(calico.k0sVars.ManifestsDir, "calico_init")); assert.NoError(t, err) {
assert.Empty(t, entries)
}
require.Len(t, crdSaver, 0)
})

t.Run("must_have_wireguard_enabled_if_config_has", func(t *testing.T) {
clusterConfig.Spec.Network.Calico.EnableWireguard = true
saver := inMemorySaver{}
crdSaver := inMemorySaver{}
calico := NewCalico(k0sVars, crdSaver, saver)
calico := newTestInstance(t)
cfg, err := calico.getConfig(clusterConfig)
require.NoError(t, err)
require.NoError(t, calico.processConfigChanges(cfg))

daemonSetManifestRaw, foundRaw := saver["calico-DaemonSet-calico-node.yaml"]
require.True(t, foundRaw, "must have daemon set for calico")
daemonSetManifestRaw, err := os.ReadFile(filepath.Join(calico.k0sVars.ManifestsDir, "calico", "calico-DaemonSet-calico-node.yaml"))
require.NoError(t, err, "must have daemon set for calico")
spec := daemonSetContainersEnv{}
require.NoError(t, yaml.Unmarshal(daemonSetManifestRaw, &spec))
spec.RequireContainerHasEnvVariable(t, "calico-node", "FELIX_WIREGUARDENABLED", "true")
})

t.Run("must_not_have_wireguard_enabled_if_config_has_no", func(t *testing.T) {
clusterConfig.Spec.Network.Calico.EnableWireguard = false
saver := inMemorySaver{}
crdSaver := inMemorySaver{}
calico := NewCalico(k0sVars, crdSaver, saver)
calico := newTestInstance(t)

cfg, err := calico.getConfig(clusterConfig)
require.NoError(t, err)
_ = calico.processConfigChanges(cfg)

daemonSetManifestRaw, foundRaw := saver["calico-DaemonSet-calico-node.yaml"]
require.True(t, foundRaw, "must have daemon set for calico")
daemonSetManifestRaw, err := os.ReadFile(filepath.Join(calico.k0sVars.ManifestsDir, "calico", "calico-DaemonSet-calico-node.yaml"))
require.NoError(t, err, "must have daemon set for calico")
spec := daemonSetContainersEnv{}
require.NoError(t, yaml.Unmarshal(daemonSetManifestRaw, &spec))
spec.RequireContainerHasNoEnvVariable(t, "calico-node", "FELIX_WIREGUARDENABLED")
Expand All @@ -90,18 +101,16 @@ func TestCalicoManifests(t *testing.T) {
t.Run("ip_autodetection", func(t *testing.T) {
t.Run("use_IPAutodetectionMethod_for_both_families_by_default", func(t *testing.T) {
clusterConfig.Spec.Network.Calico.IPAutodetectionMethod = "somemethod"
saver := inMemorySaver{}
crdSaver := inMemorySaver{}
calico := NewCalico(k0sVars, crdSaver, saver)
calico := newTestInstance(t)
templateContext, err := calico.getConfig(clusterConfig)
require.NoError(t, err)
require.Equal(t, clusterConfig.Spec.Network.Calico.IPAutodetectionMethod, templateContext.IPAutodetectionMethod)
require.Equal(t, templateContext.IPV6AutodetectionMethod, templateContext.IPV6AutodetectionMethod)
cfg, err := calico.getConfig(clusterConfig)
require.NoError(t, err)
_ = calico.processConfigChanges(cfg)
daemonSetManifestRaw, foundRaw := saver["calico-DaemonSet-calico-node.yaml"]
require.True(t, foundRaw, "must have daemon set for calico")
daemonSetManifestRaw, err := os.ReadFile(filepath.Join(calico.k0sVars.ManifestsDir, "calico", "calico-DaemonSet-calico-node.yaml"))
require.NoError(t, err, "must have daemon set for calico")

spec := daemonSetContainersEnv{}
require.NoError(t, yaml.Unmarshal(daemonSetManifestRaw, &spec))
Expand All @@ -111,19 +120,17 @@ func TestCalicoManifests(t *testing.T) {
t.Run("use_IPV6AutodetectionMethod_for_ipv6_if_specified", func(t *testing.T) {
clusterConfig.Spec.Network.Calico.IPAutodetectionMethod = "somemethod"
clusterConfig.Spec.Network.Calico.IPv6AutodetectionMethod = "anothermethod"
saver := inMemorySaver{}
crdSaver := inMemorySaver{}
calico := NewCalico(k0sVars, crdSaver, saver)
calico := newTestInstance(t)
templateContext, err := calico.getConfig(clusterConfig)
require.NoError(t, err)
require.Equal(t, clusterConfig.Spec.Network.Calico.IPAutodetectionMethod, templateContext.IPAutodetectionMethod)
require.Equal(t, clusterConfig.Spec.Network.Calico.IPv6AutodetectionMethod, templateContext.IPV6AutodetectionMethod)
cfg, err := calico.getConfig(clusterConfig)
require.NoError(t, err)
_ = calico.processConfigChanges(cfg)
daemonSetManifestRaw, foundRaw := saver["calico-DaemonSet-calico-node.yaml"]
daemonSetManifestRaw, err := os.ReadFile(filepath.Join(calico.k0sVars.ManifestsDir, "calico", "calico-DaemonSet-calico-node.yaml"))
require.NoError(t, err, "must have daemon set for calico")

require.True(t, foundRaw, "must have daemon set for calico")
spec := daemonSetContainersEnv{}
require.NoError(t, yaml.Unmarshal(daemonSetManifestRaw, &spec))
spec.RequireContainerHasEnvVariable(t, "calico-node", "IP6_AUTODETECTION_METHOD", templateContext.IPV6AutodetectionMethod)
Expand Down

0 comments on commit cb8ea7b

Please sign in to comment.