Skip to content

Commit a5f322e

Browse files
Allow in-cluster config for oc
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.
1 parent f9d8378 commit a5f322e

File tree

4 files changed

+83
-3
lines changed

4 files changed

+83
-3
lines changed

hack/test-cmd.sh

+6-1
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,12 @@ atomic-enterprise start \
187187
"${NODE_CONFIG_DIR}/node-config.yaml"
188188

189189
# test client not configured
190-
[ "$(oc get services 2>&1 | grep 'Error in configuration')" ]
190+
[ "$(oc get services 2>&1 | grep 'No configuration file found, please login')" ]
191+
unused_port="33333"
192+
# setting env bypasses the not configured message
193+
[ "$(KUBERNETES_MASTER=http://${API_HOST}:${unused_port} oc get services 2>&1 | grep 'did you specify the right host or port')" ]
194+
# setting --server bypasses the not configured message
195+
[ "$(oc get services --server=http://${API_HOST}:${unused_port} 2>&1 | grep 'did you specify the right host or port')" ]
191196

192197
# Set KUBERNETES_MASTER for oc from now on
193198
export KUBERNETES_MASTER="${API_SCHEME}://${API_HOST}:${API_PORT}"

hack/util.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ function configure_os_server {
6565
# find the same IP that openshift start will bind to. This allows access from pods that have to talk back to master
6666
if [[ -z "${ALL_IP_ADDRESSES-}" ]]; then
6767
ALL_IP_ADDRESSES="$(openshift start --print-ip)"
68-
SERVER_HOSTNAME_LIST="${PUBLIC_MASTER_HOST},localhost"
68+
SERVER_HOSTNAME_LIST="${PUBLIC_MASTER_HOST},localhost,172.30.0.1"
6969

7070
while read -r IP_ADDRESS
7171
do

pkg/cmd/util/clientcmd/factory.go

+60-1
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,20 @@ package clientcmd
33
import (
44
"errors"
55
"fmt"
6+
"os"
67
"sort"
78
"strconv"
89
"time"
910

11+
"github.com/golang/glog"
12+
1013
"github.com/spf13/pflag"
1114
"k8s.io/kubernetes/pkg/api"
1215
kerrors "k8s.io/kubernetes/pkg/api/errors"
1316
"k8s.io/kubernetes/pkg/api/meta"
1417
kclient "k8s.io/kubernetes/pkg/client/unversioned"
1518
kclientcmd "k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
19+
kclientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
1620
"k8s.io/kubernetes/pkg/fields"
1721
"k8s.io/kubernetes/pkg/kubectl"
1822
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
@@ -36,7 +40,6 @@ import (
3640
// New creates a default Factory for commands that should share identical server
3741
// connection behavior. Most commands should use this method to get a factory.
3842
func New(flags *pflag.FlagSet) *Factory {
39-
// Override global default to "" so we force the client to ask for user input
4043
// TODO refactor this upstream:
4144
// DefaultCluster should not be a global
4245
// A call to ClientConfig() should always return the best clientCfg possible
@@ -45,12 +48,68 @@ func New(flags *pflag.FlagSet) *Factory {
4548

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

5155
return f
5256
}
5357

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+
54113
// Factory provides common options for OpenShift commands
55114
type Factory struct {
56115
*cmdutil.Factory

test/end-to-end/core.sh

+16
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,22 @@ oc login -u e2e-user
137137
oc project test
138138
oc whoami
139139

140+
echo "[INFO] Running a CLI command in a container using the service account"
141+
oc policy add-role-to-user view -z default
142+
out=$(oc run cli-with-token --attach --env=POD_NAMESPACE=test --image=openshift/origin:${TAG} --restart=Never -- cli status --loglevel=4 2>&1)
143+
echo $out
144+
[ "$(echo $out | grep 'Using in-cluster configuration')" ]
145+
[ "$(echo $out | grep 'In project test')" ]
146+
oc delete pod cli-with-token
147+
out=$(oc run cli-with-token-2 --attach --env=POD_NAMESPACE=test --image=openshift/origin:${TAG} --restart=Never -- cli whoami --loglevel=4 2>&1)
148+
echo $out
149+
[ "$(echo $out | grep 'system:serviceaccount:test:default')" ]
150+
oc delete pod cli-with-token-2
151+
out=$(oc run kubectl-with-token --attach --env=POD_NAMESPACE=test --image=openshift/origin:${TAG} --restart=Never --command -- kubectl get pods --loglevel=4 2>&1)
152+
echo $out
153+
[ "$(echo $out | grep 'Using in-cluster configuration')" ]
154+
[ "$(echo $out | grep 'kubectl-with-token')" ]
155+
140156
echo "[INFO] Streaming the logs from a deployment twice..."
141157
oc create -f test/fixtures/failing-dc.yaml
142158
tryuntil oc get rc/failing-dc-1

0 commit comments

Comments
 (0)