@@ -2,6 +2,7 @@ package main
2
2
3
3
import (
4
4
"context"
5
+ "crypto/x509"
5
6
"fmt"
6
7
"io/ioutil"
7
8
"path/filepath"
@@ -12,6 +13,7 @@ import (
12
13
"github.com/sirupsen/logrus"
13
14
"github.com/spf13/cobra"
14
15
corev1 "k8s.io/api/core/v1"
16
+ apierrors "k8s.io/apimachinery/pkg/api/errors"
15
17
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
16
18
"k8s.io/apimachinery/pkg/fields"
17
19
"k8s.io/apimachinery/pkg/util/wait"
@@ -116,6 +118,10 @@ var (
116
118
logrus .Fatal (err )
117
119
}
118
120
121
+ if err = addRouterCAToClusterCA (config , rootOpts .dir ); err != nil {
122
+ logrus .Fatal (err )
123
+ }
124
+
119
125
err = logComplete (rootOpts .dir , consoleURL )
120
126
if err != nil {
121
127
logrus .Fatal (err )
@@ -186,6 +192,56 @@ func runTargetCmd(targets ...asset.WritableAsset) func(cmd *cobra.Command, args
186
192
}
187
193
}
188
194
195
+ // addRouterCAToClusterCA adds router CA to cluster CA in kubeconfig
196
+ func addRouterCAToClusterCA (config * rest.Config , directory string ) (err error ) {
197
+ client , err := kubernetes .NewForConfig (config )
198
+ if err != nil {
199
+ return errors .Wrap (err , "creating a Kubernetes client" )
200
+ }
201
+
202
+ // Configmap may not exist. log and accept not-found errors with configmap.
203
+ caConfigMap , err := client .CoreV1 ().ConfigMaps ("openshift-config-managed" ).Get ("router-ca" , metav1.GetOptions {})
204
+ if err != nil {
205
+ if apierrors .IsNotFound (err ) {
206
+ logrus .Infof ("router-ca resource not found in cluster, perhaps you are not using default router CA" )
207
+ return nil
208
+ }
209
+ return errors .Wrap (err , "fetching router-ca configmap from openshift-config-managed namespace" )
210
+ }
211
+
212
+ routerCrtBytes := []byte (caConfigMap .Data ["ca-bundle.crt" ])
213
+ kubeconfig := filepath .Join (directory , "auth" , "kubeconfig" )
214
+ kconfig , err := clientcmd .LoadFromFile (kubeconfig )
215
+ if err != nil {
216
+ return errors .Wrap (err , "loading kubeconfig" )
217
+ }
218
+
219
+ if kconfig == nil || len (kconfig .Clusters ) == 0 {
220
+ return errors .New ("kubeconfig is missing expected data" )
221
+ }
222
+
223
+ for _ , c := range kconfig .Clusters {
224
+ clusterCABytes := c .CertificateAuthorityData
225
+ if len (clusterCABytes ) == 0 {
226
+ return errors .New ("kubeconfig CertificateAuthorityData not found" )
227
+ }
228
+ certPool := x509 .NewCertPool ()
229
+ if ! certPool .AppendCertsFromPEM (clusterCABytes ) {
230
+ return errors .New ("cluster CA found in kubeconfig not valid PEM format" )
231
+ }
232
+ if ! certPool .AppendCertsFromPEM (routerCrtBytes ) {
233
+ return errors .New ("ca-bundle.crt from router-ca configmap not valid PEM format" )
234
+ }
235
+
236
+ newCA := append (routerCrtBytes , clusterCABytes ... )
237
+ c .CertificateAuthorityData = newCA
238
+ }
239
+ if err := clientcmd .WriteToFile (* kconfig , kubeconfig ); err != nil {
240
+ return errors .Wrap (err , "writing kubeconfig" )
241
+ }
242
+ return nil
243
+ }
244
+
189
245
// FIXME: pulling the kubeconfig and metadata out of the root
190
246
// directory is a bit cludgy when we already have them in memory.
191
247
func destroyBootstrap (ctx context.Context , config * rest.Config , directory string ) (err error ) {
0 commit comments