Skip to content

Commit

Permalink
Allow in-cluster config for oc
Browse files Browse the repository at this point in the history
Because we set the default env value to empty, we can't use the default
in cluster config for 'oc' (when you run inside a container, oc works).
It's really important for container integration scenarios that oc uses
the service account token by default, just like kubeconfig.
  • Loading branch information
smarterclayton committed Nov 5, 2015
1 parent d512cd0 commit 41215b8
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 3 deletions.
2 changes: 1 addition & 1 deletion hack/test-cmd.sh
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ atomic-enterprise start \
"${NODE_CONFIG_DIR}/node-config.yaml"

# test client not configured
[ "$(oc get services 2>&1 | grep 'Error in configuration')" ]
[ "$(oc get services 2>&1 | grep 'No configuration file found, please login')" ]

# Set KUBERNETES_MASTER for oc from now on
export KUBERNETES_MASTER="${API_SCHEME}://${API_HOST}:${API_PORT}"
Expand Down
56 changes: 54 additions & 2 deletions pkg/cmd/util/clientcmd/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package clientcmd
import (
"errors"
"fmt"
"os"
"reflect"
"sort"
"strconv"
"time"
Expand All @@ -13,6 +15,7 @@ import (
"k8s.io/kubernetes/pkg/api/meta"
kclient "k8s.io/kubernetes/pkg/client/unversioned"
kclientcmd "k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
kclientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
"k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/kubectl"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
Expand All @@ -33,24 +36,73 @@ import (
routegen "github.com/openshift/origin/pkg/route/generator"
)

// defaultClusterConfigURL is a local name that is used to identify when the client config
// is unspecified.
const defaultClusterConfigURL = "https://localhost:8443"

// New creates a default Factory for commands that should share identical server
// connection behavior. Most commands should use this method to get a factory.
func New(flags *pflag.FlagSet) *Factory {
// Override global default to "" so we force the client to ask for user input
// TODO refactor this upstream:
// DefaultCluster should not be a global
// A call to ClientConfig() should always return the best clientCfg possible
// even if an error was returned, and let the caller decide what to do
kclientcmd.DefaultCluster.Server = ""
kclientcmd.DefaultCluster.Server = defaultClusterConfigURL

// TODO: there should be two client configs, one for OpenShift, and one for Kubernetes
clientConfig := DefaultClientConfig(flags)
clientConfig = defaultingClientConfig{clientConfig}
f := NewFactory(clientConfig)
f.BindFlags(flags)

return f
}

// defaultingClientConfig detects whether the provided config is the default, and if
// so returns an error that indicates the user should set up their config.
type defaultingClientConfig struct {
nested kclientcmd.ClientConfig
}

// RawConfig calls the nested method
func (c defaultingClientConfig) RawConfig() (kclientcmdapi.Config, error) {
return c.nested.RawConfig()
}

// Namespace calls the nested method
func (c defaultingClientConfig) Namespace() (string, bool, error) {
return c.nested.Namespace()
}

// ClientConfig returns a complete client config
func (c defaultingClientConfig) ClientConfig() (*kclient.Config, error) {
cfg, err := c.nested.ClientConfig()
if err != nil {
return nil, err
}
if isDefaultConfig(cfg) {
return nil, fmt.Errorf(`No configuration file found, please login or point to an existing file:
1. Via the command-line flag --config
2. Via the KUBECONFIG environment variable
3. In your home directory as ~/.kube/config
To view or setup config directly use the 'config' command.`)
}
return cfg, nil
}

func isDefaultConfig(cfg *kclient.Config) bool {
if len(os.Getenv("KUBERNETES_MASTER")) > 0 {
return false
}
defaultConfig, err := kclientcmd.DefaultClientConfig.ClientConfig()
if err != nil {
return false
}
return reflect.DeepEqual(cfg, defaultConfig)
}

// Factory provides common options for OpenShift commands
type Factory struct {
*cmdutil.Factory
Expand Down

0 comments on commit 41215b8

Please sign in to comment.