Skip to content

Commit 5ea5faa

Browse files
authored
Merge pull request #1841 from vincepri/add-data-secret-name-cabpk
⚠️ Move Bootstrap data to a secret
2 parents 03c7b1c + b4b7a1d commit 5ea5faa

21 files changed

+313
-89
lines changed

api/v1alpha2/conversion.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,3 +265,12 @@ func Convert_v1alpha3_MachineSetSpec_To_v1alpha2_MachineSetSpec(in *v1alpha3.Mac
265265
func Convert_v1alpha3_MachineSpec_To_v1alpha2_MachineSpec(in *v1alpha3.MachineSpec, out *MachineSpec, s apiconversion.Scope) error {
266266
return errors.New("cannot recover removed MachineSpec Cluster Name")
267267
}
268+
269+
func Convert_v1alpha3_Bootstrap_To_v1alpha2_Bootstrap(in *v1alpha3.Bootstrap, out *Bootstrap, s apiconversion.Scope) error {
270+
// We need to fail early here given that we don't want to leak information from secrets back to the inline / plaintext field in v1alpha2.
271+
if in.Data == nil && in.DataSecretName != nil {
272+
return errors.New("cannot convert Machine's bootstrap data from Secret reference to inline field")
273+
}
274+
275+
return autoConvert_v1alpha3_Bootstrap_To_v1alpha2_Bootstrap(in, out, s)
276+
}

api/v1alpha2/zz_generated.conversion.go

Lines changed: 6 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/v1alpha3/machine_types.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,8 +190,17 @@ type Bootstrap struct {
190190

191191
// Data contains the bootstrap data, such as cloud-init details scripts.
192192
// If nil, the Machine should remain in the Pending state.
193+
//
194+
// Deprecated: This field has been deprecated in v1alpha3 and
195+
// will be removed in a future version. Switch to DataSecretName.
196+
//
193197
// +optional
194198
Data *string `json:"data,omitempty"`
199+
200+
// DataSecretName is the name of the secret that stores the bootstrap data script.
201+
// If nil, the Machine should remain in the Pending state.
202+
// +optional
203+
DataSecretName *string `json:"dataSecretName,omitempty"`
195204
}
196205

197206
// ANCHOR_END: Bootstrap

api/v1alpha3/zz_generated.deepcopy.go

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bootstrap/kubeadm/api/v1alpha2/conversion.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ limitations under the License.
1717
package v1alpha2
1818

1919
import (
20+
"errors"
21+
2022
apiconversion "k8s.io/apimachinery/pkg/conversion"
2123
kubeadmbootstrapv1alpha3 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1alpha3"
2224
"sigs.k8s.io/controller-runtime/pkg/conversion"
@@ -85,6 +87,11 @@ func Convert_v1alpha2_KubeadmConfigStatus_To_v1alpha3_KubeadmConfigStatus(in *Ku
8587

8688
// Convert_v1alpha3_KubeadmConfigStatus_To_v1alpha2_KubeadmConfigStatus converts from the Hub version (v1alpha3) of the KubeadmConfigStatus to this version.
8789
func Convert_v1alpha3_KubeadmConfigStatus_To_v1alpha2_KubeadmConfigStatus(in *kubeadmbootstrapv1alpha3.KubeadmConfigStatus, out *KubeadmConfigStatus, s apiconversion.Scope) error { // nolint
90+
// We need to fail early here given that we don't want to leak information from secrets back to the inline / plaintext field in v1alpha2.
91+
if in.BootstrapData == nil && in.DataSecretName != nil {
92+
return errors.New("cannot convert KubeadmConfigStatus's bootstrap data from Secret reference to inline field")
93+
}
94+
8895
if err := autoConvert_v1alpha3_KubeadmConfigStatus_To_v1alpha2_KubeadmConfigStatus(in, out, s); err != nil {
8996
return err
9097
}

bootstrap/kubeadm/api/v1alpha2/zz_generated.conversion.go

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bootstrap/kubeadm/api/v1alpha3/kubeadmbootstrapconfig_types.go

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,27 +36,35 @@ type KubeadmConfigSpec struct {
3636
// ClusterConfiguration along with InitConfiguration are the configurations necessary for the init command
3737
// +optional
3838
ClusterConfiguration *kubeadmv1beta1.ClusterConfiguration `json:"clusterConfiguration,omitempty"`
39+
3940
// InitConfiguration along with ClusterConfiguration are the configurations necessary for the init command
4041
// +optional
4142
InitConfiguration *kubeadmv1beta1.InitConfiguration `json:"initConfiguration,omitempty"`
43+
4244
// JoinConfiguration is the kubeadm configuration for the join command
4345
// +optional
4446
JoinConfiguration *kubeadmv1beta1.JoinConfiguration `json:"joinConfiguration,omitempty"`
47+
4548
// Files specifies extra files to be passed to user_data upon creation.
4649
// +optional
4750
Files []File `json:"files,omitempty"`
51+
4852
// PreKubeadmCommands specifies extra commands to run before kubeadm runs
4953
// +optional
5054
PreKubeadmCommands []string `json:"preKubeadmCommands,omitempty"`
55+
5156
// PostKubeadmCommands specifies extra commands to run after kubeadm runs
5257
// +optional
5358
PostKubeadmCommands []string `json:"postKubeadmCommands,omitempty"`
59+
5460
// Users specifies extra users to add
5561
// +optional
5662
Users []User `json:"users,omitempty"`
63+
5764
// NTP specifies NTP configuration
5865
// +optional
5966
NTP *NTP `json:"ntp,omitempty"`
67+
6068
// Format specifies the output format of the bootstrap data
6169
// +optional
6270
Format Format `json:"format,omitempty"`
@@ -67,7 +75,15 @@ type KubeadmConfigStatus struct {
6775
// Ready indicates the BootstrapData field is ready to be consumed
6876
Ready bool `json:"ready,omitempty"`
6977

70-
// BootstrapData will be a cloud-init script for now
78+
// DataSecretName is the name of the secret that stores the bootstrap data script.
79+
// +optional
80+
DataSecretName *string `json:"dataSecretName,omitempty"`
81+
82+
// BootstrapData will be a cloud-init script for now.
83+
//
84+
// Deprecated: This field has been deprecated in v1alpha3 and
85+
// will be removed in a future version. Switch to DataSecretName.
86+
//
7187
// +optional
7288
BootstrapData []byte `json:"bootstrapData,omitempty"`
7389

bootstrap/kubeadm/api/v1alpha3/zz_generated.deepcopy.go

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bootstrap/kubeadm/controllers/kubeadmconfig_controller.go

Lines changed: 67 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,11 @@ import (
2424

2525
"github.com/go-logr/logr"
2626
"github.com/pkg/errors"
27+
corev1 "k8s.io/api/core/v1"
2728
apierrors "k8s.io/apimachinery/pkg/api/errors"
2829
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2930
"k8s.io/apimachinery/pkg/runtime"
31+
"k8s.io/utils/pointer"
3032
clusterv1 "sigs.k8s.io/cluster-api/api/v1alpha3"
3133
bootstrapv1 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1alpha3"
3234
"sigs.k8s.io/cluster-api/bootstrap/kubeadm/cloudinit"
@@ -151,25 +153,30 @@ func (r *KubeadmConfigReconciler) Reconcile(req ctrl.Request) (_ ctrl.Result, re
151153
return ctrl.Result{}, err
152154
}
153155

156+
// Initialize the patch helper.
157+
patchHelper, err := patch.NewHelper(config, r.Client)
158+
if err != nil {
159+
return ctrl.Result{}, err
160+
}
161+
154162
switch {
155-
// Wait patiently for the infrastructure to be ready
163+
// Wait for the infrastructure to be ready.
156164
case !cluster.Status.InfrastructureReady:
157-
log.Info("Infrastructure is not ready, waiting until ready.")
165+
log.Info("Cluster infrastructure is not ready, waiting")
158166
return ctrl.Result{}, nil
159-
// bail super early if it's already ready
167+
// Migrate plaintext data to secret.
168+
case config.Status.BootstrapData != nil && config.Status.DataSecretName == nil:
169+
if err := r.storeBootstrapData(ctx, config, config.Status.BootstrapData); err != nil {
170+
return ctrl.Result{}, err
171+
}
172+
return ctrl.Result{}, patchHelper.Patch(ctx, config)
173+
// Return early if the configuration and Machine's infrastructure are ready.
160174
case config.Status.Ready && machine.Status.InfrastructureReady:
161-
log.Info("ignoring config for an already ready machine")
162175
return ctrl.Result{}, nil
163176
// Reconcile status for machines that have already copied bootstrap data
164-
case machine.Spec.Bootstrap.Data != nil && !config.Status.Ready:
177+
case machine.Spec.Bootstrap.DataSecretName != nil && !config.Status.Ready:
165178
config.Status.Ready = true
166-
// Initialize the patch helper
167-
patchHelper, err := patch.NewHelper(config, r.Client)
168-
if err != nil {
169-
return ctrl.Result{}, err
170-
}
171-
err = patchHelper.Patch(ctx, config)
172-
return ctrl.Result{}, err
179+
return ctrl.Result{}, patchHelper.Patch(ctx, config)
173180
// If we've already embedded a time-limited join token into a config, but are still waiting for the token to be used, refresh it
174181
case config.Status.Ready && (config.Spec.JoinConfiguration != nil && config.Spec.JoinConfiguration.Discovery.BootstrapToken != nil):
175182
token := config.Spec.JoinConfiguration.Discovery.BootstrapToken.Token
@@ -192,11 +199,6 @@ func (r *KubeadmConfigReconciler) Reconcile(req ctrl.Request) (_ ctrl.Result, re
192199
}, nil
193200
}
194201

195-
// Initialize the patch helper
196-
patchHelper, err := patch.NewHelper(config, r.Client)
197-
if err != nil {
198-
return ctrl.Result{}, err
199-
}
200202
// Attempt to Patch the KubeadmConfig object and status after each reconciliation if no error occurs.
201203
defer func() {
202204
if rerr == nil {
@@ -328,8 +330,10 @@ func (r *KubeadmConfigReconciler) handleClusterNotInitialized(ctx context.Contex
328330
return ctrl.Result{}, err
329331
}
330332

331-
scope.Config.Status.BootstrapData = cloudInitData
332-
scope.Config.Status.Ready = true
333+
if err := r.storeBootstrapData(ctx, scope.Config, cloudInitData); err != nil {
334+
scope.Error(err, "failed to store bootstrap data")
335+
return ctrl.Result{}, err
336+
}
333337

334338
return ctrl.Result{}, nil
335339
}
@@ -380,8 +384,11 @@ func (r *KubeadmConfigReconciler) joinWorker(ctx context.Context, scope *Scope)
380384
scope.Error(err, "failed to create a worker join configuration")
381385
return ctrl.Result{}, err
382386
}
383-
scope.Config.Status.BootstrapData = cloudJoinData
384-
scope.Config.Status.Ready = true
387+
388+
if err := r.storeBootstrapData(ctx, scope.Config, cloudJoinData); err != nil {
389+
scope.Error(err, "failed to store bootstrap data")
390+
return ctrl.Result{}, err
391+
}
385392
return ctrl.Result{}, nil
386393
}
387394

@@ -431,8 +438,11 @@ func (r *KubeadmConfigReconciler) joinControlplane(ctx context.Context, scope *S
431438
return ctrl.Result{}, err
432439
}
433440

434-
scope.Config.Status.BootstrapData = cloudJoinData
435-
scope.Config.Status.Ready = true
441+
if err := r.storeBootstrapData(ctx, scope.Config, cloudJoinData); err != nil {
442+
scope.Error(err, "failed to store bootstrap data")
443+
return ctrl.Result{}, err
444+
}
445+
436446
return ctrl.Result{}, nil
437447
}
438448

@@ -596,3 +606,37 @@ func (r *KubeadmConfigReconciler) reconcileTopLevelObjectSettings(cluster *clust
596606
log.Info("Altering ClusterConfiguration", "KubernetesVersion", config.Spec.ClusterConfiguration.KubernetesVersion)
597607
}
598608
}
609+
610+
// storeBootstrapData creates a new secret with the data passed in as input,
611+
// sets the reference in the configuration status and ready to true.
612+
func (r *KubeadmConfigReconciler) storeBootstrapData(ctx context.Context, config *bootstrapv1.KubeadmConfig, data []byte) error {
613+
secret := &corev1.Secret{
614+
ObjectMeta: v1.ObjectMeta{
615+
Name: config.Name,
616+
Namespace: config.Namespace,
617+
Labels: map[string]string{
618+
clusterv1.ClusterLabelName: config.ClusterName,
619+
},
620+
OwnerReferences: []v1.OwnerReference{
621+
{
622+
APIVersion: bootstrapv1.GroupVersion.String(),
623+
Kind: "KubeadmConfig",
624+
Name: config.Name,
625+
UID: config.UID,
626+
Controller: pointer.BoolPtr(true),
627+
},
628+
},
629+
},
630+
Data: map[string][]byte{
631+
"value": data,
632+
},
633+
}
634+
635+
if err := r.Client.Create(ctx, secret); err != nil {
636+
return errors.Wrapf(err, "failed to create kubeconfig secret for KubeadmConfig %s/%s", config.Namespace, config.Name)
637+
}
638+
639+
config.Status.DataSecretName = pointer.StringPtr(secret.Name)
640+
config.Status.Ready = true
641+
return nil
642+
}

0 commit comments

Comments
 (0)