0180469127f797b67f0a1c2a7ae81a98361c6155
[oom/registrator.git] /
1 /*
2 Copyright 2014 The Kubernetes Authors.
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8     http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 */
16
17 package clientcmd
18
19 import (
20         "io"
21         "reflect"
22         "sync"
23
24         "github.com/golang/glog"
25
26         "k8s.io/kubernetes/pkg/client/restclient"
27         clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
28 )
29
30 // DeferredLoadingClientConfig is a ClientConfig interface that is backed by a client config loader.
31 // It is used in cases where the loading rules may change after you've instantiated them and you want to be sure that
32 // the most recent rules are used.  This is useful in cases where you bind flags to loading rule parameters before
33 // the parse happens and you want your calling code to be ignorant of how the values are being mutated to avoid
34 // passing extraneous information down a call stack
35 type DeferredLoadingClientConfig struct {
36         loader         ClientConfigLoader
37         overrides      *ConfigOverrides
38         fallbackReader io.Reader
39
40         clientConfig ClientConfig
41         loadingLock  sync.Mutex
42 }
43
44 // NewNonInteractiveDeferredLoadingClientConfig creates a ConfigClientClientConfig using the passed context name
45 func NewNonInteractiveDeferredLoadingClientConfig(loader ClientConfigLoader, overrides *ConfigOverrides) ClientConfig {
46         return &DeferredLoadingClientConfig{loader: loader, overrides: overrides}
47 }
48
49 // NewInteractiveDeferredLoadingClientConfig creates a ConfigClientClientConfig using the passed context name and the fallback auth reader
50 func NewInteractiveDeferredLoadingClientConfig(loader ClientConfigLoader, overrides *ConfigOverrides, fallbackReader io.Reader) ClientConfig {
51         return &DeferredLoadingClientConfig{loader: loader, overrides: overrides, fallbackReader: fallbackReader}
52 }
53
54 func (config *DeferredLoadingClientConfig) createClientConfig() (ClientConfig, error) {
55         if config.clientConfig == nil {
56                 config.loadingLock.Lock()
57                 defer config.loadingLock.Unlock()
58
59                 if config.clientConfig == nil {
60                         mergedConfig, err := config.loader.Load()
61                         if err != nil {
62                                 return nil, err
63                         }
64
65                         var mergedClientConfig ClientConfig
66                         if config.fallbackReader != nil {
67                                 mergedClientConfig = NewInteractiveClientConfig(*mergedConfig, config.overrides.CurrentContext, config.overrides, config.fallbackReader, config.loader)
68                         } else {
69                                 mergedClientConfig = NewNonInteractiveClientConfig(*mergedConfig, config.overrides.CurrentContext, config.overrides, config.loader)
70                         }
71
72                         config.clientConfig = mergedClientConfig
73                 }
74         }
75
76         return config.clientConfig, nil
77 }
78
79 func (config *DeferredLoadingClientConfig) RawConfig() (clientcmdapi.Config, error) {
80         mergedConfig, err := config.createClientConfig()
81         if err != nil {
82                 return clientcmdapi.Config{}, err
83         }
84
85         return mergedConfig.RawConfig()
86 }
87
88 // ClientConfig implements ClientConfig
89 func (config *DeferredLoadingClientConfig) ClientConfig() (*restclient.Config, error) {
90         mergedClientConfig, err := config.createClientConfig()
91         if err != nil {
92                 return nil, err
93         }
94
95         mergedConfig, err := mergedClientConfig.ClientConfig()
96         if err != nil {
97                 return nil, err
98         }
99         // Are we running in a cluster and were no other configs found? If so, use the in-cluster-config.
100         icc := inClusterClientConfig{}
101         defaultConfig, err := DefaultClientConfig.ClientConfig()
102         if icc.Possible() && err == nil && reflect.DeepEqual(mergedConfig, defaultConfig) {
103                 glog.V(2).Info("No kubeconfig could be created, falling back to service account.")
104                 return icc.ClientConfig()
105         }
106         return mergedConfig, nil
107 }
108
109 // Namespace implements KubeConfig
110 func (config *DeferredLoadingClientConfig) Namespace() (string, bool, error) {
111         mergedKubeConfig, err := config.createClientConfig()
112         if err != nil {
113                 return "", false, err
114         }
115
116         return mergedKubeConfig.Namespace()
117 }
118
119 // ConfigAccess implements ClientConfig
120 func (config *DeferredLoadingClientConfig) ConfigAccess() ConfigAccess {
121         return config.loader
122 }