@@ -28,9 +28,14 @@ import (
2828 authenticationv1 "k8s.io/api/authentication/v1"
2929 authorizationv1 "k8s.io/api/authorization/v1"
3030 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
31+ "k8s.io/apimachinery/pkg/fields"
3132 "k8s.io/apimachinery/pkg/util/wait"
3233 "k8s.io/apiserver/pkg/authentication/authenticator"
3334 "k8s.io/apiserver/pkg/authorization/authorizer"
35+ "k8s.io/client-go/informers"
36+ corev1listers "k8s.io/client-go/listers/core/v1"
37+ "k8s.io/client-go/rest"
38+ "k8s.io/client-go/tools/clientcmd"
3439)
3540
3641func emptyURL (u * url.URL ) bool {
@@ -45,13 +50,15 @@ type OpenShiftProvider struct {
4550
4651 AuthenticationOptions DelegatingAuthenticationOptions
4752 AuthorizationOptions DelegatingAuthorizationOptions
53+ KubeClientOptions KubeClientOptions
4854
49- authenticator authenticator.Request
50- authorizer authorizer.Authorizer
51- defaultRecord authorizer.AttributesRecord
52- reviews []string
53- paths recordsByPath
54- hostreviews map [string ][]string
55+ authenticator authenticator.Request
56+ authorizer authorizer.Authorizer
57+ configMapLister corev1listers.ConfigMapLister
58+ defaultRecord authorizer.AttributesRecord
59+ reviews []string
60+ paths recordsByPath
61+ hostreviews map [string ][]string
5562
5663 // httpClientCache stores httpClient objects so that new client does not have to
5764 // be created on each request just to prevent CAs content changed
@@ -83,6 +90,7 @@ func (p *OpenShiftProvider) SetClientCAFile(file string) {
8390}
8491
8592func (p * OpenShiftProvider ) Bind (flags * flag.FlagSet ) {
93+ p .KubeClientOptions .AddFlags (flags )
8694 p .AuthenticationOptions .AddFlags (flags )
8795 p .AuthorizationOptions .AddFlags (flags )
8896}
@@ -145,7 +153,17 @@ func (p *OpenShiftProvider) newOpenShiftClient() (*http.Client, error) {
145153
146154 // try to retrieve a cached client
147155 metadataHash , err := util .GetFilesMetadataHash (capaths )
148- if httpClient , ok := p .httpClientCache .Load (metadataHash ); ok {
156+ if err != nil {
157+ return nil , err
158+ }
159+
160+ oauthServerCert , err := p .configMapLister .ConfigMaps ("openshift-config-managed" ).Get ("oauth-serving-cert" )
161+ if err != nil {
162+ return nil , err
163+ }
164+
165+ cachedKey := metadataHash + oauthServerCert .ResourceVersion
166+ if httpClient , ok := p .httpClientCache .Load (cachedKey ); ok {
149167 return httpClient .(* http.Client ), nil
150168 }
151169
@@ -155,6 +173,10 @@ func (p *OpenShiftProvider) newOpenShiftClient() (*http.Client, error) {
155173 return nil , err
156174 }
157175
176+ if ok := pool .AppendCertsFromPEM ([]byte (oauthServerCert .Data ["ca-bundle.crt" ])); ! ok {
177+ log .Println ("failed to add the oauth-server certificate to the OpenShift client CA bundle" )
178+ }
179+
158180 httpClient := & http.Client {
159181 Jar : http .DefaultClient .Jar ,
160182 Transport : & http.Transport {
@@ -163,7 +185,7 @@ func (p *OpenShiftProvider) newOpenShiftClient() (*http.Client, error) {
163185 },
164186 Timeout : 1 * time .Minute ,
165187 }
166- p .httpClientCache .Store (metadataHash , httpClient )
188+ p .httpClientCache .Store (cachedKey , httpClient )
167189
168190 return httpClient , nil
169191}
@@ -310,6 +332,21 @@ func (p *OpenShiftProvider) Complete(data *providers.ProviderData, reviewURL *ur
310332 p .ProviderData = data
311333 p .ReviewURL = reviewURL
312334
335+ kubeClient , err := p .KubeClientOptions .ToKubeClientConfig ()
336+ if err != nil {
337+ return err
338+ }
339+
340+ kubeInformersMachineConfigNS := informers .NewSharedInformerFactoryWithOptions (
341+ kubeClient ,
342+ 10 * time .Minute ,
343+ informers .WithNamespace ("openshift-config-managed" ),
344+ informers .WithTweakListOptions (func (opts * metav1.ListOptions ) {
345+ opts .FieldSelector = fields .OneTermEqualSelector ("metadata.name" , "oauth-serving-cert" ).String ()
346+ }))
347+ go kubeInformersMachineConfigNS .Core ().V1 ().ConfigMaps ().Informer ().Run (context .TODO ().Done ())
348+ p .configMapLister = kubeInformersMachineConfigNS .Core ().V1 ().ConfigMaps ().Lister ()
349+
313350 if len (p .paths ) > 0 {
314351 log .Printf ("Delegation of authentication and authorization to OpenShift is enabled for bearer tokens and client certificates." )
315352
@@ -655,3 +692,28 @@ func getKubeAPIURLWithPath(path string) *url.URL {
655692
656693 return ret
657694}
695+
696+ func GetClientConfig (remoteKubeConfigFile string ) (* rest.Config , error ) {
697+ var clientConfig * rest.Config
698+ var err error
699+ if len (remoteKubeConfigFile ) > 0 {
700+ loadingRules := & clientcmd.ClientConfigLoadingRules {ExplicitPath : remoteKubeConfigFile }
701+ loader := clientcmd .NewNonInteractiveDeferredLoadingClientConfig (loadingRules , & clientcmd.ConfigOverrides {})
702+
703+ clientConfig , err = loader .ClientConfig ()
704+
705+ } else {
706+ // without the remote kubeconfig file, try to use the in-cluster config. Most addon API servers will
707+ // use this path
708+ clientConfig , err = rest .InClusterConfig ()
709+ }
710+ if err != nil {
711+ return nil , err
712+ }
713+
714+ // set high qps/burst limits since this will effectively limit API server responsiveness
715+ clientConfig .QPS = 200
716+ clientConfig .Burst = 400
717+
718+ return clientConfig , nil
719+ }
0 commit comments