Skip to content

Commit

Permalink
Merge pull request #801 from makhov/refactor-dynamic-config-reconcile
Browse files Browse the repository at this point in the history
Move dynamic config reconciliation to K0sControlPlane
  • Loading branch information
makhov authored Nov 1, 2024
2 parents 2a64a7b + f488e13 commit a77451a
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 42 deletions.
42 changes: 0 additions & 42 deletions internal/controller/bootstrap/controlplane_bootstrap_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,41 +185,6 @@ func (c *ControlPlaneController) Reconcile(ctx context.Context, req ctrl.Request
}

if config.Spec.K0s != nil {
nllbEnabled, found, err := unstructured.NestedBool(config.Spec.K0s.Object, "spec", "network", "nodeLocalLoadBalancing", "enabled")
if err != nil {
return ctrl.Result{}, fmt.Errorf("error getting nodeLocalLoadBalancing: %v", err)
}
// Set the external address if NLLB is not enabled
// Otherwise, just add the external address to the SANs to allow the clients to connect using LB address
if !(found && nllbEnabled) {
err = unstructured.SetNestedField(config.Spec.K0s.Object, scope.Cluster.Spec.ControlPlaneEndpoint.Host, "spec", "api", "externalAddress")
if err != nil {
return ctrl.Result{}, fmt.Errorf("error setting control plane endpoint: %v", err)
}
} else {
sans := []string{scope.Cluster.Spec.ControlPlaneEndpoint.Host}
existingSANs, sansFound, err := unstructured.NestedStringSlice(config.Spec.K0s.Object, "spec", "api", "sans")
if err == nil && sansFound {
sans = append(sans, existingSANs...)
}
err = unstructured.SetNestedStringSlice(config.Spec.K0s.Object, sans, "spec", "api", "sans")
if err != nil {
return ctrl.Result{}, fmt.Errorf("error setting sans: %v", err)
}
}

if config.Spec.Tunneling.ServerAddress != "" {
sans, _, err := unstructured.NestedSlice(config.Spec.K0s.Object, "spec", "api", "sans")
if err != nil {
return ctrl.Result{}, fmt.Errorf("error getting sans from config: %v", err)
}
sans = append(sans, config.Spec.Tunneling.ServerAddress)
err = unstructured.SetNestedSlice(config.Spec.K0s.Object, sans, "spec", "api", "sans")
if err != nil {
return ctrl.Result{}, fmt.Errorf("error setting sans to the config: %v", err)
}
}

k0sConfigBytes, err := config.Spec.K0s.MarshalJSON()
if err != nil {
return ctrl.Result{}, fmt.Errorf("error marshalling k0s config: %v", err)
Expand All @@ -230,13 +195,6 @@ func (c *ControlPlaneController) Reconcile(ctx context.Context, req ctrl.Request
Content: string(k0sConfigBytes),
})
config.Spec.Args = append(config.Spec.Args, "--config", "/etc/k0s.yaml")

// Reconcile the dynamic config
dErr := kutil.ReconcileDynamicConfig(ctx, cluster, c.Client, *config.Spec.K0s)
if dErr != nil {
// Don't return error from dynamic config reconciliation, as it may not be created yet
log.Error(fmt.Errorf("failed to reconcile dynamic config, kubeconfig may not be available yet: %w", dErr), "Failed to reconcile dynamic config")
}
}

if config.Status.Ready {
Expand Down
56 changes: 56 additions & 0 deletions internal/controller/controlplane/k0s_controlplane_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/client-go/kubernetes"
Expand All @@ -48,6 +49,7 @@ import (

bootstrapv1 "github.com/k0sproject/k0smotron/api/bootstrap/v1beta1"
cpv1beta1 "github.com/k0sproject/k0smotron/api/controlplane/v1beta1"
kutil "github.com/k0sproject/k0smotron/internal/util"
)

const (
Expand Down Expand Up @@ -160,6 +162,11 @@ func (c *K0sController) Reconcile(ctx context.Context, req ctrl.Request) (res ct
return ctrl.Result{}, err
}

if err := c.reconcileConfig(ctx, cluster, kcp); err != nil {
log.Error(err, "Failed to reconcile config")
return ctrl.Result{}, err
}

_, err = c.reconcile(ctx, cluster, kcp)
if err != nil {
if errors.Is(err, ErrNewMachinesNotReady) {
Expand Down Expand Up @@ -513,6 +520,55 @@ func (c *K0sController) ensureCertificates(ctx context.Context, cluster *cluster
return certificates.LookupOrGenerate(ctx, c.Client, capiutil.ObjectKey(cluster), *metav1.NewControllerRef(kcp, cpv1beta1.GroupVersion.WithKind("K0sControlPlane")))
}

func (c *K0sController) reconcileConfig(ctx context.Context, cluster *clusterv1.Cluster, kcp *cpv1beta1.K0sControlPlane) error {
log := log.FromContext(ctx)
if kcp.Spec.K0sConfigSpec.K0s != nil {
nllbEnabled, found, err := unstructured.NestedBool(kcp.Spec.K0sConfigSpec.K0s.Object, "spec", "network", "nodeLocalLoadBalancing", "enabled")
if err != nil {
return fmt.Errorf("error getting nodeLocalLoadBalancing: %v", err)
}
// Set the external address if NLLB is not enabled
// Otherwise, just add the external address to the SANs to allow the clients to connect using LB address
if !(found && nllbEnabled) {
err = unstructured.SetNestedField(kcp.Spec.K0sConfigSpec.K0s.Object, cluster.Spec.ControlPlaneEndpoint.Host, "spec", "api", "externalAddress")
if err != nil {
return fmt.Errorf("error setting control plane endpoint: %v", err)
}
} else {
sans := []string{cluster.Spec.ControlPlaneEndpoint.Host}
existingSANs, sansFound, err := unstructured.NestedStringSlice(kcp.Spec.K0sConfigSpec.K0s.Object, "spec", "api", "sans")
if err == nil && sansFound {
sans = append(sans, existingSANs...)
}
err = unstructured.SetNestedStringSlice(kcp.Spec.K0sConfigSpec.K0s.Object, sans, "spec", "api", "sans")
if err != nil {
return fmt.Errorf("error setting sans: %v", err)
}
}

if kcp.Spec.K0sConfigSpec.Tunneling.ServerAddress != "" {
sans, _, err := unstructured.NestedSlice(kcp.Spec.K0sConfigSpec.K0s.Object, "spec", "api", "sans")
if err != nil {
return fmt.Errorf("error getting sans from config: %v", err)
}
sans = append(sans, kcp.Spec.K0sConfigSpec.Tunneling.ServerAddress)
err = unstructured.SetNestedSlice(kcp.Spec.K0sConfigSpec.K0s.Object, sans, "spec", "api", "sans")
if err != nil {
return fmt.Errorf("error setting sans to the config: %v", err)
}
}

// Reconcile the dynamic config
dErr := kutil.ReconcileDynamicConfig(ctx, cluster, c.Client, *kcp.Spec.K0sConfigSpec.K0s.DeepCopy())
if dErr != nil {
// Don't return error from dynamic config reconciliation, as it may not be created yet
log.Error(fmt.Errorf("failed to reconcile dynamic config, kubeconfig may not be available yet: %w", dErr), "Failed to reconcile dynamic config")
}
}

return nil
}

func (c *K0sController) reconcileTunneling(ctx context.Context, cluster *clusterv1.Cluster, kcp *cpv1beta1.K0sControlPlane) error {
if !kcp.Spec.K0sConfigSpec.Tunneling.Enabled {
return nil
Expand Down

0 comments on commit a77451a

Please sign in to comment.