@@ -17,8 +17,11 @@ limitations under the License.
17
17
package bootstrapper
18
18
19
19
import (
20
+ "encoding/pem"
20
21
"fmt"
22
+ "io/ioutil"
21
23
"net"
24
+ "os"
22
25
"path"
23
26
"path/filepath"
24
27
"strings"
@@ -66,6 +69,19 @@ func SetupCerts(cmd command.Runner, k8s config.KubernetesConfig) error {
66
69
copyableFiles = append (copyableFiles , certFile )
67
70
}
68
71
72
+ caCerts , err := collectCACerts ()
73
+ if err != nil {
74
+ return err
75
+ }
76
+ for src , dst := range caCerts {
77
+ certFile , err := assets .NewFileAsset (src , path .Dir (dst ), path .Base (dst ), "0644" )
78
+ if err != nil {
79
+ return err
80
+ }
81
+
82
+ copyableFiles = append (copyableFiles , certFile )
83
+ }
84
+
69
85
kubeCfgSetup := & util.KubeConfigSetup {
70
86
ClusterName : k8s .NodeName ,
71
87
ClusterServerAddress : fmt .Sprintf ("https://localhost:%d" , k8s .NodePort ),
@@ -76,7 +92,7 @@ func SetupCerts(cmd command.Runner, k8s config.KubernetesConfig) error {
76
92
}
77
93
78
94
kubeCfg := api .NewConfig ()
79
- err : = util .PopulateKubeConfig (kubeCfgSetup , kubeCfg )
95
+ err = util .PopulateKubeConfig (kubeCfgSetup , kubeCfg )
80
96
if err != nil {
81
97
return errors .Wrap (err , "populating kubeconfig" )
82
98
}
@@ -94,6 +110,11 @@ func SetupCerts(cmd command.Runner, k8s config.KubernetesConfig) error {
94
110
return err
95
111
}
96
112
}
113
+
114
+ // configure CA certificates
115
+ if err := configureCACerts (cmd , caCerts ); err != nil {
116
+ return errors .Wrapf (err , "error configuring CA certificates during provisioning %v" , err )
117
+ }
97
118
return nil
98
119
}
99
120
@@ -197,3 +218,102 @@ func generateCerts(k8s config.KubernetesConfig) error {
197
218
198
219
return nil
199
220
}
221
+
222
+ func collectCACerts () (map [string ]string , error ) {
223
+ localPath := constants .GetMinipath ()
224
+
225
+ isValidPem := func (hostpath string ) (bool , error ) {
226
+ fileBytes , err := ioutil .ReadFile (hostpath )
227
+ if err != nil {
228
+ return false , err
229
+ }
230
+
231
+ for {
232
+ block , rest := pem .Decode (fileBytes )
233
+ if block == nil {
234
+ break
235
+ }
236
+
237
+ if block .Type == "CERTIFICATE" {
238
+ // certificate found
239
+ return true , nil
240
+ }
241
+ fileBytes = rest
242
+ }
243
+
244
+ return false , nil
245
+ }
246
+
247
+ certFiles := map [string ]string {}
248
+
249
+ certsDir := filepath .Join (localPath , "certs" )
250
+ err := filepath .Walk (certsDir , func (hostpath string , info os.FileInfo , err error ) error {
251
+ if info != nil && ! info .IsDir () {
252
+ ext := strings .ToLower (filepath .Ext (hostpath ))
253
+ if ext == ".crt" || ext == ".pem" {
254
+ validPem , err := isValidPem (hostpath )
255
+ if err != nil {
256
+ return err
257
+ }
258
+ if validPem {
259
+ filename := filepath .Base (hostpath )
260
+ dst := fmt .Sprintf ("%s.%s" , strings .TrimSuffix (filename , ext ), "pem" )
261
+ certFiles [hostpath ] = path .Join (constants .CACertificatesDir , dst )
262
+ }
263
+ }
264
+ }
265
+ return nil
266
+ })
267
+ if err != nil {
268
+ return nil , errors .Wrapf (err , "provisioning: traversal certificates dir %s" , certsDir )
269
+ }
270
+
271
+ for _ , excluded := range []string {"ca.pem" , "cert.pem" } {
272
+ certFiles [filepath .Join (certsDir , excluded )] = ""
273
+ }
274
+
275
+ // populates minikube CA
276
+ certFiles [filepath .Join (localPath , "ca.crt" )] = path .Join (constants .CACertificatesDir , "minikubeCA.pem" )
277
+
278
+ filtered := map [string ]string {}
279
+ for k , v := range certFiles {
280
+ if v != "" {
281
+ filtered [k ] = v
282
+ }
283
+ }
284
+ return filtered , nil
285
+ }
286
+
287
+ func configureCACerts (cmd command.Runner , caCerts map [string ]string ) error {
288
+ getSubjectHash := func (hostpath string ) (string , error ) {
289
+ out , err := cmd .CombinedOutput (fmt .Sprintf ("openssl x509 -hash -noout -in '%s'" , hostpath ))
290
+ if err != nil {
291
+ return "" , err
292
+ }
293
+
294
+ stringHash := strings .ReplaceAll (out , "\n " , "" )
295
+ return stringHash , nil
296
+ }
297
+
298
+ for _ , caCertFile := range caCerts {
299
+ dstFilename := path .Base (caCertFile )
300
+ certStorePath := path .Join (constants .SSLCertStoreDir , dstFilename )
301
+ if err := cmd .Run (fmt .Sprintf ("sudo test -f '%s'" , certStorePath )); err != nil {
302
+ if err := cmd .Run (fmt .Sprintf ("sudo ln -s '%s' '%s'" , caCertFile , certStorePath )); err != nil {
303
+ return errors .Wrapf (err , "error making symbol link for certificate %s" , caCertFile )
304
+ }
305
+ }
306
+ subjectHash , err := getSubjectHash (caCertFile )
307
+ if err != nil {
308
+ return errors .Wrapf (err , "error calculating subject hash for certificate %s" , caCertFile )
309
+ }
310
+ subjectHashLink := path .Join (constants .SSLCertStoreDir , fmt .Sprintf ("%s.0" , subjectHash ))
311
+ if err := cmd .Run (fmt .Sprintf ("sudo test -f '%s'" , subjectHashLink )); err != nil {
312
+ if err := cmd .Run (fmt .Sprintf ("sudo ln -s '%s' '%s'" , certStorePath , subjectHashLink )); err != nil {
313
+ return errors .Wrapf (err , "error making subject hash symbol link for certificate %s" , caCertFile )
314
+ }
315
+ }
316
+ }
317
+
318
+ return nil
319
+ }
0 commit comments