@@ -28,6 +28,7 @@ import (
28
28
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
29
29
certutil "k8s.io/client-go/util/cert"
30
30
"k8s.io/client-go/util/keyutil"
31
+ certsphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs"
31
32
pkiutil "k8s.io/kubernetes/cmd/kubeadm/app/util/pkiutil"
32
33
)
33
34
@@ -104,14 +105,19 @@ type kubeConfigReadWriter struct {
104
105
kubeConfigFileName string
105
106
kubeConfigFilePath string
106
107
kubeConfig * clientcmdapi.Config
108
+ baseName string
109
+ certificateDir string
110
+ caCert * x509.Certificate
107
111
}
108
112
109
113
// newKubeconfigReadWriter return a new kubeConfigReadWriter
110
- func newKubeconfigReadWriter (kubernetesDir string , kubeConfigFileName string ) * kubeConfigReadWriter {
114
+ func newKubeconfigReadWriter (kubernetesDir string , kubeConfigFileName string , certificateDir , baseName string ) * kubeConfigReadWriter {
111
115
return & kubeConfigReadWriter {
112
116
kubernetesDir : kubernetesDir ,
113
117
kubeConfigFileName : kubeConfigFileName ,
114
118
kubeConfigFilePath : filepath .Join (kubernetesDir , kubeConfigFileName ),
119
+ certificateDir : certificateDir ,
120
+ baseName : baseName ,
115
121
}
116
122
}
117
123
@@ -130,6 +136,16 @@ func (rw *kubeConfigReadWriter) Read() (*x509.Certificate, error) {
130
136
return nil , errors .Wrapf (err , "failed to load kubeConfig file %s" , rw .kubeConfigFilePath )
131
137
}
132
138
139
+ // The CA cert is required for updating kubeconfig files.
140
+ // For local CA renewal, the local CA on disk could have changed, thus a reload is needed.
141
+ // For CSR renewal we assume the same CA on disk is mounted for usage with KCM's
142
+ // '--cluster-signing-cert-file' flag.
143
+ caCert , _ , err := certsphase .LoadCertificateAuthority (rw .certificateDir , rw .baseName )
144
+ if err != nil {
145
+ return nil , err
146
+ }
147
+ rw .caCert = caCert
148
+
133
149
// get current context
134
150
if _ , ok := kubeConfig .Contexts [kubeConfig .CurrentContext ]; ! ok {
135
151
return nil , errors .Errorf ("invalid kubeConfig file %s: missing context %s" , rw .kubeConfigFilePath , kubeConfig .CurrentContext )
@@ -143,7 +159,7 @@ func (rw *kubeConfigReadWriter) Read() (*x509.Certificate, error) {
143
159
144
160
cluster := kubeConfig .Clusters [clusterName ]
145
161
if len (cluster .CertificateAuthorityData ) == 0 {
146
- return nil , errors .Errorf ("kubeConfig file %s does not have and embedded server certificate" , rw .kubeConfigFilePath )
162
+ return nil , errors .Errorf ("kubeConfig file %s does not have an embedded server certificate" , rw .kubeConfigFilePath )
147
163
}
148
164
149
165
// get auth info for current context and ensure a client certificate is embedded in it
@@ -154,7 +170,7 @@ func (rw *kubeConfigReadWriter) Read() (*x509.Certificate, error) {
154
170
155
171
authInfo := kubeConfig .AuthInfos [authInfoName ]
156
172
if len (authInfo .ClientCertificateData ) == 0 {
157
- return nil , errors .Errorf ("kubeConfig file %s does not have and embedded client certificate" , rw .kubeConfigFilePath )
173
+ return nil , errors .Errorf ("kubeConfig file %s does not have an embedded client certificate" , rw .kubeConfigFilePath )
158
174
}
159
175
160
176
// parse the client certificate, retrive the cert config and then renew it
@@ -174,7 +190,7 @@ func (rw *kubeConfigReadWriter) Read() (*x509.Certificate, error) {
174
190
func (rw * kubeConfigReadWriter ) Write (newCert * x509.Certificate , newKey crypto.Signer ) error {
175
191
// check if Read was called before Write
176
192
if rw .kubeConfig == nil {
177
- return errors .Errorf ("failed to Write kubeConfig file with renewd certs. It is necessary to call Read before Write" )
193
+ return errors .Errorf ("failed to Write kubeConfig file with renewed certs. It is necessary to call Read before Write" )
178
194
}
179
195
180
196
// encodes the new key
@@ -183,6 +199,12 @@ func (rw *kubeConfigReadWriter) Write(newCert *x509.Certificate, newKey crypto.S
183
199
return errors .Wrapf (err , "failed to marshal private key to PEM" )
184
200
}
185
201
202
+ // Update the embedded CA in the kubeconfig file.
203
+ // This assumes that the user has kept the current context to the desired one.
204
+ clusterName := rw .kubeConfig .Contexts [rw .kubeConfig .CurrentContext ].Cluster
205
+ cluster := rw .kubeConfig .Clusters [clusterName ]
206
+ cluster .CertificateAuthorityData = pkiutil .EncodeCertPEM (rw .caCert )
207
+
186
208
// get auth info for current context and ensure a client certificate is embedded in it
187
209
authInfoName := rw .kubeConfig .Contexts [rw .kubeConfig .CurrentContext ].AuthInfo
188
210
0 commit comments