Skip to content

Commit

Permalink
populate metadata for bootstrap
Browse files Browse the repository at this point in the history
  • Loading branch information
AshleyDumaine authored and eljohnson92 committed Feb 1, 2024
1 parent 92feaa0 commit 8f75031
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 9 deletions.
37 changes: 37 additions & 0 deletions cloud/scope/machine.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package scope

import (
"context"
b64 "encoding/base64"
"errors"
"fmt"

corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types"

infrav1 "github.com/linode/cluster-api-provider-linode/api/v1alpha1"
"github.com/linode/linodego"
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
Expand Down Expand Up @@ -69,3 +74,35 @@ func NewMachineScope(apiKey string, params MachineScopeParams) (*MachineScope, e
LinodeMachine: params.LinodeMachine,
}, nil
}

// GetBootstrapData returns the bootstrap data from the secret in the Machine's bootstrap.dataSecretName.
func (m *MachineScope) GetBootstrapData(ctx context.Context) (string, error) {
if m.Machine.Spec.Bootstrap.DataSecretName == nil {
return "", fmt.Errorf(
"bootstrap data secret is nil for LinodeMachine %s/%s",
m.LinodeMachine.Namespace,
m.LinodeMachine.Name,
)
}

secret := &corev1.Secret{}
key := types.NamespacedName{Namespace: m.LinodeMachine.Namespace, Name: *m.Machine.Spec.Bootstrap.DataSecretName}
if err := m.client.Get(ctx, key, secret); err != nil {
return "", fmt.Errorf(
"failed to retrieve bootstrap data secret for LinodeMachine %s/%s",
m.LinodeMachine.Namespace,
m.LinodeMachine.Name,
)
}

value, ok := secret.Data["value"]
if !ok {
return "", fmt.Errorf(
"bootstrap data secret value key is missing for LinodeMachine %s/%s",
m.LinodeMachine.Namespace,
m.LinodeMachine.Name,
)
}

return b64.StdEncoding.EncodeToString(value), nil
}
11 changes: 11 additions & 0 deletions config/rbac/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,19 @@ rules:
- events
verbs:
- create
- get
- list
- patch
- update
- watch
- apiGroups:
- ""
resources:
- secrets
verbs:
- get
- list
- watch
- apiGroups:
- cluster.x-k8s.io
resources:
Expand Down
35 changes: 26 additions & 9 deletions controller/linodemachine_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,14 @@ type LinodeMachineReconciler struct {
ReconcileTimeout time.Duration
}

//+kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=linodemachines,verbs=get;list;watch;create;update;patch;delete
//+kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=linodemachines/status,verbs=get;update;patch
//+kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=linodemachines/finalizers,verbs=update
// +kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=linodemachines,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=linodemachines/status,verbs=get;update;patch
// +kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=linodemachines/finalizers,verbs=update

//+kubebuilder:rbac:groups=cluster.x-k8s.io,resources=clusters,verbs=get;watch;list
//+kubebuilder:rbac:groups=cluster.x-k8s.io,resources=machines,verbs=get;watch;list
//+kubebuilder:rbac:groups="",resources=events,verbs=create;update;patch
// +kubebuilder:rbac:groups=cluster.x-k8s.io,resources=clusters,verbs=get;watch;list
// +kubebuilder:rbac:groups=cluster.x-k8s.io,resources=machines,verbs=get;watch;list
// +kubebuilder:rbac:groups="",resources=events,verbs=get;list;watch;create;update;patch
// +kubebuilder:rbac:groups="",resources=secrets;,verbs=get;list;watch

// Reconcile is part of the main kubernetes reconciliation loop which aims to
// move the current state of the cluster closer to the desired state.
Expand Down Expand Up @@ -118,7 +119,6 @@ func (r *LinodeMachineReconciler) Reconcile(ctx context.Context, req ctrl.Reques

return ctrl.Result{}, nil
case skippedMachinePhases[machine.Status.Phase]:
log.Info("Machine phase is not the one we are looking for, skipping reconciliation", "phase", machine.Status.Phase)

return ctrl.Result{}, nil
default:
Expand Down Expand Up @@ -209,6 +209,9 @@ func (r *LinodeMachineReconciler) reconcile(
}
}()

// Add the finalizer if not already there
controllerutil.AddFinalizer(machineScope.LinodeMachine, infrav1.GroupVersion.String())

// Delete
if !machineScope.LinodeMachine.ObjectMeta.DeletionTimestamp.IsZero() {
failureReason = cerrs.DeleteMachineError
Expand All @@ -218,8 +221,6 @@ func (r *LinodeMachineReconciler) reconcile(
return
}

controllerutil.AddFinalizer(machineScope.LinodeMachine, infrav1.GroupVersion.String())

var linodeInstance *linodego.Instance
defer func() {
machineScope.LinodeMachine.Status.InstanceState = util.Pointer(linodego.InstanceOffline)
Expand All @@ -241,7 +242,12 @@ func (r *LinodeMachineReconciler) reconcile(

// Create
failureReason = cerrs.CreateMachineError
// Make sure bootstrap data is available and populated.
if machineScope.Machine.Spec.Bootstrap.DataSecretName == nil {
logger.Info("Bootstrap data secret is not yet available")

return ctrl.Result{RequeueAfter: reconciler.DefaultMachineControllerWaitForBootstrapDelay}, nil
}
linodeInstance, err = r.reconcileCreate(ctx, machineScope, logger)

return
Expand Down Expand Up @@ -281,6 +287,17 @@ func (*LinodeMachineReconciler) reconcileCreate(ctx context.Context, machineScop
}
createConfig.Tags = tags

// get the bootstrap data for the Linode instance and set it for create config
bootstrapData, err := machineScope.GetBootstrapData(ctx)
if err != nil {
logger.Info("Failed to get bootstrap data", "error", err.Error())

return nil, err
}
createConfig.Metadata = &linodego.InstanceMetadataOptions{
UserData: bootstrapData,
}

if linodeInstance, err = machineScope.LinodeClient.CreateInstance(ctx, *createConfig); err != nil {
logger.Info("Failed to create Linode machine instance", "error", err.Error())

Expand Down
2 changes: 2 additions & 0 deletions util/reconciler/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ const (
// DefaultMappingTimeout is the default timeout for a controller request mapping func.
DefaultMappingTimeout = 60 * time.Second

// DefaultMachineControllerWaitForBootstrapDelay is the default requeue delay if bootstrap data is not ready.
DefaultMachineControllerWaitForBootstrapDelay = 5 * time.Second
// DefaultMachineControllerWaitForRunningDelay is the default requeue delay if instance is not running.
DefaultMachineControllerWaitForRunningDelay = 5 * time.Second
// DefaultMachineControllerWaitForRunningTimeout is the default timeout if instance is not running.
Expand Down

0 comments on commit 8f75031

Please sign in to comment.