@@ -6,12 +6,12 @@ package controllers
6
6
7
7
import (
8
8
"context"
9
- "encoding/base64"
10
9
"encoding/json"
11
10
"errors"
12
11
"fmt"
13
12
"strconv"
14
13
"strings"
14
+ "time"
15
15
16
16
jsonpatch "github.com/evanphx/json-patch"
17
17
"github.com/go-logr/logr"
@@ -21,6 +21,7 @@ import (
21
21
"github.com/talos-systems/talos/pkg/machinery/config/types/v1alpha1/generate"
22
22
"github.com/talos-systems/talos/pkg/machinery/config/types/v1alpha1/machine"
23
23
"github.com/talos-systems/talos/pkg/machinery/constants"
24
+ "github.com/talos-systems/talos/pkg/machinery/role"
24
25
"gopkg.in/yaml.v2"
25
26
apierrors "k8s.io/apimachinery/pkg/api/errors"
26
27
"k8s.io/apimachinery/pkg/runtime"
@@ -29,6 +30,7 @@ import (
29
30
expv1 "sigs.k8s.io/cluster-api/exp/api/v1alpha4"
30
31
"sigs.k8s.io/cluster-api/feature"
31
32
"sigs.k8s.io/cluster-api/util"
33
+ "sigs.k8s.io/cluster-api/util/annotations"
32
34
"sigs.k8s.io/cluster-api/util/conditions"
33
35
"sigs.k8s.io/cluster-api/util/patch"
34
36
"sigs.k8s.io/cluster-api/util/predicates"
@@ -70,18 +72,6 @@ type TalosConfigBundle struct {
70
72
TalosConfig string
71
73
}
72
74
73
- type talosConfig struct {
74
- Context string
75
- Contexts map [string ]* talosConfigContext
76
- }
77
-
78
- type talosConfigContext struct {
79
- Target string
80
- CA string
81
- Crt string
82
- Key string
83
- }
84
-
85
75
func (r * TalosConfigReconciler ) SetupWithManager (ctx context.Context , mgr ctrl.Manager , options controller.Options ) error {
86
76
r .Scheme = mgr .GetScheme ()
87
77
@@ -148,6 +138,7 @@ func (r *TalosConfigReconciler) Reconcile(ctx context.Context, req ctrl.Request)
148
138
if err != nil {
149
139
return ctrl.Result {}, err
150
140
}
141
+
151
142
// Always attempt to Patch the TalosConfig object and status after each reconciliation.
152
143
defer func () {
153
144
// always update the readyCondition; the summary is represented using the "1 of x completed" notation.
@@ -156,14 +147,16 @@ func (r *TalosConfigReconciler) Reconcile(ctx context.Context, req ctrl.Request)
156
147
bootstrapv1alpha3 .DataSecretAvailableCondition ,
157
148
),
158
149
)
159
- // Patch ObservedGeneration only if the reconciliation completed successfully
150
+
160
151
patchOpts := []patch.Option {
161
152
patch.WithOwnedConditions {
162
153
Conditions : []capiv1.ConditionType {
163
154
bootstrapv1alpha3 .DataSecretAvailableCondition ,
164
155
},
165
156
},
166
157
}
158
+
159
+ // Patch ObservedGeneration only if the reconciliation completed successfully
167
160
if rerr == nil {
168
161
patchOpts = append (patchOpts , patch.WithStatusObservedGeneration {})
169
162
}
@@ -214,11 +207,32 @@ func (r *TalosConfigReconciler) Reconcile(ctx context.Context, req ctrl.Request)
214
207
return ctrl.Result {}, err
215
208
}
216
209
210
+ if annotations .IsPaused (cluster , config ) {
211
+ log .Info ("Reconciliation is paused for this object" )
212
+ return ctrl.Result {}, nil
213
+ }
214
+
215
+ tcScope := & TalosConfigScope {
216
+ Config : config ,
217
+ ConfigOwner : owner ,
218
+ Cluster : cluster ,
219
+ }
220
+
217
221
// bail super early if it's already ready
218
222
if config .Status .Ready {
219
223
log .Info ("ignoring an already ready config" )
220
224
conditions .MarkTrue (config , bootstrapv1alpha3 .DataSecretAvailableCondition )
221
- return ctrl.Result {}, nil
225
+
226
+ // reconcile cluster-wide talosconfig
227
+ err = r .reconcileClientConfig (ctx , log , tcScope )
228
+
229
+ if err == nil {
230
+ conditions .MarkTrue (config , bootstrapv1alpha3 .ClientConfigAvailableCondition )
231
+ } else {
232
+ conditions .MarkFalse (config , bootstrapv1alpha3 .ClientConfigAvailableCondition , bootstrapv1alpha3 .ClientConfigGenerationFailedReason , capiv1 .ConditionSeverityError , "talosconfig generation failure: %s" , err )
233
+ }
234
+
235
+ return ctrl.Result {}, err
222
236
}
223
237
224
238
// Wait patiently for the infrastructure to be ready
@@ -239,12 +253,6 @@ func (r *TalosConfigReconciler) Reconcile(ctx context.Context, req ctrl.Request)
239
253
return ctrl.Result {}, nil
240
254
}
241
255
242
- tcScope := & TalosConfigScope {
243
- Config : config ,
244
- ConfigOwner : owner ,
245
- Cluster : cluster ,
246
- }
247
-
248
256
if err = r .reconcileGenerate (ctx , tcScope ); err != nil {
249
257
conditions .MarkFalse (config , bootstrapv1alpha3 .DataSecretAvailableCondition , bootstrapv1alpha3 .DataSecretGenerationFailedReason , capiv1 .ConditionSeverityError , err .Error ())
250
258
@@ -341,7 +349,7 @@ func (r *TalosConfigReconciler) reconcileGenerate(ctx context.Context, tcScope *
341
349
}
342
350
343
351
config .Status .DataSecretName = & dataSecretName
344
- config .Status .TalosConfig = retData .TalosConfig
352
+ config .Status .TalosConfig = retData .TalosConfig //nolint:staticcheck // deprecated, for backwards compatibility only
345
353
346
354
return nil
347
355
}
@@ -352,19 +360,31 @@ func (r *TalosConfigReconciler) reconcileDelete(ctx context.Context, config *boo
352
360
return ctrl.Result {}, nil
353
361
}
354
362
355
- func genTalosConfigFile (clusterName string , certs * generate.Certs ) (string , error ) {
356
- talosConfig := & talosConfig {
357
- Context : clusterName ,
358
- Contexts : map [string ]* talosConfigContext {
359
- clusterName : {
360
- Target : "" ,
361
- CA : base64 .StdEncoding .EncodeToString (certs .OS .Crt ),
362
- Crt : base64 .StdEncoding .EncodeToString (certs .Admin .Crt ),
363
- Key : base64 .StdEncoding .EncodeToString (certs .Admin .Key ),
364
- },
363
+ func genTalosConfigFile (clusterName string , bundle * generate.SecretsBundle , endpoints []string ) (string , error ) {
364
+ in := & generate.Input {
365
+ ClusterName : clusterName ,
366
+ Certs : & generate.Certs {
367
+ OS : bundle .Certs .OS ,
365
368
},
366
369
}
367
370
371
+ var err error
372
+
373
+ in .Certs .Admin , err = generate .NewAdminCertificateAndKey (
374
+ bundle .Clock .Now (),
375
+ bundle .Certs .OS ,
376
+ role .MakeSet (role .Admin ),
377
+ 87600 * time .Hour ,
378
+ )
379
+ if err != nil {
380
+ return "" , err
381
+ }
382
+
383
+ talosConfig , err := generate .Talosconfig (in , generate .WithEndpointList (endpoints ))
384
+ if err != nil {
385
+ return "" , err
386
+ }
387
+
368
388
talosConfigBytes , err := yaml .Marshal (talosConfig )
369
389
if err != nil {
370
390
return "" , err
@@ -398,6 +418,15 @@ func (r *TalosConfigReconciler) userConfigs(ctx context.Context, scope *TalosCon
398
418
399
419
retBundle .BootstrapData = userConfigStr
400
420
421
+ if userConfig .Machine ().Security ().CA () != nil && len (userConfig .Machine ().Security ().CA ().Crt ) > 0 && len (userConfig .Machine ().Security ().CA ().Key ) > 0 {
422
+ bundle := generate .NewSecretsBundleFromConfig (generate .NewClock (), userConfig )
423
+
424
+ retBundle .TalosConfig , err = genTalosConfigFile (userConfig .Cluster ().Name (), bundle , nil )
425
+ if err != nil {
426
+ r .Log .Error (err , "failed generating talosconfig for user-supplied machine configuration" )
427
+ }
428
+ }
429
+
401
430
return retBundle , nil
402
431
}
403
432
@@ -453,7 +482,7 @@ func (r *TalosConfigReconciler) genConfigs(ctx context.Context, scope *TalosConf
453
482
454
483
genOptions = append (genOptions , generate .WithVersionContract (versionContract ))
455
484
456
- secretBundle , err := r .getSecretsBundle (ctx , scope , scope . Cluster . Name + "-talos" , genOptions ... )
485
+ secretBundle , err := r .getSecretsBundle (ctx , scope , true , genOptions ... )
457
486
if err != nil {
458
487
return retBundle , err
459
488
}
@@ -476,7 +505,7 @@ func (r *TalosConfigReconciler) genConfigs(ctx context.Context, scope *TalosConf
476
505
return retBundle , err
477
506
}
478
507
479
- tcString , err := genTalosConfigFile (input .ClusterName , input . Certs )
508
+ tcString , err := genTalosConfigFile (input .ClusterName , secretBundle , nil )
480
509
if err != nil {
481
510
return retBundle , err
482
511
}
0 commit comments