diff --git a/cmd/cloud-controller-manager/app/BUILD b/cmd/cloud-controller-manager/app/BUILD index 381a6e9ae39..f3a1fc2387c 100644 --- a/cmd/cloud-controller-manager/app/BUILD +++ b/cmd/cloud-controller-manager/app/BUILD @@ -19,7 +19,6 @@ go_library( "//pkg/client/leaderelection:go_default_library", "//pkg/client/leaderelection/resourcelock:go_default_library", "//pkg/client/record:go_default_library", - "//pkg/client/unversioned/clientcmd:go_default_library", "//pkg/cloudprovider:go_default_library", "//pkg/controller:go_default_library", "//pkg/controller/cloud:go_default_library", @@ -35,6 +34,7 @@ go_library( "//vendor:k8s.io/apimachinery/pkg/util/wait", "//vendor:k8s.io/apiserver/pkg/server/healthz", "//vendor:k8s.io/client-go/rest", + "//vendor:k8s.io/client-go/tools/clientcmd", ], ) diff --git a/cmd/cloud-controller-manager/app/controllermanager.go b/cmd/cloud-controller-manager/app/controllermanager.go index 4dbbec9c45a..9946ff65d39 100644 --- a/cmd/cloud-controller-manager/app/controllermanager.go +++ b/cmd/cloud-controller-manager/app/controllermanager.go @@ -29,6 +29,7 @@ import ( "k8s.io/apimachinery/pkg/util/wait" "k8s.io/apiserver/pkg/server/healthz" restclient "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" "k8s.io/kubernetes/cmd/cloud-controller-manager/app/options" "k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/client/clientset_generated/clientset" @@ -36,7 +37,6 @@ import ( "k8s.io/kubernetes/pkg/client/leaderelection" "k8s.io/kubernetes/pkg/client/leaderelection/resourcelock" "k8s.io/kubernetes/pkg/client/record" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" "k8s.io/kubernetes/pkg/cloudprovider" "k8s.io/kubernetes/pkg/controller" nodecontroller "k8s.io/kubernetes/pkg/controller/cloud" diff --git a/cmd/kube-controller-manager/app/BUILD b/cmd/kube-controller-manager/app/BUILD index 32b64137378..94ffd25ca14 100644 --- a/cmd/kube-controller-manager/app/BUILD +++ b/cmd/kube-controller-manager/app/BUILD @@ -36,7 +36,6 @@ go_library( "//pkg/client/record:go_default_library", "//pkg/client/typed/discovery:go_default_library", "//pkg/client/typed/dynamic:go_default_library", - "//pkg/client/unversioned/clientcmd:go_default_library", "//pkg/cloudprovider:go_default_library", "//pkg/cloudprovider/providers:go_default_library", "//pkg/cloudprovider/providers/aws:go_default_library", @@ -101,6 +100,7 @@ go_library( "//vendor:k8s.io/apiserver/pkg/server/healthz", "//vendor:k8s.io/client-go/pkg/util/cert", "//vendor:k8s.io/client-go/rest", + "//vendor:k8s.io/client-go/tools/clientcmd", ], ) diff --git a/cmd/kube-controller-manager/app/controllermanager.go b/cmd/kube-controller-manager/app/controllermanager.go index 7f21b1d2cb9..ebbfc58afc2 100644 --- a/cmd/kube-controller-manager/app/controllermanager.go +++ b/cmd/kube-controller-manager/app/controllermanager.go @@ -38,6 +38,7 @@ import ( "k8s.io/apiserver/pkg/server/healthz" certutil "k8s.io/client-go/pkg/util/cert" restclient "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" "k8s.io/kubernetes/cmd/kube-controller-manager/app/options" "k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/client/clientset_generated/clientset" @@ -46,7 +47,6 @@ import ( "k8s.io/kubernetes/pkg/client/leaderelection/resourcelock" "k8s.io/kubernetes/pkg/client/record" "k8s.io/kubernetes/pkg/client/typed/discovery" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" "k8s.io/kubernetes/pkg/cloudprovider" "k8s.io/kubernetes/pkg/controller" "k8s.io/kubernetes/pkg/controller/informers" diff --git a/cmd/kube-proxy/app/BUILD b/cmd/kube-proxy/app/BUILD index 36b6dc2c509..1a1c68ea7a5 100644 --- a/cmd/kube-proxy/app/BUILD +++ b/cmd/kube-proxy/app/BUILD @@ -22,7 +22,6 @@ go_library( "//pkg/client/clientset_generated/internalclientset:go_default_library", "//pkg/client/clientset_generated/internalclientset/typed/core/internalversion:go_default_library", "//pkg/client/record:go_default_library", - "//pkg/client/unversioned/clientcmd:go_default_library", "//pkg/proxy:go_default_library", "//pkg/proxy/config:go_default_library", "//pkg/proxy/iptables:go_default_library", @@ -45,6 +44,7 @@ go_library( "//vendor:k8s.io/apimachinery/pkg/types", "//vendor:k8s.io/apimachinery/pkg/util/net", "//vendor:k8s.io/apimachinery/pkg/util/wait", + "//vendor:k8s.io/client-go/tools/clientcmd", "//vendor:k8s.io/client-go/tools/clientcmd/api", ], ) diff --git a/cmd/kube-proxy/app/server.go b/cmd/kube-proxy/app/server.go index 09593d846b7..214c75d687e 100644 --- a/cmd/kube-proxy/app/server.go +++ b/cmd/kube-proxy/app/server.go @@ -32,6 +32,7 @@ import ( "k8s.io/apimachinery/pkg/types" utilnet "k8s.io/apimachinery/pkg/util/net" "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" "k8s.io/kubernetes/cmd/kube-proxy/app/options" "k8s.io/kubernetes/pkg/api" @@ -39,7 +40,6 @@ import ( clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" unversionedcore "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion" "k8s.io/kubernetes/pkg/client/record" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" "k8s.io/kubernetes/pkg/proxy" proxyconfig "k8s.io/kubernetes/pkg/proxy/config" "k8s.io/kubernetes/pkg/proxy/iptables" diff --git a/cmd/kubeadm/app/discovery/BUILD b/cmd/kubeadm/app/discovery/BUILD index c3e9d8c8f70..5f4d4d85569 100644 --- a/cmd/kubeadm/app/discovery/BUILD +++ b/cmd/kubeadm/app/discovery/BUILD @@ -22,8 +22,8 @@ go_library( "//cmd/kubeadm/app/discovery/token:go_default_library", "//cmd/kubeadm/app/node:go_default_library", "//cmd/kubeadm/app/util:go_default_library", - "//pkg/client/unversioned/clientcmd:go_default_library", "//vendor:github.com/spf13/pflag", + "//vendor:k8s.io/client-go/tools/clientcmd", "//vendor:k8s.io/client-go/tools/clientcmd/api", ], ) diff --git a/cmd/kubeadm/app/discovery/discovery.go b/cmd/kubeadm/app/discovery/discovery.go index 8a1d1d6cc88..7cf6178b445 100644 --- a/cmd/kubeadm/app/discovery/discovery.go +++ b/cmd/kubeadm/app/discovery/discovery.go @@ -21,11 +21,11 @@ import ( "io/ioutil" "net/http" + "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubenode "k8s.io/kubernetes/cmd/kubeadm/app/node" kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" ) // For identifies and executes the desired discovery mechanism. diff --git a/cmd/kubeadm/app/master/BUILD b/cmd/kubeadm/app/master/BUILD index a7d3a811da6..9aba3152302 100644 --- a/cmd/kubeadm/app/master/BUILD +++ b/cmd/kubeadm/app/master/BUILD @@ -31,7 +31,6 @@ go_library( "//pkg/api/v1:go_default_library", "//pkg/apis/extensions/v1beta1:go_default_library", "//pkg/client/clientset_generated/clientset:go_default_library", - "//pkg/client/unversioned/clientcmd:go_default_library", "//pkg/kubectl/cmd/util:go_default_library", "//pkg/registry/core/service/ipallocator:go_default_library", "//pkg/util/intstr:go_default_library", @@ -41,6 +40,7 @@ go_library( "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", "//vendor:k8s.io/apimachinery/pkg/util/wait", "//vendor:k8s.io/client-go/pkg/util/cert", + "//vendor:k8s.io/client-go/tools/clientcmd", "//vendor:k8s.io/client-go/tools/clientcmd/api", ], ) diff --git a/cmd/kubeadm/app/master/apiclient.go b/cmd/kubeadm/app/master/apiclient.go index c36fa9c67c6..8bbe075674b 100644 --- a/cmd/kubeadm/app/master/apiclient.go +++ b/cmd/kubeadm/app/master/apiclient.go @@ -25,13 +25,13 @@ import ( apierrs "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" "k8s.io/kubernetes/cmd/kubeadm/app/images" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/v1" extensions "k8s.io/kubernetes/pkg/apis/extensions/v1beta1" "k8s.io/kubernetes/pkg/client/clientset_generated/clientset" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" ) const apiCallRetryInterval = 500 * time.Millisecond diff --git a/cmd/kubeadm/app/node/BUILD b/cmd/kubeadm/app/node/BUILD index a30ecb5d868..2b10f0065a3 100644 --- a/cmd/kubeadm/app/node/BUILD +++ b/cmd/kubeadm/app/node/BUILD @@ -22,7 +22,6 @@ go_library( "//cmd/kubeadm/app/util:go_default_library", "//pkg/apis/certificates:go_default_library", "//pkg/client/clientset_generated/clientset:go_default_library", - "//pkg/client/unversioned/clientcmd:go_default_library", "//pkg/kubelet/util/csr:go_default_library", "//vendor:github.com/square/go-jose", "//vendor:k8s.io/apimachinery/pkg/api/errors", @@ -30,6 +29,7 @@ go_library( "//vendor:k8s.io/apimachinery/pkg/types", "//vendor:k8s.io/apimachinery/pkg/util/wait", "//vendor:k8s.io/client-go/pkg/util/cert", + "//vendor:k8s.io/client-go/tools/clientcmd", "//vendor:k8s.io/client-go/tools/clientcmd/api", ], ) diff --git a/cmd/kubeadm/app/node/bootstrap.go b/cmd/kubeadm/app/node/bootstrap.go index b1fa25f58bc..9207e4d4a70 100644 --- a/cmd/kubeadm/app/node/bootstrap.go +++ b/cmd/kubeadm/app/node/bootstrap.go @@ -26,13 +26,13 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubeconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig" kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util" "k8s.io/kubernetes/pkg/apis/certificates" "k8s.io/kubernetes/pkg/client/clientset_generated/clientset" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" ) // retryTimeout between the subsequent attempts to connect diff --git a/cmd/kubeadm/app/node/csr.go b/cmd/kubeadm/app/node/csr.go index c472440691d..65e0f72ab38 100644 --- a/cmd/kubeadm/app/node/csr.go +++ b/cmd/kubeadm/app/node/csr.go @@ -22,9 +22,9 @@ import ( "k8s.io/apimachinery/pkg/types" certutil "k8s.io/client-go/pkg/util/cert" + "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" "k8s.io/kubernetes/pkg/client/clientset_generated/clientset" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" "k8s.io/kubernetes/pkg/kubelet/util/csr" ) diff --git a/cmd/kubeadm/app/phases/kubeconfig/BUILD b/cmd/kubeadm/app/phases/kubeconfig/BUILD index 796fe7db9f3..1fd03a9d656 100644 --- a/cmd/kubeadm/app/phases/kubeconfig/BUILD +++ b/cmd/kubeadm/app/phases/kubeconfig/BUILD @@ -26,8 +26,8 @@ go_library( deps = [ "//cmd/kubeadm/app/constants:go_default_library", "//cmd/kubeadm/app/phases/certs/pkiutil:go_default_library", - "//pkg/client/unversioned/clientcmd:go_default_library", "//vendor:k8s.io/client-go/pkg/util/cert", + "//vendor:k8s.io/client-go/tools/clientcmd", "//vendor:k8s.io/client-go/tools/clientcmd/api", ], ) diff --git a/cmd/kubeadm/app/phases/kubeconfig/kubeconfig.go b/cmd/kubeadm/app/phases/kubeconfig/kubeconfig.go index 2adaf9a22e9..044021f238b 100644 --- a/cmd/kubeadm/app/phases/kubeconfig/kubeconfig.go +++ b/cmd/kubeadm/app/phases/kubeconfig/kubeconfig.go @@ -26,10 +26,10 @@ import ( "path/filepath" certutil "k8s.io/client-go/pkg/util/cert" + "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs/pkiutil" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" ) const ( diff --git a/cmd/kubelet/app/BUILD b/cmd/kubelet/app/BUILD index 8ce96840541..3f75e1776f9 100644 --- a/cmd/kubelet/app/BUILD +++ b/cmd/kubelet/app/BUILD @@ -47,8 +47,6 @@ go_library( "//pkg/client/clientset_generated/clientset/typed/certificates/v1beta1:go_default_library", "//pkg/client/clientset_generated/clientset/typed/core/v1:go_default_library", "//pkg/client/record:go_default_library", - "//pkg/client/unversioned/auth:go_default_library", - "//pkg/client/unversioned/clientcmd:go_default_library", "//pkg/cloudprovider:go_default_library", "//pkg/cloudprovider/providers:go_default_library", "//pkg/credentialprovider:go_default_library", diff --git a/cmd/kubelet/app/bootstrap.go b/cmd/kubelet/app/bootstrap.go index 1d1ee9c27bd..96262065215 100644 --- a/cmd/kubelet/app/bootstrap.go +++ b/cmd/kubelet/app/bootstrap.go @@ -28,9 +28,9 @@ import ( "k8s.io/apimachinery/pkg/types" certutil "k8s.io/client-go/pkg/util/cert" restclient "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" certificates "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/certificates/v1beta1" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" "k8s.io/kubernetes/pkg/kubelet/util/csr" ) diff --git a/cmd/kubelet/app/server.go b/cmd/kubelet/app/server.go index 1885d886c70..779eb6e28ae 100644 --- a/cmd/kubelet/app/server.go +++ b/cmd/kubelet/app/server.go @@ -47,6 +47,8 @@ import ( "k8s.io/client-go/pkg/util/cert" certutil "k8s.io/client-go/pkg/util/cert" restclient "k8s.io/client-go/rest" + clientauth "k8s.io/client-go/tools/auth" + "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" "k8s.io/kubernetes/cmd/kubelet/app/options" "k8s.io/kubernetes/pkg/api" @@ -58,8 +60,6 @@ import ( "k8s.io/kubernetes/pkg/client/clientset_generated/clientset" v1core "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/core/v1" "k8s.io/kubernetes/pkg/client/record" - clientauth "k8s.io/kubernetes/pkg/client/unversioned/auth" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" "k8s.io/kubernetes/pkg/cloudprovider" "k8s.io/kubernetes/pkg/credentialprovider" "k8s.io/kubernetes/pkg/kubelet" diff --git a/cmd/kubemark/BUILD b/cmd/kubemark/BUILD index d0e1cbb3a72..a8ea9693330 100644 --- a/cmd/kubemark/BUILD +++ b/cmd/kubemark/BUILD @@ -24,7 +24,6 @@ go_library( "//pkg/client/clientset_generated/internalclientset:go_default_library", "//pkg/client/metrics/prometheus:go_default_library", "//pkg/client/record:go_default_library", - "//pkg/client/unversioned/clientcmd:go_default_library", "//pkg/kubelet/cadvisor/testing:go_default_library", "//pkg/kubelet/cm:go_default_library", "//pkg/kubelet/dockertools:go_default_library", @@ -37,6 +36,7 @@ go_library( "//vendor:github.com/spf13/pflag", "//vendor:k8s.io/apimachinery/pkg/util/sets", "//vendor:k8s.io/client-go/rest", + "//vendor:k8s.io/client-go/tools/clientcmd", ], ) diff --git a/cmd/kubemark/hollow-node.go b/cmd/kubemark/hollow-node.go index 31effc693c5..42d2287e7ba 100644 --- a/cmd/kubemark/hollow-node.go +++ b/cmd/kubemark/hollow-node.go @@ -21,12 +21,12 @@ import ( "k8s.io/apimachinery/pkg/util/sets" restclient "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" "k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/client/clientset_generated/clientset" "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" _ "k8s.io/kubernetes/pkg/client/metrics/prometheus" // for client metric registration "k8s.io/kubernetes/pkg/client/record" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" cadvisortest "k8s.io/kubernetes/pkg/kubelet/cadvisor/testing" "k8s.io/kubernetes/pkg/kubelet/cm" "k8s.io/kubernetes/pkg/kubelet/dockertools" diff --git a/federation/cmd/federation-controller-manager/app/BUILD b/federation/cmd/federation-controller-manager/app/BUILD index 4fd50233878..4bd67337647 100644 --- a/federation/cmd/federation-controller-manager/app/BUILD +++ b/federation/cmd/federation-controller-manager/app/BUILD @@ -33,7 +33,6 @@ go_library( "//federation/pkg/federation-controller/service:go_default_library", "//federation/pkg/federation-controller/util:go_default_library", "//pkg/client/typed/discovery:go_default_library", - "//pkg/client/unversioned/clientcmd:go_default_library", "//pkg/util/config:go_default_library", "//pkg/util/configz:go_default_library", "//pkg/version:go_default_library", @@ -46,6 +45,7 @@ go_library( "//vendor:k8s.io/apimachinery/pkg/util/wait", "//vendor:k8s.io/apiserver/pkg/server/healthz", "//vendor:k8s.io/client-go/rest", + "//vendor:k8s.io/client-go/tools/clientcmd", ], ) diff --git a/federation/cmd/federation-controller-manager/app/controllermanager.go b/federation/cmd/federation-controller-manager/app/controllermanager.go index 9ff7b19efaf..a153753c71f 100644 --- a/federation/cmd/federation-controller-manager/app/controllermanager.go +++ b/federation/cmd/federation-controller-manager/app/controllermanager.go @@ -30,6 +30,7 @@ import ( "k8s.io/apimachinery/pkg/util/wait" "k8s.io/apiserver/pkg/server/healthz" restclient "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" federationclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset" "k8s.io/kubernetes/federation/cmd/federation-controller-manager/app/options" "k8s.io/kubernetes/federation/pkg/dnsprovider" @@ -43,7 +44,6 @@ import ( secretcontroller "k8s.io/kubernetes/federation/pkg/federation-controller/secret" servicecontroller "k8s.io/kubernetes/federation/pkg/federation-controller/service" "k8s.io/kubernetes/federation/pkg/federation-controller/util" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" "k8s.io/kubernetes/pkg/util/configz" "k8s.io/kubernetes/pkg/version" diff --git a/federation/pkg/federation-controller/cluster/BUILD b/federation/pkg/federation-controller/cluster/BUILD index a3c6e790ff8..00d568f40d6 100644 --- a/federation/pkg/federation-controller/cluster/BUILD +++ b/federation/pkg/federation-controller/cluster/BUILD @@ -49,10 +49,10 @@ go_test( "//federation/pkg/federation-controller/util:go_default_library", "//pkg/api/testapi:go_default_library", "//pkg/api/v1:go_default_library", - "//pkg/client/unversioned/clientcmd:go_default_library", "//pkg/util/uuid:go_default_library", "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", "//vendor:k8s.io/client-go/rest", + "//vendor:k8s.io/client-go/tools/clientcmd", "//vendor:k8s.io/client-go/tools/clientcmd/api", ], ) diff --git a/federation/pkg/federation-controller/cluster/clustercontroller_test.go b/federation/pkg/federation-controller/cluster/clustercontroller_test.go index ac1eeea1acd..44dcce1f6ef 100644 --- a/federation/pkg/federation-controller/cluster/clustercontroller_test.go +++ b/federation/pkg/federation-controller/cluster/clustercontroller_test.go @@ -25,13 +25,13 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" restclient "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" federationv1beta1 "k8s.io/kubernetes/federation/apis/federation/v1beta1" federationclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset" controllerutil "k8s.io/kubernetes/federation/pkg/federation-controller/util" "k8s.io/kubernetes/pkg/api/testapi" "k8s.io/kubernetes/pkg/api/v1" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" "k8s.io/kubernetes/pkg/util/uuid" ) diff --git a/federation/pkg/federation-controller/util/BUILD b/federation/pkg/federation-controller/util/BUILD index 810ccbd28c8..936d08be354 100644 --- a/federation/pkg/federation-controller/util/BUILD +++ b/federation/pkg/federation-controller/util/BUILD @@ -33,7 +33,6 @@ go_library( "//pkg/client/cache:go_default_library", "//pkg/client/clientset_generated/clientset:go_default_library", "//pkg/client/clientset_generated/internalclientset:go_default_library", - "//pkg/client/unversioned/clientcmd:go_default_library", "//pkg/controller/deployment/util:go_default_library", "//vendor:github.com/golang/glog", "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", @@ -43,6 +42,7 @@ go_library( "//vendor:k8s.io/apimachinery/pkg/watch", "//vendor:k8s.io/client-go/pkg/util/flowcontrol", "//vendor:k8s.io/client-go/rest", + "//vendor:k8s.io/client-go/tools/clientcmd", "//vendor:k8s.io/client-go/tools/clientcmd/api", ], ) diff --git a/federation/pkg/federation-controller/util/cluster_util.go b/federation/pkg/federation-controller/util/cluster_util.go index 6c78485746a..7a575773167 100644 --- a/federation/pkg/federation-controller/util/cluster_util.go +++ b/federation/pkg/federation-controller/util/cluster_util.go @@ -27,12 +27,12 @@ import ( utilnet "k8s.io/apimachinery/pkg/util/net" "k8s.io/apimachinery/pkg/util/wait" restclient "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" federation_v1beta1 "k8s.io/kubernetes/federation/apis/federation/v1beta1" fedclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset" "k8s.io/kubernetes/pkg/api" clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" ) const ( diff --git a/federation/pkg/kubefed/BUILD b/federation/pkg/kubefed/BUILD index 2cb399e7fa0..d39c87dac00 100644 --- a/federation/pkg/kubefed/BUILD +++ b/federation/pkg/kubefed/BUILD @@ -21,7 +21,6 @@ go_library( "//federation/pkg/kubefed/init:go_default_library", "//federation/pkg/kubefed/util:go_default_library", "//pkg/api:go_default_library", - "//pkg/client/unversioned/clientcmd:go_default_library", "//pkg/kubectl:go_default_library", "//pkg/kubectl/cmd:go_default_library", "//pkg/kubectl/cmd/templates:go_default_library", @@ -33,6 +32,7 @@ go_library( "//vendor:k8s.io/apimachinery/pkg/api/errors", "//vendor:k8s.io/apimachinery/pkg/runtime", "//vendor:k8s.io/apimachinery/pkg/runtime/schema", + "//vendor:k8s.io/client-go/tools/clientcmd", "//vendor:k8s.io/client-go/tools/clientcmd/api", ], ) @@ -55,12 +55,12 @@ go_test( "//pkg/api/v1:go_default_library", "//pkg/client/restclient/fake:go_default_library", "//pkg/client/typed/dynamic:go_default_library", - "//pkg/client/unversioned/clientcmd:go_default_library", "//pkg/kubectl/cmd/testing:go_default_library", "//pkg/kubectl/cmd/util:go_default_library", "//vendor:k8s.io/apimachinery/pkg/api/errors", "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", "//vendor:k8s.io/apimachinery/pkg/util/diff", + "//vendor:k8s.io/client-go/tools/clientcmd", "//vendor:k8s.io/client-go/tools/clientcmd/api", ], ) diff --git a/federation/pkg/kubefed/init/BUILD b/federation/pkg/kubefed/init/BUILD index c5ea9b1a05a..34616819a1e 100644 --- a/federation/pkg/kubefed/init/BUILD +++ b/federation/pkg/kubefed/init/BUILD @@ -19,7 +19,6 @@ go_library( "//pkg/api/resource:go_default_library", "//pkg/apis/extensions:go_default_library", "//pkg/client/clientset_generated/internalclientset:go_default_library", - "//pkg/client/unversioned/clientcmd:go_default_library", "//pkg/kubectl/cmd/templates:go_default_library", "//pkg/kubectl/cmd/util:go_default_library", "//pkg/util/intstr:go_default_library", @@ -29,6 +28,7 @@ go_library( "//vendor:k8s.io/apimachinery/pkg/util/wait", "//vendor:k8s.io/client-go/pkg/util/cert", "//vendor:k8s.io/client-go/pkg/util/cert/triple", + "//vendor:k8s.io/client-go/tools/clientcmd", "//vendor:k8s.io/client-go/tools/clientcmd/api", ], ) @@ -48,13 +48,13 @@ go_test( "//pkg/apis/extensions/v1beta1:go_default_library", "//pkg/client/restclient/fake:go_default_library", "//pkg/client/typed/dynamic:go_default_library", - "//pkg/client/unversioned/clientcmd:go_default_library", "//pkg/kubectl/cmd/testing:go_default_library", "//pkg/kubectl/cmd/util:go_default_library", "//pkg/util/intstr:go_default_library", "//vendor:k8s.io/apimachinery/pkg/api/errors", "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", "//vendor:k8s.io/apimachinery/pkg/util/diff", + "//vendor:k8s.io/client-go/tools/clientcmd", ], ) diff --git a/federation/pkg/kubefed/init/init.go b/federation/pkg/kubefed/init/init.go index f658968af50..f2d793b2ffb 100644 --- a/federation/pkg/kubefed/init/init.go +++ b/federation/pkg/kubefed/init/init.go @@ -40,6 +40,7 @@ import ( "k8s.io/apimachinery/pkg/util/wait" certutil "k8s.io/client-go/pkg/util/cert" triple "k8s.io/client-go/pkg/util/cert/triple" + "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" kubeadmkubeconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig" "k8s.io/kubernetes/federation/pkg/kubefed/util" @@ -47,7 +48,6 @@ import ( "k8s.io/kubernetes/pkg/api/resource" "k8s.io/kubernetes/pkg/apis/extensions" client "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" "k8s.io/kubernetes/pkg/kubectl/cmd/templates" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" "k8s.io/kubernetes/pkg/util/intstr" diff --git a/federation/pkg/kubefed/init/init_test.go b/federation/pkg/kubefed/init/init_test.go index 7c4352b7d46..660bf1011eb 100644 --- a/federation/pkg/kubefed/init/init_test.go +++ b/federation/pkg/kubefed/init/init_test.go @@ -33,6 +33,7 @@ import ( "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/diff" + "k8s.io/client-go/tools/clientcmd" kubefedtesting "k8s.io/kubernetes/federation/pkg/kubefed/testing" "k8s.io/kubernetes/federation/pkg/kubefed/util" "k8s.io/kubernetes/pkg/api" @@ -42,7 +43,6 @@ import ( "k8s.io/kubernetes/pkg/apis/extensions/v1beta1" "k8s.io/kubernetes/pkg/client/restclient/fake" "k8s.io/kubernetes/pkg/client/typed/dynamic" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" "k8s.io/kubernetes/pkg/util/intstr" diff --git a/federation/pkg/kubefed/join_test.go b/federation/pkg/kubefed/join_test.go index d5691f382a3..0bd75448ab0 100644 --- a/federation/pkg/kubefed/join_test.go +++ b/federation/pkg/kubefed/join_test.go @@ -25,6 +25,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/diff" + "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" federationapi "k8s.io/kubernetes/federation/apis/federation/v1beta1" kubefedtesting "k8s.io/kubernetes/federation/pkg/kubefed/testing" @@ -34,7 +35,6 @@ import ( "k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/client/restclient/fake" "k8s.io/kubernetes/pkg/client/typed/dynamic" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" ) diff --git a/federation/pkg/kubefed/kubefed.go b/federation/pkg/kubefed/kubefed.go index df9bf9793e8..9e0a40de540 100644 --- a/federation/pkg/kubefed/kubefed.go +++ b/federation/pkg/kubefed/kubefed.go @@ -19,9 +19,9 @@ package kubefed import ( "io" + "k8s.io/client-go/tools/clientcmd" kubefedinit "k8s.io/kubernetes/federation/pkg/kubefed/init" "k8s.io/kubernetes/federation/pkg/kubefed/util" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" kubectl "k8s.io/kubernetes/pkg/kubectl/cmd" "k8s.io/kubernetes/pkg/kubectl/cmd/templates" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" diff --git a/federation/pkg/kubefed/testing/BUILD b/federation/pkg/kubefed/testing/BUILD index 63060583c91..326f5bfeac5 100644 --- a/federation/pkg/kubefed/testing/BUILD +++ b/federation/pkg/kubefed/testing/BUILD @@ -15,10 +15,10 @@ go_library( "//federation/client/clientset_generated/federation_clientset:go_default_library", "//federation/pkg/kubefed/util:go_default_library", "//pkg/api:go_default_library", - "//pkg/client/unversioned/clientcmd:go_default_library", "//pkg/kubectl/cmd/util:go_default_library", "//vendor:k8s.io/apimachinery/pkg/runtime", "//vendor:k8s.io/client-go/rest", + "//vendor:k8s.io/client-go/tools/clientcmd", "//vendor:k8s.io/client-go/tools/clientcmd/api", ], ) diff --git a/federation/pkg/kubefed/testing/testing.go b/federation/pkg/kubefed/testing/testing.go index c615135750d..884d9c58e82 100644 --- a/federation/pkg/kubefed/testing/testing.go +++ b/federation/pkg/kubefed/testing/testing.go @@ -25,11 +25,11 @@ import ( "k8s.io/apimachinery/pkg/runtime" restclient "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" fedclient "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset" "k8s.io/kubernetes/federation/pkg/kubefed/util" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" ) diff --git a/federation/pkg/kubefed/util/BUILD b/federation/pkg/kubefed/util/BUILD index 7af319491de..0e1778233a4 100644 --- a/federation/pkg/kubefed/util/BUILD +++ b/federation/pkg/kubefed/util/BUILD @@ -15,11 +15,11 @@ go_library( "//federation/client/clientset_generated/federation_clientset:go_default_library", "//pkg/api:go_default_library", "//pkg/client/clientset_generated/internalclientset:go_default_library", - "//pkg/client/unversioned/clientcmd:go_default_library", "//pkg/kubectl/cmd:go_default_library", "//pkg/kubectl/cmd/util:go_default_library", "//vendor:github.com/spf13/cobra", "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", + "//vendor:k8s.io/client-go/tools/clientcmd", "//vendor:k8s.io/client-go/tools/clientcmd/api", ], ) diff --git a/federation/pkg/kubefed/util/util.go b/federation/pkg/kubefed/util/util.go index 433b5323e6c..cf0ea426f82 100644 --- a/federation/pkg/kubefed/util/util.go +++ b/federation/pkg/kubefed/util/util.go @@ -18,11 +18,11 @@ package util import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" fedclient "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset" "k8s.io/kubernetes/pkg/api" client "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" kubectlcmd "k8s.io/kubernetes/pkg/kubectl/cmd" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" diff --git a/pkg/client/unversioned/BUILD b/pkg/client/unversioned/BUILD index 07ca472a2f3..de8a9ebcaa6 100644 --- a/pkg/client/unversioned/BUILD +++ b/pkg/client/unversioned/BUILD @@ -60,8 +60,6 @@ filegroup( name = "all-srcs", srcs = [ ":package-srcs", - "//pkg/client/unversioned/auth:all-srcs", - "//pkg/client/unversioned/clientcmd:all-srcs", "//pkg/client/unversioned/portforward:all-srcs", "//pkg/client/unversioned/remotecommand:all-srcs", "//pkg/client/unversioned/testclient/simple:all-srcs", diff --git a/pkg/client/unversioned/auth/BUILD b/pkg/client/unversioned/auth/BUILD deleted file mode 100644 index eb351c89feb..00000000000 --- a/pkg/client/unversioned/auth/BUILD +++ /dev/null @@ -1,36 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -licenses(["notice"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", - "go_test", -) - -go_library( - name = "go_default_library", - srcs = ["clientauth.go"], - tags = ["automanaged"], - deps = ["//vendor:k8s.io/client-go/rest"], -) - -go_test( - name = "go_default_xtest", - srcs = ["clientauth_test.go"], - tags = ["automanaged"], - deps = ["//pkg/client/unversioned/auth:go_default_library"], -) - -filegroup( - name = "package-srcs", - srcs = glob(["**"]), - tags = ["automanaged"], - visibility = ["//visibility:private"], -) - -filegroup( - name = "all-srcs", - srcs = [":package-srcs"], - tags = ["automanaged"], -) diff --git a/pkg/client/unversioned/auth/clientauth.go b/pkg/client/unversioned/auth/clientauth.go deleted file mode 100644 index 2213b987816..00000000000 --- a/pkg/client/unversioned/auth/clientauth.go +++ /dev/null @@ -1,125 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -/* -Package auth defines a file format for holding authentication -information needed by clients of Kubernetes. Typically, -a Kubernetes cluster will put auth info for the admin in a known -location when it is created, and will (soon) put it in a known -location within a Container's file tree for Containers that -need access to the Kubernetes API. - -Having a defined format allows: - - clients to be implmented in multiple languages - - applications which link clients to be portable across - clusters with different authentication styles (e.g. - some may use SSL Client certs, others may not, etc) - - when the format changes, applications only - need to update this code. - -The file format is json, marshalled from a struct authcfg.Info. - -Clinet libraries in other languages should use the same format. - -It is not intended to store general preferences, such as default -namespace, output options, etc. CLIs (such as kubectl) and UIs should -develop their own format and may wish to inline the authcfg.Info type. - -The authcfg.Info is just a file format. It is distinct from -client.Config which holds options for creating a client.Client. -Helper functions are provided in this package to fill in a -client.Client from an authcfg.Info. - -Example: - - import ( - "pkg/client" - "pkg/client/auth" - ) - - info, err := auth.LoadFromFile(filename) - if err != nil { - // handle error - } - clientConfig = client.Config{} - clientConfig.Host = "example.com:4901" - clientConfig = info.MergeWithConfig() - client := client.New(clientConfig) - client.Pods(ns).List() -*/ -package auth - -// TODO: need a way to rotate Tokens. Therefore, need a way for client object to be reset when the authcfg is updated. -import ( - "encoding/json" - "io/ioutil" - "os" - - restclient "k8s.io/client-go/rest" -) - -// Info holds Kubernetes API authorization config. It is intended -// to be read/written from a file as a JSON object. -type Info struct { - User string - Password string - CAFile string - CertFile string - KeyFile string - BearerToken string - Insecure *bool -} - -// LoadFromFile parses an Info object from a file path. -// If the file does not exist, then os.IsNotExist(err) == true -func LoadFromFile(path string) (*Info, error) { - var info Info - if _, err := os.Stat(path); os.IsNotExist(err) { - return nil, err - } - data, err := ioutil.ReadFile(path) - if err != nil { - return nil, err - } - err = json.Unmarshal(data, &info) - if err != nil { - return nil, err - } - return &info, err -} - -// MergeWithConfig returns a copy of a client.Config with values from the Info. -// The fields of client.Config with a corresponding field in the Info are set -// with the value from the Info. -func (info Info) MergeWithConfig(c restclient.Config) (restclient.Config, error) { - var config restclient.Config = c - config.Username = info.User - config.Password = info.Password - config.CAFile = info.CAFile - config.CertFile = info.CertFile - config.KeyFile = info.KeyFile - config.BearerToken = info.BearerToken - if info.Insecure != nil { - config.Insecure = *info.Insecure - } - return config, nil -} - -func (info Info) Complete() bool { - return len(info.User) > 0 || - len(info.CertFile) > 0 || - len(info.BearerToken) > 0 -} diff --git a/pkg/client/unversioned/auth/clientauth_test.go b/pkg/client/unversioned/auth/clientauth_test.go deleted file mode 100644 index 03bf6a52f14..00000000000 --- a/pkg/client/unversioned/auth/clientauth_test.go +++ /dev/null @@ -1,69 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package auth_test - -import ( - "io/ioutil" - "os" - "reflect" - "testing" - - clientauth "k8s.io/kubernetes/pkg/client/unversioned/auth" -) - -func TestLoadFromFile(t *testing.T) { - loadAuthInfoTests := []struct { - authData string - authInfo *clientauth.Info - expectErr bool - }{ - { - `{"user": "user", "password": "pass"}`, - &clientauth.Info{User: "user", Password: "pass"}, - false, - }, - { - "", nil, true, - }, - } - for _, loadAuthInfoTest := range loadAuthInfoTests { - tt := loadAuthInfoTest - aifile, err := ioutil.TempFile("", "testAuthInfo") - if err != nil { - t.Errorf("Unexpected error: %v", err) - } - if tt.authData != "missing" { - defer os.Remove(aifile.Name()) - defer aifile.Close() - _, err = aifile.WriteString(tt.authData) - if err != nil { - t.Errorf("Unexpected error: %v", err) - } - } else { - aifile.Close() - os.Remove(aifile.Name()) - } - authInfo, err := clientauth.LoadFromFile(aifile.Name()) - gotErr := err != nil - if gotErr != tt.expectErr { - t.Errorf("expected errorness: %v, actual errorness: %v", tt.expectErr, gotErr) - } - if !reflect.DeepEqual(authInfo, tt.authInfo) { - t.Errorf("Expected %v, got %v", tt.authInfo, authInfo) - } - } -} diff --git a/pkg/client/unversioned/clientcmd/BUILD b/pkg/client/unversioned/clientcmd/BUILD deleted file mode 100644 index d97075135c3..00000000000 --- a/pkg/client/unversioned/clientcmd/BUILD +++ /dev/null @@ -1,75 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -licenses(["notice"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", - "go_test", -) - -go_library( - name = "go_default_library", - srcs = [ - "auth_loaders.go", - "client_config.go", - "config.go", - "doc.go", - "helpers.go", - "loader.go", - "merged_client_builder.go", - "overrides.go", - "validation.go", - ], - tags = ["automanaged"], - deps = [ - "//pkg/api:go_default_library", - "//pkg/client/unversioned/auth:go_default_library", - "//pkg/util/homedir:go_default_library", - "//vendor:github.com/golang/glog", - "//vendor:github.com/howeyc/gopass", - "//vendor:github.com/imdario/mergo", - "//vendor:github.com/spf13/pflag", - "//vendor:k8s.io/apimachinery/pkg/runtime", - "//vendor:k8s.io/apimachinery/pkg/runtime/schema", - "//vendor:k8s.io/apimachinery/pkg/util/errors", - "//vendor:k8s.io/apimachinery/pkg/util/validation", - "//vendor:k8s.io/client-go/rest", - "//vendor:k8s.io/client-go/tools/clientcmd/api", - "//vendor:k8s.io/client-go/tools/clientcmd/api/latest", - ], -) - -go_test( - name = "go_default_test", - srcs = [ - "client_config_test.go", - "loader_test.go", - "merged_client_builder_test.go", - "validation_test.go", - ], - library = ":go_default_library", - tags = ["automanaged"], - deps = [ - "//vendor:github.com/ghodss/yaml", - "//vendor:github.com/imdario/mergo", - "//vendor:k8s.io/apimachinery/pkg/runtime", - "//vendor:k8s.io/apimachinery/pkg/util/errors", - "//vendor:k8s.io/client-go/rest", - "//vendor:k8s.io/client-go/tools/clientcmd/api", - "//vendor:k8s.io/client-go/tools/clientcmd/api/latest", - ], -) - -filegroup( - name = "package-srcs", - srcs = glob(["**"]), - tags = ["automanaged"], - visibility = ["//visibility:private"], -) - -filegroup( - name = "all-srcs", - srcs = [":package-srcs"], - tags = ["automanaged"], -) diff --git a/pkg/client/unversioned/clientcmd/auth_loaders.go b/pkg/client/unversioned/clientcmd/auth_loaders.go deleted file mode 100644 index 1e7c1159e4b..00000000000 --- a/pkg/client/unversioned/clientcmd/auth_loaders.go +++ /dev/null @@ -1,106 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package clientcmd - -import ( - "encoding/json" - "fmt" - "io" - "io/ioutil" - "os" - - "github.com/howeyc/gopass" - clientauth "k8s.io/kubernetes/pkg/client/unversioned/auth" -) - -// AuthLoaders are used to build clientauth.Info objects. -type AuthLoader interface { - // LoadAuth takes a path to a config file and can then do anything it needs in order to return a valid clientauth.Info - LoadAuth(path string) (*clientauth.Info, error) -} - -// default implementation of an AuthLoader -type defaultAuthLoader struct{} - -// LoadAuth for defaultAuthLoader simply delegates to clientauth.LoadFromFile -func (*defaultAuthLoader) LoadAuth(path string) (*clientauth.Info, error) { - return clientauth.LoadFromFile(path) -} - -type PromptingAuthLoader struct { - reader io.Reader -} - -// LoadAuth parses an AuthInfo object from a file path. It prompts user and creates file if it doesn't exist. -func (a *PromptingAuthLoader) LoadAuth(path string) (*clientauth.Info, error) { - // Prompt for user/pass and write a file if none exists. - if _, err := os.Stat(path); os.IsNotExist(err) { - authPtr, err := a.Prompt() - auth := *authPtr - if err != nil { - return nil, err - } - data, err := json.Marshal(auth) - if err != nil { - return &auth, err - } - err = ioutil.WriteFile(path, data, 0600) - return &auth, err - } - authPtr, err := clientauth.LoadFromFile(path) - if err != nil { - return nil, err - } - return authPtr, nil -} - -// Prompt pulls the user and password from a reader -func (a *PromptingAuthLoader) Prompt() (*clientauth.Info, error) { - var err error - auth := &clientauth.Info{} - auth.User, err = promptForString("Username", a.reader, true) - if err != nil { - return nil, err - } - auth.Password, err = promptForString("Password", nil, false) - if err != nil { - return nil, err - } - return auth, nil -} - -func promptForString(field string, r io.Reader, show bool) (result string, err error) { - fmt.Printf("Please enter %s: ", field) - if show { - _, err = fmt.Fscan(r, &result) - } else { - var data []byte - data, err = gopass.GetPasswdMasked() - result = string(data) - } - return result, err -} - -// NewPromptingAuthLoader is an AuthLoader that parses an AuthInfo object from a file path. It prompts user and creates file if it doesn't exist. -func NewPromptingAuthLoader(reader io.Reader) *PromptingAuthLoader { - return &PromptingAuthLoader{reader} -} - -// NewDefaultAuthLoader returns a default implementation of an AuthLoader that only reads from a config file -func NewDefaultAuthLoader() AuthLoader { - return &defaultAuthLoader{} -} diff --git a/pkg/client/unversioned/clientcmd/client_config.go b/pkg/client/unversioned/clientcmd/client_config.go deleted file mode 100644 index 4185b23d841..00000000000 --- a/pkg/client/unversioned/clientcmd/client_config.go +++ /dev/null @@ -1,537 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package clientcmd - -import ( - "fmt" - "io" - "io/ioutil" - "net/url" - "os" - "strings" - - "github.com/golang/glog" - "github.com/imdario/mergo" - - restclient "k8s.io/client-go/rest" - clientcmdapi "k8s.io/client-go/tools/clientcmd/api" - "k8s.io/kubernetes/pkg/api" - clientauth "k8s.io/kubernetes/pkg/client/unversioned/auth" -) - -var ( - // ClusterDefaults has the same behavior as the old EnvVar and DefaultCluster fields - // DEPRECATED will be replaced - ClusterDefaults = clientcmdapi.Cluster{Server: getDefaultServer()} - // DefaultClientConfig represents the legacy behavior of this package for defaulting - // DEPRECATED will be replace - DefaultClientConfig = DirectClientConfig{*clientcmdapi.NewConfig(), "", &ConfigOverrides{ - ClusterDefaults: ClusterDefaults, - }, nil, NewDefaultClientConfigLoadingRules(), promptedCredentials{}} -) - -// getDefaultServer returns a default setting for DefaultClientConfig -// DEPRECATED -func getDefaultServer() string { - if server := os.Getenv("KUBERNETES_MASTER"); len(server) > 0 { - return server - } - return "http://localhost:8080" -} - -// ClientConfig is used to make it easy to get an api server client -type ClientConfig interface { - // RawConfig returns the merged result of all overrides - RawConfig() (clientcmdapi.Config, error) - // ClientConfig returns a complete client config - ClientConfig() (*restclient.Config, error) - // Namespace returns the namespace resulting from the merged - // result of all overrides and a boolean indicating if it was - // overridden - Namespace() (string, bool, error) - // ConfigAccess returns the rules for loading/persisting the config. - ConfigAccess() ConfigAccess -} - -type PersistAuthProviderConfigForUser func(user string) restclient.AuthProviderConfigPersister - -type promptedCredentials struct { - username string - password string -} - -// DirectClientConfig is a ClientConfig interface that is backed by a clientcmdapi.Config, options overrides, and an optional fallbackReader for auth information -type DirectClientConfig struct { - config clientcmdapi.Config - contextName string - overrides *ConfigOverrides - fallbackReader io.Reader - configAccess ConfigAccess - // promptedCredentials store the credentials input by the user - promptedCredentials promptedCredentials -} - -// NewDefaultClientConfig creates a DirectClientConfig using the config.CurrentContext as the context name -func NewDefaultClientConfig(config clientcmdapi.Config, overrides *ConfigOverrides) ClientConfig { - return &DirectClientConfig{config, config.CurrentContext, overrides, nil, NewDefaultClientConfigLoadingRules(), promptedCredentials{}} -} - -// NewNonInteractiveClientConfig creates a DirectClientConfig using the passed context name and does not have a fallback reader for auth information -func NewNonInteractiveClientConfig(config clientcmdapi.Config, contextName string, overrides *ConfigOverrides, configAccess ConfigAccess) ClientConfig { - return &DirectClientConfig{config, contextName, overrides, nil, configAccess, promptedCredentials{}} -} - -// NewInteractiveClientConfig creates a DirectClientConfig using the passed context name and a reader in case auth information is not provided via files or flags -func NewInteractiveClientConfig(config clientcmdapi.Config, contextName string, overrides *ConfigOverrides, fallbackReader io.Reader, configAccess ConfigAccess) ClientConfig { - return &DirectClientConfig{config, contextName, overrides, fallbackReader, configAccess, promptedCredentials{}} -} - -func (config *DirectClientConfig) RawConfig() (clientcmdapi.Config, error) { - return config.config, nil -} - -// ClientConfig implements ClientConfig -func (config *DirectClientConfig) ClientConfig() (*restclient.Config, error) { - // check that getAuthInfo, getContext, and getCluster do not return an error. - // Do this before checking if the curent config is usable in the event that an - // AuthInfo, Context, or Cluster config with user-defined names are not found. - // This provides a user with the immediate cause for error if one is found - configAuthInfo, err := config.getAuthInfo() - if err != nil { - return nil, err - } - - _, err = config.getContext() - if err != nil { - return nil, err - } - - configClusterInfo, err := config.getCluster() - if err != nil { - return nil, err - } - - if err := config.ConfirmUsable(); err != nil { - return nil, err - } - - clientConfig := &restclient.Config{} - clientConfig.Host = configClusterInfo.Server - - if len(config.overrides.Timeout) > 0 { - timeout, err := ParseTimeout(config.overrides.Timeout) - if err != nil { - return nil, err - } - clientConfig.Timeout = timeout - } - - if u, err := url.ParseRequestURI(clientConfig.Host); err == nil && u.Opaque == "" && len(u.Path) > 1 { - u.RawQuery = "" - u.Fragment = "" - clientConfig.Host = u.String() - } - if len(configAuthInfo.Impersonate) > 0 { - clientConfig.Impersonate = restclient.ImpersonationConfig{UserName: configAuthInfo.Impersonate} - } - - // only try to read the auth information if we are secure - if restclient.IsConfigTransportTLS(*clientConfig) { - var err error - - // mergo is a first write wins for map value and a last writing wins for interface values - // NOTE: This behavior changed with https://github.com/imdario/mergo/commit/d304790b2ed594794496464fadd89d2bb266600a. - // Our mergo.Merge version is older than this change. - var persister restclient.AuthProviderConfigPersister - if config.configAccess != nil { - authInfoName, _ := config.getAuthInfoName() - persister = PersisterForUser(config.configAccess, authInfoName) - } - userAuthPartialConfig, err := config.getUserIdentificationPartialConfig(configAuthInfo, config.fallbackReader, persister) - if err != nil { - return nil, err - } - mergo.Merge(clientConfig, userAuthPartialConfig) - - serverAuthPartialConfig, err := getServerIdentificationPartialConfig(configAuthInfo, configClusterInfo) - if err != nil { - return nil, err - } - mergo.Merge(clientConfig, serverAuthPartialConfig) - } - - return clientConfig, nil -} - -// clientauth.Info object contain both user identification and server identification. We want different precedence orders for -// both, so we have to split the objects and merge them separately -// we want this order of precedence for the server identification -// 1. configClusterInfo (the final result of command line flags and merged .kubeconfig files) -// 2. configAuthInfo.auth-path (this file can contain information that conflicts with #1, and we want #1 to win the priority) -// 3. load the ~/.kubernetes_auth file as a default -func getServerIdentificationPartialConfig(configAuthInfo clientcmdapi.AuthInfo, configClusterInfo clientcmdapi.Cluster) (*restclient.Config, error) { - mergedConfig := &restclient.Config{} - - // configClusterInfo holds the information identify the server provided by .kubeconfig - configClientConfig := &restclient.Config{} - configClientConfig.CAFile = configClusterInfo.CertificateAuthority - configClientConfig.CAData = configClusterInfo.CertificateAuthorityData - configClientConfig.Insecure = configClusterInfo.InsecureSkipTLSVerify - mergo.Merge(mergedConfig, configClientConfig) - - return mergedConfig, nil -} - -// clientauth.Info object contain both user identification and server identification. We want different precedence orders for -// both, so we have to split the objects and merge them separately -// we want this order of precedence for user identifcation -// 1. configAuthInfo minus auth-path (the final result of command line flags and merged .kubeconfig files) -// 2. configAuthInfo.auth-path (this file can contain information that conflicts with #1, and we want #1 to win the priority) -// 3. if there is not enough information to idenfity the user, load try the ~/.kubernetes_auth file -// 4. if there is not enough information to identify the user, prompt if possible -func (config *DirectClientConfig) getUserIdentificationPartialConfig(configAuthInfo clientcmdapi.AuthInfo, fallbackReader io.Reader, persistAuthConfig restclient.AuthProviderConfigPersister) (*restclient.Config, error) { - mergedConfig := &restclient.Config{} - - // blindly overwrite existing values based on precedence - if len(configAuthInfo.Token) > 0 { - mergedConfig.BearerToken = configAuthInfo.Token - } else if len(configAuthInfo.TokenFile) > 0 { - tokenBytes, err := ioutil.ReadFile(configAuthInfo.TokenFile) - if err != nil { - return nil, err - } - mergedConfig.BearerToken = string(tokenBytes) - } - if len(configAuthInfo.Impersonate) > 0 { - mergedConfig.Impersonate = restclient.ImpersonationConfig{UserName: configAuthInfo.Impersonate} - } - if len(configAuthInfo.ClientCertificate) > 0 || len(configAuthInfo.ClientCertificateData) > 0 { - mergedConfig.CertFile = configAuthInfo.ClientCertificate - mergedConfig.CertData = configAuthInfo.ClientCertificateData - mergedConfig.KeyFile = configAuthInfo.ClientKey - mergedConfig.KeyData = configAuthInfo.ClientKeyData - } - if len(configAuthInfo.Username) > 0 || len(configAuthInfo.Password) > 0 { - mergedConfig.Username = configAuthInfo.Username - mergedConfig.Password = configAuthInfo.Password - } - if configAuthInfo.AuthProvider != nil { - mergedConfig.AuthProvider = configAuthInfo.AuthProvider - mergedConfig.AuthConfigPersister = persistAuthConfig - } - - // if there still isn't enough information to authenticate the user, try prompting - if !canIdentifyUser(*mergedConfig) && (fallbackReader != nil) { - if len(config.promptedCredentials.username) > 0 && len(config.promptedCredentials.password) > 0 { - mergedConfig.Username = config.promptedCredentials.username - mergedConfig.Password = config.promptedCredentials.password - return mergedConfig, nil - } - prompter := NewPromptingAuthLoader(fallbackReader) - promptedAuthInfo, err := prompter.Prompt() - if err != nil { - return nil, err - } - promptedConfig := makeUserIdentificationConfig(*promptedAuthInfo) - previouslyMergedConfig := mergedConfig - mergedConfig = &restclient.Config{} - mergo.Merge(mergedConfig, promptedConfig) - mergo.Merge(mergedConfig, previouslyMergedConfig) - config.promptedCredentials.username = mergedConfig.Username - config.promptedCredentials.password = mergedConfig.Password - } - - return mergedConfig, nil -} - -// makeUserIdentificationFieldsConfig returns a client.Config capable of being merged using mergo for only user identification information -func makeUserIdentificationConfig(info clientauth.Info) *restclient.Config { - config := &restclient.Config{} - config.Username = info.User - config.Password = info.Password - config.CertFile = info.CertFile - config.KeyFile = info.KeyFile - config.BearerToken = info.BearerToken - return config -} - -// makeUserIdentificationFieldsConfig returns a client.Config capable of being merged using mergo for only server identification information -func makeServerIdentificationConfig(info clientauth.Info) restclient.Config { - config := restclient.Config{} - config.CAFile = info.CAFile - if info.Insecure != nil { - config.Insecure = *info.Insecure - } - return config -} - -func canIdentifyUser(config restclient.Config) bool { - return len(config.Username) > 0 || - (len(config.CertFile) > 0 || len(config.CertData) > 0) || - len(config.BearerToken) > 0 || - config.AuthProvider != nil -} - -// Namespace implements ClientConfig -func (config *DirectClientConfig) Namespace() (string, bool, error) { - if err := config.ConfirmUsable(); err != nil { - return "", false, err - } - - configContext, err := config.getContext() - if err != nil { - return "", false, err - } - - if len(configContext.Namespace) == 0 { - return api.NamespaceDefault, false, nil - } - - overridden := false - if config.overrides != nil && config.overrides.Context.Namespace != "" { - overridden = true - } - return configContext.Namespace, overridden, nil -} - -// ConfigAccess implements ClientConfig -func (config *DirectClientConfig) ConfigAccess() ConfigAccess { - return config.configAccess -} - -// ConfirmUsable looks a particular context and determines if that particular part of the config is useable. There might still be errors in the config, -// but no errors in the sections requested or referenced. It does not return early so that it can find as many errors as possible. -func (config *DirectClientConfig) ConfirmUsable() error { - validationErrors := make([]error, 0) - - var contextName string - if len(config.contextName) != 0 { - contextName = config.contextName - } else { - contextName = config.config.CurrentContext - } - - if len(contextName) > 0 { - _, exists := config.config.Contexts[contextName] - if !exists { - validationErrors = append(validationErrors, &errContextNotFound{contextName}) - } - } - - authInfoName, _ := config.getAuthInfoName() - authInfo, _ := config.getAuthInfo() - validationErrors = append(validationErrors, validateAuthInfo(authInfoName, authInfo)...) - clusterName, _ := config.getClusterName() - cluster, _ := config.getCluster() - validationErrors = append(validationErrors, validateClusterInfo(clusterName, cluster)...) - // when direct client config is specified, and our only error is that no server is defined, we should - // return a standard "no config" error - if len(validationErrors) == 1 && validationErrors[0] == ErrEmptyCluster { - return newErrConfigurationInvalid([]error{ErrEmptyConfig}) - } - return newErrConfigurationInvalid(validationErrors) -} - -// getContextName returns the default, or user-set context name, and a boolean that indicates -// whether the default context name has been overwritten by a user-set flag, or left as its default value -func (config *DirectClientConfig) getContextName() (string, bool) { - if len(config.overrides.CurrentContext) != 0 { - return config.overrides.CurrentContext, true - } - if len(config.contextName) != 0 { - return config.contextName, false - } - - return config.config.CurrentContext, false -} - -// getAuthInfoName returns a string containing the current authinfo name for the current context, -// and a boolean indicating whether the default authInfo name is overwritten by a user-set flag, or -// left as its default value -func (config *DirectClientConfig) getAuthInfoName() (string, bool) { - if len(config.overrides.Context.AuthInfo) != 0 { - return config.overrides.Context.AuthInfo, true - } - context, _ := config.getContext() - return context.AuthInfo, false -} - -// getClusterName returns a string containing the default, or user-set cluster name, and a boolean -// indicating whether the default clusterName has been overwritten by a user-set flag, or left as -// its default value -func (config *DirectClientConfig) getClusterName() (string, bool) { - if len(config.overrides.Context.Cluster) != 0 { - return config.overrides.Context.Cluster, true - } - context, _ := config.getContext() - return context.Cluster, false -} - -// getContext returns the clientcmdapi.Context, or an error if a required context is not found. -func (config *DirectClientConfig) getContext() (clientcmdapi.Context, error) { - contexts := config.config.Contexts - contextName, required := config.getContextName() - - var mergedContext clientcmdapi.Context - if configContext, exists := contexts[contextName]; exists { - mergo.Merge(&mergedContext, configContext) - } else if required { - return clientcmdapi.Context{}, fmt.Errorf("context %q does not exist", contextName) - } - mergo.Merge(&mergedContext, config.overrides.Context) - - return mergedContext, nil -} - -// getAuthInfo returns the clientcmdapi.AuthInfo, or an error if a required auth info is not found. -func (config *DirectClientConfig) getAuthInfo() (clientcmdapi.AuthInfo, error) { - authInfos := config.config.AuthInfos - authInfoName, required := config.getAuthInfoName() - - var mergedAuthInfo clientcmdapi.AuthInfo - if configAuthInfo, exists := authInfos[authInfoName]; exists { - mergo.Merge(&mergedAuthInfo, configAuthInfo) - } else if required { - return clientcmdapi.AuthInfo{}, fmt.Errorf("auth info %q does not exist", authInfoName) - } - mergo.Merge(&mergedAuthInfo, config.overrides.AuthInfo) - - return mergedAuthInfo, nil -} - -// getCluster returns the clientcmdapi.Cluster, or an error if a required cluster is not found. -func (config *DirectClientConfig) getCluster() (clientcmdapi.Cluster, error) { - clusterInfos := config.config.Clusters - clusterInfoName, required := config.getClusterName() - - var mergedClusterInfo clientcmdapi.Cluster - mergo.Merge(&mergedClusterInfo, config.overrides.ClusterDefaults) - if configClusterInfo, exists := clusterInfos[clusterInfoName]; exists { - mergo.Merge(&mergedClusterInfo, configClusterInfo) - } else if required { - return clientcmdapi.Cluster{}, fmt.Errorf("cluster %q does not exist", clusterInfoName) - } - mergo.Merge(&mergedClusterInfo, config.overrides.ClusterInfo) - // An override of --insecure-skip-tls-verify=true and no accompanying CA/CA data should clear already-set CA/CA data - // otherwise, a kubeconfig containing a CA reference would return an error that "CA and insecure-skip-tls-verify couldn't both be set" - caLen := len(config.overrides.ClusterInfo.CertificateAuthority) - caDataLen := len(config.overrides.ClusterInfo.CertificateAuthorityData) - if config.overrides.ClusterInfo.InsecureSkipTLSVerify && caLen == 0 && caDataLen == 0 { - mergedClusterInfo.CertificateAuthority = "" - mergedClusterInfo.CertificateAuthorityData = nil - } - - return mergedClusterInfo, nil -} - -// inClusterClientConfig makes a config that will work from within a kubernetes cluster container environment. -// Can take options overrides for flags explicitly provided to the command inside the cluster container. -type inClusterClientConfig struct { - overrides *ConfigOverrides - inClusterConfigProvider func() (*restclient.Config, error) -} - -var _ ClientConfig = &inClusterClientConfig{} - -func (config *inClusterClientConfig) RawConfig() (clientcmdapi.Config, error) { - return clientcmdapi.Config{}, fmt.Errorf("inCluster environment config doesn't support multiple clusters") -} - -func (config *inClusterClientConfig) ClientConfig() (*restclient.Config, error) { - if config.inClusterConfigProvider == nil { - config.inClusterConfigProvider = restclient.InClusterConfig - } - - icc, err := config.inClusterConfigProvider() - if err != nil { - return nil, err - } - - // in-cluster configs only takes a host, token, or CA file - // if any of them were individually provided, ovewrite anything else - if config.overrides != nil { - if server := config.overrides.ClusterInfo.Server; len(server) > 0 { - icc.Host = server - } - if token := config.overrides.AuthInfo.Token; len(token) > 0 { - icc.BearerToken = token - } - if certificateAuthorityFile := config.overrides.ClusterInfo.CertificateAuthority; len(certificateAuthorityFile) > 0 { - icc.TLSClientConfig.CAFile = certificateAuthorityFile - } - } - - return icc, err -} - -func (config *inClusterClientConfig) Namespace() (string, bool, error) { - // This way assumes you've set the POD_NAMESPACE environment variable using the downward API. - // This check has to be done first for backwards compatibility with the way InClusterConfig was originally set up - if ns := os.Getenv("POD_NAMESPACE"); ns != "" { - return ns, true, nil - } - - // Fall back to the namespace associated with the service account token, if available - if data, err := ioutil.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/namespace"); err == nil { - if ns := strings.TrimSpace(string(data)); len(ns) > 0 { - return ns, true, nil - } - } - - return "default", false, nil -} - -func (config *inClusterClientConfig) ConfigAccess() ConfigAccess { - return NewDefaultClientConfigLoadingRules() -} - -// Possible returns true if loading an inside-kubernetes-cluster is possible. -func (config *inClusterClientConfig) Possible() bool { - fi, err := os.Stat("/var/run/secrets/kubernetes.io/serviceaccount/token") - return os.Getenv("KUBERNETES_SERVICE_HOST") != "" && - os.Getenv("KUBERNETES_SERVICE_PORT") != "" && - err == nil && !fi.IsDir() -} - -// BuildConfigFromFlags is a helper function that builds configs from a master -// url or a kubeconfig filepath. These are passed in as command line flags for cluster -// components. Warnings should reflect this usage. If neither masterUrl or kubeconfigPath -// are passed in we fallback to inClusterConfig. If inClusterConfig fails, we fallback -// to the default config. -func BuildConfigFromFlags(masterUrl, kubeconfigPath string) (*restclient.Config, error) { - if kubeconfigPath == "" && masterUrl == "" { - glog.Warningf("Neither --kubeconfig nor --master was specified. Using the inClusterConfig. This might not work.") - kubeconfig, err := restclient.InClusterConfig() - if err == nil { - return kubeconfig, nil - } - glog.Warning("error creating inClusterConfig, falling back to default config: ", err) - } - return NewNonInteractiveDeferredLoadingClientConfig( - &ClientConfigLoadingRules{ExplicitPath: kubeconfigPath}, - &ConfigOverrides{ClusterInfo: clientcmdapi.Cluster{Server: masterUrl}}).ClientConfig() -} - -// BuildConfigFromKubeconfigGetter is a helper function that builds configs from a master -// url and a kubeconfigGetter. -func BuildConfigFromKubeconfigGetter(masterUrl string, kubeconfigGetter KubeconfigGetter) (*restclient.Config, error) { - // TODO: We do not need a DeferredLoader here. Refactor code and see if we can use DirectClientConfig here. - cc := NewNonInteractiveDeferredLoadingClientConfig( - &ClientConfigGetter{kubeconfigGetter: kubeconfigGetter}, - &ConfigOverrides{ClusterInfo: clientcmdapi.Cluster{Server: masterUrl}}) - return cc.ClientConfig() -} diff --git a/pkg/client/unversioned/clientcmd/client_config_test.go b/pkg/client/unversioned/clientcmd/client_config_test.go deleted file mode 100644 index 0cbff3f8efa..00000000000 --- a/pkg/client/unversioned/clientcmd/client_config_test.go +++ /dev/null @@ -1,506 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package clientcmd - -import ( - "io/ioutil" - "os" - "reflect" - "strings" - "testing" - - "github.com/imdario/mergo" - restclient "k8s.io/client-go/rest" - clientcmdapi "k8s.io/client-go/tools/clientcmd/api" -) - -func TestOldMergoLib(t *testing.T) { - type T struct { - X string - } - dst := T{X: "one"} - src := T{X: "two"} - mergo.Merge(&dst, &src) - if dst.X != "two" { - // mergo.Merge changed in an incompatible way with - // - // https://github.com/imdario/mergo/commit/d304790b2ed594794496464fadd89d2bb266600a - // - // We have to stay with the old version which still does eager - // copying from src to dst in structs. - t.Errorf("mergo.Merge library found with incompatible, new behavior") - } -} - -func createValidTestConfig() *clientcmdapi.Config { - const ( - server = "https://anything.com:8080" - token = "the-token" - ) - - config := clientcmdapi.NewConfig() - config.Clusters["clean"] = &clientcmdapi.Cluster{ - Server: server, - } - config.AuthInfos["clean"] = &clientcmdapi.AuthInfo{ - Token: token, - } - config.Contexts["clean"] = &clientcmdapi.Context{ - Cluster: "clean", - AuthInfo: "clean", - } - config.CurrentContext = "clean" - - return config -} - -func createCAValidTestConfig() *clientcmdapi.Config { - - config := createValidTestConfig() - config.Clusters["clean"].CertificateAuthorityData = []byte{0, 0} - return config -} - -func TestInsecureOverridesCA(t *testing.T) { - config := createCAValidTestConfig() - clientBuilder := NewNonInteractiveClientConfig(*config, "clean", &ConfigOverrides{ - ClusterInfo: clientcmdapi.Cluster{ - InsecureSkipTLSVerify: true, - }, - }, nil) - - actualCfg, err := clientBuilder.ClientConfig() - if err != nil { - t.Errorf("Unexpected error: %v", err) - } - - matchBoolArg(true, actualCfg.Insecure, t) - matchStringArg("", actualCfg.TLSClientConfig.CAFile, t) - matchByteArg(nil, actualCfg.TLSClientConfig.CAData, t) -} - -func TestMergeContext(t *testing.T) { - const namespace = "overriden-namespace" - - config := createValidTestConfig() - clientBuilder := NewNonInteractiveClientConfig(*config, "clean", &ConfigOverrides{}, nil) - - _, overridden, err := clientBuilder.Namespace() - if err != nil { - t.Errorf("Unexpected error: %v", err) - } - - if overridden { - t.Error("Expected namespace to not be overridden") - } - - clientBuilder = NewNonInteractiveClientConfig(*config, "clean", &ConfigOverrides{ - Context: clientcmdapi.Context{ - Namespace: namespace, - }, - }, nil) - - actual, overridden, err := clientBuilder.Namespace() - if err != nil { - t.Errorf("Unexpected error: %v", err) - } - - if !overridden { - t.Error("Expected namespace to be overridden") - } - - matchStringArg(namespace, actual, t) -} - -func TestCertificateData(t *testing.T) { - caData := []byte("ca-data") - certData := []byte("cert-data") - keyData := []byte("key-data") - - config := clientcmdapi.NewConfig() - config.Clusters["clean"] = &clientcmdapi.Cluster{ - Server: "https://localhost:8443", - CertificateAuthorityData: caData, - } - config.AuthInfos["clean"] = &clientcmdapi.AuthInfo{ - ClientCertificateData: certData, - ClientKeyData: keyData, - } - config.Contexts["clean"] = &clientcmdapi.Context{ - Cluster: "clean", - AuthInfo: "clean", - } - config.CurrentContext = "clean" - - clientBuilder := NewNonInteractiveClientConfig(*config, "clean", &ConfigOverrides{}, nil) - - clientConfig, err := clientBuilder.ClientConfig() - if err != nil { - t.Fatalf("Unexpected error: %v", err) - } - - // Make sure cert data gets into config (will override file paths) - matchByteArg(caData, clientConfig.TLSClientConfig.CAData, t) - matchByteArg(certData, clientConfig.TLSClientConfig.CertData, t) - matchByteArg(keyData, clientConfig.TLSClientConfig.KeyData, t) -} - -func TestBasicAuthData(t *testing.T) { - username := "myuser" - password := "mypass" - - config := clientcmdapi.NewConfig() - config.Clusters["clean"] = &clientcmdapi.Cluster{ - Server: "https://localhost:8443", - } - config.AuthInfos["clean"] = &clientcmdapi.AuthInfo{ - Username: username, - Password: password, - } - config.Contexts["clean"] = &clientcmdapi.Context{ - Cluster: "clean", - AuthInfo: "clean", - } - config.CurrentContext = "clean" - - clientBuilder := NewNonInteractiveClientConfig(*config, "clean", &ConfigOverrides{}, nil) - - clientConfig, err := clientBuilder.ClientConfig() - if err != nil { - t.Fatalf("Unexpected error: %v", err) - } - - // Make sure basic auth data gets into config - matchStringArg(username, clientConfig.Username, t) - matchStringArg(password, clientConfig.Password, t) -} - -func TestBasicTokenFile(t *testing.T) { - token := "exampletoken" - f, err := ioutil.TempFile("", "tokenfile") - if err != nil { - t.Errorf("Unexpected error: %v", err) - return - } - defer os.Remove(f.Name()) - if err := ioutil.WriteFile(f.Name(), []byte(token), 0644); err != nil { - t.Errorf("Unexpected error: %v", err) - return - } - - config := clientcmdapi.NewConfig() - config.Clusters["clean"] = &clientcmdapi.Cluster{ - Server: "https://localhost:8443", - } - config.AuthInfos["clean"] = &clientcmdapi.AuthInfo{ - TokenFile: f.Name(), - } - config.Contexts["clean"] = &clientcmdapi.Context{ - Cluster: "clean", - AuthInfo: "clean", - } - config.CurrentContext = "clean" - - clientBuilder := NewNonInteractiveClientConfig(*config, "clean", &ConfigOverrides{}, nil) - - clientConfig, err := clientBuilder.ClientConfig() - if err != nil { - t.Fatalf("Unexpected error: %v", err) - } - - matchStringArg(token, clientConfig.BearerToken, t) -} - -func TestPrecedenceTokenFile(t *testing.T) { - token := "exampletoken" - f, err := ioutil.TempFile("", "tokenfile") - if err != nil { - t.Errorf("Unexpected error: %v", err) - return - } - defer os.Remove(f.Name()) - if err := ioutil.WriteFile(f.Name(), []byte(token), 0644); err != nil { - t.Errorf("Unexpected error: %v", err) - return - } - - config := clientcmdapi.NewConfig() - config.Clusters["clean"] = &clientcmdapi.Cluster{ - Server: "https://localhost:8443", - } - expectedToken := "expected" - config.AuthInfos["clean"] = &clientcmdapi.AuthInfo{ - Token: expectedToken, - TokenFile: f.Name(), - } - config.Contexts["clean"] = &clientcmdapi.Context{ - Cluster: "clean", - AuthInfo: "clean", - } - config.CurrentContext = "clean" - - clientBuilder := NewNonInteractiveClientConfig(*config, "clean", &ConfigOverrides{}, nil) - - clientConfig, err := clientBuilder.ClientConfig() - if err != nil { - t.Fatalf("Unexpected error: %v", err) - } - - matchStringArg(expectedToken, clientConfig.BearerToken, t) -} - -func TestCreateClean(t *testing.T) { - config := createValidTestConfig() - clientBuilder := NewNonInteractiveClientConfig(*config, "clean", &ConfigOverrides{}, nil) - - clientConfig, err := clientBuilder.ClientConfig() - if err != nil { - t.Errorf("Unexpected error: %v", err) - } - - matchStringArg(config.Clusters["clean"].Server, clientConfig.Host, t) - matchStringArg("", clientConfig.APIPath, t) - matchBoolArg(config.Clusters["clean"].InsecureSkipTLSVerify, clientConfig.Insecure, t) - matchStringArg(config.AuthInfos["clean"].Token, clientConfig.BearerToken, t) -} - -func TestCreateCleanWithPrefix(t *testing.T) { - tt := []struct { - server string - host string - }{ - {"https://anything.com:8080/foo/bar", "https://anything.com:8080/foo/bar"}, - {"http://anything.com:8080/foo/bar", "http://anything.com:8080/foo/bar"}, - {"http://anything.com:8080/foo/bar/", "http://anything.com:8080/foo/bar/"}, - {"http://anything.com:8080/", "http://anything.com:8080/"}, - {"http://anything.com:8080//", "http://anything.com:8080//"}, - {"anything.com:8080/foo/bar", "anything.com:8080/foo/bar"}, - {"anything.com:8080", "anything.com:8080"}, - {"anything.com", "anything.com"}, - {"anything", "anything"}, - } - - tt = append(tt, struct{ server, host string }{"", "http://localhost:8080"}) - - for _, tc := range tt { - config := createValidTestConfig() - - cleanConfig := config.Clusters["clean"] - cleanConfig.Server = tc.server - config.Clusters["clean"] = cleanConfig - - clientBuilder := NewNonInteractiveClientConfig(*config, "clean", &ConfigOverrides{ - ClusterDefaults: clientcmdapi.Cluster{Server: "http://localhost:8080"}, - }, nil) - - clientConfig, err := clientBuilder.ClientConfig() - if err != nil { - t.Fatalf("Unexpected error: %v", err) - } - - matchStringArg(tc.host, clientConfig.Host, t) - } -} - -func TestCreateCleanDefault(t *testing.T) { - config := createValidTestConfig() - clientBuilder := NewDefaultClientConfig(*config, &ConfigOverrides{}) - - clientConfig, err := clientBuilder.ClientConfig() - if err != nil { - t.Fatalf("Unexpected error: %v", err) - } - - matchStringArg(config.Clusters["clean"].Server, clientConfig.Host, t) - matchBoolArg(config.Clusters["clean"].InsecureSkipTLSVerify, clientConfig.Insecure, t) - matchStringArg(config.AuthInfos["clean"].Token, clientConfig.BearerToken, t) -} - -func TestCreateCleanDefaultCluster(t *testing.T) { - config := createValidTestConfig() - clientBuilder := NewDefaultClientConfig(*config, &ConfigOverrides{ - ClusterDefaults: clientcmdapi.Cluster{Server: "http://localhost:8080"}, - }) - - clientConfig, err := clientBuilder.ClientConfig() - if err != nil { - t.Fatalf("Unexpected error: %v", err) - } - - matchStringArg(config.Clusters["clean"].Server, clientConfig.Host, t) - matchBoolArg(config.Clusters["clean"].InsecureSkipTLSVerify, clientConfig.Insecure, t) - matchStringArg(config.AuthInfos["clean"].Token, clientConfig.BearerToken, t) -} - -func TestCreateMissingContextNoDefault(t *testing.T) { - const expectedErrorContains = "Context was not found for specified context" - config := createValidTestConfig() - clientBuilder := NewNonInteractiveClientConfig(*config, "not-present", &ConfigOverrides{}, nil) - - _, err := clientBuilder.ClientConfig() - if err == nil { - t.Fatalf("Unexpected error: %v", err) - } -} - -func TestCreateMissingContext(t *testing.T) { - const expectedErrorContains = "context was not found for specified context: not-present" - config := createValidTestConfig() - clientBuilder := NewNonInteractiveClientConfig(*config, "not-present", &ConfigOverrides{ - ClusterDefaults: clientcmdapi.Cluster{Server: "http://localhost:8080"}, - }, nil) - - _, err := clientBuilder.ClientConfig() - if err == nil { - t.Fatalf("Expected error: %v", expectedErrorContains) - } - if !strings.Contains(err.Error(), expectedErrorContains) { - t.Fatalf("Expected error: %v, but got %v", expectedErrorContains, err) - } -} - -func TestInClusterClientConfigPrecedence(t *testing.T) { - tt := []struct { - overrides *ConfigOverrides - }{ - { - overrides: &ConfigOverrides{ - ClusterInfo: clientcmdapi.Cluster{ - Server: "https://host-from-overrides.com", - }, - }, - }, - { - overrides: &ConfigOverrides{ - AuthInfo: clientcmdapi.AuthInfo{ - Token: "https://host-from-overrides.com", - }, - }, - }, - { - overrides: &ConfigOverrides{ - ClusterInfo: clientcmdapi.Cluster{ - CertificateAuthority: "/path/to/ca-from-overrides.crt", - }, - }, - }, - { - overrides: &ConfigOverrides{ - ClusterInfo: clientcmdapi.Cluster{ - Server: "https://host-from-overrides.com", - }, - AuthInfo: clientcmdapi.AuthInfo{ - Token: "https://host-from-overrides.com", - }, - }, - }, - { - overrides: &ConfigOverrides{ - ClusterInfo: clientcmdapi.Cluster{ - Server: "https://host-from-overrides.com", - CertificateAuthority: "/path/to/ca-from-overrides.crt", - }, - }, - }, - { - overrides: &ConfigOverrides{ - ClusterInfo: clientcmdapi.Cluster{ - CertificateAuthority: "/path/to/ca-from-overrides.crt", - }, - AuthInfo: clientcmdapi.AuthInfo{ - Token: "https://host-from-overrides.com", - }, - }, - }, - { - overrides: &ConfigOverrides{ - ClusterInfo: clientcmdapi.Cluster{ - Server: "https://host-from-overrides.com", - CertificateAuthority: "/path/to/ca-from-overrides.crt", - }, - AuthInfo: clientcmdapi.AuthInfo{ - Token: "https://host-from-overrides.com", - }, - }, - }, - { - overrides: &ConfigOverrides{}, - }, - } - - for _, tc := range tt { - expectedServer := "https://host-from-cluster.com" - expectedToken := "token-from-cluster" - expectedCAFile := "/path/to/ca-from-cluster.crt" - - icc := &inClusterClientConfig{ - inClusterConfigProvider: func() (*restclient.Config, error) { - return &restclient.Config{ - Host: expectedServer, - BearerToken: expectedToken, - TLSClientConfig: restclient.TLSClientConfig{ - CAFile: expectedCAFile, - }, - }, nil - }, - overrides: tc.overrides, - } - - clientConfig, err := icc.ClientConfig() - if err != nil { - t.Fatalf("Unxpected error: %v", err) - } - - if overridenServer := tc.overrides.ClusterInfo.Server; len(overridenServer) > 0 { - expectedServer = overridenServer - } - if overridenToken := tc.overrides.AuthInfo.Token; len(overridenToken) > 0 { - expectedToken = overridenToken - } - if overridenCAFile := tc.overrides.ClusterInfo.CertificateAuthority; len(overridenCAFile) > 0 { - expectedCAFile = overridenCAFile - } - - if clientConfig.Host != expectedServer { - t.Errorf("Expected server %v, got %v", expectedServer, clientConfig.Host) - } - if clientConfig.BearerToken != expectedToken { - t.Errorf("Expected token %v, got %v", expectedToken, clientConfig.BearerToken) - } - if clientConfig.TLSClientConfig.CAFile != expectedCAFile { - t.Errorf("Expected Certificate Authority %v, got %v", expectedCAFile, clientConfig.TLSClientConfig.CAFile) - } - } -} - -func matchBoolArg(expected, got bool, t *testing.T) { - if expected != got { - t.Errorf("Expected %v, got %v", expected, got) - } -} - -func matchStringArg(expected, got string, t *testing.T) { - if expected != got { - t.Errorf("Expected %q, got %q", expected, got) - } -} - -func matchByteArg(expected, got []byte, t *testing.T) { - if !reflect.DeepEqual(expected, got) { - t.Errorf("Expected %v, got %v", expected, got) - } -} diff --git a/pkg/client/unversioned/clientcmd/config.go b/pkg/client/unversioned/clientcmd/config.go deleted file mode 100644 index 16ccdaf20a2..00000000000 --- a/pkg/client/unversioned/clientcmd/config.go +++ /dev/null @@ -1,472 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package clientcmd - -import ( - "errors" - "os" - "path" - "path/filepath" - "reflect" - "sort" - - "github.com/golang/glog" - - restclient "k8s.io/client-go/rest" - clientcmdapi "k8s.io/client-go/tools/clientcmd/api" -) - -// ConfigAccess is used by subcommands and methods in this package to load and modify the appropriate config files -type ConfigAccess interface { - // GetLoadingPrecedence returns the slice of files that should be used for loading and inspecting the config - GetLoadingPrecedence() []string - // GetStartingConfig returns the config that subcommands should being operating against. It may or may not be merged depending on loading rules - GetStartingConfig() (*clientcmdapi.Config, error) - // GetDefaultFilename returns the name of the file you should write into (create if necessary), if you're trying to create a new stanza as opposed to updating an existing one. - GetDefaultFilename() string - // IsExplicitFile indicates whether or not this command is interested in exactly one file. This implementation only ever does that via a flag, but implementations that handle local, global, and flags may have more - IsExplicitFile() bool - // GetExplicitFile returns the particular file this command is operating against. This implementation only ever has one, but implementations that handle local, global, and flags may have more - GetExplicitFile() string -} - -type PathOptions struct { - // GlobalFile is the full path to the file to load as the global (final) option - GlobalFile string - // EnvVar is the env var name that points to the list of kubeconfig files to load - EnvVar string - // ExplicitFileFlag is the name of the flag to use for prompting for the kubeconfig file - ExplicitFileFlag string - - // GlobalFileSubpath is an optional value used for displaying help - GlobalFileSubpath string - - LoadingRules *ClientConfigLoadingRules -} - -func (o *PathOptions) GetEnvVarFiles() []string { - if len(o.EnvVar) == 0 { - return []string{} - } - - envVarValue := os.Getenv(o.EnvVar) - if len(envVarValue) == 0 { - return []string{} - } - - return filepath.SplitList(envVarValue) -} - -func (o *PathOptions) GetLoadingPrecedence() []string { - if envVarFiles := o.GetEnvVarFiles(); len(envVarFiles) > 0 { - return envVarFiles - } - - return []string{o.GlobalFile} -} - -func (o *PathOptions) GetStartingConfig() (*clientcmdapi.Config, error) { - // don't mutate the original - loadingRules := *o.LoadingRules - loadingRules.Precedence = o.GetLoadingPrecedence() - - clientConfig := NewNonInteractiveDeferredLoadingClientConfig(&loadingRules, &ConfigOverrides{}) - rawConfig, err := clientConfig.RawConfig() - if os.IsNotExist(err) { - return clientcmdapi.NewConfig(), nil - } - if err != nil { - return nil, err - } - - return &rawConfig, nil -} - -func (o *PathOptions) GetDefaultFilename() string { - if o.IsExplicitFile() { - return o.GetExplicitFile() - } - - if envVarFiles := o.GetEnvVarFiles(); len(envVarFiles) > 0 { - if len(envVarFiles) == 1 { - return envVarFiles[0] - } - - // if any of the envvar files already exists, return it - for _, envVarFile := range envVarFiles { - if _, err := os.Stat(envVarFile); err == nil { - return envVarFile - } - } - - // otherwise, return the last one in the list - return envVarFiles[len(envVarFiles)-1] - } - - return o.GlobalFile -} - -func (o *PathOptions) IsExplicitFile() bool { - if len(o.LoadingRules.ExplicitPath) > 0 { - return true - } - - return false -} - -func (o *PathOptions) GetExplicitFile() string { - return o.LoadingRules.ExplicitPath -} - -func NewDefaultPathOptions() *PathOptions { - ret := &PathOptions{ - GlobalFile: RecommendedHomeFile, - EnvVar: RecommendedConfigPathEnvVar, - ExplicitFileFlag: RecommendedConfigPathFlag, - - GlobalFileSubpath: path.Join(RecommendedHomeDir, RecommendedFileName), - - LoadingRules: NewDefaultClientConfigLoadingRules(), - } - ret.LoadingRules.DoNotResolvePaths = true - - return ret -} - -// ModifyConfig takes a Config object, iterates through Clusters, AuthInfos, and Contexts, uses the LocationOfOrigin if specified or -// uses the default destination file to write the results into. This results in multiple file reads, but it's very easy to follow. -// Preferences and CurrentContext should always be set in the default destination file. Since we can't distinguish between empty and missing values -// (no nil strings), we're forced have separate handling for them. In the kubeconfig cases, newConfig should have at most one difference, -// that means that this code will only write into a single file. If you want to relativizePaths, you must provide a fully qualified path in any -// modified element. -func ModifyConfig(configAccess ConfigAccess, newConfig clientcmdapi.Config, relativizePaths bool) error { - possibleSources := configAccess.GetLoadingPrecedence() - // sort the possible kubeconfig files so we always "lock" in the same order - // to avoid deadlock (note: this can fail w/ symlinks, but... come on). - sort.Strings(possibleSources) - for _, filename := range possibleSources { - if err := lockFile(filename); err != nil { - return err - } - defer unlockFile(filename) - } - - startingConfig, err := configAccess.GetStartingConfig() - if err != nil { - return err - } - - // We need to find all differences, locate their original files, read a partial config to modify only that stanza and write out the file. - // Special case the test for current context and preferences since those always write to the default file. - if reflect.DeepEqual(*startingConfig, newConfig) { - // nothing to do - return nil - } - - if startingConfig.CurrentContext != newConfig.CurrentContext { - if err := writeCurrentContext(configAccess, newConfig.CurrentContext); err != nil { - return err - } - } - - if !reflect.DeepEqual(startingConfig.Preferences, newConfig.Preferences) { - if err := writePreferences(configAccess, newConfig.Preferences); err != nil { - return err - } - } - - // Search every cluster, authInfo, and context. First from new to old for differences, then from old to new for deletions - for key, cluster := range newConfig.Clusters { - startingCluster, exists := startingConfig.Clusters[key] - if !reflect.DeepEqual(cluster, startingCluster) || !exists { - destinationFile := cluster.LocationOfOrigin - if len(destinationFile) == 0 { - destinationFile = configAccess.GetDefaultFilename() - } - - configToWrite, err := getConfigFromFile(destinationFile) - if err != nil { - return err - } - t := *cluster - - configToWrite.Clusters[key] = &t - configToWrite.Clusters[key].LocationOfOrigin = destinationFile - if relativizePaths { - if err := RelativizeClusterLocalPaths(configToWrite.Clusters[key]); err != nil { - return err - } - } - - if err := WriteToFile(*configToWrite, destinationFile); err != nil { - return err - } - } - } - - for key, context := range newConfig.Contexts { - startingContext, exists := startingConfig.Contexts[key] - if !reflect.DeepEqual(context, startingContext) || !exists { - destinationFile := context.LocationOfOrigin - if len(destinationFile) == 0 { - destinationFile = configAccess.GetDefaultFilename() - } - - configToWrite, err := getConfigFromFile(destinationFile) - if err != nil { - return err - } - configToWrite.Contexts[key] = context - - if err := WriteToFile(*configToWrite, destinationFile); err != nil { - return err - } - } - } - - for key, authInfo := range newConfig.AuthInfos { - startingAuthInfo, exists := startingConfig.AuthInfos[key] - if !reflect.DeepEqual(authInfo, startingAuthInfo) || !exists { - destinationFile := authInfo.LocationOfOrigin - if len(destinationFile) == 0 { - destinationFile = configAccess.GetDefaultFilename() - } - - configToWrite, err := getConfigFromFile(destinationFile) - if err != nil { - return err - } - t := *authInfo - configToWrite.AuthInfos[key] = &t - configToWrite.AuthInfos[key].LocationOfOrigin = destinationFile - if relativizePaths { - if err := RelativizeAuthInfoLocalPaths(configToWrite.AuthInfos[key]); err != nil { - return err - } - } - - if err := WriteToFile(*configToWrite, destinationFile); err != nil { - return err - } - } - } - - for key, cluster := range startingConfig.Clusters { - if _, exists := newConfig.Clusters[key]; !exists { - destinationFile := cluster.LocationOfOrigin - if len(destinationFile) == 0 { - destinationFile = configAccess.GetDefaultFilename() - } - - configToWrite, err := getConfigFromFile(destinationFile) - if err != nil { - return err - } - delete(configToWrite.Clusters, key) - - if err := WriteToFile(*configToWrite, destinationFile); err != nil { - return err - } - } - } - - for key, context := range startingConfig.Contexts { - if _, exists := newConfig.Contexts[key]; !exists { - destinationFile := context.LocationOfOrigin - if len(destinationFile) == 0 { - destinationFile = configAccess.GetDefaultFilename() - } - - configToWrite, err := getConfigFromFile(destinationFile) - if err != nil { - return err - } - delete(configToWrite.Contexts, key) - - if err := WriteToFile(*configToWrite, destinationFile); err != nil { - return err - } - } - } - - for key, authInfo := range startingConfig.AuthInfos { - if _, exists := newConfig.AuthInfos[key]; !exists { - destinationFile := authInfo.LocationOfOrigin - if len(destinationFile) == 0 { - destinationFile = configAccess.GetDefaultFilename() - } - - configToWrite, err := getConfigFromFile(destinationFile) - if err != nil { - return err - } - delete(configToWrite.AuthInfos, key) - - if err := WriteToFile(*configToWrite, destinationFile); err != nil { - return err - } - } - } - - return nil -} - -func PersisterForUser(configAccess ConfigAccess, user string) restclient.AuthProviderConfigPersister { - return &persister{configAccess, user} -} - -type persister struct { - configAccess ConfigAccess - user string -} - -func (p *persister) Persist(config map[string]string) error { - newConfig, err := p.configAccess.GetStartingConfig() - if err != nil { - return err - } - authInfo, ok := newConfig.AuthInfos[p.user] - if ok && authInfo.AuthProvider != nil { - authInfo.AuthProvider.Config = config - ModifyConfig(p.configAccess, *newConfig, false) - } - return nil -} - -// writeCurrentContext takes three possible paths. -// If newCurrentContext is the same as the startingConfig's current context, then we exit. -// If newCurrentContext has a value, then that value is written into the default destination file. -// If newCurrentContext is empty, then we find the config file that is setting the CurrentContext and clear the value from that file -func writeCurrentContext(configAccess ConfigAccess, newCurrentContext string) error { - if startingConfig, err := configAccess.GetStartingConfig(); err != nil { - return err - } else if startingConfig.CurrentContext == newCurrentContext { - return nil - } - - if configAccess.IsExplicitFile() { - file := configAccess.GetExplicitFile() - currConfig, err := getConfigFromFile(file) - if err != nil { - return err - } - currConfig.CurrentContext = newCurrentContext - if err := WriteToFile(*currConfig, file); err != nil { - return err - } - - return nil - } - - if len(newCurrentContext) > 0 { - destinationFile := configAccess.GetDefaultFilename() - config, err := getConfigFromFile(destinationFile) - if err != nil { - return err - } - config.CurrentContext = newCurrentContext - - if err := WriteToFile(*config, destinationFile); err != nil { - return err - } - - return nil - } - - // we're supposed to be clearing the current context. We need to find the first spot in the chain that is setting it and clear it - for _, file := range configAccess.GetLoadingPrecedence() { - if _, err := os.Stat(file); err == nil { - currConfig, err := getConfigFromFile(file) - if err != nil { - return err - } - - if len(currConfig.CurrentContext) > 0 { - currConfig.CurrentContext = newCurrentContext - if err := WriteToFile(*currConfig, file); err != nil { - return err - } - - return nil - } - } - } - - return errors.New("no config found to write context") -} - -func writePreferences(configAccess ConfigAccess, newPrefs clientcmdapi.Preferences) error { - if startingConfig, err := configAccess.GetStartingConfig(); err != nil { - return err - } else if reflect.DeepEqual(startingConfig.Preferences, newPrefs) { - return nil - } - - if configAccess.IsExplicitFile() { - file := configAccess.GetExplicitFile() - currConfig, err := getConfigFromFile(file) - if err != nil { - return err - } - currConfig.Preferences = newPrefs - if err := WriteToFile(*currConfig, file); err != nil { - return err - } - - return nil - } - - for _, file := range configAccess.GetLoadingPrecedence() { - currConfig, err := getConfigFromFile(file) - if err != nil { - return err - } - - if !reflect.DeepEqual(currConfig.Preferences, newPrefs) { - currConfig.Preferences = newPrefs - if err := WriteToFile(*currConfig, file); err != nil { - return err - } - - return nil - } - } - - return errors.New("no config found to write preferences") -} - -// getConfigFromFile tries to read a kubeconfig file and if it can't, returns an error. One exception, missing files result in empty configs, not an error. -func getConfigFromFile(filename string) (*clientcmdapi.Config, error) { - config, err := LoadFromFile(filename) - if err != nil && !os.IsNotExist(err) { - return nil, err - } - if config == nil { - config = clientcmdapi.NewConfig() - } - return config, nil -} - -// GetConfigFromFileOrDie tries to read a kubeconfig file and if it can't, it calls exit. One exception, missing files result in empty configs, not an exit -func GetConfigFromFileOrDie(filename string) *clientcmdapi.Config { - config, err := getConfigFromFile(filename) - if err != nil { - glog.FatalDepth(1, err) - } - - return config -} diff --git a/pkg/client/unversioned/clientcmd/doc.go b/pkg/client/unversioned/clientcmd/doc.go deleted file mode 100644 index 0c5979f1f7c..00000000000 --- a/pkg/client/unversioned/clientcmd/doc.go +++ /dev/null @@ -1,37 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -/* -Package clientcmd provides one stop shopping for building a working client from a fixed config, -from a .kubeconfig file, from command line flags, or from any merged combination. - -Sample usage from merged .kubeconfig files (local directory, home directory) - - loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() - // if you want to change the loading rules (which files in which order), you can do so here - - configOverrides := &clientcmd.ConfigOverrides{} - // if you want to change override values or bind them to flags, there are methods to help you - - kubeConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, configOverrides) - config, err := kubeConfig.ClientConfig() - if err != nil { - // Do something - } - client, err := metav1.New(config) - // ... -*/ -package clientcmd // import "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" diff --git a/pkg/client/unversioned/clientcmd/helpers.go b/pkg/client/unversioned/clientcmd/helpers.go deleted file mode 100644 index b609d1a766c..00000000000 --- a/pkg/client/unversioned/clientcmd/helpers.go +++ /dev/null @@ -1,35 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package clientcmd - -import ( - "fmt" - "strconv" - "time" -) - -// ParseTimeout returns a parsed duration from a string -// A duration string value must be a positive integer, optionally followed by a corresponding time unit (s|m|h). -func ParseTimeout(duration string) (time.Duration, error) { - if i, err := strconv.ParseInt(duration, 10, 64); err == nil && i >= 0 { - return (time.Duration(i) * time.Second), nil - } - if requestTimeout, err := time.ParseDuration(duration); err == nil { - return requestTimeout, nil - } - return 0, fmt.Errorf("Invalid timeout value. Timeout must be a single integer in seconds, or an integer followed by a corresponding time unit (e.g. 1s | 2m | 3h)") -} diff --git a/pkg/client/unversioned/clientcmd/loader.go b/pkg/client/unversioned/clientcmd/loader.go deleted file mode 100644 index 99e607abc52..00000000000 --- a/pkg/client/unversioned/clientcmd/loader.go +++ /dev/null @@ -1,609 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package clientcmd - -import ( - "fmt" - "io" - "io/ioutil" - "os" - "path" - "path/filepath" - "reflect" - goruntime "runtime" - "strings" - - "github.com/golang/glog" - "github.com/imdario/mergo" - - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" - utilerrors "k8s.io/apimachinery/pkg/util/errors" - restclient "k8s.io/client-go/rest" - clientcmdapi "k8s.io/client-go/tools/clientcmd/api" - clientcmdlatest "k8s.io/client-go/tools/clientcmd/api/latest" - "k8s.io/kubernetes/pkg/util/homedir" -) - -const ( - RecommendedConfigPathFlag = "kubeconfig" - RecommendedConfigPathEnvVar = "KUBECONFIG" - RecommendedHomeDir = ".kube" - RecommendedFileName = "config" - RecommendedSchemaName = "schema" -) - -var RecommendedHomeFile = path.Join(homedir.HomeDir(), RecommendedHomeDir, RecommendedFileName) -var RecommendedSchemaFile = path.Join(homedir.HomeDir(), RecommendedHomeDir, RecommendedSchemaName) - -// currentMigrationRules returns a map that holds the history of recommended home directories used in previous versions. -// Any future changes to RecommendedHomeFile and related are expected to add a migration rule here, in order to make -// sure existing config files are migrated to their new locations properly. -func currentMigrationRules() map[string]string { - oldRecommendedHomeFile := path.Join(os.Getenv("HOME"), "/.kube/.kubeconfig") - oldRecommendedWindowsHomeFile := path.Join(os.Getenv("HOME"), RecommendedHomeDir, RecommendedFileName) - - migrationRules := map[string]string{} - migrationRules[RecommendedHomeFile] = oldRecommendedHomeFile - if goruntime.GOOS == "windows" { - migrationRules[RecommendedHomeFile] = oldRecommendedWindowsHomeFile - } - return migrationRules -} - -type ClientConfigLoader interface { - ConfigAccess - // IsDefaultConfig returns true if the returned config matches the defaults. - IsDefaultConfig(*restclient.Config) bool - // Load returns the latest config - Load() (*clientcmdapi.Config, error) -} - -type KubeconfigGetter func() (*clientcmdapi.Config, error) - -type ClientConfigGetter struct { - kubeconfigGetter KubeconfigGetter -} - -// ClientConfigGetter implements the ClientConfigLoader interface. -var _ ClientConfigLoader = &ClientConfigGetter{} - -func (g *ClientConfigGetter) Load() (*clientcmdapi.Config, error) { - return g.kubeconfigGetter() -} - -func (g *ClientConfigGetter) GetLoadingPrecedence() []string { - return nil -} -func (g *ClientConfigGetter) GetStartingConfig() (*clientcmdapi.Config, error) { - return g.kubeconfigGetter() -} -func (g *ClientConfigGetter) GetDefaultFilename() string { - return "" -} -func (g *ClientConfigGetter) IsExplicitFile() bool { - return false -} -func (g *ClientConfigGetter) GetExplicitFile() string { - return "" -} -func (g *ClientConfigGetter) IsDefaultConfig(config *restclient.Config) bool { - return false -} - -// ClientConfigLoadingRules is an ExplicitPath and string slice of specific locations that are used for merging together a Config -// Callers can put the chain together however they want, but we'd recommend: -// EnvVarPathFiles if set (a list of files if set) OR the HomeDirectoryPath -// ExplicitPath is special, because if a user specifically requests a certain file be used and error is reported if thie file is not present -type ClientConfigLoadingRules struct { - ExplicitPath string - Precedence []string - - // MigrationRules is a map of destination files to source files. If a destination file is not present, then the source file is checked. - // If the source file is present, then it is copied to the destination file BEFORE any further loading happens. - MigrationRules map[string]string - - // DoNotResolvePaths indicates whether or not to resolve paths with respect to the originating files. This is phrased as a negative so - // that a default object that doesn't set this will usually get the behavior it wants. - DoNotResolvePaths bool - - // DefaultClientConfig is an optional field indicating what rules to use to calculate a default configuration. - // This should match the overrides passed in to ClientConfig loader. - DefaultClientConfig ClientConfig -} - -// ClientConfigLoadingRules implements the ClientConfigLoader interface. -var _ ClientConfigLoader = &ClientConfigLoadingRules{} - -// NewDefaultClientConfigLoadingRules returns a ClientConfigLoadingRules object with default fields filled in. You are not required to -// use this constructor -func NewDefaultClientConfigLoadingRules() *ClientConfigLoadingRules { - chain := []string{} - - envVarFiles := os.Getenv(RecommendedConfigPathEnvVar) - if len(envVarFiles) != 0 { - chain = append(chain, filepath.SplitList(envVarFiles)...) - - } else { - chain = append(chain, RecommendedHomeFile) - } - - return &ClientConfigLoadingRules{ - Precedence: chain, - MigrationRules: currentMigrationRules(), - } -} - -// Load starts by running the MigrationRules and then -// takes the loading rules and returns a Config object based on following rules. -// if the ExplicitPath, return the unmerged explicit file -// Otherwise, return a merged config based on the Precedence slice -// A missing ExplicitPath file produces an error. Empty filenames or other missing files are ignored. -// Read errors or files with non-deserializable content produce errors. -// The first file to set a particular map key wins and map key's value is never changed. -// BUT, if you set a struct value that is NOT contained inside of map, the value WILL be changed. -// This results in some odd looking logic to merge in one direction, merge in the other, and then merge the two. -// It also means that if two files specify a "red-user", only values from the first file's red-user are used. Even -// non-conflicting entries from the second file's "red-user" are discarded. -// Relative paths inside of the .kubeconfig files are resolved against the .kubeconfig file's parent folder -// and only absolute file paths are returned. -func (rules *ClientConfigLoadingRules) Load() (*clientcmdapi.Config, error) { - if err := rules.Migrate(); err != nil { - return nil, err - } - - errlist := []error{} - - kubeConfigFiles := []string{} - - // Make sure a file we were explicitly told to use exists - if len(rules.ExplicitPath) > 0 { - if _, err := os.Stat(rules.ExplicitPath); os.IsNotExist(err) { - return nil, err - } - kubeConfigFiles = append(kubeConfigFiles, rules.ExplicitPath) - - } else { - kubeConfigFiles = append(kubeConfigFiles, rules.Precedence...) - } - - kubeconfigs := []*clientcmdapi.Config{} - // read and cache the config files so that we only look at them once - for _, filename := range kubeConfigFiles { - if len(filename) == 0 { - // no work to do - continue - } - - config, err := LoadFromFile(filename) - if os.IsNotExist(err) { - // skip missing files - continue - } - if err != nil { - errlist = append(errlist, fmt.Errorf("Error loading config file \"%s\": %v", filename, err)) - continue - } - - kubeconfigs = append(kubeconfigs, config) - } - - // first merge all of our maps - mapConfig := clientcmdapi.NewConfig() - - for _, kubeconfig := range kubeconfigs { - mergo.Merge(mapConfig, kubeconfig) - } - - // merge all of the struct values in the reverse order so that priority is given correctly - // errors are not added to the list the second time - nonMapConfig := clientcmdapi.NewConfig() - for i := len(kubeconfigs) - 1; i >= 0; i-- { - kubeconfig := kubeconfigs[i] - mergo.Merge(nonMapConfig, kubeconfig) - } - - // since values are overwritten, but maps values are not, we can merge the non-map config on top of the map config and - // get the values we expect. - config := clientcmdapi.NewConfig() - mergo.Merge(config, mapConfig) - mergo.Merge(config, nonMapConfig) - - if rules.ResolvePaths() { - if err := ResolveLocalPaths(config); err != nil { - errlist = append(errlist, err) - } - } - return config, utilerrors.NewAggregate(errlist) -} - -// Migrate uses the MigrationRules map. If a destination file is not present, then the source file is checked. -// If the source file is present, then it is copied to the destination file BEFORE any further loading happens. -func (rules *ClientConfigLoadingRules) Migrate() error { - if rules.MigrationRules == nil { - return nil - } - - for destination, source := range rules.MigrationRules { - if _, err := os.Stat(destination); err == nil { - // if the destination already exists, do nothing - continue - } else if os.IsPermission(err) { - // if we can't access the file, skip it - continue - } else if !os.IsNotExist(err) { - // if we had an error other than non-existence, fail - return err - } - - if sourceInfo, err := os.Stat(source); err != nil { - if os.IsNotExist(err) || os.IsPermission(err) { - // if the source file doesn't exist or we can't access it, there's no work to do. - continue - } - - // if we had an error other than non-existence, fail - return err - } else if sourceInfo.IsDir() { - return fmt.Errorf("cannot migrate %v to %v because it is a directory", source, destination) - } - - in, err := os.Open(source) - if err != nil { - return err - } - defer in.Close() - out, err := os.Create(destination) - if err != nil { - return err - } - defer out.Close() - - if _, err = io.Copy(out, in); err != nil { - return err - } - } - - return nil -} - -// GetLoadingPrecedence implements ConfigAccess -func (rules *ClientConfigLoadingRules) GetLoadingPrecedence() []string { - return rules.Precedence -} - -// GetStartingConfig implements ConfigAccess -func (rules *ClientConfigLoadingRules) GetStartingConfig() (*clientcmdapi.Config, error) { - clientConfig := NewNonInteractiveDeferredLoadingClientConfig(rules, &ConfigOverrides{}) - rawConfig, err := clientConfig.RawConfig() - if os.IsNotExist(err) { - return clientcmdapi.NewConfig(), nil - } - if err != nil { - return nil, err - } - - return &rawConfig, nil -} - -// GetDefaultFilename implements ConfigAccess -func (rules *ClientConfigLoadingRules) GetDefaultFilename() string { - // Explicit file if we have one. - if rules.IsExplicitFile() { - return rules.GetExplicitFile() - } - // Otherwise, first existing file from precedence. - for _, filename := range rules.GetLoadingPrecedence() { - if _, err := os.Stat(filename); err == nil { - return filename - } - } - // If none exists, use the first from precedence. - if len(rules.Precedence) > 0 { - return rules.Precedence[0] - } - return "" -} - -// IsExplicitFile implements ConfigAccess -func (rules *ClientConfigLoadingRules) IsExplicitFile() bool { - return len(rules.ExplicitPath) > 0 -} - -// GetExplicitFile implements ConfigAccess -func (rules *ClientConfigLoadingRules) GetExplicitFile() string { - return rules.ExplicitPath -} - -// IsDefaultConfig returns true if the provided configuration matches the default -func (rules *ClientConfigLoadingRules) IsDefaultConfig(config *restclient.Config) bool { - if rules.DefaultClientConfig == nil { - return false - } - defaultConfig, err := rules.DefaultClientConfig.ClientConfig() - if err != nil { - return false - } - return reflect.DeepEqual(config, defaultConfig) -} - -// LoadFromFile takes a filename and deserializes the contents into Config object -func LoadFromFile(filename string) (*clientcmdapi.Config, error) { - kubeconfigBytes, err := ioutil.ReadFile(filename) - if err != nil { - return nil, err - } - config, err := Load(kubeconfigBytes) - if err != nil { - return nil, err - } - glog.V(6).Infoln("Config loaded from file", filename) - - // set LocationOfOrigin on every Cluster, User, and Context - for key, obj := range config.AuthInfos { - obj.LocationOfOrigin = filename - config.AuthInfos[key] = obj - } - for key, obj := range config.Clusters { - obj.LocationOfOrigin = filename - config.Clusters[key] = obj - } - for key, obj := range config.Contexts { - obj.LocationOfOrigin = filename - config.Contexts[key] = obj - } - - if config.AuthInfos == nil { - config.AuthInfos = map[string]*clientcmdapi.AuthInfo{} - } - if config.Clusters == nil { - config.Clusters = map[string]*clientcmdapi.Cluster{} - } - if config.Contexts == nil { - config.Contexts = map[string]*clientcmdapi.Context{} - } - - return config, nil -} - -// Load takes a byte slice and deserializes the contents into Config object. -// Encapsulates deserialization without assuming the source is a file. -func Load(data []byte) (*clientcmdapi.Config, error) { - config := clientcmdapi.NewConfig() - // if there's no data in a file, return the default object instead of failing (DecodeInto reject empty input) - if len(data) == 0 { - return config, nil - } - decoded, _, err := clientcmdlatest.Codec.Decode(data, &schema.GroupVersionKind{Version: clientcmdlatest.Version, Kind: "Config"}, config) - if err != nil { - return nil, err - } - return decoded.(*clientcmdapi.Config), nil -} - -// WriteToFile serializes the config to yaml and writes it out to a file. If not present, it creates the file with the mode 0600. If it is present -// it stomps the contents -func WriteToFile(config clientcmdapi.Config, filename string) error { - content, err := Write(config) - if err != nil { - return err - } - dir := filepath.Dir(filename) - if _, err := os.Stat(dir); os.IsNotExist(err) { - if err = os.MkdirAll(dir, 0755); err != nil { - return err - } - } - - if err := ioutil.WriteFile(filename, content, 0600); err != nil { - return err - } - return nil -} - -func lockFile(filename string) error { - // TODO: find a way to do this with actual file locks. Will - // probably need seperate solution for windows and linux. - - // Make sure the dir exists before we try to create a lock file. - dir := filepath.Dir(filename) - if _, err := os.Stat(dir); os.IsNotExist(err) { - if err = os.MkdirAll(dir, 0755); err != nil { - return err - } - } - f, err := os.OpenFile(lockName(filename), os.O_CREATE|os.O_EXCL, 0) - if err != nil { - return err - } - f.Close() - return nil -} - -func unlockFile(filename string) error { - return os.Remove(lockName(filename)) -} - -func lockName(filename string) string { - return filename + ".lock" -} - -// Write serializes the config to yaml. -// Encapsulates serialization without assuming the destination is a file. -func Write(config clientcmdapi.Config) ([]byte, error) { - return runtime.Encode(clientcmdlatest.Codec, &config) -} - -func (rules ClientConfigLoadingRules) ResolvePaths() bool { - return !rules.DoNotResolvePaths -} - -// ResolveLocalPaths resolves all relative paths in the config object with respect to the stanza's LocationOfOrigin -// this cannot be done directly inside of LoadFromFile because doing so there would make it impossible to load a file without -// modification of its contents. -func ResolveLocalPaths(config *clientcmdapi.Config) error { - for _, cluster := range config.Clusters { - if len(cluster.LocationOfOrigin) == 0 { - continue - } - base, err := filepath.Abs(filepath.Dir(cluster.LocationOfOrigin)) - if err != nil { - return fmt.Errorf("Could not determine the absolute path of config file %s: %v", cluster.LocationOfOrigin, err) - } - - if err := ResolvePaths(GetClusterFileReferences(cluster), base); err != nil { - return err - } - } - for _, authInfo := range config.AuthInfos { - if len(authInfo.LocationOfOrigin) == 0 { - continue - } - base, err := filepath.Abs(filepath.Dir(authInfo.LocationOfOrigin)) - if err != nil { - return fmt.Errorf("Could not determine the absolute path of config file %s: %v", authInfo.LocationOfOrigin, err) - } - - if err := ResolvePaths(GetAuthInfoFileReferences(authInfo), base); err != nil { - return err - } - } - - return nil -} - -// RelativizeClusterLocalPaths first absolutizes the paths by calling ResolveLocalPaths. This assumes that any NEW path is already -// absolute, but any existing path will be resolved relative to LocationOfOrigin -func RelativizeClusterLocalPaths(cluster *clientcmdapi.Cluster) error { - if len(cluster.LocationOfOrigin) == 0 { - return fmt.Errorf("no location of origin for %s", cluster.Server) - } - base, err := filepath.Abs(filepath.Dir(cluster.LocationOfOrigin)) - if err != nil { - return fmt.Errorf("could not determine the absolute path of config file %s: %v", cluster.LocationOfOrigin, err) - } - - if err := ResolvePaths(GetClusterFileReferences(cluster), base); err != nil { - return err - } - if err := RelativizePathWithNoBacksteps(GetClusterFileReferences(cluster), base); err != nil { - return err - } - - return nil -} - -// RelativizeAuthInfoLocalPaths first absolutizes the paths by calling ResolveLocalPaths. This assumes that any NEW path is already -// absolute, but any existing path will be resolved relative to LocationOfOrigin -func RelativizeAuthInfoLocalPaths(authInfo *clientcmdapi.AuthInfo) error { - if len(authInfo.LocationOfOrigin) == 0 { - return fmt.Errorf("no location of origin for %v", authInfo) - } - base, err := filepath.Abs(filepath.Dir(authInfo.LocationOfOrigin)) - if err != nil { - return fmt.Errorf("could not determine the absolute path of config file %s: %v", authInfo.LocationOfOrigin, err) - } - - if err := ResolvePaths(GetAuthInfoFileReferences(authInfo), base); err != nil { - return err - } - if err := RelativizePathWithNoBacksteps(GetAuthInfoFileReferences(authInfo), base); err != nil { - return err - } - - return nil -} - -func RelativizeConfigPaths(config *clientcmdapi.Config, base string) error { - return RelativizePathWithNoBacksteps(GetConfigFileReferences(config), base) -} - -func ResolveConfigPaths(config *clientcmdapi.Config, base string) error { - return ResolvePaths(GetConfigFileReferences(config), base) -} - -func GetConfigFileReferences(config *clientcmdapi.Config) []*string { - refs := []*string{} - - for _, cluster := range config.Clusters { - refs = append(refs, GetClusterFileReferences(cluster)...) - } - for _, authInfo := range config.AuthInfos { - refs = append(refs, GetAuthInfoFileReferences(authInfo)...) - } - - return refs -} - -func GetClusterFileReferences(cluster *clientcmdapi.Cluster) []*string { - return []*string{&cluster.CertificateAuthority} -} - -func GetAuthInfoFileReferences(authInfo *clientcmdapi.AuthInfo) []*string { - return []*string{&authInfo.ClientCertificate, &authInfo.ClientKey, &authInfo.TokenFile} -} - -// ResolvePaths updates the given refs to be absolute paths, relative to the given base directory -func ResolvePaths(refs []*string, base string) error { - for _, ref := range refs { - // Don't resolve empty paths - if len(*ref) > 0 { - // Don't resolve absolute paths - if !filepath.IsAbs(*ref) { - *ref = filepath.Join(base, *ref) - } - } - } - return nil -} - -// RelativizePathWithNoBacksteps updates the given refs to be relative paths, relative to the given base directory as long as they do not require backsteps. -// Any path requiring a backstep is left as-is as long it is absolute. Any non-absolute path that can't be relativized produces an error -func RelativizePathWithNoBacksteps(refs []*string, base string) error { - for _, ref := range refs { - // Don't relativize empty paths - if len(*ref) > 0 { - rel, err := MakeRelative(*ref, base) - if err != nil { - return err - } - - // if we have a backstep, don't mess with the path - if strings.HasPrefix(rel, "../") { - if filepath.IsAbs(*ref) { - continue - } - - return fmt.Errorf("%v requires backsteps and is not absolute", *ref) - } - - *ref = rel - } - } - return nil -} - -func MakeRelative(path, base string) (string, error) { - if len(path) > 0 { - rel, err := filepath.Rel(base, path) - if err != nil { - return path, err - } - return rel, nil - } - return path, nil -} diff --git a/pkg/client/unversioned/clientcmd/loader_test.go b/pkg/client/unversioned/clientcmd/loader_test.go deleted file mode 100644 index 74319788aba..00000000000 --- a/pkg/client/unversioned/clientcmd/loader_test.go +++ /dev/null @@ -1,579 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package clientcmd - -import ( - "fmt" - "io/ioutil" - "os" - "path" - "path/filepath" - "reflect" - "strings" - "testing" - - "github.com/ghodss/yaml" - - "k8s.io/apimachinery/pkg/runtime" - clientcmdapi "k8s.io/client-go/tools/clientcmd/api" - clientcmdlatest "k8s.io/client-go/tools/clientcmd/api/latest" -) - -var ( - testConfigAlfa = clientcmdapi.Config{ - AuthInfos: map[string]*clientcmdapi.AuthInfo{ - "red-user": {Token: "red-token"}}, - Clusters: map[string]*clientcmdapi.Cluster{ - "cow-cluster": {Server: "http://cow.org:8080"}}, - Contexts: map[string]*clientcmdapi.Context{ - "federal-context": {AuthInfo: "red-user", Cluster: "cow-cluster", Namespace: "hammer-ns"}}, - } - testConfigBravo = clientcmdapi.Config{ - AuthInfos: map[string]*clientcmdapi.AuthInfo{ - "black-user": {Token: "black-token"}}, - Clusters: map[string]*clientcmdapi.Cluster{ - "pig-cluster": {Server: "http://pig.org:8080"}}, - Contexts: map[string]*clientcmdapi.Context{ - "queen-anne-context": {AuthInfo: "black-user", Cluster: "pig-cluster", Namespace: "saw-ns"}}, - } - testConfigCharlie = clientcmdapi.Config{ - AuthInfos: map[string]*clientcmdapi.AuthInfo{ - "green-user": {Token: "green-token"}}, - Clusters: map[string]*clientcmdapi.Cluster{ - "horse-cluster": {Server: "http://horse.org:8080"}}, - Contexts: map[string]*clientcmdapi.Context{ - "shaker-context": {AuthInfo: "green-user", Cluster: "horse-cluster", Namespace: "chisel-ns"}}, - } - testConfigDelta = clientcmdapi.Config{ - AuthInfos: map[string]*clientcmdapi.AuthInfo{ - "blue-user": {Token: "blue-token"}}, - Clusters: map[string]*clientcmdapi.Cluster{ - "chicken-cluster": {Server: "http://chicken.org:8080"}}, - Contexts: map[string]*clientcmdapi.Context{ - "gothic-context": {AuthInfo: "blue-user", Cluster: "chicken-cluster", Namespace: "plane-ns"}}, - } - - testConfigConflictAlfa = clientcmdapi.Config{ - AuthInfos: map[string]*clientcmdapi.AuthInfo{ - "red-user": {Token: "a-different-red-token"}, - "yellow-user": {Token: "yellow-token"}}, - Clusters: map[string]*clientcmdapi.Cluster{ - "cow-cluster": {Server: "http://a-different-cow.org:8080", InsecureSkipTLSVerify: true}, - "donkey-cluster": {Server: "http://donkey.org:8080", InsecureSkipTLSVerify: true}}, - CurrentContext: "federal-context", - } -) - -func TestNonExistentCommandLineFile(t *testing.T) { - loadingRules := ClientConfigLoadingRules{ - ExplicitPath: "bogus_file", - } - - _, err := loadingRules.Load() - if err == nil { - t.Fatalf("Expected error for missing command-line file, got none") - } - if !strings.Contains(err.Error(), "bogus_file") { - t.Fatalf("Expected error about 'bogus_file', got %s", err.Error()) - } -} - -func TestToleratingMissingFiles(t *testing.T) { - loadingRules := ClientConfigLoadingRules{ - Precedence: []string{"bogus1", "bogus2", "bogus3"}, - } - - _, err := loadingRules.Load() - if err != nil { - t.Fatalf("Unexpected error: %v", err) - } -} - -func TestErrorReadingFile(t *testing.T) { - commandLineFile, _ := ioutil.TempFile("", "") - defer os.Remove(commandLineFile.Name()) - - if err := ioutil.WriteFile(commandLineFile.Name(), []byte("bogus value"), 0644); err != nil { - t.Fatalf("Error creating tempfile: %v", err) - } - - loadingRules := ClientConfigLoadingRules{ - ExplicitPath: commandLineFile.Name(), - } - - _, err := loadingRules.Load() - if err == nil { - t.Fatalf("Expected error for unloadable file, got none") - } - if !strings.Contains(err.Error(), commandLineFile.Name()) { - t.Fatalf("Expected error about '%s', got %s", commandLineFile.Name(), err.Error()) - } -} - -func TestErrorReadingNonFile(t *testing.T) { - tmpdir, err := ioutil.TempDir("", "") - if err != nil { - t.Fatalf("Couldn't create tmpdir") - } - defer os.RemoveAll(tmpdir) - - loadingRules := ClientConfigLoadingRules{ - ExplicitPath: tmpdir, - } - - _, err = loadingRules.Load() - if err == nil { - t.Fatalf("Expected error for non-file, got none") - } - if !strings.Contains(err.Error(), tmpdir) { - t.Fatalf("Expected error about '%s', got %s", tmpdir, err.Error()) - } -} - -func TestConflictingCurrentContext(t *testing.T) { - commandLineFile, _ := ioutil.TempFile("", "") - defer os.Remove(commandLineFile.Name()) - envVarFile, _ := ioutil.TempFile("", "") - defer os.Remove(envVarFile.Name()) - - mockCommandLineConfig := clientcmdapi.Config{ - CurrentContext: "any-context-value", - } - mockEnvVarConfig := clientcmdapi.Config{ - CurrentContext: "a-different-context", - } - - WriteToFile(mockCommandLineConfig, commandLineFile.Name()) - WriteToFile(mockEnvVarConfig, envVarFile.Name()) - - loadingRules := ClientConfigLoadingRules{ - ExplicitPath: commandLineFile.Name(), - Precedence: []string{envVarFile.Name()}, - } - - mergedConfig, err := loadingRules.Load() - if err != nil { - t.Errorf("Unexpected error: %v", err) - } - - if mergedConfig.CurrentContext != mockCommandLineConfig.CurrentContext { - t.Errorf("expected %v, got %v", mockCommandLineConfig.CurrentContext, mergedConfig.CurrentContext) - } -} - -func TestLoadingEmptyMaps(t *testing.T) { - configFile, _ := ioutil.TempFile("", "") - defer os.Remove(configFile.Name()) - - mockConfig := clientcmdapi.Config{ - CurrentContext: "any-context-value", - } - - WriteToFile(mockConfig, configFile.Name()) - - config, err := LoadFromFile(configFile.Name()) - if err != nil { - t.Errorf("Unexpected error: %v", err) - } - - if config.Clusters == nil { - t.Error("expected config.Clusters to be non-nil") - } - if config.AuthInfos == nil { - t.Error("expected config.AuthInfos to be non-nil") - } - if config.Contexts == nil { - t.Error("expected config.Contexts to be non-nil") - } -} - -func TestResolveRelativePaths(t *testing.T) { - pathResolutionConfig1 := clientcmdapi.Config{ - AuthInfos: map[string]*clientcmdapi.AuthInfo{ - "relative-user-1": {ClientCertificate: "relative/client/cert", ClientKey: "../relative/client/key"}, - "absolute-user-1": {ClientCertificate: "/absolute/client/cert", ClientKey: "/absolute/client/key"}, - }, - Clusters: map[string]*clientcmdapi.Cluster{ - "relative-server-1": {CertificateAuthority: "../relative/ca"}, - "absolute-server-1": {CertificateAuthority: "/absolute/ca"}, - }, - } - pathResolutionConfig2 := clientcmdapi.Config{ - AuthInfos: map[string]*clientcmdapi.AuthInfo{ - "relative-user-2": {ClientCertificate: "relative/client/cert2", ClientKey: "../relative/client/key2"}, - "absolute-user-2": {ClientCertificate: "/absolute/client/cert2", ClientKey: "/absolute/client/key2"}, - }, - Clusters: map[string]*clientcmdapi.Cluster{ - "relative-server-2": {CertificateAuthority: "../relative/ca2"}, - "absolute-server-2": {CertificateAuthority: "/absolute/ca2"}, - }, - } - - configDir1, _ := ioutil.TempDir("", "") - defer os.RemoveAll(configDir1) - configFile1 := path.Join(configDir1, ".kubeconfig") - configDir1, _ = filepath.Abs(configDir1) - - configDir2, _ := ioutil.TempDir("", "") - defer os.RemoveAll(configDir2) - configDir2, _ = ioutil.TempDir(configDir2, "") - configFile2 := path.Join(configDir2, ".kubeconfig") - configDir2, _ = filepath.Abs(configDir2) - - WriteToFile(pathResolutionConfig1, configFile1) - WriteToFile(pathResolutionConfig2, configFile2) - - loadingRules := ClientConfigLoadingRules{ - Precedence: []string{configFile1, configFile2}, - } - - mergedConfig, err := loadingRules.Load() - if err != nil { - t.Errorf("Unexpected error: %v", err) - } - - foundClusterCount := 0 - for key, cluster := range mergedConfig.Clusters { - if key == "relative-server-1" { - foundClusterCount++ - matchStringArg(path.Join(configDir1, pathResolutionConfig1.Clusters["relative-server-1"].CertificateAuthority), cluster.CertificateAuthority, t) - } - if key == "relative-server-2" { - foundClusterCount++ - matchStringArg(path.Join(configDir2, pathResolutionConfig2.Clusters["relative-server-2"].CertificateAuthority), cluster.CertificateAuthority, t) - } - if key == "absolute-server-1" { - foundClusterCount++ - matchStringArg(pathResolutionConfig1.Clusters["absolute-server-1"].CertificateAuthority, cluster.CertificateAuthority, t) - } - if key == "absolute-server-2" { - foundClusterCount++ - matchStringArg(pathResolutionConfig2.Clusters["absolute-server-2"].CertificateAuthority, cluster.CertificateAuthority, t) - } - } - if foundClusterCount != 4 { - t.Errorf("Expected 4 clusters, found %v: %v", foundClusterCount, mergedConfig.Clusters) - } - - foundAuthInfoCount := 0 - for key, authInfo := range mergedConfig.AuthInfos { - if key == "relative-user-1" { - foundAuthInfoCount++ - matchStringArg(path.Join(configDir1, pathResolutionConfig1.AuthInfos["relative-user-1"].ClientCertificate), authInfo.ClientCertificate, t) - matchStringArg(path.Join(configDir1, pathResolutionConfig1.AuthInfos["relative-user-1"].ClientKey), authInfo.ClientKey, t) - } - if key == "relative-user-2" { - foundAuthInfoCount++ - matchStringArg(path.Join(configDir2, pathResolutionConfig2.AuthInfos["relative-user-2"].ClientCertificate), authInfo.ClientCertificate, t) - matchStringArg(path.Join(configDir2, pathResolutionConfig2.AuthInfos["relative-user-2"].ClientKey), authInfo.ClientKey, t) - } - if key == "absolute-user-1" { - foundAuthInfoCount++ - matchStringArg(pathResolutionConfig1.AuthInfos["absolute-user-1"].ClientCertificate, authInfo.ClientCertificate, t) - matchStringArg(pathResolutionConfig1.AuthInfos["absolute-user-1"].ClientKey, authInfo.ClientKey, t) - } - if key == "absolute-user-2" { - foundAuthInfoCount++ - matchStringArg(pathResolutionConfig2.AuthInfos["absolute-user-2"].ClientCertificate, authInfo.ClientCertificate, t) - matchStringArg(pathResolutionConfig2.AuthInfos["absolute-user-2"].ClientKey, authInfo.ClientKey, t) - } - } - if foundAuthInfoCount != 4 { - t.Errorf("Expected 4 users, found %v: %v", foundAuthInfoCount, mergedConfig.AuthInfos) - } - -} - -func TestMigratingFile(t *testing.T) { - sourceFile, _ := ioutil.TempFile("", "") - defer os.Remove(sourceFile.Name()) - destinationFile, _ := ioutil.TempFile("", "") - // delete the file so that we'll write to it - os.Remove(destinationFile.Name()) - - WriteToFile(testConfigAlfa, sourceFile.Name()) - - loadingRules := ClientConfigLoadingRules{ - MigrationRules: map[string]string{destinationFile.Name(): sourceFile.Name()}, - } - - if _, err := loadingRules.Load(); err != nil { - t.Errorf("unexpected error %v", err) - } - - // the load should have recreated this file - defer os.Remove(destinationFile.Name()) - - sourceContent, err := ioutil.ReadFile(sourceFile.Name()) - if err != nil { - t.Errorf("unexpected error %v", err) - } - destinationContent, err := ioutil.ReadFile(destinationFile.Name()) - if err != nil { - t.Errorf("unexpected error %v", err) - } - - if !reflect.DeepEqual(sourceContent, destinationContent) { - t.Errorf("source and destination do not match") - } -} - -func TestMigratingFileLeaveExistingFileAlone(t *testing.T) { - sourceFile, _ := ioutil.TempFile("", "") - defer os.Remove(sourceFile.Name()) - destinationFile, _ := ioutil.TempFile("", "") - defer os.Remove(destinationFile.Name()) - - WriteToFile(testConfigAlfa, sourceFile.Name()) - - loadingRules := ClientConfigLoadingRules{ - MigrationRules: map[string]string{destinationFile.Name(): sourceFile.Name()}, - } - - if _, err := loadingRules.Load(); err != nil { - t.Errorf("unexpected error %v", err) - } - - destinationContent, err := ioutil.ReadFile(destinationFile.Name()) - if err != nil { - t.Errorf("unexpected error %v", err) - } - - if len(destinationContent) > 0 { - t.Errorf("destination should not have been touched") - } -} - -func TestMigratingFileSourceMissingSkip(t *testing.T) { - sourceFilename := "some-missing-file" - destinationFile, _ := ioutil.TempFile("", "") - // delete the file so that we'll write to it - os.Remove(destinationFile.Name()) - - loadingRules := ClientConfigLoadingRules{ - MigrationRules: map[string]string{destinationFile.Name(): sourceFilename}, - } - - if _, err := loadingRules.Load(); err != nil { - t.Errorf("unexpected error %v", err) - } - - if _, err := os.Stat(destinationFile.Name()); !os.IsNotExist(err) { - t.Errorf("destination should not exist") - } -} - -func TestFileLocking(t *testing.T) { - f, _ := ioutil.TempFile("", "") - defer os.Remove(f.Name()) - - err := lockFile(f.Name()) - if err != nil { - t.Errorf("unexpected error while locking file: %v", err) - } - defer unlockFile(f.Name()) - - err = lockFile(f.Name()) - if err == nil { - t.Error("expected error while locking file.") - } -} - -func Example_noMergingOnExplicitPaths() { - commandLineFile, _ := ioutil.TempFile("", "") - defer os.Remove(commandLineFile.Name()) - envVarFile, _ := ioutil.TempFile("", "") - defer os.Remove(envVarFile.Name()) - - WriteToFile(testConfigAlfa, commandLineFile.Name()) - WriteToFile(testConfigConflictAlfa, envVarFile.Name()) - - loadingRules := ClientConfigLoadingRules{ - ExplicitPath: commandLineFile.Name(), - Precedence: []string{envVarFile.Name()}, - } - - mergedConfig, err := loadingRules.Load() - - json, err := runtime.Encode(clientcmdlatest.Codec, mergedConfig) - if err != nil { - fmt.Printf("Unexpected error: %v", err) - } - output, err := yaml.JSONToYAML(json) - if err != nil { - fmt.Printf("Unexpected error: %v", err) - } - - fmt.Printf("%v", string(output)) - // Output: - // apiVersion: v1 - // clusters: - // - cluster: - // server: http://cow.org:8080 - // name: cow-cluster - // contexts: - // - context: - // cluster: cow-cluster - // namespace: hammer-ns - // user: red-user - // name: federal-context - // current-context: "" - // kind: Config - // preferences: {} - // users: - // - name: red-user - // user: - // token: red-token -} - -func Example_mergingSomeWithConflict() { - commandLineFile, _ := ioutil.TempFile("", "") - defer os.Remove(commandLineFile.Name()) - envVarFile, _ := ioutil.TempFile("", "") - defer os.Remove(envVarFile.Name()) - - WriteToFile(testConfigAlfa, commandLineFile.Name()) - WriteToFile(testConfigConflictAlfa, envVarFile.Name()) - - loadingRules := ClientConfigLoadingRules{ - Precedence: []string{commandLineFile.Name(), envVarFile.Name()}, - } - - mergedConfig, err := loadingRules.Load() - - json, err := runtime.Encode(clientcmdlatest.Codec, mergedConfig) - if err != nil { - fmt.Printf("Unexpected error: %v", err) - } - output, err := yaml.JSONToYAML(json) - if err != nil { - fmt.Printf("Unexpected error: %v", err) - } - - fmt.Printf("%v", string(output)) - // Output: - // apiVersion: v1 - // clusters: - // - cluster: - // server: http://cow.org:8080 - // name: cow-cluster - // - cluster: - // insecure-skip-tls-verify: true - // server: http://donkey.org:8080 - // name: donkey-cluster - // contexts: - // - context: - // cluster: cow-cluster - // namespace: hammer-ns - // user: red-user - // name: federal-context - // current-context: federal-context - // kind: Config - // preferences: {} - // users: - // - name: red-user - // user: - // token: red-token - // - name: yellow-user - // user: - // token: yellow-token -} - -func Example_mergingEverythingNoConflicts() { - commandLineFile, _ := ioutil.TempFile("", "") - defer os.Remove(commandLineFile.Name()) - envVarFile, _ := ioutil.TempFile("", "") - defer os.Remove(envVarFile.Name()) - currentDirFile, _ := ioutil.TempFile("", "") - defer os.Remove(currentDirFile.Name()) - homeDirFile, _ := ioutil.TempFile("", "") - defer os.Remove(homeDirFile.Name()) - - WriteToFile(testConfigAlfa, commandLineFile.Name()) - WriteToFile(testConfigBravo, envVarFile.Name()) - WriteToFile(testConfigCharlie, currentDirFile.Name()) - WriteToFile(testConfigDelta, homeDirFile.Name()) - - loadingRules := ClientConfigLoadingRules{ - Precedence: []string{commandLineFile.Name(), envVarFile.Name(), currentDirFile.Name(), homeDirFile.Name()}, - } - - mergedConfig, err := loadingRules.Load() - - json, err := runtime.Encode(clientcmdlatest.Codec, mergedConfig) - if err != nil { - fmt.Printf("Unexpected error: %v", err) - } - output, err := yaml.JSONToYAML(json) - if err != nil { - fmt.Printf("Unexpected error: %v", err) - } - - fmt.Printf("%v", string(output)) - // Output: - // apiVersion: v1 - // clusters: - // - cluster: - // server: http://chicken.org:8080 - // name: chicken-cluster - // - cluster: - // server: http://cow.org:8080 - // name: cow-cluster - // - cluster: - // server: http://horse.org:8080 - // name: horse-cluster - // - cluster: - // server: http://pig.org:8080 - // name: pig-cluster - // contexts: - // - context: - // cluster: cow-cluster - // namespace: hammer-ns - // user: red-user - // name: federal-context - // - context: - // cluster: chicken-cluster - // namespace: plane-ns - // user: blue-user - // name: gothic-context - // - context: - // cluster: pig-cluster - // namespace: saw-ns - // user: black-user - // name: queen-anne-context - // - context: - // cluster: horse-cluster - // namespace: chisel-ns - // user: green-user - // name: shaker-context - // current-context: "" - // kind: Config - // preferences: {} - // users: - // - name: black-user - // user: - // token: black-token - // - name: blue-user - // user: - // token: blue-token - // - name: green-user - // user: - // token: green-token - // - name: red-user - // user: - // token: red-token -} diff --git a/pkg/client/unversioned/clientcmd/merged_client_builder.go b/pkg/client/unversioned/clientcmd/merged_client_builder.go deleted file mode 100644 index 92c1a5a0061..00000000000 --- a/pkg/client/unversioned/clientcmd/merged_client_builder.go +++ /dev/null @@ -1,154 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package clientcmd - -import ( - "io" - "sync" - - "github.com/golang/glog" - - restclient "k8s.io/client-go/rest" - clientcmdapi "k8s.io/client-go/tools/clientcmd/api" -) - -// DeferredLoadingClientConfig is a ClientConfig interface that is backed by a client config loader. -// It is used in cases where the loading rules may change after you've instantiated them and you want to be sure that -// the most recent rules are used. This is useful in cases where you bind flags to loading rule parameters before -// the parse happens and you want your calling code to be ignorant of how the values are being mutated to avoid -// passing extraneous information down a call stack -type DeferredLoadingClientConfig struct { - loader ClientConfigLoader - overrides *ConfigOverrides - fallbackReader io.Reader - - clientConfig ClientConfig - loadingLock sync.Mutex - - // provided for testing - icc InClusterConfig -} - -// InClusterConfig abstracts details of whether the client is running in a cluster for testing. -type InClusterConfig interface { - ClientConfig - Possible() bool -} - -// NewNonInteractiveDeferredLoadingClientConfig creates a ConfigClientClientConfig using the passed context name -func NewNonInteractiveDeferredLoadingClientConfig(loader ClientConfigLoader, overrides *ConfigOverrides) ClientConfig { - return &DeferredLoadingClientConfig{loader: loader, overrides: overrides, icc: &inClusterClientConfig{overrides: overrides}} -} - -// NewInteractiveDeferredLoadingClientConfig creates a ConfigClientClientConfig using the passed context name and the fallback auth reader -func NewInteractiveDeferredLoadingClientConfig(loader ClientConfigLoader, overrides *ConfigOverrides, fallbackReader io.Reader) ClientConfig { - return &DeferredLoadingClientConfig{loader: loader, overrides: overrides, icc: &inClusterClientConfig{overrides: overrides}, fallbackReader: fallbackReader} -} - -func (config *DeferredLoadingClientConfig) createClientConfig() (ClientConfig, error) { - if config.clientConfig == nil { - config.loadingLock.Lock() - defer config.loadingLock.Unlock() - - if config.clientConfig == nil { - mergedConfig, err := config.loader.Load() - if err != nil { - return nil, err - } - - var mergedClientConfig ClientConfig - if config.fallbackReader != nil { - mergedClientConfig = NewInteractiveClientConfig(*mergedConfig, config.overrides.CurrentContext, config.overrides, config.fallbackReader, config.loader) - } else { - mergedClientConfig = NewNonInteractiveClientConfig(*mergedConfig, config.overrides.CurrentContext, config.overrides, config.loader) - } - - config.clientConfig = mergedClientConfig - } - } - - return config.clientConfig, nil -} - -func (config *DeferredLoadingClientConfig) RawConfig() (clientcmdapi.Config, error) { - mergedConfig, err := config.createClientConfig() - if err != nil { - return clientcmdapi.Config{}, err - } - - return mergedConfig.RawConfig() -} - -// ClientConfig implements ClientConfig -func (config *DeferredLoadingClientConfig) ClientConfig() (*restclient.Config, error) { - mergedClientConfig, err := config.createClientConfig() - if err != nil { - return nil, err - } - - // load the configuration and return on non-empty errors and if the - // content differs from the default config - mergedConfig, err := mergedClientConfig.ClientConfig() - switch { - case err != nil: - if !IsEmptyConfig(err) { - // return on any error except empty config - return nil, err - } - case mergedConfig != nil: - // the configuration is valid, but if this is equal to the defaults we should try - // in-cluster configuration - if !config.loader.IsDefaultConfig(mergedConfig) { - return mergedConfig, nil - } - } - - // check for in-cluster configuration and use it - if config.icc.Possible() { - glog.V(4).Infof("Using in-cluster configuration") - return config.icc.ClientConfig() - } - - // return the result of the merged client config - return mergedConfig, err -} - -// Namespace implements KubeConfig -func (config *DeferredLoadingClientConfig) Namespace() (string, bool, error) { - mergedKubeConfig, err := config.createClientConfig() - if err != nil { - return "", false, err - } - - ns, ok, err := mergedKubeConfig.Namespace() - // if we get an error and it is not empty config, or if the merged config defined an explicit namespace, or - // if in-cluster config is not possible, return immediately - if (err != nil && !IsEmptyConfig(err)) || ok || !config.icc.Possible() { - // return on any error except empty config - return ns, ok, err - } - - glog.V(4).Infof("Using in-cluster namespace") - - // allow the namespace from the service account token directory to be used. - return config.icc.Namespace() -} - -// ConfigAccess implements ClientConfig -func (config *DeferredLoadingClientConfig) ConfigAccess() ConfigAccess { - return config.loader -} diff --git a/pkg/client/unversioned/clientcmd/merged_client_builder_test.go b/pkg/client/unversioned/clientcmd/merged_client_builder_test.go deleted file mode 100644 index 8b0386764d5..00000000000 --- a/pkg/client/unversioned/clientcmd/merged_client_builder_test.go +++ /dev/null @@ -1,328 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package clientcmd - -import ( - "fmt" - "testing" - - restclient "k8s.io/client-go/rest" - clientcmdapi "k8s.io/client-go/tools/clientcmd/api" -) - -type testLoader struct { - ClientConfigLoader - - called bool - config *clientcmdapi.Config - err error -} - -func (l *testLoader) Load() (*clientcmdapi.Config, error) { - l.called = true - return l.config, l.err -} - -type testClientConfig struct { - config *restclient.Config - namespace string - namespaceSpecified bool - err error -} - -func (c *testClientConfig) RawConfig() (clientcmdapi.Config, error) { - return clientcmdapi.Config{}, fmt.Errorf("unexpected call") -} -func (c *testClientConfig) ClientConfig() (*restclient.Config, error) { - return c.config, c.err -} -func (c *testClientConfig) Namespace() (string, bool, error) { - return c.namespace, c.namespaceSpecified, c.err -} -func (c *testClientConfig) ConfigAccess() ConfigAccess { - return nil -} - -type testICC struct { - testClientConfig - - possible bool - called bool -} - -func (icc *testICC) Possible() bool { - icc.called = true - return icc.possible -} - -func TestInClusterConfig(t *testing.T) { - default1 := &DirectClientConfig{ - config: *createValidTestConfig(), - contextName: "clean", - overrides: &ConfigOverrides{}, - } - invalidDefaultConfig := clientcmdapi.NewConfig() - invalidDefaultConfig.Clusters["clean"] = &clientcmdapi.Cluster{ - Server: "http://localhost:8080", - } - invalidDefaultConfig.Contexts["other"] = &clientcmdapi.Context{ - Cluster: "clean", - } - invalidDefaultConfig.CurrentContext = "clean" - - defaultInvalid := &DirectClientConfig{ - config: *invalidDefaultConfig, - overrides: &ConfigOverrides{}, - } - if _, err := defaultInvalid.ClientConfig(); err == nil || !IsConfigurationInvalid(err) { - t.Fatal(err) - } - config1, err := default1.ClientConfig() - if err != nil { - t.Fatal(err) - } - config2 := &restclient.Config{Host: "config2"} - err1 := fmt.Errorf("unique error") - - testCases := map[string]struct { - clientConfig *testClientConfig - icc *testICC - defaultConfig *DirectClientConfig - - checkedICC bool - result *restclient.Config - err error - }{ - "in-cluster checked on other error": { - clientConfig: &testClientConfig{err: ErrEmptyConfig}, - icc: &testICC{}, - - checkedICC: true, - result: nil, - err: ErrEmptyConfig, - }, - - "in-cluster not checked on non-empty error": { - clientConfig: &testClientConfig{err: ErrEmptyCluster}, - icc: &testICC{}, - - checkedICC: false, - result: nil, - err: ErrEmptyCluster, - }, - - "in-cluster checked when config is default": { - defaultConfig: default1, - clientConfig: &testClientConfig{config: config1}, - icc: &testICC{}, - - checkedICC: true, - result: config1, - err: nil, - }, - - "in-cluster not checked when default config is invalid": { - defaultConfig: defaultInvalid, - clientConfig: &testClientConfig{config: config1}, - icc: &testICC{}, - - checkedICC: false, - result: config1, - err: nil, - }, - - "in-cluster not checked when config is not equal to default": { - defaultConfig: default1, - clientConfig: &testClientConfig{config: config2}, - icc: &testICC{}, - - checkedICC: false, - result: config2, - err: nil, - }, - - "in-cluster checked when config is not equal to default and error is empty": { - clientConfig: &testClientConfig{config: config2, err: ErrEmptyConfig}, - icc: &testICC{}, - - checkedICC: true, - result: config2, - err: ErrEmptyConfig, - }, - - "in-cluster error returned when config is empty": { - clientConfig: &testClientConfig{err: ErrEmptyConfig}, - icc: &testICC{ - possible: true, - testClientConfig: testClientConfig{ - err: err1, - }, - }, - - checkedICC: true, - result: nil, - err: err1, - }, - - "in-cluster config returned when config is empty": { - clientConfig: &testClientConfig{err: ErrEmptyConfig}, - icc: &testICC{ - possible: true, - testClientConfig: testClientConfig{ - config: config2, - }, - }, - - checkedICC: true, - result: config2, - err: nil, - }, - - "in-cluster not checked when standard default is invalid": { - defaultConfig: &DefaultClientConfig, - clientConfig: &testClientConfig{config: config2}, - icc: &testICC{}, - - checkedICC: false, - result: config2, - err: nil, - }, - } - - for name, test := range testCases { - c := &DeferredLoadingClientConfig{icc: test.icc} - c.loader = &ClientConfigLoadingRules{DefaultClientConfig: test.defaultConfig} - c.clientConfig = test.clientConfig - - cfg, err := c.ClientConfig() - if test.icc.called != test.checkedICC { - t.Errorf("%s: unexpected in-cluster-config call %t", name, test.icc.called) - } - if err != test.err || cfg != test.result { - t.Errorf("%s: unexpected result: %v %#v", name, err, cfg) - } - } -} - -func TestInClusterConfigNamespace(t *testing.T) { - err1 := fmt.Errorf("unique error") - - testCases := map[string]struct { - clientConfig *testClientConfig - icc *testICC - - checkedICC bool - result string - ok bool - err error - }{ - "in-cluster checked on empty error": { - clientConfig: &testClientConfig{err: ErrEmptyConfig}, - icc: &testICC{}, - - checkedICC: true, - err: ErrEmptyConfig, - }, - - "in-cluster not checked on non-empty error": { - clientConfig: &testClientConfig{err: ErrEmptyCluster}, - icc: &testICC{}, - - err: ErrEmptyCluster, - }, - - "in-cluster checked when config is default": { - clientConfig: &testClientConfig{}, - icc: &testICC{}, - - checkedICC: true, - }, - - "in-cluster not checked when config is not equal to default": { - clientConfig: &testClientConfig{namespace: "test", namespaceSpecified: true}, - icc: &testICC{}, - - result: "test", - ok: true, - }, - - "in-cluster checked when namespace is not specified, but is defaulted": { - clientConfig: &testClientConfig{namespace: "test", namespaceSpecified: false}, - icc: &testICC{}, - - checkedICC: true, - result: "test", - ok: false, - }, - - "in-cluster error returned when config is empty": { - clientConfig: &testClientConfig{err: ErrEmptyConfig}, - icc: &testICC{ - possible: true, - testClientConfig: testClientConfig{ - err: err1, - }, - }, - - checkedICC: true, - err: err1, - }, - - "in-cluster config returned when config is empty": { - clientConfig: &testClientConfig{err: ErrEmptyConfig}, - icc: &testICC{ - possible: true, - testClientConfig: testClientConfig{ - namespace: "test", - namespaceSpecified: true, - }, - }, - - checkedICC: true, - result: "test", - ok: true, - }, - - "in-cluster config returned when config is empty and namespace is defaulted but not explicitly set": { - clientConfig: &testClientConfig{err: ErrEmptyConfig}, - icc: &testICC{ - possible: true, - testClientConfig: testClientConfig{ - namespace: "test", - namespaceSpecified: false, - }, - }, - - checkedICC: true, - result: "test", - ok: false, - }, - } - - for name, test := range testCases { - c := &DeferredLoadingClientConfig{icc: test.icc} - c.clientConfig = test.clientConfig - - ns, ok, err := c.Namespace() - if test.icc.called != test.checkedICC { - t.Errorf("%s: unexpected in-cluster-config call %t", name, test.icc.called) - } - if err != test.err || ns != test.result || ok != test.ok { - t.Errorf("%s: unexpected result: %v %s %t", name, err, ns, ok) - } - } -} diff --git a/pkg/client/unversioned/clientcmd/overrides.go b/pkg/client/unversioned/clientcmd/overrides.go deleted file mode 100644 index 8622981a9e7..00000000000 --- a/pkg/client/unversioned/clientcmd/overrides.go +++ /dev/null @@ -1,206 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package clientcmd - -import ( - "strconv" - - "github.com/spf13/pflag" - - clientcmdapi "k8s.io/client-go/tools/clientcmd/api" -) - -// ConfigOverrides holds values that should override whatever information is pulled from the actual Config object. You can't -// simply use an actual Config object, because Configs hold maps, but overrides are restricted to "at most one" -type ConfigOverrides struct { - AuthInfo clientcmdapi.AuthInfo - // ClusterDefaults are applied before the configured cluster info is loaded. - ClusterDefaults clientcmdapi.Cluster - ClusterInfo clientcmdapi.Cluster - Context clientcmdapi.Context - CurrentContext string - Timeout string -} - -// ConfigOverrideFlags holds the flag names to be used for binding command line flags. Notice that this structure tightly -// corresponds to ConfigOverrides -type ConfigOverrideFlags struct { - AuthOverrideFlags AuthOverrideFlags - ClusterOverrideFlags ClusterOverrideFlags - ContextOverrideFlags ContextOverrideFlags - CurrentContext FlagInfo - Timeout FlagInfo -} - -// AuthOverrideFlags holds the flag names to be used for binding command line flags for AuthInfo objects -type AuthOverrideFlags struct { - ClientCertificate FlagInfo - ClientKey FlagInfo - Token FlagInfo - Impersonate FlagInfo - Username FlagInfo - Password FlagInfo -} - -// ContextOverrideFlags holds the flag names to be used for binding command line flags for Cluster objects -type ContextOverrideFlags struct { - ClusterName FlagInfo - AuthInfoName FlagInfo - Namespace FlagInfo -} - -// ClusterOverride holds the flag names to be used for binding command line flags for Cluster objects -type ClusterOverrideFlags struct { - APIServer FlagInfo - APIVersion FlagInfo - CertificateAuthority FlagInfo - InsecureSkipTLSVerify FlagInfo -} - -// FlagInfo contains information about how to register a flag. This struct is useful if you want to provide a way for an extender to -// get back a set of recommended flag names, descriptions, and defaults, but allow for customization by an extender. This makes for -// coherent extension, without full prescription -type FlagInfo struct { - // LongName is the long string for a flag. If this is empty, then the flag will not be bound - LongName string - // ShortName is the single character for a flag. If this is empty, then there will be no short flag - ShortName string - // Default is the default value for the flag - Default string - // Description is the description for the flag - Description string -} - -// BindStringFlag binds the flag based on the provided info. If LongName == "", nothing is registered -func (f FlagInfo) BindStringFlag(flags *pflag.FlagSet, target *string) { - // you can't register a flag without a long name - if len(f.LongName) > 0 { - flags.StringVarP(target, f.LongName, f.ShortName, f.Default, f.Description) - } -} - -// BindBoolFlag binds the flag based on the provided info. If LongName == "", nothing is registered -func (f FlagInfo) BindBoolFlag(flags *pflag.FlagSet, target *bool) { - // you can't register a flag without a long name - if len(f.LongName) > 0 { - // try to parse Default as a bool. If it fails, assume false - boolVal, err := strconv.ParseBool(f.Default) - if err != nil { - boolVal = false - } - - flags.BoolVarP(target, f.LongName, f.ShortName, boolVal, f.Description) - } -} - -const ( - FlagClusterName = "cluster" - FlagAuthInfoName = "user" - FlagContext = "context" - FlagNamespace = "namespace" - FlagAPIServer = "server" - FlagAPIVersion = "api-version" - FlagInsecure = "insecure-skip-tls-verify" - FlagCertFile = "client-certificate" - FlagKeyFile = "client-key" - FlagCAFile = "certificate-authority" - FlagEmbedCerts = "embed-certs" - FlagBearerToken = "token" - FlagImpersonate = "as" - FlagUsername = "username" - FlagPassword = "password" - FlagTimeout = "request-timeout" -) - -// RecommendedConfigOverrideFlags is a convenience method to return recommended flag names prefixed with a string of your choosing -func RecommendedConfigOverrideFlags(prefix string) ConfigOverrideFlags { - return ConfigOverrideFlags{ - AuthOverrideFlags: RecommendedAuthOverrideFlags(prefix), - ClusterOverrideFlags: RecommendedClusterOverrideFlags(prefix), - ContextOverrideFlags: RecommendedContextOverrideFlags(prefix), - - CurrentContext: FlagInfo{prefix + FlagContext, "", "", "The name of the kubeconfig context to use"}, - Timeout: FlagInfo{prefix + FlagTimeout, "", "0", "The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests."}, - } -} - -// RecommendedAuthOverrideFlags is a convenience method to return recommended flag names prefixed with a string of your choosing -func RecommendedAuthOverrideFlags(prefix string) AuthOverrideFlags { - return AuthOverrideFlags{ - ClientCertificate: FlagInfo{prefix + FlagCertFile, "", "", "Path to a client certificate file for TLS"}, - ClientKey: FlagInfo{prefix + FlagKeyFile, "", "", "Path to a client key file for TLS"}, - Token: FlagInfo{prefix + FlagBearerToken, "", "", "Bearer token for authentication to the API server"}, - Impersonate: FlagInfo{prefix + FlagImpersonate, "", "", "Username to impersonate for the operation"}, - Username: FlagInfo{prefix + FlagUsername, "", "", "Username for basic authentication to the API server"}, - Password: FlagInfo{prefix + FlagPassword, "", "", "Password for basic authentication to the API server"}, - } -} - -// RecommendedClusterOverrideFlags is a convenience method to return recommended flag names prefixed with a string of your choosing -func RecommendedClusterOverrideFlags(prefix string) ClusterOverrideFlags { - return ClusterOverrideFlags{ - APIServer: FlagInfo{prefix + FlagAPIServer, "", "", "The address and port of the Kubernetes API server"}, - APIVersion: FlagInfo{prefix + FlagAPIVersion, "", "", "DEPRECATED: The API version to use when talking to the server"}, - CertificateAuthority: FlagInfo{prefix + FlagCAFile, "", "", "Path to a cert. file for the certificate authority"}, - InsecureSkipTLSVerify: FlagInfo{prefix + FlagInsecure, "", "false", "If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure"}, - } -} - -// RecommendedContextOverrideFlags is a convenience method to return recommended flag names prefixed with a string of your choosing -func RecommendedContextOverrideFlags(prefix string) ContextOverrideFlags { - return ContextOverrideFlags{ - ClusterName: FlagInfo{prefix + FlagClusterName, "", "", "The name of the kubeconfig cluster to use"}, - AuthInfoName: FlagInfo{prefix + FlagAuthInfoName, "", "", "The name of the kubeconfig user to use"}, - Namespace: FlagInfo{prefix + FlagNamespace, "n", "", "If present, the namespace scope for this CLI request"}, - } -} - -// BindOverrideFlags is a convenience method to bind the specified flags to their associated variables -func BindOverrideFlags(overrides *ConfigOverrides, flags *pflag.FlagSet, flagNames ConfigOverrideFlags) { - BindAuthInfoFlags(&overrides.AuthInfo, flags, flagNames.AuthOverrideFlags) - BindClusterFlags(&overrides.ClusterInfo, flags, flagNames.ClusterOverrideFlags) - BindContextFlags(&overrides.Context, flags, flagNames.ContextOverrideFlags) - flagNames.CurrentContext.BindStringFlag(flags, &overrides.CurrentContext) - flagNames.Timeout.BindStringFlag(flags, &overrides.Timeout) -} - -// BindAuthInfoFlags is a convenience method to bind the specified flags to their associated variables -func BindAuthInfoFlags(authInfo *clientcmdapi.AuthInfo, flags *pflag.FlagSet, flagNames AuthOverrideFlags) { - flagNames.ClientCertificate.BindStringFlag(flags, &authInfo.ClientCertificate) - flagNames.ClientKey.BindStringFlag(flags, &authInfo.ClientKey) - flagNames.Token.BindStringFlag(flags, &authInfo.Token) - flagNames.Impersonate.BindStringFlag(flags, &authInfo.Impersonate) - flagNames.Username.BindStringFlag(flags, &authInfo.Username) - flagNames.Password.BindStringFlag(flags, &authInfo.Password) -} - -// BindClusterFlags is a convenience method to bind the specified flags to their associated variables -func BindClusterFlags(clusterInfo *clientcmdapi.Cluster, flags *pflag.FlagSet, flagNames ClusterOverrideFlags) { - flagNames.APIServer.BindStringFlag(flags, &clusterInfo.Server) - // TODO: remove --api-version flag in 1.3. - flagNames.APIVersion.BindStringFlag(flags, &clusterInfo.APIVersion) - flags.MarkDeprecated(FlagAPIVersion, "flag is no longer respected and will be deleted in the next release") - flagNames.CertificateAuthority.BindStringFlag(flags, &clusterInfo.CertificateAuthority) - flagNames.InsecureSkipTLSVerify.BindBoolFlag(flags, &clusterInfo.InsecureSkipTLSVerify) -} - -// BindFlags is a convenience method to bind the specified flags to their associated variables -func BindContextFlags(contextInfo *clientcmdapi.Context, flags *pflag.FlagSet, flagNames ContextOverrideFlags) { - flagNames.ClusterName.BindStringFlag(flags, &contextInfo.Cluster) - flagNames.AuthInfoName.BindStringFlag(flags, &contextInfo.AuthInfo) - flagNames.Namespace.BindStringFlag(flags, &contextInfo.Namespace) -} diff --git a/pkg/client/unversioned/clientcmd/validation.go b/pkg/client/unversioned/clientcmd/validation.go deleted file mode 100644 index ceeeb042e8e..00000000000 --- a/pkg/client/unversioned/clientcmd/validation.go +++ /dev/null @@ -1,270 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package clientcmd - -import ( - "errors" - "fmt" - "os" - "reflect" - "strings" - - utilerrors "k8s.io/apimachinery/pkg/util/errors" - "k8s.io/apimachinery/pkg/util/validation" - clientcmdapi "k8s.io/client-go/tools/clientcmd/api" -) - -var ( - ErrNoContext = errors.New("no context chosen") - ErrEmptyConfig = errors.New("no configuration has been provided") - // message is for consistency with old behavior - ErrEmptyCluster = errors.New("cluster has no server defined") -) - -type errContextNotFound struct { - ContextName string -} - -func (e *errContextNotFound) Error() string { - return fmt.Sprintf("context was not found for specified context: %v", e.ContextName) -} - -// IsContextNotFound returns a boolean indicating whether the error is known to -// report that a context was not found -func IsContextNotFound(err error) bool { - if err == nil { - return false - } - if _, ok := err.(*errContextNotFound); ok || err == ErrNoContext { - return true - } - return strings.Contains(err.Error(), "context was not found for specified context") -} - -// IsEmptyConfig returns true if the provided error indicates the provided configuration -// is empty. -func IsEmptyConfig(err error) bool { - switch t := err.(type) { - case errConfigurationInvalid: - return len(t) == 1 && t[0] == ErrEmptyConfig - } - return err == ErrEmptyConfig -} - -// errConfigurationInvalid is a set of errors indicating the configuration is invalid. -type errConfigurationInvalid []error - -// errConfigurationInvalid implements error and Aggregate -var _ error = errConfigurationInvalid{} -var _ utilerrors.Aggregate = errConfigurationInvalid{} - -func newErrConfigurationInvalid(errs []error) error { - switch len(errs) { - case 0: - return nil - default: - return errConfigurationInvalid(errs) - } -} - -// Error implements the error interface -func (e errConfigurationInvalid) Error() string { - return fmt.Sprintf("invalid configuration: %v", utilerrors.NewAggregate(e).Error()) -} - -// Errors implements the AggregateError interface -func (e errConfigurationInvalid) Errors() []error { - return e -} - -// IsConfigurationInvalid returns true if the provided error indicates the configuration is invalid. -func IsConfigurationInvalid(err error) bool { - switch err.(type) { - case *errContextNotFound, errConfigurationInvalid: - return true - } - return IsContextNotFound(err) -} - -// Validate checks for errors in the Config. It does not return early so that it can find as many errors as possible. -func Validate(config clientcmdapi.Config) error { - validationErrors := make([]error, 0) - - if clientcmdapi.IsConfigEmpty(&config) { - return newErrConfigurationInvalid([]error{ErrEmptyConfig}) - } - - if len(config.CurrentContext) != 0 { - if _, exists := config.Contexts[config.CurrentContext]; !exists { - validationErrors = append(validationErrors, &errContextNotFound{config.CurrentContext}) - } - } - - for contextName, context := range config.Contexts { - validationErrors = append(validationErrors, validateContext(contextName, *context, config)...) - } - - for authInfoName, authInfo := range config.AuthInfos { - validationErrors = append(validationErrors, validateAuthInfo(authInfoName, *authInfo)...) - } - - for clusterName, clusterInfo := range config.Clusters { - validationErrors = append(validationErrors, validateClusterInfo(clusterName, *clusterInfo)...) - } - - return newErrConfigurationInvalid(validationErrors) -} - -// ConfirmUsable looks a particular context and determines if that particular part of the config is useable. There might still be errors in the config, -// but no errors in the sections requested or referenced. It does not return early so that it can find as many errors as possible. -func ConfirmUsable(config clientcmdapi.Config, passedContextName string) error { - validationErrors := make([]error, 0) - - if clientcmdapi.IsConfigEmpty(&config) { - return newErrConfigurationInvalid([]error{ErrEmptyConfig}) - } - - var contextName string - if len(passedContextName) != 0 { - contextName = passedContextName - } else { - contextName = config.CurrentContext - } - - if len(contextName) == 0 { - return ErrNoContext - } - - context, exists := config.Contexts[contextName] - if !exists { - validationErrors = append(validationErrors, &errContextNotFound{contextName}) - } - - if exists { - validationErrors = append(validationErrors, validateContext(contextName, *context, config)...) - validationErrors = append(validationErrors, validateAuthInfo(context.AuthInfo, *config.AuthInfos[context.AuthInfo])...) - validationErrors = append(validationErrors, validateClusterInfo(context.Cluster, *config.Clusters[context.Cluster])...) - } - - return newErrConfigurationInvalid(validationErrors) -} - -// validateClusterInfo looks for conflicts and errors in the cluster info -func validateClusterInfo(clusterName string, clusterInfo clientcmdapi.Cluster) []error { - validationErrors := make([]error, 0) - - if reflect.DeepEqual(clientcmdapi.Cluster{}, clusterInfo) { - return []error{ErrEmptyCluster} - } - - if len(clusterInfo.Server) == 0 { - if len(clusterName) == 0 { - validationErrors = append(validationErrors, fmt.Errorf("default cluster has no server defined")) - } else { - validationErrors = append(validationErrors, fmt.Errorf("no server found for cluster %q", clusterName)) - } - } - // Make sure CA data and CA file aren't both specified - if len(clusterInfo.CertificateAuthority) != 0 && len(clusterInfo.CertificateAuthorityData) != 0 { - validationErrors = append(validationErrors, fmt.Errorf("certificate-authority-data and certificate-authority are both specified for %v. certificate-authority-data will override.", clusterName)) - } - if len(clusterInfo.CertificateAuthority) != 0 { - clientCertCA, err := os.Open(clusterInfo.CertificateAuthority) - defer clientCertCA.Close() - if err != nil { - validationErrors = append(validationErrors, fmt.Errorf("unable to read certificate-authority %v for %v due to %v", clusterInfo.CertificateAuthority, clusterName, err)) - } - } - - return validationErrors -} - -// validateAuthInfo looks for conflicts and errors in the auth info -func validateAuthInfo(authInfoName string, authInfo clientcmdapi.AuthInfo) []error { - validationErrors := make([]error, 0) - - usingAuthPath := false - methods := make([]string, 0, 3) - if len(authInfo.Token) != 0 { - methods = append(methods, "token") - } - if len(authInfo.Username) != 0 || len(authInfo.Password) != 0 { - methods = append(methods, "basicAuth") - } - - if len(authInfo.ClientCertificate) != 0 || len(authInfo.ClientCertificateData) != 0 { - // Make sure cert data and file aren't both specified - if len(authInfo.ClientCertificate) != 0 && len(authInfo.ClientCertificateData) != 0 { - validationErrors = append(validationErrors, fmt.Errorf("client-cert-data and client-cert are both specified for %v. client-cert-data will override.", authInfoName)) - } - // Make sure key data and file aren't both specified - if len(authInfo.ClientKey) != 0 && len(authInfo.ClientKeyData) != 0 { - validationErrors = append(validationErrors, fmt.Errorf("client-key-data and client-key are both specified for %v; client-key-data will override", authInfoName)) - } - // Make sure a key is specified - if len(authInfo.ClientKey) == 0 && len(authInfo.ClientKeyData) == 0 { - validationErrors = append(validationErrors, fmt.Errorf("client-key-data or client-key must be specified for %v to use the clientCert authentication method.", authInfoName)) - } - - if len(authInfo.ClientCertificate) != 0 { - clientCertFile, err := os.Open(authInfo.ClientCertificate) - defer clientCertFile.Close() - if err != nil { - validationErrors = append(validationErrors, fmt.Errorf("unable to read client-cert %v for %v due to %v", authInfo.ClientCertificate, authInfoName, err)) - } - } - if len(authInfo.ClientKey) != 0 { - clientKeyFile, err := os.Open(authInfo.ClientKey) - defer clientKeyFile.Close() - if err != nil { - validationErrors = append(validationErrors, fmt.Errorf("unable to read client-key %v for %v due to %v", authInfo.ClientKey, authInfoName, err)) - } - } - } - - // authPath also provides information for the client to identify the server, so allow multiple auth methods in that case - if (len(methods) > 1) && (!usingAuthPath) { - validationErrors = append(validationErrors, fmt.Errorf("more than one authentication method found for %v; found %v, only one is allowed", authInfoName, methods)) - } - - return validationErrors -} - -// validateContext looks for errors in the context. It is not transitive, so errors in the reference authInfo or cluster configs are not included in this return -func validateContext(contextName string, context clientcmdapi.Context, config clientcmdapi.Config) []error { - validationErrors := make([]error, 0) - - if len(context.AuthInfo) == 0 { - validationErrors = append(validationErrors, fmt.Errorf("user was not specified for context %q", contextName)) - } else if _, exists := config.AuthInfos[context.AuthInfo]; !exists { - validationErrors = append(validationErrors, fmt.Errorf("user %q was not found for context %q", context.AuthInfo, contextName)) - } - - if len(context.Cluster) == 0 { - validationErrors = append(validationErrors, fmt.Errorf("cluster was not specified for context %q", contextName)) - } else if _, exists := config.Clusters[context.Cluster]; !exists { - validationErrors = append(validationErrors, fmt.Errorf("cluster %q was not found for context %q", context.Cluster, contextName)) - } - - if len(context.Namespace) != 0 { - if len(validation.IsDNS1123Label(context.Namespace)) != 0 { - validationErrors = append(validationErrors, fmt.Errorf("namespace %q for context %q does not conform to the kubernetes DNS_LABEL rules", context.Namespace, contextName)) - } - } - - return validationErrors -} diff --git a/pkg/client/unversioned/clientcmd/validation_test.go b/pkg/client/unversioned/clientcmd/validation_test.go deleted file mode 100644 index ab7dc268519..00000000000 --- a/pkg/client/unversioned/clientcmd/validation_test.go +++ /dev/null @@ -1,432 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package clientcmd - -import ( - "io/ioutil" - "os" - "strings" - "testing" - - utilerrors "k8s.io/apimachinery/pkg/util/errors" - clientcmdapi "k8s.io/client-go/tools/clientcmd/api" -) - -func TestConfirmUsableBadInfoButOkConfig(t *testing.T) { - config := clientcmdapi.NewConfig() - config.Clusters["missing ca"] = &clientcmdapi.Cluster{ - Server: "anything", - CertificateAuthority: "missing", - } - config.AuthInfos["error"] = &clientcmdapi.AuthInfo{ - Username: "anything", - Token: "here", - } - config.Contexts["dirty"] = &clientcmdapi.Context{ - Cluster: "missing ca", - AuthInfo: "error", - } - config.Clusters["clean"] = &clientcmdapi.Cluster{ - Server: "anything", - } - config.AuthInfos["clean"] = &clientcmdapi.AuthInfo{ - Token: "here", - } - config.Contexts["clean"] = &clientcmdapi.Context{ - Cluster: "clean", - AuthInfo: "clean", - } - - badValidation := configValidationTest{ - config: config, - expectedErrorSubstring: []string{"unable to read certificate-authority"}, - } - okTest := configValidationTest{ - config: config, - } - - okTest.testConfirmUsable("clean", t) - badValidation.testConfig(t) -} -func TestConfirmUsableBadInfoConfig(t *testing.T) { - config := clientcmdapi.NewConfig() - config.Clusters["missing ca"] = &clientcmdapi.Cluster{ - Server: "anything", - CertificateAuthority: "missing", - } - config.AuthInfos["error"] = &clientcmdapi.AuthInfo{ - Username: "anything", - Token: "here", - } - config.Contexts["first"] = &clientcmdapi.Context{ - Cluster: "missing ca", - AuthInfo: "error", - } - test := configValidationTest{ - config: config, - expectedErrorSubstring: []string{"unable to read certificate-authority"}, - } - - test.testConfirmUsable("first", t) -} -func TestConfirmUsableEmptyConfig(t *testing.T) { - config := clientcmdapi.NewConfig() - test := configValidationTest{ - config: config, - expectedErrorSubstring: []string{"invalid configuration: no configuration has been provided"}, - } - - test.testConfirmUsable("", t) -} -func TestConfirmUsableMissingConfig(t *testing.T) { - config := clientcmdapi.NewConfig() - test := configValidationTest{ - config: config, - expectedErrorSubstring: []string{"invalid configuration: no configuration has been provided"}, - } - - test.testConfirmUsable("not-here", t) -} -func TestValidateEmptyConfig(t *testing.T) { - config := clientcmdapi.NewConfig() - test := configValidationTest{ - config: config, - expectedErrorSubstring: []string{"invalid configuration: no configuration has been provided"}, - } - - test.testConfig(t) -} -func TestValidateMissingCurrentContextConfig(t *testing.T) { - config := clientcmdapi.NewConfig() - config.CurrentContext = "anything" - test := configValidationTest{ - config: config, - expectedErrorSubstring: []string{"context was not found for specified "}, - } - - test.testConfig(t) -} -func TestIsContextNotFound(t *testing.T) { - config := clientcmdapi.NewConfig() - config.CurrentContext = "anything" - - err := Validate(*config) - if !IsContextNotFound(err) { - t.Errorf("Expected context not found, but got %v", err) - } - if !IsConfigurationInvalid(err) { - t.Errorf("Expected configuration invalid, but got %v", err) - } -} - -func TestIsEmptyConfig(t *testing.T) { - config := clientcmdapi.NewConfig() - - err := Validate(*config) - if !IsEmptyConfig(err) { - t.Errorf("Expected context not found, but got %v", err) - } - if !IsConfigurationInvalid(err) { - t.Errorf("Expected configuration invalid, but got %v", err) - } -} - -func TestIsConfigurationInvalid(t *testing.T) { - if newErrConfigurationInvalid([]error{}) != nil { - t.Errorf("unexpected error") - } - if newErrConfigurationInvalid([]error{ErrNoContext}) == ErrNoContext { - t.Errorf("unexpected error") - } - if newErrConfigurationInvalid([]error{ErrNoContext, ErrNoContext}) == nil { - t.Errorf("unexpected error") - } - if !IsConfigurationInvalid(newErrConfigurationInvalid([]error{ErrNoContext, ErrNoContext})) { - t.Errorf("unexpected error") - } -} - -func TestValidateMissingReferencesConfig(t *testing.T) { - config := clientcmdapi.NewConfig() - config.CurrentContext = "anything" - config.Contexts["anything"] = &clientcmdapi.Context{Cluster: "missing", AuthInfo: "missing"} - test := configValidationTest{ - config: config, - expectedErrorSubstring: []string{"user \"missing\" was not found for context \"anything\"", "cluster \"missing\" was not found for context \"anything\""}, - } - - test.testContext("anything", t) - test.testConfig(t) -} -func TestValidateEmptyContext(t *testing.T) { - config := clientcmdapi.NewConfig() - config.CurrentContext = "anything" - config.Contexts["anything"] = &clientcmdapi.Context{} - test := configValidationTest{ - config: config, - expectedErrorSubstring: []string{"user was not specified for context \"anything\"", "cluster was not specified for context \"anything\""}, - } - - test.testContext("anything", t) - test.testConfig(t) -} - -func TestValidateEmptyClusterInfo(t *testing.T) { - config := clientcmdapi.NewConfig() - config.Clusters["empty"] = &clientcmdapi.Cluster{} - test := configValidationTest{ - config: config, - expectedErrorSubstring: []string{"cluster has no server defined"}, - } - - test.testCluster("empty", t) - test.testConfig(t) -} -func TestValidateMissingCAFileClusterInfo(t *testing.T) { - config := clientcmdapi.NewConfig() - config.Clusters["missing ca"] = &clientcmdapi.Cluster{ - Server: "anything", - CertificateAuthority: "missing", - } - test := configValidationTest{ - config: config, - expectedErrorSubstring: []string{"unable to read certificate-authority"}, - } - - test.testCluster("missing ca", t) - test.testConfig(t) -} -func TestValidateCleanClusterInfo(t *testing.T) { - config := clientcmdapi.NewConfig() - config.Clusters["clean"] = &clientcmdapi.Cluster{ - Server: "anything", - } - test := configValidationTest{ - config: config, - } - - test.testCluster("clean", t) - test.testConfig(t) -} -func TestValidateCleanWithCAClusterInfo(t *testing.T) { - tempFile, _ := ioutil.TempFile("", "") - defer os.Remove(tempFile.Name()) - - config := clientcmdapi.NewConfig() - config.Clusters["clean"] = &clientcmdapi.Cluster{ - Server: "anything", - CertificateAuthority: tempFile.Name(), - } - test := configValidationTest{ - config: config, - } - - test.testCluster("clean", t) - test.testConfig(t) -} - -func TestValidateEmptyAuthInfo(t *testing.T) { - config := clientcmdapi.NewConfig() - config.AuthInfos["error"] = &clientcmdapi.AuthInfo{} - test := configValidationTest{ - config: config, - } - - test.testAuthInfo("error", t) - test.testConfig(t) -} -func TestValidateCertFilesNotFoundAuthInfo(t *testing.T) { - config := clientcmdapi.NewConfig() - config.AuthInfos["error"] = &clientcmdapi.AuthInfo{ - ClientCertificate: "missing", - ClientKey: "missing", - } - test := configValidationTest{ - config: config, - expectedErrorSubstring: []string{"unable to read client-cert", "unable to read client-key"}, - } - - test.testAuthInfo("error", t) - test.testConfig(t) -} -func TestValidateCertDataOverridesFiles(t *testing.T) { - tempFile, _ := ioutil.TempFile("", "") - defer os.Remove(tempFile.Name()) - - config := clientcmdapi.NewConfig() - config.AuthInfos["clean"] = &clientcmdapi.AuthInfo{ - ClientCertificate: tempFile.Name(), - ClientCertificateData: []byte("certdata"), - ClientKey: tempFile.Name(), - ClientKeyData: []byte("keydata"), - } - test := configValidationTest{ - config: config, - expectedErrorSubstring: []string{"client-cert-data and client-cert are both specified", "client-key-data and client-key are both specified"}, - } - - test.testAuthInfo("clean", t) - test.testConfig(t) -} -func TestValidateCleanCertFilesAuthInfo(t *testing.T) { - tempFile, _ := ioutil.TempFile("", "") - defer os.Remove(tempFile.Name()) - - config := clientcmdapi.NewConfig() - config.AuthInfos["clean"] = &clientcmdapi.AuthInfo{ - ClientCertificate: tempFile.Name(), - ClientKey: tempFile.Name(), - } - test := configValidationTest{ - config: config, - } - - test.testAuthInfo("clean", t) - test.testConfig(t) -} -func TestValidateCleanTokenAuthInfo(t *testing.T) { - config := clientcmdapi.NewConfig() - config.AuthInfos["clean"] = &clientcmdapi.AuthInfo{ - Token: "any-value", - } - test := configValidationTest{ - config: config, - } - - test.testAuthInfo("clean", t) - test.testConfig(t) -} - -func TestValidateMultipleMethodsAuthInfo(t *testing.T) { - config := clientcmdapi.NewConfig() - config.AuthInfos["error"] = &clientcmdapi.AuthInfo{ - Token: "token", - Username: "username", - } - test := configValidationTest{ - config: config, - expectedErrorSubstring: []string{"more than one authentication method", "token", "basicAuth"}, - } - - test.testAuthInfo("error", t) - test.testConfig(t) -} - -type configValidationTest struct { - config *clientcmdapi.Config - expectedErrorSubstring []string -} - -func (c configValidationTest) testContext(contextName string, t *testing.T) { - errs := validateContext(contextName, *c.config.Contexts[contextName], *c.config) - - if len(c.expectedErrorSubstring) != 0 { - if len(errs) == 0 { - t.Errorf("Expected error containing: %v", c.expectedErrorSubstring) - } - for _, curr := range c.expectedErrorSubstring { - if len(errs) != 0 && !strings.Contains(utilerrors.NewAggregate(errs).Error(), curr) { - t.Errorf("Expected error containing: %v, but got %v", c.expectedErrorSubstring, utilerrors.NewAggregate(errs)) - } - } - - } else { - if len(errs) != 0 { - t.Errorf("Unexpected error: %v", utilerrors.NewAggregate(errs)) - } - } -} -func (c configValidationTest) testConfirmUsable(contextName string, t *testing.T) { - err := ConfirmUsable(*c.config, contextName) - - if len(c.expectedErrorSubstring) != 0 { - if err == nil { - t.Errorf("Expected error containing: %v", c.expectedErrorSubstring) - } else { - for _, curr := range c.expectedErrorSubstring { - if err != nil && !strings.Contains(err.Error(), curr) { - t.Errorf("Expected error containing: %v, but got %v", c.expectedErrorSubstring, err) - } - } - } - } else { - if err != nil { - t.Errorf("Unexpected error: %v", err) - } - } -} -func (c configValidationTest) testConfig(t *testing.T) { - err := Validate(*c.config) - - if len(c.expectedErrorSubstring) != 0 { - if err == nil { - t.Errorf("Expected error containing: %v", c.expectedErrorSubstring) - } else { - for _, curr := range c.expectedErrorSubstring { - if err != nil && !strings.Contains(err.Error(), curr) { - t.Errorf("Expected error containing: %v, but got %v", c.expectedErrorSubstring, err) - } - } - if !IsConfigurationInvalid(err) { - t.Errorf("all errors should be configuration invalid: %v", err) - } - } - } else { - if err != nil { - t.Errorf("Unexpected error: %v", err) - } - } -} -func (c configValidationTest) testCluster(clusterName string, t *testing.T) { - errs := validateClusterInfo(clusterName, *c.config.Clusters[clusterName]) - - if len(c.expectedErrorSubstring) != 0 { - if len(errs) == 0 { - t.Errorf("Expected error containing: %v", c.expectedErrorSubstring) - } - for _, curr := range c.expectedErrorSubstring { - if len(errs) != 0 && !strings.Contains(utilerrors.NewAggregate(errs).Error(), curr) { - t.Errorf("Expected error containing: %v, but got %v", c.expectedErrorSubstring, utilerrors.NewAggregate(errs)) - } - } - - } else { - if len(errs) != 0 { - t.Errorf("Unexpected error: %v", utilerrors.NewAggregate(errs)) - } - } -} - -func (c configValidationTest) testAuthInfo(authInfoName string, t *testing.T) { - errs := validateAuthInfo(authInfoName, *c.config.AuthInfos[authInfoName]) - - if len(c.expectedErrorSubstring) != 0 { - if len(errs) == 0 { - t.Errorf("Expected error containing: %v", c.expectedErrorSubstring) - } - for _, curr := range c.expectedErrorSubstring { - if len(errs) != 0 && !strings.Contains(utilerrors.NewAggregate(errs).Error(), curr) { - t.Errorf("Expected error containing: %v, but got %v", c.expectedErrorSubstring, utilerrors.NewAggregate(errs)) - } - } - - } else { - if len(errs) != 0 { - t.Errorf("Unexpected error: %v", utilerrors.NewAggregate(errs)) - } - } -} diff --git a/pkg/kubectl/cmd/BUILD b/pkg/kubectl/cmd/BUILD index c0bc9835b0c..a14a205a421 100644 --- a/pkg/kubectl/cmd/BUILD +++ b/pkg/kubectl/cmd/BUILD @@ -74,7 +74,6 @@ go_library( "//pkg/client/clientset_generated/internalclientset/typed/core/internalversion:go_default_library", "//pkg/client/typed/discovery:go_default_library", "//pkg/client/unversioned:go_default_library", - "//pkg/client/unversioned/clientcmd:go_default_library", "//pkg/client/unversioned/portforward:go_default_library", "//pkg/client/unversioned/remotecommand:go_default_library", "//pkg/kubectl:go_default_library", @@ -124,6 +123,7 @@ go_library( "//vendor:k8s.io/apimachinery/pkg/util/yaml", "//vendor:k8s.io/apimachinery/pkg/watch", "//vendor:k8s.io/client-go/rest", + "//vendor:k8s.io/client-go/tools/clientcmd", ], ) diff --git a/pkg/kubectl/cmd/cmd.go b/pkg/kubectl/cmd/cmd.go index d3978c8f6cd..50368393561 100644 --- a/pkg/kubectl/cmd/cmd.go +++ b/pkg/kubectl/cmd/cmd.go @@ -20,7 +20,7 @@ import ( "fmt" "io" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" + "k8s.io/client-go/tools/clientcmd" cmdconfig "k8s.io/kubernetes/pkg/kubectl/cmd/config" "k8s.io/kubernetes/pkg/kubectl/cmd/rollout" "k8s.io/kubernetes/pkg/kubectl/cmd/set" diff --git a/pkg/kubectl/cmd/config/BUILD b/pkg/kubectl/cmd/config/BUILD index 6d4c314d8ad..396c4d50aab 100644 --- a/pkg/kubectl/cmd/config/BUILD +++ b/pkg/kubectl/cmd/config/BUILD @@ -28,7 +28,6 @@ go_library( ], tags = ["automanaged"], deps = [ - "//pkg/client/unversioned/clientcmd:go_default_library", "//pkg/kubectl:go_default_library", "//pkg/kubectl/cmd/templates:go_default_library", "//pkg/kubectl/cmd/util:go_default_library", @@ -36,6 +35,7 @@ go_library( "//vendor:github.com/spf13/cobra", "//vendor:k8s.io/apimachinery/pkg/util/errors", "//vendor:k8s.io/apimachinery/pkg/util/sets", + "//vendor:k8s.io/client-go/tools/clientcmd", "//vendor:k8s.io/client-go/tools/clientcmd/api", "//vendor:k8s.io/client-go/tools/clientcmd/api/latest", ], @@ -57,10 +57,10 @@ go_test( tags = ["automanaged"], deps = [ "//pkg/api:go_default_library", - "//pkg/client/unversioned/clientcmd:go_default_library", "//pkg/kubectl/cmd/util:go_default_library", "//pkg/util/flag:go_default_library", "//vendor:k8s.io/apimachinery/pkg/util/diff", + "//vendor:k8s.io/client-go/tools/clientcmd", "//vendor:k8s.io/client-go/tools/clientcmd/api", ], ) diff --git a/pkg/kubectl/cmd/config/config.go b/pkg/kubectl/cmd/config/config.go index 2b445f16fb4..e910e0fac1c 100644 --- a/pkg/kubectl/cmd/config/config.go +++ b/pkg/kubectl/cmd/config/config.go @@ -23,7 +23,7 @@ import ( "github.com/spf13/cobra" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" + "k8s.io/client-go/tools/clientcmd" "k8s.io/kubernetes/pkg/kubectl/cmd/templates" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" ) diff --git a/pkg/kubectl/cmd/config/config_test.go b/pkg/kubectl/cmd/config/config_test.go index b0927a85ddb..0bd896da660 100644 --- a/pkg/kubectl/cmd/config/config_test.go +++ b/pkg/kubectl/cmd/config/config_test.go @@ -27,9 +27,9 @@ import ( "testing" "k8s.io/apimachinery/pkg/util/diff" + "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" ) diff --git a/pkg/kubectl/cmd/config/create_authinfo.go b/pkg/kubectl/cmd/config/create_authinfo.go index c217aee14f5..ba71a47cd29 100644 --- a/pkg/kubectl/cmd/config/create_authinfo.go +++ b/pkg/kubectl/cmd/config/create_authinfo.go @@ -26,8 +26,8 @@ import ( "github.com/spf13/cobra" + "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" "k8s.io/kubernetes/pkg/kubectl/cmd/templates" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" "k8s.io/kubernetes/pkg/util/flag" diff --git a/pkg/kubectl/cmd/config/create_cluster.go b/pkg/kubectl/cmd/config/create_cluster.go index 82e11da8854..f08b28a4af3 100644 --- a/pkg/kubectl/cmd/config/create_cluster.go +++ b/pkg/kubectl/cmd/config/create_cluster.go @@ -25,8 +25,8 @@ import ( "github.com/spf13/cobra" + "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" "k8s.io/kubernetes/pkg/kubectl/cmd/templates" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" "k8s.io/kubernetes/pkg/util/flag" diff --git a/pkg/kubectl/cmd/config/create_context.go b/pkg/kubectl/cmd/config/create_context.go index 48989cd0ea3..d7509cf9371 100644 --- a/pkg/kubectl/cmd/config/create_context.go +++ b/pkg/kubectl/cmd/config/create_context.go @@ -23,8 +23,8 @@ import ( "github.com/spf13/cobra" + "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" "k8s.io/kubernetes/pkg/kubectl/cmd/templates" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" "k8s.io/kubernetes/pkg/util/flag" diff --git a/pkg/kubectl/cmd/config/current_context.go b/pkg/kubectl/cmd/config/current_context.go index 7a576590b7a..17e9e92196d 100644 --- a/pkg/kubectl/cmd/config/current_context.go +++ b/pkg/kubectl/cmd/config/current_context.go @@ -22,7 +22,7 @@ import ( "github.com/spf13/cobra" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" + "k8s.io/client-go/tools/clientcmd" "k8s.io/kubernetes/pkg/kubectl/cmd/templates" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" ) diff --git a/pkg/kubectl/cmd/config/current_context_test.go b/pkg/kubectl/cmd/config/current_context_test.go index cd2db6fbac2..627c79bc880 100644 --- a/pkg/kubectl/cmd/config/current_context_test.go +++ b/pkg/kubectl/cmd/config/current_context_test.go @@ -23,8 +23,8 @@ import ( "strings" "testing" + "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" ) type currentContextTest struct { diff --git a/pkg/kubectl/cmd/config/delete_cluster.go b/pkg/kubectl/cmd/config/delete_cluster.go index f1700e3f960..9b89c92a70e 100644 --- a/pkg/kubectl/cmd/config/delete_cluster.go +++ b/pkg/kubectl/cmd/config/delete_cluster.go @@ -21,7 +21,7 @@ import ( "io" "github.com/spf13/cobra" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" + "k8s.io/client-go/tools/clientcmd" "k8s.io/kubernetes/pkg/kubectl/cmd/templates" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" ) diff --git a/pkg/kubectl/cmd/config/delete_cluster_test.go b/pkg/kubectl/cmd/config/delete_cluster_test.go index 523854097d2..684e47bf795 100644 --- a/pkg/kubectl/cmd/config/delete_cluster_test.go +++ b/pkg/kubectl/cmd/config/delete_cluster_test.go @@ -24,8 +24,8 @@ import ( "reflect" "testing" + "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" ) type deleteClusterTest struct { diff --git a/pkg/kubectl/cmd/config/delete_context.go b/pkg/kubectl/cmd/config/delete_context.go index 78fa334035a..61cb6d46721 100644 --- a/pkg/kubectl/cmd/config/delete_context.go +++ b/pkg/kubectl/cmd/config/delete_context.go @@ -21,7 +21,7 @@ import ( "io" "github.com/spf13/cobra" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" + "k8s.io/client-go/tools/clientcmd" "k8s.io/kubernetes/pkg/kubectl/cmd/templates" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" ) diff --git a/pkg/kubectl/cmd/config/delete_context_test.go b/pkg/kubectl/cmd/config/delete_context_test.go index 130de20ed51..a53ef9c98c2 100644 --- a/pkg/kubectl/cmd/config/delete_context_test.go +++ b/pkg/kubectl/cmd/config/delete_context_test.go @@ -24,8 +24,8 @@ import ( "reflect" "testing" + "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" ) type deleteContextTest struct { diff --git a/pkg/kubectl/cmd/config/get_clusters.go b/pkg/kubectl/cmd/config/get_clusters.go index 9b31d28b07c..e9ca71dcea6 100644 --- a/pkg/kubectl/cmd/config/get_clusters.go +++ b/pkg/kubectl/cmd/config/get_clusters.go @@ -21,7 +21,7 @@ import ( "io" "github.com/spf13/cobra" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" + "k8s.io/client-go/tools/clientcmd" "k8s.io/kubernetes/pkg/kubectl/cmd/templates" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" ) diff --git a/pkg/kubectl/cmd/config/get_clusters_test.go b/pkg/kubectl/cmd/config/get_clusters_test.go index ec77b79f8fa..4c9d3da8926 100644 --- a/pkg/kubectl/cmd/config/get_clusters_test.go +++ b/pkg/kubectl/cmd/config/get_clusters_test.go @@ -22,8 +22,8 @@ import ( "os" "testing" + "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" ) type getClustersTest struct { diff --git a/pkg/kubectl/cmd/config/get_contexts.go b/pkg/kubectl/cmd/config/get_contexts.go index dfa67c9eb2d..ef761006633 100644 --- a/pkg/kubectl/cmd/config/get_contexts.go +++ b/pkg/kubectl/cmd/config/get_contexts.go @@ -25,8 +25,8 @@ import ( "github.com/spf13/cobra" utilerrors "k8s.io/apimachinery/pkg/util/errors" "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" "k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl/cmd/templates" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" diff --git a/pkg/kubectl/cmd/config/get_contexts_test.go b/pkg/kubectl/cmd/config/get_contexts_test.go index b4c78a7bf11..5a7da24ebb0 100644 --- a/pkg/kubectl/cmd/config/get_contexts_test.go +++ b/pkg/kubectl/cmd/config/get_contexts_test.go @@ -22,8 +22,8 @@ import ( "os" "testing" + "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" ) type getContextsTest struct { diff --git a/pkg/kubectl/cmd/config/set.go b/pkg/kubectl/cmd/config/set.go index faf02308389..6b72cf2e8ff 100644 --- a/pkg/kubectl/cmd/config/set.go +++ b/pkg/kubectl/cmd/config/set.go @@ -26,7 +26,7 @@ import ( "github.com/spf13/cobra" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" + "k8s.io/client-go/tools/clientcmd" "k8s.io/kubernetes/pkg/kubectl/cmd/templates" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" "k8s.io/kubernetes/pkg/util/flag" diff --git a/pkg/kubectl/cmd/config/unset.go b/pkg/kubectl/cmd/config/unset.go index 48a56f8b46e..38560a22e14 100644 --- a/pkg/kubectl/cmd/config/unset.go +++ b/pkg/kubectl/cmd/config/unset.go @@ -25,7 +25,7 @@ import ( "github.com/spf13/cobra" "k8s.io/kubernetes/pkg/kubectl/cmd/templates" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" + "k8s.io/client-go/tools/clientcmd" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" ) diff --git a/pkg/kubectl/cmd/config/use_context.go b/pkg/kubectl/cmd/config/use_context.go index 0f2fed7f87d..584a59272e9 100644 --- a/pkg/kubectl/cmd/config/use_context.go +++ b/pkg/kubectl/cmd/config/use_context.go @@ -23,8 +23,8 @@ import ( "github.com/spf13/cobra" + "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" "k8s.io/kubernetes/pkg/kubectl/cmd/templates" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" ) diff --git a/pkg/kubectl/cmd/config/view.go b/pkg/kubectl/cmd/config/view.go index 157d713c011..0baaf43e8d8 100644 --- a/pkg/kubectl/cmd/config/view.go +++ b/pkg/kubectl/cmd/config/view.go @@ -23,9 +23,9 @@ import ( "github.com/spf13/cobra" + "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" "k8s.io/client-go/tools/clientcmd/api/latest" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" "k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl/cmd/templates" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" diff --git a/pkg/kubectl/cmd/util/BUILD b/pkg/kubectl/cmd/util/BUILD index 91d762386fe..5d64492e5a4 100644 --- a/pkg/kubectl/cmd/util/BUILD +++ b/pkg/kubectl/cmd/util/BUILD @@ -37,14 +37,12 @@ go_library( "//pkg/client/typed/discovery:go_default_library", "//pkg/client/typed/dynamic:go_default_library", "//pkg/client/unversioned:go_default_library", - "//pkg/client/unversioned/clientcmd:go_default_library", "//pkg/controller:go_default_library", "//pkg/kubectl:go_default_library", "//pkg/kubectl/resource:go_default_library", "//pkg/registry/extensions/thirdpartyresourcedata:go_default_library", "//pkg/util/exec:go_default_library", "//pkg/util/flag:go_default_library", - "//pkg/util/homedir:go_default_library", "//pkg/util/strategicpatch:go_default_library", "//vendor:github.com/emicklei/go-restful/swagger", "//vendor:github.com/evanphx/json-patch", @@ -63,7 +61,9 @@ go_library( "//vendor:k8s.io/apimachinery/pkg/util/sets", "//vendor:k8s.io/apimachinery/pkg/version", "//vendor:k8s.io/apimachinery/pkg/watch", + "//vendor:k8s.io/client-go/pkg/util/homedir", "//vendor:k8s.io/client-go/rest", + "//vendor:k8s.io/client-go/tools/clientcmd", ], ) @@ -91,7 +91,6 @@ go_test( "//pkg/client/restclient/fake:go_default_library", "//pkg/client/testing/core:go_default_library", "//pkg/client/typed/discovery:go_default_library", - "//pkg/client/unversioned/clientcmd:go_default_library", "//pkg/controller:go_default_library", "//pkg/kubectl:go_default_library", "//pkg/kubectl/resource:go_default_library", @@ -109,6 +108,7 @@ go_test( "//vendor:k8s.io/apimachinery/pkg/version", "//vendor:k8s.io/apimachinery/pkg/watch", "//vendor:k8s.io/client-go/rest", + "//vendor:k8s.io/client-go/tools/clientcmd", "//vendor:k8s.io/client-go/tools/clientcmd/api", ], ) diff --git a/pkg/kubectl/cmd/util/clientcache.go b/pkg/kubectl/cmd/util/clientcache.go index 8626159e72f..5604bbf14b0 100644 --- a/pkg/kubectl/cmd/util/clientcache.go +++ b/pkg/kubectl/cmd/util/clientcache.go @@ -21,12 +21,12 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" restclient "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" fedclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_internalclientset" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" "k8s.io/kubernetes/pkg/client/typed/discovery" oldclient "k8s.io/kubernetes/pkg/client/unversioned" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" ) func NewClientCache(loader clientcmd.ClientConfig, discoveryClientFactory DiscoveryClientFactory) *ClientCache { diff --git a/pkg/kubectl/cmd/util/factory.go b/pkg/kubectl/cmd/util/factory.go index 783e374d6ae..53778cc5fb4 100644 --- a/pkg/kubectl/cmd/util/factory.go +++ b/pkg/kubectl/cmd/util/factory.go @@ -40,6 +40,7 @@ import ( "k8s.io/apimachinery/pkg/runtime/serializer/json" "k8s.io/apimachinery/pkg/watch" restclient "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" fedclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_internalclientset" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/v1" @@ -47,7 +48,6 @@ import ( "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion" "k8s.io/kubernetes/pkg/client/typed/discovery" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" "k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl/resource" "k8s.io/kubernetes/pkg/registry/extensions/thirdpartyresourcedata" diff --git a/pkg/kubectl/cmd/util/factory_client_access.go b/pkg/kubectl/cmd/util/factory_client_access.go index 72f03ec216e..5738e205a69 100644 --- a/pkg/kubectl/cmd/util/factory_client_access.go +++ b/pkg/kubectl/cmd/util/factory_client_access.go @@ -35,7 +35,9 @@ import ( "k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/pkg/util/homedir" restclient "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" fedclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_internalclientset" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/service" @@ -44,12 +46,10 @@ import ( "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" "k8s.io/kubernetes/pkg/client/typed/discovery" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" "k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl/resource" "k8s.io/kubernetes/pkg/registry/extensions/thirdpartyresourcedata" utilflag "k8s.io/kubernetes/pkg/util/flag" - "k8s.io/kubernetes/pkg/util/homedir" ) type ring0Factory struct { diff --git a/pkg/kubectl/cmd/util/factory_test.go b/pkg/kubectl/cmd/util/factory_test.go index 20b81781e77..a75ae9875a0 100644 --- a/pkg/kubectl/cmd/util/factory_test.go +++ b/pkg/kubectl/cmd/util/factory_test.go @@ -37,6 +37,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/testapi" @@ -46,7 +47,6 @@ import ( "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake" manualfake "k8s.io/kubernetes/pkg/client/restclient/fake" testcore "k8s.io/kubernetes/pkg/client/testing/core" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" "k8s.io/kubernetes/pkg/controller" "k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl/resource" diff --git a/pkg/kubectl/cmd/util/helpers.go b/pkg/kubectl/cmd/util/helpers.go index 5db4086d3e2..193512c9c6f 100644 --- a/pkg/kubectl/cmd/util/helpers.go +++ b/pkg/kubectl/cmd/util/helpers.go @@ -40,9 +40,9 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" utilerrors "k8s.io/apimachinery/pkg/util/errors" "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/client-go/tools/clientcmd" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/apis/extensions" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" "k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl/resource" utilexec "k8s.io/kubernetes/pkg/util/exec" diff --git a/pkg/util/BUILD b/pkg/util/BUILD index a5dcd03d3ad..78e2d8ea05f 100644 --- a/pkg/util/BUILD +++ b/pkg/util/BUILD @@ -64,7 +64,6 @@ filegroup( "//pkg/util/framer:all-srcs", "//pkg/util/goroutinemap:all-srcs", "//pkg/util/hash:all-srcs", - "//pkg/util/homedir:all-srcs", "//pkg/util/httpstream:all-srcs", "//pkg/util/i18n:all-srcs", "//pkg/util/initsystem:all-srcs", diff --git a/pkg/util/homedir/BUILD b/pkg/util/homedir/BUILD deleted file mode 100644 index 3454c2c0a88..00000000000 --- a/pkg/util/homedir/BUILD +++ /dev/null @@ -1,27 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -licenses(["notice"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", -) - -go_library( - name = "go_default_library", - srcs = ["homedir.go"], - tags = ["automanaged"], -) - -filegroup( - name = "package-srcs", - srcs = glob(["**"]), - tags = ["automanaged"], - visibility = ["//visibility:private"], -) - -filegroup( - name = "all-srcs", - srcs = [":package-srcs"], - tags = ["automanaged"], -) diff --git a/pkg/util/homedir/homedir.go b/pkg/util/homedir/homedir.go deleted file mode 100644 index 816db57f599..00000000000 --- a/pkg/util/homedir/homedir.go +++ /dev/null @@ -1,47 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package homedir - -import ( - "os" - "runtime" -) - -// HomeDir returns the home directory for the current user -func HomeDir() string { - if runtime.GOOS == "windows" { - - // First prefer the HOME environmental variable - if home := os.Getenv("HOME"); len(home) > 0 { - if _, err := os.Stat(home); err == nil { - return home - } - } - if homeDrive, homePath := os.Getenv("HOMEDRIVE"), os.Getenv("HOMEPATH"); len(homeDrive) > 0 && len(homePath) > 0 { - homeDir := homeDrive + homePath - if _, err := os.Stat(homeDir); err == nil { - return homeDir - } - } - if userProfile := os.Getenv("USERPROFILE"); len(userProfile) > 0 { - if _, err := os.Stat(userProfile); err == nil { - return userProfile - } - } - } - return os.Getenv("HOME") -} diff --git a/plugin/cmd/kube-scheduler/app/BUILD b/plugin/cmd/kube-scheduler/app/BUILD index c824f6e5e15..2c75cbe9969 100644 --- a/plugin/cmd/kube-scheduler/app/BUILD +++ b/plugin/cmd/kube-scheduler/app/BUILD @@ -18,7 +18,6 @@ go_library( "//pkg/client/leaderelection:go_default_library", "//pkg/client/leaderelection/resourcelock:go_default_library", "//pkg/client/record:go_default_library", - "//pkg/client/unversioned/clientcmd:go_default_library", "//pkg/util/configz:go_default_library", "//plugin/cmd/kube-scheduler/app/options:go_default_library", "//plugin/pkg/scheduler:go_default_library", @@ -34,6 +33,7 @@ go_library( "//vendor:k8s.io/apimachinery/pkg/runtime", "//vendor:k8s.io/apiserver/pkg/server/healthz", "//vendor:k8s.io/client-go/rest", + "//vendor:k8s.io/client-go/tools/clientcmd", ], ) diff --git a/plugin/cmd/kube-scheduler/app/server.go b/plugin/cmd/kube-scheduler/app/server.go index 5569ae5f565..ac040808a13 100644 --- a/plugin/cmd/kube-scheduler/app/server.go +++ b/plugin/cmd/kube-scheduler/app/server.go @@ -31,13 +31,13 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apiserver/pkg/server/healthz" restclient "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" "k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/client/clientset_generated/clientset" v1core "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/core/v1" "k8s.io/kubernetes/pkg/client/leaderelection" "k8s.io/kubernetes/pkg/client/leaderelection/resourcelock" "k8s.io/kubernetes/pkg/client/record" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" "k8s.io/kubernetes/pkg/util/configz" "k8s.io/kubernetes/plugin/cmd/kube-scheduler/app/options" "k8s.io/kubernetes/plugin/pkg/scheduler" diff --git a/plugin/pkg/admission/initialresources/BUILD b/plugin/pkg/admission/initialresources/BUILD index 4bab6d9f460..9c0b6f0f5b3 100644 --- a/plugin/pkg/admission/initialresources/BUILD +++ b/plugin/pkg/admission/initialresources/BUILD @@ -21,7 +21,6 @@ go_library( deps = [ "//pkg/api:go_default_library", "//pkg/api/resource:go_default_library", - "//pkg/client/unversioned/clientcmd:go_default_library", "//vendor:cloud.google.com/go/compute/metadata", "//vendor:github.com/golang/glog", "//vendor:github.com/hawkular/hawkular-client-go/metrics", @@ -32,6 +31,7 @@ go_library( "//vendor:k8s.io/apimachinery/pkg/api/errors", "//vendor:k8s.io/apiserver/pkg/admission", "//vendor:k8s.io/client-go/rest", + "//vendor:k8s.io/client-go/tools/clientcmd", ], ) diff --git a/plugin/pkg/admission/initialresources/hawkular.go b/plugin/pkg/admission/initialresources/hawkular.go index ce6edcc6a02..4d2401ca45d 100644 --- a/plugin/pkg/admission/initialresources/hawkular.go +++ b/plugin/pkg/admission/initialresources/hawkular.go @@ -32,7 +32,7 @@ import ( "k8s.io/kubernetes/pkg/api" restclient "k8s.io/client-go/rest" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" + "k8s.io/client-go/tools/clientcmd" ) type hawkularSource struct { diff --git a/test/e2e/framework/BUILD b/test/e2e/framework/BUILD index 3b564f6731d..f01f62a482b 100644 --- a/test/e2e/framework/BUILD +++ b/test/e2e/framework/BUILD @@ -52,7 +52,6 @@ go_library( "//pkg/client/conditions:go_default_library", "//pkg/client/typed/discovery:go_default_library", "//pkg/client/typed/dynamic:go_default_library", - "//pkg/client/unversioned/clientcmd:go_default_library", "//pkg/client/unversioned/remotecommand:go_default_library", "//pkg/cloudprovider:go_default_library", "//pkg/cloudprovider/providers/gce:go_default_library", @@ -108,6 +107,7 @@ go_library( "//vendor:k8s.io/apimachinery/pkg/watch", "//vendor:k8s.io/client-go/kubernetes", "//vendor:k8s.io/client-go/rest", + "//vendor:k8s.io/client-go/tools/clientcmd", "//vendor:k8s.io/client-go/tools/clientcmd/api", ], ) diff --git a/test/e2e/framework/test_context.go b/test/e2e/framework/test_context.go index bfdd7cc7add..ceddefcbc02 100644 --- a/test/e2e/framework/test_context.go +++ b/test/e2e/framework/test_context.go @@ -23,8 +23,8 @@ import ( "github.com/onsi/ginkgo/config" "github.com/spf13/viper" + "k8s.io/client-go/tools/clientcmd" "k8s.io/kubernetes/pkg/apis/componentconfig" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" "k8s.io/kubernetes/pkg/cloudprovider" ) diff --git a/test/e2e/framework/util.go b/test/e2e/framework/util.go index c93fefe219a..b142549e743 100644 --- a/test/e2e/framework/util.go +++ b/test/e2e/framework/util.go @@ -63,6 +63,7 @@ import ( "k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/watch" restclient "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/v1" @@ -76,7 +77,6 @@ import ( "k8s.io/kubernetes/pkg/client/conditions" "k8s.io/kubernetes/pkg/client/typed/discovery" "k8s.io/kubernetes/pkg/client/typed/dynamic" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" gcecloud "k8s.io/kubernetes/pkg/cloudprovider/providers/gce" "k8s.io/kubernetes/pkg/controller" deploymentutil "k8s.io/kubernetes/pkg/controller/deployment/util" diff --git a/test/e2e_federation/BUILD b/test/e2e_federation/BUILD index 6e948e91e7a..aac855eeb5a 100644 --- a/test/e2e_federation/BUILD +++ b/test/e2e_federation/BUILD @@ -32,7 +32,6 @@ go_library( "//pkg/api/v1:go_default_library", "//pkg/apis/extensions/v1beta1:go_default_library", "//pkg/client/clientset_generated/clientset:go_default_library", - "//pkg/client/unversioned/clientcmd:go_default_library", "//pkg/util/intstr:go_default_library", "//test/e2e/common:go_default_library", "//test/e2e/framework:go_default_library", @@ -43,6 +42,7 @@ go_library( "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", "//vendor:k8s.io/apimachinery/pkg/util/wait", "//vendor:k8s.io/client-go/rest", + "//vendor:k8s.io/client-go/tools/clientcmd", "//vendor:k8s.io/client-go/tools/clientcmd/api", ], ) diff --git a/test/e2e_federation/federation-authn.go b/test/e2e_federation/federation-authn.go index e431ce1bdd3..dee2b95b076 100644 --- a/test/e2e_federation/federation-authn.go +++ b/test/e2e_federation/federation-authn.go @@ -20,9 +20,9 @@ import ( "fmt" "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" "k8s.io/kubernetes/test/e2e/framework" fedframework "k8s.io/kubernetes/test/e2e_federation/framework" diff --git a/test/e2e_federation/federation-util.go b/test/e2e_federation/federation-util.go index b59d1d12bf2..4e405d09e42 100644 --- a/test/e2e_federation/federation-util.go +++ b/test/e2e_federation/federation-util.go @@ -26,13 +26,13 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/wait" restclient "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" federationapi "k8s.io/kubernetes/federation/apis/federation/v1beta1" fedclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/v1" kubeclientset "k8s.io/kubernetes/pkg/client/clientset_generated/clientset" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" "k8s.io/kubernetes/test/e2e/common" "k8s.io/kubernetes/test/e2e/framework" fedframework "k8s.io/kubernetes/test/e2e_federation/framework" diff --git a/test/e2e_federation/framework/BUILD b/test/e2e_federation/framework/BUILD index 7461abdf15b..3d98d57591d 100644 --- a/test/e2e_federation/framework/BUILD +++ b/test/e2e_federation/framework/BUILD @@ -21,7 +21,6 @@ go_library( "//pkg/api/v1:go_default_library", "//pkg/api/validation:go_default_library", "//pkg/client/clientset_generated/clientset:go_default_library", - "//pkg/client/unversioned/clientcmd:go_default_library", "//test/e2e/framework:go_default_library", "//vendor:github.com/onsi/ginkgo", "//vendor:github.com/onsi/gomega", @@ -31,6 +30,7 @@ go_library( "//vendor:k8s.io/apimachinery/pkg/util/validation", "//vendor:k8s.io/apimachinery/pkg/util/wait", "//vendor:k8s.io/client-go/rest", + "//vendor:k8s.io/client-go/tools/clientcmd", ], ) diff --git a/test/e2e_federation/framework/util.go b/test/e2e_federation/framework/util.go index 587d05b4dc7..b292e486dd1 100644 --- a/test/e2e_federation/framework/util.go +++ b/test/e2e_federation/framework/util.go @@ -27,13 +27,13 @@ import ( validationutil "k8s.io/apimachinery/pkg/util/validation" "k8s.io/apimachinery/pkg/util/wait" restclient "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" federationapi "k8s.io/kubernetes/federation/apis/federation/v1beta1" "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/api/validation" "k8s.io/kubernetes/pkg/client/clientset_generated/clientset" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" "k8s.io/kubernetes/test/e2e/framework" ) diff --git a/test/integration/kubectl/kubectl_test.go b/test/integration/kubectl/kubectl_test.go index 8d9893ca560..f1202b31b23 100644 --- a/test/integration/kubectl/kubectl_test.go +++ b/test/integration/kubectl/kubectl_test.go @@ -21,8 +21,8 @@ package kubectl import ( "testing" + "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" "k8s.io/kubernetes/pkg/kubectl/cmd/util" "k8s.io/kubernetes/test/integration/framework" ) diff --git a/test/soak/serve_hostnames/BUILD b/test/soak/serve_hostnames/BUILD index cffad4efda5..337b7d396fa 100644 --- a/test/soak/serve_hostnames/BUILD +++ b/test/soak/serve_hostnames/BUILD @@ -22,7 +22,6 @@ go_library( "//pkg/api:go_default_library", "//pkg/api/v1:go_default_library", "//pkg/client/clientset_generated/clientset:go_default_library", - "//pkg/client/unversioned/clientcmd:go_default_library", "//pkg/util/intstr:go_default_library", "//test/e2e/framework:go_default_library", "//vendor:github.com/golang/glog", @@ -30,6 +29,7 @@ go_library( "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", "//vendor:k8s.io/apimachinery/pkg/runtime", "//vendor:k8s.io/client-go/rest", + "//vendor:k8s.io/client-go/tools/clientcmd", ], ) diff --git a/test/soak/serve_hostnames/serve_hostnames.go b/test/soak/serve_hostnames/serve_hostnames.go index 17671df14cd..0b0f630876f 100644 --- a/test/soak/serve_hostnames/serve_hostnames.go +++ b/test/soak/serve_hostnames/serve_hostnames.go @@ -33,10 +33,10 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" restclient "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/client/clientset_generated/clientset" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" "k8s.io/kubernetes/pkg/util/intstr" e2e "k8s.io/kubernetes/test/e2e/framework"