Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feat]: Set metadata for LinodeMachines, disable swap #74

Merged
merged 4 commits into from
Feb 1, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should the b64 encoding happen by the callee incase anyone is looking for the string? this feels like a generic function and how it's used shouldn't be determined by this func

}
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
3 changes: 1 addition & 2 deletions controller/linodecluster_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,13 +143,12 @@ func (r *LinodeClusterReconciler) reconcile(
if err := r.reconcileCreate(ctx, logger, clusterScope); err != nil {
return res, err
}
r.Recorder.Event(clusterScope.LinodeCluster, corev1.EventTypeNormal, string(clusterv1.ReadyCondition), "Load balancer is ready")
}

clusterScope.LinodeCluster.Status.Ready = true
conditions.MarkTrue(clusterScope.LinodeCluster, clusterv1.ReadyCondition)

r.Recorder.Event(clusterScope.LinodeCluster, corev1.EventTypeNormal, string(clusterv1.ReadyCondition), "Load balancer is ready")

return res, nil
}

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())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call, I'll get that added 👍


// 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