From ebe03251bb5cc1d3c77924c1928112e8b689fad2 Mon Sep 17 00:00:00 2001 From: Gerrit Date: Thu, 14 Nov 2024 16:11:13 +0100 Subject: [PATCH] Read userdata from bootstrap secret. --- api/v1alpha1/metalstackmachine_types.go | 1 + config/samples/example.yaml | 7 +++++ .../metalstackcluster_controller.go | 2 ++ .../metalstackmachine_controller.go | 28 ++++++++++++++++++- 4 files changed, 37 insertions(+), 1 deletion(-) diff --git a/api/v1alpha1/metalstackmachine_types.go b/api/v1alpha1/metalstackmachine_types.go index dbd04b0..4942310 100644 --- a/api/v1alpha1/metalstackmachine_types.go +++ b/api/v1alpha1/metalstackmachine_types.go @@ -29,6 +29,7 @@ const ( TagInfraMachineID = "metal-stack.infrastructure.cluster.x-k8s.io/machine-id" ProviderMachineCreated clusterv1.ConditionType = "MachineCreated" + ProviderMachineReady clusterv1.ConditionType = "MachineReady" ProviderMachineHealthy clusterv1.ConditionType = "MachineHealthy" ) diff --git a/config/samples/example.yaml b/config/samples/example.yaml index 572a5bc..948c757 100644 --- a/config/samples/example.yaml +++ b/config/samples/example.yaml @@ -34,6 +34,13 @@ apiVersion: controlplane.cluster.x-k8s.io/v1beta1 metadata: name: metal-test-controlplane spec: + kubeadmConfigSpec: + format: ignition + initConfiguration: + nodeRegistration: {} + joinConfiguration: + controlPlane: {} + nodeRegistration: {} machineTemplate: nodeDrainTimeout: 10m infrastructureRef: diff --git a/internal/controller/metalstackcluster_controller.go b/internal/controller/metalstackcluster_controller.go index c6fa2da..9b88bf1 100644 --- a/internal/controller/metalstackcluster_controller.go +++ b/internal/controller/metalstackcluster_controller.go @@ -113,6 +113,8 @@ func (r *MetalStackClusterReconciler) Reconcile(ctx context.Context, req ctrl.Re statusErr := reconciler.status() if statusErr != nil { err = errors.Join(err, fmt.Errorf("unable to update status: %w", statusErr)) + } else if !reconciler.infraCluster.Status.Ready { + err = errors.New("cluster is not yet ready, requeueing") } }() diff --git a/internal/controller/metalstackmachine_controller.go b/internal/controller/metalstackmachine_controller.go index 9ad04da..0454187 100644 --- a/internal/controller/metalstackmachine_controller.go +++ b/internal/controller/metalstackmachine_controller.go @@ -143,6 +143,8 @@ func (r *MetalStackMachineReconciler) Reconcile(ctx context.Context, req ctrl.Re statusErr := reconciler.status() if statusErr != nil { err = errors.Join(err, fmt.Errorf("unable to update status: %w", statusErr)) + } else if !reconciler.infraMachine.Status.Ready { + err = errors.New("machine is not yet ready, requeueing") } }() @@ -188,6 +190,10 @@ func (r *MetalStackMachineReconciler) Reconcile(ctx context.Context, req ctrl.Re return ctrl.Result{}, errors.New("waiting until control plane ip was set to cluster spec") } + if machine.Spec.Bootstrap.DataSecretName == nil { + return ctrl.Result{}, errors.New("waiting until bootstrap data secret was created") + } + err = reconciler.reconcile() return ctrl.Result{}, err // remember to return err here and not nil because the defer func can influence this @@ -256,6 +262,17 @@ func (r *machineReconciler) delete() error { } func (r *machineReconciler) create() (*models.V1MachineResponse, error) { + bootstrapSecret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: *r.clusterMachine.Spec.Bootstrap.DataSecretName, + Namespace: r.infraMachine.Namespace, + }, + } + err := r.client.Get(r.ctx, client.ObjectKeyFromObject(bootstrapSecret), bootstrapSecret) + if err != nil { + return nil, fmt.Errorf("unable to fetch bootstrap secret: %w", err) + } + var ( ips []string nws = []*models.V1MachineAllocationNetwork{ @@ -292,7 +309,8 @@ func (r *machineReconciler) create() (*models.V1MachineResponse, error) { Description: fmt.Sprintf("%s/%s for cluster %s/%s", r.infraMachine.Namespace, r.infraMachine.Name, r.infraCluster.Namespace, r.infraCluster.Name), Networks: nws, Ips: ips, - // TODO: UserData, SSHPubKeys, ... + UserData: string(bootstrapSecret.Data["value"]), + // TODO: SSHPubKeys, ... }), nil) if err != nil { return nil, fmt.Errorf("failed to allocate machine: %w", err) @@ -330,9 +348,11 @@ func (r *machineReconciler) status() error { case err != nil && !errors.Is(err, errProviderMachineNotFound): conditions.MarkFalse(r.infraMachine, v1alpha1.ProviderMachineCreated, "InternalError", clusterv1.ConditionSeverityError, "%s", err.Error()) conditions.MarkFalse(r.infraMachine, v1alpha1.ProviderMachineHealthy, "NotHealthy", clusterv1.ConditionSeverityWarning, "machine not created") + conditions.MarkFalse(r.infraMachine, v1alpha1.ProviderMachineReady, "NotReady", clusterv1.ConditionSeverityWarning, "machine not created") case err != nil && errors.Is(err, errProviderMachineNotFound): conditions.MarkFalse(r.infraMachine, v1alpha1.ProviderMachineCreated, "NotCreated", clusterv1.ConditionSeverityError, "%s", err.Error()) conditions.MarkFalse(r.infraMachine, v1alpha1.ProviderMachineHealthy, "NotHealthy", clusterv1.ConditionSeverityWarning, "machine not created") + conditions.MarkFalse(r.infraMachine, v1alpha1.ProviderMachineReady, "NotReady", clusterv1.ConditionSeverityWarning, "machine not created") default: if r.infraMachine.Spec.ProviderID == *m.ID { conditions.MarkTrue(r.infraMachine, v1alpha1.ProviderMachineCreated) @@ -357,6 +377,12 @@ func (r *machineReconciler) status() error { } } + if m.Events != nil && len(m.Events.Log) > 0 && ptr.Deref(m.Events.Log[0].Event, "") == "Phoned Home" { + conditions.MarkTrue(r.infraMachine, v1alpha1.ProviderMachineReady) + } else { + conditions.MarkFalse(r.infraMachine, v1alpha1.ProviderMachineReady, "NotReady", clusterv1.ConditionSeverityWarning, "machine is not in phoned home state") + } + if len(errs) == 0 { conditions.MarkTrue(r.infraMachine, v1alpha1.ProviderMachineHealthy) } else {