@@ -34,27 +34,74 @@ func (r *TalosConfigReconciler) fetchSecret(ctx context.Context, config *bootstr
34
34
return retSecret , nil
35
35
}
36
36
37
- func (r * TalosConfigReconciler ) writeInputSecret (ctx context.Context , scope * TalosConfigScope , input * generate.Input ) (* corev1.Secret , error ) {
37
+ // getSecretsBundle either generates or loads existing secret.
38
+ func (r * TalosConfigReconciler ) getSecretsBundle (ctx context.Context , scope * TalosConfigScope , secretName string , opts ... generate.GenOption ) (* generate.SecretsBundle , error ) {
39
+ var secretsBundle * generate.SecretsBundle
38
40
39
- certMarshal , err := yaml .Marshal (input .Certs )
40
- if err != nil {
41
- return nil , err
42
- }
41
+ retry:
42
+ secret , err := r .fetchSecret (ctx , scope .Config , secretName )
43
43
44
- kubeSecretsMarshal , err := yaml .Marshal (input .Secrets )
45
- if err != nil {
46
- return nil , err
44
+ switch {
45
+ case err != nil && k8serrors .IsNotFound (err ):
46
+ // no cluster secret yet, generate new one
47
+ secretsBundle , err = generate .NewSecretsBundle (generate .NewClock (), opts ... )
48
+ if err != nil {
49
+ return nil , fmt .Errorf ("error generating new secrets bundle: %w" , err )
50
+ }
51
+
52
+ if err = r .writeSecretsBundleSecret (ctx , scope , secretName , secretsBundle ); err != nil {
53
+ if k8serrors .IsAlreadyExists (err ) {
54
+ // conflict on creation, retry loading
55
+ goto retry
56
+ }
57
+
58
+ return nil , fmt .Errorf ("error writing secrets bundle: %w" , err )
59
+ }
60
+ case err != nil :
61
+ return nil , fmt .Errorf ("error reading secrets bundle: %w" , err )
62
+ default :
63
+ // successfully loaded secret, initialize secretsBundle from it
64
+ secretsBundle = & generate.SecretsBundle {
65
+ Clock : generate .NewClock (),
66
+ }
67
+
68
+ if _ , ok := secret .Data ["bundle" ]; ok {
69
+ // new format
70
+ if err = yaml .Unmarshal (secret .Data ["bundle" ], secretsBundle ); err != nil {
71
+ return nil , fmt .Errorf ("error unmarshaling secrets bundle: %w" , err )
72
+ }
73
+ } else {
74
+ // legacy format
75
+ if err = yaml .Unmarshal (secret .Data ["certs" ], & secretsBundle .Certs ); err != nil {
76
+ return nil , fmt .Errorf ("error unmarshaling certs: %w" , err )
77
+ }
78
+
79
+ if err = yaml .Unmarshal (secret .Data ["kubeSecrets" ], & secretsBundle .Secrets ); err != nil {
80
+ return nil , fmt .Errorf ("error unmarshaling secrets: %w" , err )
81
+ }
82
+
83
+ if err = yaml .Unmarshal (secret .Data ["trustdInfo" ], & secretsBundle .TrustdInfo ); err != nil {
84
+ return nil , fmt .Errorf ("error unmarshaling trustd info: %w" , err )
85
+ }
86
+
87
+ // not stored in legacy format, use empty values
88
+ secretsBundle .Cluster = & generate.Cluster {}
89
+ }
47
90
}
48
91
49
- trustdInfoMarshal , err := yaml .Marshal (input .TrustdInfo )
92
+ return secretsBundle , nil
93
+ }
94
+
95
+ func (r * TalosConfigReconciler ) writeSecretsBundleSecret (ctx context.Context , scope * TalosConfigScope , secretName string , secretsBundle * generate.SecretsBundle ) error {
96
+ bundle , err := yaml .Marshal (secretsBundle )
50
97
if err != nil {
51
- return nil , err
98
+ return fmt . Errorf ( "error marshaling secrets bundle: %w" , err )
52
99
}
53
100
54
- certSecret := & corev1.Secret {
101
+ secret := & corev1.Secret {
55
102
ObjectMeta : metav1.ObjectMeta {
56
103
Namespace : scope .Config .Namespace ,
57
- Name : scope . Cluster . Name + "-talos" ,
104
+ Name : secretName ,
58
105
Labels : map [string ]string {
59
106
capiv1 .ClusterLabelName : scope .Cluster .Name ,
60
107
},
@@ -63,45 +110,43 @@ func (r *TalosConfigReconciler) writeInputSecret(ctx context.Context, scope *Tal
63
110
},
64
111
},
65
112
Data : map [string ][]byte {
66
- "certs" : certMarshal ,
67
- "kubeSecrets" : kubeSecretsMarshal ,
68
- "trustdInfo" : trustdInfoMarshal ,
113
+ "bundle" : bundle ,
69
114
},
70
115
}
71
116
72
- err = r .Client .Create (ctx , certSecret )
73
- if err != nil {
74
- return nil , err
75
- }
76
- return certSecret , nil
117
+ return r .Client .Create (ctx , secret )
77
118
}
78
119
79
120
func (r * TalosConfigReconciler ) writeK8sCASecret (ctx context.Context , scope * TalosConfigScope , certs * x509.PEMEncodedCertificateAndKey ) error {
80
121
// Create ca secret only if it doesn't already exist
81
122
_ , err := r .fetchSecret (ctx , scope .Config , scope .Cluster .Name + "-ca" )
82
- if k8serrors .IsNotFound (err ) {
83
- certSecret := & corev1.Secret {
84
- ObjectMeta : metav1.ObjectMeta {
85
- Namespace : scope .Config .Namespace ,
86
- Name : scope .Cluster .Name + "-ca" ,
87
- Labels : map [string ]string {
88
- capiv1 .ClusterLabelName : scope .Cluster .Name ,
89
- },
90
- OwnerReferences : []metav1.OwnerReference {
91
- * metav1 .NewControllerRef (scope .Cluster , capiv1 .GroupVersion .WithKind ("Cluster" )),
92
- },
123
+ if err == nil {
124
+ return nil
125
+ }
126
+
127
+ if ! k8serrors .IsNotFound (err ) {
128
+ return err
129
+ }
130
+
131
+ certSecret := & corev1.Secret {
132
+ ObjectMeta : metav1.ObjectMeta {
133
+ Namespace : scope .Config .Namespace ,
134
+ Name : scope .Cluster .Name + "-ca" ,
135
+ Labels : map [string ]string {
136
+ capiv1 .ClusterLabelName : scope .Cluster .Name ,
93
137
},
94
- Data : map [string ][]byte {
95
- "tls.crt" : certs .Crt ,
96
- "tls.key" : certs .Key ,
138
+ OwnerReferences : []metav1.OwnerReference {
139
+ * metav1 .NewControllerRef (scope .Cluster , capiv1 .GroupVersion .WithKind ("Cluster" )),
97
140
},
98
- }
141
+ },
142
+ Data : map [string ][]byte {
143
+ "tls.crt" : certs .Crt ,
144
+ "tls.key" : certs .Key ,
145
+ },
146
+ }
99
147
100
- err = r .Client .Create (ctx , certSecret )
101
- if err != nil {
102
- return err
103
- }
104
- } else if err != nil {
148
+ err = r .Client .Create (ctx , certSecret )
149
+ if err != nil && ! k8serrors .IsAlreadyExists (err ) {
105
150
return err
106
151
}
107
152
0 commit comments