@@ -3,16 +3,20 @@ package clientcmd
3
3
import (
4
4
"errors"
5
5
"fmt"
6
+ "os"
6
7
"sort"
7
8
"strconv"
8
9
"time"
9
10
11
+ "github.com/golang/glog"
12
+
10
13
"github.com/spf13/pflag"
11
14
"k8s.io/kubernetes/pkg/api"
12
15
kerrors "k8s.io/kubernetes/pkg/api/errors"
13
16
"k8s.io/kubernetes/pkg/api/meta"
14
17
kclient "k8s.io/kubernetes/pkg/client/unversioned"
15
18
kclientcmd "k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
19
+ kclientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
16
20
"k8s.io/kubernetes/pkg/fields"
17
21
"k8s.io/kubernetes/pkg/kubectl"
18
22
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
@@ -36,7 +40,6 @@ import (
36
40
// New creates a default Factory for commands that should share identical server
37
41
// connection behavior. Most commands should use this method to get a factory.
38
42
func New (flags * pflag.FlagSet ) * Factory {
39
- // Override global default to "" so we force the client to ask for user input
40
43
// TODO refactor this upstream:
41
44
// DefaultCluster should not be a global
42
45
// A call to ClientConfig() should always return the best clientCfg possible
@@ -45,12 +48,68 @@ func New(flags *pflag.FlagSet) *Factory {
45
48
46
49
// TODO: there should be two client configs, one for OpenShift, and one for Kubernetes
47
50
clientConfig := DefaultClientConfig (flags )
51
+ clientConfig = defaultingClientConfig {clientConfig }
48
52
f := NewFactory (clientConfig )
49
53
f .BindFlags (flags )
50
54
51
55
return f
52
56
}
53
57
58
+ // defaultingClientConfig detects whether the provided config is the default, and if
59
+ // so returns an error that indicates the user should set up their config.
60
+ type defaultingClientConfig struct {
61
+ nested kclientcmd.ClientConfig
62
+ }
63
+
64
+ // RawConfig calls the nested method
65
+ func (c defaultingClientConfig ) RawConfig () (kclientcmdapi.Config , error ) {
66
+ return c .nested .RawConfig ()
67
+ }
68
+
69
+ // Namespace calls the nested method, and if an empty config error is returned
70
+ // it checks for the same default as kubectl - the value of POD_NAMESPACE or
71
+ // "default".
72
+ func (c defaultingClientConfig ) Namespace () (string , bool , error ) {
73
+ namespace , ok , err := c .nested .Namespace ()
74
+ if err == nil {
75
+ return namespace , ok , nil
76
+ }
77
+ if ! kclientcmd .IsEmptyConfig (err ) {
78
+ return "" , false , err
79
+ }
80
+ // TODO: can we inject the namespace as a file in the secret?
81
+ namespace = os .Getenv ("POD_NAMESPACE" )
82
+ if len (namespace ) == 0 {
83
+ return api .NamespaceDefault , false , nil
84
+ }
85
+ return namespace , true , nil
86
+ }
87
+
88
+ // ClientConfig returns a complete client config
89
+ func (c defaultingClientConfig ) ClientConfig () (* kclient.Config , error ) {
90
+ cfg , err := c .nested .ClientConfig ()
91
+ if err == nil {
92
+ return cfg , nil
93
+ }
94
+
95
+ if ! kclientcmd .IsEmptyConfig (err ) {
96
+ return nil , err
97
+ }
98
+
99
+ if icc , err := kclient .InClusterConfig (); err == nil {
100
+ glog .V (4 ).Infof ("Using in-cluster configuration" )
101
+ return icc , nil
102
+ }
103
+
104
+ return nil , fmt .Errorf (`No configuration file found, please login or point to an existing file:
105
+
106
+ 1. Via the command-line flag --config
107
+ 2. Via the KUBECONFIG environment variable
108
+ 3. In your home directory as ~/.kube/config
109
+
110
+ To view or setup config directly use the 'config' command.` )
111
+ }
112
+
54
113
// Factory provides common options for OpenShift commands
55
114
type Factory struct {
56
115
* cmdutil.Factory
0 commit comments