mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-10-31 18:28:13 +00:00 
			
		
		
		
	mechanical
This commit is contained in:
		| @@ -19,7 +19,6 @@ go_library( | |||||||
|         "//pkg/client/leaderelection:go_default_library", |         "//pkg/client/leaderelection:go_default_library", | ||||||
|         "//pkg/client/leaderelection/resourcelock:go_default_library", |         "//pkg/client/leaderelection/resourcelock:go_default_library", | ||||||
|         "//pkg/client/record:go_default_library", |         "//pkg/client/record:go_default_library", | ||||||
|         "//pkg/client/unversioned/clientcmd:go_default_library", |  | ||||||
|         "//pkg/cloudprovider:go_default_library", |         "//pkg/cloudprovider:go_default_library", | ||||||
|         "//pkg/controller:go_default_library", |         "//pkg/controller:go_default_library", | ||||||
|         "//pkg/controller/cloud: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/apimachinery/pkg/util/wait", | ||||||
|         "//vendor:k8s.io/apiserver/pkg/server/healthz", |         "//vendor:k8s.io/apiserver/pkg/server/healthz", | ||||||
|         "//vendor:k8s.io/client-go/rest", |         "//vendor:k8s.io/client-go/rest", | ||||||
|  |         "//vendor:k8s.io/client-go/tools/clientcmd", | ||||||
|     ], |     ], | ||||||
| ) | ) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -29,6 +29,7 @@ import ( | |||||||
| 	"k8s.io/apimachinery/pkg/util/wait" | 	"k8s.io/apimachinery/pkg/util/wait" | ||||||
| 	"k8s.io/apiserver/pkg/server/healthz" | 	"k8s.io/apiserver/pkg/server/healthz" | ||||||
| 	restclient "k8s.io/client-go/rest" | 	restclient "k8s.io/client-go/rest" | ||||||
|  | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	"k8s.io/kubernetes/cmd/cloud-controller-manager/app/options" | 	"k8s.io/kubernetes/cmd/cloud-controller-manager/app/options" | ||||||
| 	"k8s.io/kubernetes/pkg/api/v1" | 	"k8s.io/kubernetes/pkg/api/v1" | ||||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | 	"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" | ||||||
| 	"k8s.io/kubernetes/pkg/client/leaderelection/resourcelock" | 	"k8s.io/kubernetes/pkg/client/leaderelection/resourcelock" | ||||||
| 	"k8s.io/kubernetes/pkg/client/record" | 	"k8s.io/kubernetes/pkg/client/record" | ||||||
| 	"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" |  | ||||||
| 	"k8s.io/kubernetes/pkg/cloudprovider" | 	"k8s.io/kubernetes/pkg/cloudprovider" | ||||||
| 	"k8s.io/kubernetes/pkg/controller" | 	"k8s.io/kubernetes/pkg/controller" | ||||||
| 	nodecontroller "k8s.io/kubernetes/pkg/controller/cloud" | 	nodecontroller "k8s.io/kubernetes/pkg/controller/cloud" | ||||||
|   | |||||||
| @@ -36,7 +36,6 @@ go_library( | |||||||
|         "//pkg/client/record:go_default_library", |         "//pkg/client/record:go_default_library", | ||||||
|         "//pkg/client/typed/discovery:go_default_library", |         "//pkg/client/typed/discovery:go_default_library", | ||||||
|         "//pkg/client/typed/dynamic:go_default_library", |         "//pkg/client/typed/dynamic:go_default_library", | ||||||
|         "//pkg/client/unversioned/clientcmd:go_default_library", |  | ||||||
|         "//pkg/cloudprovider:go_default_library", |         "//pkg/cloudprovider:go_default_library", | ||||||
|         "//pkg/cloudprovider/providers:go_default_library", |         "//pkg/cloudprovider/providers:go_default_library", | ||||||
|         "//pkg/cloudprovider/providers/aws: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/apiserver/pkg/server/healthz", | ||||||
|         "//vendor:k8s.io/client-go/pkg/util/cert", |         "//vendor:k8s.io/client-go/pkg/util/cert", | ||||||
|         "//vendor:k8s.io/client-go/rest", |         "//vendor:k8s.io/client-go/rest", | ||||||
|  |         "//vendor:k8s.io/client-go/tools/clientcmd", | ||||||
|     ], |     ], | ||||||
| ) | ) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -38,6 +38,7 @@ import ( | |||||||
| 	"k8s.io/apiserver/pkg/server/healthz" | 	"k8s.io/apiserver/pkg/server/healthz" | ||||||
| 	certutil "k8s.io/client-go/pkg/util/cert" | 	certutil "k8s.io/client-go/pkg/util/cert" | ||||||
| 	restclient "k8s.io/client-go/rest" | 	restclient "k8s.io/client-go/rest" | ||||||
|  | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	"k8s.io/kubernetes/cmd/kube-controller-manager/app/options" | 	"k8s.io/kubernetes/cmd/kube-controller-manager/app/options" | ||||||
| 	"k8s.io/kubernetes/pkg/api/v1" | 	"k8s.io/kubernetes/pkg/api/v1" | ||||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | 	"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/leaderelection/resourcelock" | ||||||
| 	"k8s.io/kubernetes/pkg/client/record" | 	"k8s.io/kubernetes/pkg/client/record" | ||||||
| 	"k8s.io/kubernetes/pkg/client/typed/discovery" | 	"k8s.io/kubernetes/pkg/client/typed/discovery" | ||||||
| 	"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" |  | ||||||
| 	"k8s.io/kubernetes/pkg/cloudprovider" | 	"k8s.io/kubernetes/pkg/cloudprovider" | ||||||
| 	"k8s.io/kubernetes/pkg/controller" | 	"k8s.io/kubernetes/pkg/controller" | ||||||
| 	"k8s.io/kubernetes/pkg/controller/informers" | 	"k8s.io/kubernetes/pkg/controller/informers" | ||||||
|   | |||||||
| @@ -22,7 +22,6 @@ go_library( | |||||||
|         "//pkg/client/clientset_generated/internalclientset:go_default_library", |         "//pkg/client/clientset_generated/internalclientset:go_default_library", | ||||||
|         "//pkg/client/clientset_generated/internalclientset/typed/core/internalversion:go_default_library", |         "//pkg/client/clientset_generated/internalclientset/typed/core/internalversion:go_default_library", | ||||||
|         "//pkg/client/record:go_default_library", |         "//pkg/client/record:go_default_library", | ||||||
|         "//pkg/client/unversioned/clientcmd:go_default_library", |  | ||||||
|         "//pkg/proxy:go_default_library", |         "//pkg/proxy:go_default_library", | ||||||
|         "//pkg/proxy/config:go_default_library", |         "//pkg/proxy/config:go_default_library", | ||||||
|         "//pkg/proxy/iptables: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/types", | ||||||
|         "//vendor:k8s.io/apimachinery/pkg/util/net", |         "//vendor:k8s.io/apimachinery/pkg/util/net", | ||||||
|         "//vendor:k8s.io/apimachinery/pkg/util/wait", |         "//vendor:k8s.io/apimachinery/pkg/util/wait", | ||||||
|  |         "//vendor:k8s.io/client-go/tools/clientcmd", | ||||||
|         "//vendor:k8s.io/client-go/tools/clientcmd/api", |         "//vendor:k8s.io/client-go/tools/clientcmd/api", | ||||||
|     ], |     ], | ||||||
| ) | ) | ||||||
|   | |||||||
| @@ -32,6 +32,7 @@ import ( | |||||||
| 	"k8s.io/apimachinery/pkg/types" | 	"k8s.io/apimachinery/pkg/types" | ||||||
| 	utilnet "k8s.io/apimachinery/pkg/util/net" | 	utilnet "k8s.io/apimachinery/pkg/util/net" | ||||||
| 	"k8s.io/apimachinery/pkg/util/wait" | 	"k8s.io/apimachinery/pkg/util/wait" | ||||||
|  | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | ||||||
| 	"k8s.io/kubernetes/cmd/kube-proxy/app/options" | 	"k8s.io/kubernetes/cmd/kube-proxy/app/options" | ||||||
| 	"k8s.io/kubernetes/pkg/api" | 	"k8s.io/kubernetes/pkg/api" | ||||||
| @@ -39,7 +40,6 @@ import ( | |||||||
| 	clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" | 	clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" | ||||||
| 	unversionedcore "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion" | 	unversionedcore "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion" | ||||||
| 	"k8s.io/kubernetes/pkg/client/record" | 	"k8s.io/kubernetes/pkg/client/record" | ||||||
| 	"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" |  | ||||||
| 	"k8s.io/kubernetes/pkg/proxy" | 	"k8s.io/kubernetes/pkg/proxy" | ||||||
| 	proxyconfig "k8s.io/kubernetes/pkg/proxy/config" | 	proxyconfig "k8s.io/kubernetes/pkg/proxy/config" | ||||||
| 	"k8s.io/kubernetes/pkg/proxy/iptables" | 	"k8s.io/kubernetes/pkg/proxy/iptables" | ||||||
|   | |||||||
| @@ -22,8 +22,8 @@ go_library( | |||||||
|         "//cmd/kubeadm/app/discovery/token:go_default_library", |         "//cmd/kubeadm/app/discovery/token:go_default_library", | ||||||
|         "//cmd/kubeadm/app/node:go_default_library", |         "//cmd/kubeadm/app/node:go_default_library", | ||||||
|         "//cmd/kubeadm/app/util:go_default_library", |         "//cmd/kubeadm/app/util:go_default_library", | ||||||
|         "//pkg/client/unversioned/clientcmd:go_default_library", |  | ||||||
|         "//vendor:github.com/spf13/pflag", |         "//vendor:github.com/spf13/pflag", | ||||||
|  |         "//vendor:k8s.io/client-go/tools/clientcmd", | ||||||
|         "//vendor:k8s.io/client-go/tools/clientcmd/api", |         "//vendor:k8s.io/client-go/tools/clientcmd/api", | ||||||
|     ], |     ], | ||||||
| ) | ) | ||||||
|   | |||||||
| @@ -21,11 +21,11 @@ import ( | |||||||
| 	"io/ioutil" | 	"io/ioutil" | ||||||
| 	"net/http" | 	"net/http" | ||||||
|  |  | ||||||
|  | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | ||||||
| 	kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" | 	kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" | ||||||
| 	kubenode "k8s.io/kubernetes/cmd/kubeadm/app/node" | 	kubenode "k8s.io/kubernetes/cmd/kubeadm/app/node" | ||||||
| 	kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util" | 	kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util" | ||||||
| 	"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // For identifies and executes the desired discovery mechanism. | // For identifies and executes the desired discovery mechanism. | ||||||
|   | |||||||
| @@ -31,7 +31,6 @@ go_library( | |||||||
|         "//pkg/api/v1:go_default_library", |         "//pkg/api/v1:go_default_library", | ||||||
|         "//pkg/apis/extensions/v1beta1:go_default_library", |         "//pkg/apis/extensions/v1beta1:go_default_library", | ||||||
|         "//pkg/client/clientset_generated/clientset: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/kubectl/cmd/util:go_default_library", | ||||||
|         "//pkg/registry/core/service/ipallocator:go_default_library", |         "//pkg/registry/core/service/ipallocator:go_default_library", | ||||||
|         "//pkg/util/intstr: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/apis/meta/v1", | ||||||
|         "//vendor:k8s.io/apimachinery/pkg/util/wait", |         "//vendor:k8s.io/apimachinery/pkg/util/wait", | ||||||
|         "//vendor:k8s.io/client-go/pkg/util/cert", |         "//vendor:k8s.io/client-go/pkg/util/cert", | ||||||
|  |         "//vendor:k8s.io/client-go/tools/clientcmd", | ||||||
|         "//vendor:k8s.io/client-go/tools/clientcmd/api", |         "//vendor:k8s.io/client-go/tools/clientcmd/api", | ||||||
|     ], |     ], | ||||||
| ) | ) | ||||||
|   | |||||||
| @@ -25,13 +25,13 @@ import ( | |||||||
| 	apierrs "k8s.io/apimachinery/pkg/api/errors" | 	apierrs "k8s.io/apimachinery/pkg/api/errors" | ||||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||||
| 	"k8s.io/apimachinery/pkg/util/wait" | 	"k8s.io/apimachinery/pkg/util/wait" | ||||||
|  | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | ||||||
| 	"k8s.io/kubernetes/cmd/kubeadm/app/images" | 	"k8s.io/kubernetes/cmd/kubeadm/app/images" | ||||||
| 	"k8s.io/kubernetes/pkg/api" | 	"k8s.io/kubernetes/pkg/api" | ||||||
| 	"k8s.io/kubernetes/pkg/api/v1" | 	"k8s.io/kubernetes/pkg/api/v1" | ||||||
| 	extensions "k8s.io/kubernetes/pkg/apis/extensions/v1beta1" | 	extensions "k8s.io/kubernetes/pkg/apis/extensions/v1beta1" | ||||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||||
| 	"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
| const apiCallRetryInterval = 500 * time.Millisecond | const apiCallRetryInterval = 500 * time.Millisecond | ||||||
|   | |||||||
| @@ -22,7 +22,6 @@ go_library( | |||||||
|         "//cmd/kubeadm/app/util:go_default_library", |         "//cmd/kubeadm/app/util:go_default_library", | ||||||
|         "//pkg/apis/certificates:go_default_library", |         "//pkg/apis/certificates:go_default_library", | ||||||
|         "//pkg/client/clientset_generated/clientset: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", |         "//pkg/kubelet/util/csr:go_default_library", | ||||||
|         "//vendor:github.com/square/go-jose", |         "//vendor:github.com/square/go-jose", | ||||||
|         "//vendor:k8s.io/apimachinery/pkg/api/errors", |         "//vendor:k8s.io/apimachinery/pkg/api/errors", | ||||||
| @@ -30,6 +29,7 @@ go_library( | |||||||
|         "//vendor:k8s.io/apimachinery/pkg/types", |         "//vendor:k8s.io/apimachinery/pkg/types", | ||||||
|         "//vendor:k8s.io/apimachinery/pkg/util/wait", |         "//vendor:k8s.io/apimachinery/pkg/util/wait", | ||||||
|         "//vendor:k8s.io/client-go/pkg/util/cert", |         "//vendor:k8s.io/client-go/pkg/util/cert", | ||||||
|  |         "//vendor:k8s.io/client-go/tools/clientcmd", | ||||||
|         "//vendor:k8s.io/client-go/tools/clientcmd/api", |         "//vendor:k8s.io/client-go/tools/clientcmd/api", | ||||||
|     ], |     ], | ||||||
| ) | ) | ||||||
|   | |||||||
| @@ -26,13 +26,13 @@ import ( | |||||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||||
| 	"k8s.io/apimachinery/pkg/types" | 	"k8s.io/apimachinery/pkg/types" | ||||||
| 	"k8s.io/apimachinery/pkg/util/wait" | 	"k8s.io/apimachinery/pkg/util/wait" | ||||||
|  | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | ||||||
| 	kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" | 	kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" | ||||||
| 	kubeconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig" | 	kubeconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig" | ||||||
| 	kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util" | 	kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util" | ||||||
| 	"k8s.io/kubernetes/pkg/apis/certificates" | 	"k8s.io/kubernetes/pkg/apis/certificates" | ||||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||||
| 	"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // retryTimeout between the subsequent attempts to connect | // retryTimeout between the subsequent attempts to connect | ||||||
|   | |||||||
| @@ -22,9 +22,9 @@ import ( | |||||||
|  |  | ||||||
| 	"k8s.io/apimachinery/pkg/types" | 	"k8s.io/apimachinery/pkg/types" | ||||||
| 	certutil "k8s.io/client-go/pkg/util/cert" | 	certutil "k8s.io/client-go/pkg/util/cert" | ||||||
|  | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | ||||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||||
| 	"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" |  | ||||||
| 	"k8s.io/kubernetes/pkg/kubelet/util/csr" | 	"k8s.io/kubernetes/pkg/kubelet/util/csr" | ||||||
| ) | ) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -26,8 +26,8 @@ go_library( | |||||||
|     deps = [ |     deps = [ | ||||||
|         "//cmd/kubeadm/app/constants:go_default_library", |         "//cmd/kubeadm/app/constants:go_default_library", | ||||||
|         "//cmd/kubeadm/app/phases/certs/pkiutil: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/pkg/util/cert", | ||||||
|  |         "//vendor:k8s.io/client-go/tools/clientcmd", | ||||||
|         "//vendor:k8s.io/client-go/tools/clientcmd/api", |         "//vendor:k8s.io/client-go/tools/clientcmd/api", | ||||||
|     ], |     ], | ||||||
| ) | ) | ||||||
|   | |||||||
| @@ -26,10 +26,10 @@ import ( | |||||||
| 	"path/filepath" | 	"path/filepath" | ||||||
|  |  | ||||||
| 	certutil "k8s.io/client-go/pkg/util/cert" | 	certutil "k8s.io/client-go/pkg/util/cert" | ||||||
|  | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | ||||||
| 	kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" | 	kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" | ||||||
| 	"k8s.io/kubernetes/cmd/kubeadm/app/phases/certs/pkiutil" | 	"k8s.io/kubernetes/cmd/kubeadm/app/phases/certs/pkiutil" | ||||||
| 	"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
| const ( | const ( | ||||||
|   | |||||||
| @@ -47,8 +47,6 @@ go_library( | |||||||
|         "//pkg/client/clientset_generated/clientset/typed/certificates/v1beta1:go_default_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/clientset_generated/clientset/typed/core/v1:go_default_library", | ||||||
|         "//pkg/client/record: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:go_default_library", | ||||||
|         "//pkg/cloudprovider/providers:go_default_library", |         "//pkg/cloudprovider/providers:go_default_library", | ||||||
|         "//pkg/credentialprovider:go_default_library", |         "//pkg/credentialprovider:go_default_library", | ||||||
|   | |||||||
| @@ -28,9 +28,9 @@ import ( | |||||||
| 	"k8s.io/apimachinery/pkg/types" | 	"k8s.io/apimachinery/pkg/types" | ||||||
| 	certutil "k8s.io/client-go/pkg/util/cert" | 	certutil "k8s.io/client-go/pkg/util/cert" | ||||||
| 	restclient "k8s.io/client-go/rest" | 	restclient "k8s.io/client-go/rest" | ||||||
|  | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | ||||||
| 	certificates "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/certificates/v1beta1" | 	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" | 	"k8s.io/kubernetes/pkg/kubelet/util/csr" | ||||||
| ) | ) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -47,6 +47,8 @@ import ( | |||||||
| 	"k8s.io/client-go/pkg/util/cert" | 	"k8s.io/client-go/pkg/util/cert" | ||||||
| 	certutil "k8s.io/client-go/pkg/util/cert" | 	certutil "k8s.io/client-go/pkg/util/cert" | ||||||
| 	restclient "k8s.io/client-go/rest" | 	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" | 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | ||||||
| 	"k8s.io/kubernetes/cmd/kubelet/app/options" | 	"k8s.io/kubernetes/cmd/kubelet/app/options" | ||||||
| 	"k8s.io/kubernetes/pkg/api" | 	"k8s.io/kubernetes/pkg/api" | ||||||
| @@ -58,8 +60,6 @@ import ( | |||||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||||
| 	v1core "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/core/v1" | 	v1core "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/core/v1" | ||||||
| 	"k8s.io/kubernetes/pkg/client/record" | 	"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/cloudprovider" | ||||||
| 	"k8s.io/kubernetes/pkg/credentialprovider" | 	"k8s.io/kubernetes/pkg/credentialprovider" | ||||||
| 	"k8s.io/kubernetes/pkg/kubelet" | 	"k8s.io/kubernetes/pkg/kubelet" | ||||||
|   | |||||||
| @@ -24,7 +24,6 @@ go_library( | |||||||
|         "//pkg/client/clientset_generated/internalclientset:go_default_library", |         "//pkg/client/clientset_generated/internalclientset:go_default_library", | ||||||
|         "//pkg/client/metrics/prometheus:go_default_library", |         "//pkg/client/metrics/prometheus:go_default_library", | ||||||
|         "//pkg/client/record: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/cadvisor/testing:go_default_library", | ||||||
|         "//pkg/kubelet/cm:go_default_library", |         "//pkg/kubelet/cm:go_default_library", | ||||||
|         "//pkg/kubelet/dockertools:go_default_library", |         "//pkg/kubelet/dockertools:go_default_library", | ||||||
| @@ -37,6 +36,7 @@ go_library( | |||||||
|         "//vendor:github.com/spf13/pflag", |         "//vendor:github.com/spf13/pflag", | ||||||
|         "//vendor:k8s.io/apimachinery/pkg/util/sets", |         "//vendor:k8s.io/apimachinery/pkg/util/sets", | ||||||
|         "//vendor:k8s.io/client-go/rest", |         "//vendor:k8s.io/client-go/rest", | ||||||
|  |         "//vendor:k8s.io/client-go/tools/clientcmd", | ||||||
|     ], |     ], | ||||||
| ) | ) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -21,12 +21,12 @@ import ( | |||||||
|  |  | ||||||
| 	"k8s.io/apimachinery/pkg/util/sets" | 	"k8s.io/apimachinery/pkg/util/sets" | ||||||
| 	restclient "k8s.io/client-go/rest" | 	restclient "k8s.io/client-go/rest" | ||||||
|  | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	"k8s.io/kubernetes/pkg/api/v1" | 	"k8s.io/kubernetes/pkg/api/v1" | ||||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" | 	"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" | ||||||
| 	_ "k8s.io/kubernetes/pkg/client/metrics/prometheus" // for client metric registration | 	_ "k8s.io/kubernetes/pkg/client/metrics/prometheus" // for client metric registration | ||||||
| 	"k8s.io/kubernetes/pkg/client/record" | 	"k8s.io/kubernetes/pkg/client/record" | ||||||
| 	"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" |  | ||||||
| 	cadvisortest "k8s.io/kubernetes/pkg/kubelet/cadvisor/testing" | 	cadvisortest "k8s.io/kubernetes/pkg/kubelet/cadvisor/testing" | ||||||
| 	"k8s.io/kubernetes/pkg/kubelet/cm" | 	"k8s.io/kubernetes/pkg/kubelet/cm" | ||||||
| 	"k8s.io/kubernetes/pkg/kubelet/dockertools" | 	"k8s.io/kubernetes/pkg/kubelet/dockertools" | ||||||
|   | |||||||
| @@ -33,7 +33,6 @@ go_library( | |||||||
|         "//federation/pkg/federation-controller/service:go_default_library", |         "//federation/pkg/federation-controller/service:go_default_library", | ||||||
|         "//federation/pkg/federation-controller/util:go_default_library", |         "//federation/pkg/federation-controller/util:go_default_library", | ||||||
|         "//pkg/client/typed/discovery: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/config:go_default_library", | ||||||
|         "//pkg/util/configz:go_default_library", |         "//pkg/util/configz:go_default_library", | ||||||
|         "//pkg/version:go_default_library", |         "//pkg/version:go_default_library", | ||||||
| @@ -46,6 +45,7 @@ go_library( | |||||||
|         "//vendor:k8s.io/apimachinery/pkg/util/wait", |         "//vendor:k8s.io/apimachinery/pkg/util/wait", | ||||||
|         "//vendor:k8s.io/apiserver/pkg/server/healthz", |         "//vendor:k8s.io/apiserver/pkg/server/healthz", | ||||||
|         "//vendor:k8s.io/client-go/rest", |         "//vendor:k8s.io/client-go/rest", | ||||||
|  |         "//vendor:k8s.io/client-go/tools/clientcmd", | ||||||
|     ], |     ], | ||||||
| ) | ) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -30,6 +30,7 @@ import ( | |||||||
| 	"k8s.io/apimachinery/pkg/util/wait" | 	"k8s.io/apimachinery/pkg/util/wait" | ||||||
| 	"k8s.io/apiserver/pkg/server/healthz" | 	"k8s.io/apiserver/pkg/server/healthz" | ||||||
| 	restclient "k8s.io/client-go/rest" | 	restclient "k8s.io/client-go/rest" | ||||||
|  | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	federationclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset" | 	federationclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset" | ||||||
| 	"k8s.io/kubernetes/federation/cmd/federation-controller-manager/app/options" | 	"k8s.io/kubernetes/federation/cmd/federation-controller-manager/app/options" | ||||||
| 	"k8s.io/kubernetes/federation/pkg/dnsprovider" | 	"k8s.io/kubernetes/federation/pkg/dnsprovider" | ||||||
| @@ -43,7 +44,6 @@ import ( | |||||||
| 	secretcontroller "k8s.io/kubernetes/federation/pkg/federation-controller/secret" | 	secretcontroller "k8s.io/kubernetes/federation/pkg/federation-controller/secret" | ||||||
| 	servicecontroller "k8s.io/kubernetes/federation/pkg/federation-controller/service" | 	servicecontroller "k8s.io/kubernetes/federation/pkg/federation-controller/service" | ||||||
| 	"k8s.io/kubernetes/federation/pkg/federation-controller/util" | 	"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/util/configz" | ||||||
| 	"k8s.io/kubernetes/pkg/version" | 	"k8s.io/kubernetes/pkg/version" | ||||||
|  |  | ||||||
|   | |||||||
| @@ -49,10 +49,10 @@ go_test( | |||||||
|         "//federation/pkg/federation-controller/util:go_default_library", |         "//federation/pkg/federation-controller/util:go_default_library", | ||||||
|         "//pkg/api/testapi:go_default_library", |         "//pkg/api/testapi:go_default_library", | ||||||
|         "//pkg/api/v1:go_default_library", |         "//pkg/api/v1:go_default_library", | ||||||
|         "//pkg/client/unversioned/clientcmd:go_default_library", |  | ||||||
|         "//pkg/util/uuid:go_default_library", |         "//pkg/util/uuid:go_default_library", | ||||||
|         "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", |         "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", | ||||||
|         "//vendor:k8s.io/client-go/rest", |         "//vendor:k8s.io/client-go/rest", | ||||||
|  |         "//vendor:k8s.io/client-go/tools/clientcmd", | ||||||
|         "//vendor:k8s.io/client-go/tools/clientcmd/api", |         "//vendor:k8s.io/client-go/tools/clientcmd/api", | ||||||
|     ], |     ], | ||||||
| ) | ) | ||||||
|   | |||||||
| @@ -25,13 +25,13 @@ import ( | |||||||
|  |  | ||||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||||
| 	restclient "k8s.io/client-go/rest" | 	restclient "k8s.io/client-go/rest" | ||||||
|  | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | ||||||
| 	federationv1beta1 "k8s.io/kubernetes/federation/apis/federation/v1beta1" | 	federationv1beta1 "k8s.io/kubernetes/federation/apis/federation/v1beta1" | ||||||
| 	federationclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset" | 	federationclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset" | ||||||
| 	controllerutil "k8s.io/kubernetes/federation/pkg/federation-controller/util" | 	controllerutil "k8s.io/kubernetes/federation/pkg/federation-controller/util" | ||||||
| 	"k8s.io/kubernetes/pkg/api/testapi" | 	"k8s.io/kubernetes/pkg/api/testapi" | ||||||
| 	"k8s.io/kubernetes/pkg/api/v1" | 	"k8s.io/kubernetes/pkg/api/v1" | ||||||
| 	"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" |  | ||||||
| 	"k8s.io/kubernetes/pkg/util/uuid" | 	"k8s.io/kubernetes/pkg/util/uuid" | ||||||
| ) | ) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -33,7 +33,6 @@ go_library( | |||||||
|         "//pkg/client/cache:go_default_library", |         "//pkg/client/cache:go_default_library", | ||||||
|         "//pkg/client/clientset_generated/clientset:go_default_library", |         "//pkg/client/clientset_generated/clientset:go_default_library", | ||||||
|         "//pkg/client/clientset_generated/internalclientset: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", |         "//pkg/controller/deployment/util:go_default_library", | ||||||
|         "//vendor:github.com/golang/glog", |         "//vendor:github.com/golang/glog", | ||||||
|         "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", |         "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", | ||||||
| @@ -43,6 +42,7 @@ go_library( | |||||||
|         "//vendor:k8s.io/apimachinery/pkg/watch", |         "//vendor:k8s.io/apimachinery/pkg/watch", | ||||||
|         "//vendor:k8s.io/client-go/pkg/util/flowcontrol", |         "//vendor:k8s.io/client-go/pkg/util/flowcontrol", | ||||||
|         "//vendor:k8s.io/client-go/rest", |         "//vendor:k8s.io/client-go/rest", | ||||||
|  |         "//vendor:k8s.io/client-go/tools/clientcmd", | ||||||
|         "//vendor:k8s.io/client-go/tools/clientcmd/api", |         "//vendor:k8s.io/client-go/tools/clientcmd/api", | ||||||
|     ], |     ], | ||||||
| ) | ) | ||||||
|   | |||||||
| @@ -27,12 +27,12 @@ import ( | |||||||
| 	utilnet "k8s.io/apimachinery/pkg/util/net" | 	utilnet "k8s.io/apimachinery/pkg/util/net" | ||||||
| 	"k8s.io/apimachinery/pkg/util/wait" | 	"k8s.io/apimachinery/pkg/util/wait" | ||||||
| 	restclient "k8s.io/client-go/rest" | 	restclient "k8s.io/client-go/rest" | ||||||
|  | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | ||||||
| 	federation_v1beta1 "k8s.io/kubernetes/federation/apis/federation/v1beta1" | 	federation_v1beta1 "k8s.io/kubernetes/federation/apis/federation/v1beta1" | ||||||
| 	fedclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset" | 	fedclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset" | ||||||
| 	"k8s.io/kubernetes/pkg/api" | 	"k8s.io/kubernetes/pkg/api" | ||||||
| 	clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" | 	clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" | ||||||
| 	"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
| const ( | const ( | ||||||
|   | |||||||
| @@ -21,7 +21,6 @@ go_library( | |||||||
|         "//federation/pkg/kubefed/init:go_default_library", |         "//federation/pkg/kubefed/init:go_default_library", | ||||||
|         "//federation/pkg/kubefed/util:go_default_library", |         "//federation/pkg/kubefed/util:go_default_library", | ||||||
|         "//pkg/api:go_default_library", |         "//pkg/api:go_default_library", | ||||||
|         "//pkg/client/unversioned/clientcmd:go_default_library", |  | ||||||
|         "//pkg/kubectl:go_default_library", |         "//pkg/kubectl:go_default_library", | ||||||
|         "//pkg/kubectl/cmd:go_default_library", |         "//pkg/kubectl/cmd:go_default_library", | ||||||
|         "//pkg/kubectl/cmd/templates: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/api/errors", | ||||||
|         "//vendor:k8s.io/apimachinery/pkg/runtime", |         "//vendor:k8s.io/apimachinery/pkg/runtime", | ||||||
|         "//vendor:k8s.io/apimachinery/pkg/runtime/schema", |         "//vendor:k8s.io/apimachinery/pkg/runtime/schema", | ||||||
|  |         "//vendor:k8s.io/client-go/tools/clientcmd", | ||||||
|         "//vendor:k8s.io/client-go/tools/clientcmd/api", |         "//vendor:k8s.io/client-go/tools/clientcmd/api", | ||||||
|     ], |     ], | ||||||
| ) | ) | ||||||
| @@ -55,12 +55,12 @@ go_test( | |||||||
|         "//pkg/api/v1:go_default_library", |         "//pkg/api/v1:go_default_library", | ||||||
|         "//pkg/client/restclient/fake:go_default_library", |         "//pkg/client/restclient/fake:go_default_library", | ||||||
|         "//pkg/client/typed/dynamic: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/testing:go_default_library", | ||||||
|         "//pkg/kubectl/cmd/util:go_default_library", |         "//pkg/kubectl/cmd/util:go_default_library", | ||||||
|         "//vendor:k8s.io/apimachinery/pkg/api/errors", |         "//vendor:k8s.io/apimachinery/pkg/api/errors", | ||||||
|         "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", |         "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", | ||||||
|         "//vendor:k8s.io/apimachinery/pkg/util/diff", |         "//vendor:k8s.io/apimachinery/pkg/util/diff", | ||||||
|  |         "//vendor:k8s.io/client-go/tools/clientcmd", | ||||||
|         "//vendor:k8s.io/client-go/tools/clientcmd/api", |         "//vendor:k8s.io/client-go/tools/clientcmd/api", | ||||||
|     ], |     ], | ||||||
| ) | ) | ||||||
|   | |||||||
| @@ -19,7 +19,6 @@ go_library( | |||||||
|         "//pkg/api/resource:go_default_library", |         "//pkg/api/resource:go_default_library", | ||||||
|         "//pkg/apis/extensions:go_default_library", |         "//pkg/apis/extensions:go_default_library", | ||||||
|         "//pkg/client/clientset_generated/internalclientset: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/templates:go_default_library", | ||||||
|         "//pkg/kubectl/cmd/util:go_default_library", |         "//pkg/kubectl/cmd/util:go_default_library", | ||||||
|         "//pkg/util/intstr: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/apimachinery/pkg/util/wait", | ||||||
|         "//vendor:k8s.io/client-go/pkg/util/cert", |         "//vendor:k8s.io/client-go/pkg/util/cert", | ||||||
|         "//vendor:k8s.io/client-go/pkg/util/cert/triple", |         "//vendor:k8s.io/client-go/pkg/util/cert/triple", | ||||||
|  |         "//vendor:k8s.io/client-go/tools/clientcmd", | ||||||
|         "//vendor:k8s.io/client-go/tools/clientcmd/api", |         "//vendor:k8s.io/client-go/tools/clientcmd/api", | ||||||
|     ], |     ], | ||||||
| ) | ) | ||||||
| @@ -48,13 +48,13 @@ go_test( | |||||||
|         "//pkg/apis/extensions/v1beta1:go_default_library", |         "//pkg/apis/extensions/v1beta1:go_default_library", | ||||||
|         "//pkg/client/restclient/fake:go_default_library", |         "//pkg/client/restclient/fake:go_default_library", | ||||||
|         "//pkg/client/typed/dynamic: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/testing:go_default_library", | ||||||
|         "//pkg/kubectl/cmd/util:go_default_library", |         "//pkg/kubectl/cmd/util:go_default_library", | ||||||
|         "//pkg/util/intstr:go_default_library", |         "//pkg/util/intstr:go_default_library", | ||||||
|         "//vendor:k8s.io/apimachinery/pkg/api/errors", |         "//vendor:k8s.io/apimachinery/pkg/api/errors", | ||||||
|         "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", |         "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", | ||||||
|         "//vendor:k8s.io/apimachinery/pkg/util/diff", |         "//vendor:k8s.io/apimachinery/pkg/util/diff", | ||||||
|  |         "//vendor:k8s.io/client-go/tools/clientcmd", | ||||||
|     ], |     ], | ||||||
| ) | ) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -40,6 +40,7 @@ import ( | |||||||
| 	"k8s.io/apimachinery/pkg/util/wait" | 	"k8s.io/apimachinery/pkg/util/wait" | ||||||
| 	certutil "k8s.io/client-go/pkg/util/cert" | 	certutil "k8s.io/client-go/pkg/util/cert" | ||||||
| 	triple "k8s.io/client-go/pkg/util/cert/triple" | 	triple "k8s.io/client-go/pkg/util/cert/triple" | ||||||
|  | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | ||||||
| 	kubeadmkubeconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig" | 	kubeadmkubeconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig" | ||||||
| 	"k8s.io/kubernetes/federation/pkg/kubefed/util" | 	"k8s.io/kubernetes/federation/pkg/kubefed/util" | ||||||
| @@ -47,7 +48,6 @@ import ( | |||||||
| 	"k8s.io/kubernetes/pkg/api/resource" | 	"k8s.io/kubernetes/pkg/api/resource" | ||||||
| 	"k8s.io/kubernetes/pkg/apis/extensions" | 	"k8s.io/kubernetes/pkg/apis/extensions" | ||||||
| 	client "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" | 	client "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" | ||||||
| 	"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" |  | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | ||||||
| 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | ||||||
| 	"k8s.io/kubernetes/pkg/util/intstr" | 	"k8s.io/kubernetes/pkg/util/intstr" | ||||||
|   | |||||||
| @@ -33,6 +33,7 @@ import ( | |||||||
| 	"k8s.io/apimachinery/pkg/api/errors" | 	"k8s.io/apimachinery/pkg/api/errors" | ||||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||||
| 	"k8s.io/apimachinery/pkg/util/diff" | 	"k8s.io/apimachinery/pkg/util/diff" | ||||||
|  | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	kubefedtesting "k8s.io/kubernetes/federation/pkg/kubefed/testing" | 	kubefedtesting "k8s.io/kubernetes/federation/pkg/kubefed/testing" | ||||||
| 	"k8s.io/kubernetes/federation/pkg/kubefed/util" | 	"k8s.io/kubernetes/federation/pkg/kubefed/util" | ||||||
| 	"k8s.io/kubernetes/pkg/api" | 	"k8s.io/kubernetes/pkg/api" | ||||||
| @@ -42,7 +43,6 @@ import ( | |||||||
| 	"k8s.io/kubernetes/pkg/apis/extensions/v1beta1" | 	"k8s.io/kubernetes/pkg/apis/extensions/v1beta1" | ||||||
| 	"k8s.io/kubernetes/pkg/client/restclient/fake" | 	"k8s.io/kubernetes/pkg/client/restclient/fake" | ||||||
| 	"k8s.io/kubernetes/pkg/client/typed/dynamic" | 	"k8s.io/kubernetes/pkg/client/typed/dynamic" | ||||||
| 	"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" |  | ||||||
| 	cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing" | 	cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing" | ||||||
| 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | ||||||
| 	"k8s.io/kubernetes/pkg/util/intstr" | 	"k8s.io/kubernetes/pkg/util/intstr" | ||||||
|   | |||||||
| @@ -25,6 +25,7 @@ import ( | |||||||
|  |  | ||||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||||
| 	"k8s.io/apimachinery/pkg/util/diff" | 	"k8s.io/apimachinery/pkg/util/diff" | ||||||
|  | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | ||||||
| 	federationapi "k8s.io/kubernetes/federation/apis/federation/v1beta1" | 	federationapi "k8s.io/kubernetes/federation/apis/federation/v1beta1" | ||||||
| 	kubefedtesting "k8s.io/kubernetes/federation/pkg/kubefed/testing" | 	kubefedtesting "k8s.io/kubernetes/federation/pkg/kubefed/testing" | ||||||
| @@ -34,7 +35,6 @@ import ( | |||||||
| 	"k8s.io/kubernetes/pkg/api/v1" | 	"k8s.io/kubernetes/pkg/api/v1" | ||||||
| 	"k8s.io/kubernetes/pkg/client/restclient/fake" | 	"k8s.io/kubernetes/pkg/client/restclient/fake" | ||||||
| 	"k8s.io/kubernetes/pkg/client/typed/dynamic" | 	"k8s.io/kubernetes/pkg/client/typed/dynamic" | ||||||
| 	"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" |  | ||||||
| 	cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing" | 	cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing" | ||||||
| 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | ||||||
| ) | ) | ||||||
|   | |||||||
| @@ -19,9 +19,9 @@ package kubefed | |||||||
| import ( | import ( | ||||||
| 	"io" | 	"io" | ||||||
|  |  | ||||||
|  | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	kubefedinit "k8s.io/kubernetes/federation/pkg/kubefed/init" | 	kubefedinit "k8s.io/kubernetes/federation/pkg/kubefed/init" | ||||||
| 	"k8s.io/kubernetes/federation/pkg/kubefed/util" | 	"k8s.io/kubernetes/federation/pkg/kubefed/util" | ||||||
| 	"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" |  | ||||||
| 	kubectl "k8s.io/kubernetes/pkg/kubectl/cmd" | 	kubectl "k8s.io/kubernetes/pkg/kubectl/cmd" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | ||||||
| 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | ||||||
|   | |||||||
| @@ -15,10 +15,10 @@ go_library( | |||||||
|         "//federation/client/clientset_generated/federation_clientset:go_default_library", |         "//federation/client/clientset_generated/federation_clientset:go_default_library", | ||||||
|         "//federation/pkg/kubefed/util:go_default_library", |         "//federation/pkg/kubefed/util:go_default_library", | ||||||
|         "//pkg/api:go_default_library", |         "//pkg/api:go_default_library", | ||||||
|         "//pkg/client/unversioned/clientcmd:go_default_library", |  | ||||||
|         "//pkg/kubectl/cmd/util:go_default_library", |         "//pkg/kubectl/cmd/util:go_default_library", | ||||||
|         "//vendor:k8s.io/apimachinery/pkg/runtime", |         "//vendor:k8s.io/apimachinery/pkg/runtime", | ||||||
|         "//vendor:k8s.io/client-go/rest", |         "//vendor:k8s.io/client-go/rest", | ||||||
|  |         "//vendor:k8s.io/client-go/tools/clientcmd", | ||||||
|         "//vendor:k8s.io/client-go/tools/clientcmd/api", |         "//vendor:k8s.io/client-go/tools/clientcmd/api", | ||||||
|     ], |     ], | ||||||
| ) | ) | ||||||
|   | |||||||
| @@ -25,11 +25,11 @@ import ( | |||||||
|  |  | ||||||
| 	"k8s.io/apimachinery/pkg/runtime" | 	"k8s.io/apimachinery/pkg/runtime" | ||||||
| 	restclient "k8s.io/client-go/rest" | 	restclient "k8s.io/client-go/rest" | ||||||
|  | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | ||||||
| 	fedclient "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset" | 	fedclient "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset" | ||||||
| 	"k8s.io/kubernetes/federation/pkg/kubefed/util" | 	"k8s.io/kubernetes/federation/pkg/kubefed/util" | ||||||
| 	"k8s.io/kubernetes/pkg/api" | 	"k8s.io/kubernetes/pkg/api" | ||||||
| 	"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" |  | ||||||
| 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | ||||||
| ) | ) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -15,11 +15,11 @@ go_library( | |||||||
|         "//federation/client/clientset_generated/federation_clientset:go_default_library", |         "//federation/client/clientset_generated/federation_clientset:go_default_library", | ||||||
|         "//pkg/api:go_default_library", |         "//pkg/api:go_default_library", | ||||||
|         "//pkg/client/clientset_generated/internalclientset: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:go_default_library", | ||||||
|         "//pkg/kubectl/cmd/util:go_default_library", |         "//pkg/kubectl/cmd/util:go_default_library", | ||||||
|         "//vendor:github.com/spf13/cobra", |         "//vendor:github.com/spf13/cobra", | ||||||
|         "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", |         "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", | ||||||
|  |         "//vendor:k8s.io/client-go/tools/clientcmd", | ||||||
|         "//vendor:k8s.io/client-go/tools/clientcmd/api", |         "//vendor:k8s.io/client-go/tools/clientcmd/api", | ||||||
|     ], |     ], | ||||||
| ) | ) | ||||||
|   | |||||||
| @@ -18,11 +18,11 @@ package util | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||||
|  | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | ||||||
| 	fedclient "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset" | 	fedclient "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset" | ||||||
| 	"k8s.io/kubernetes/pkg/api" | 	"k8s.io/kubernetes/pkg/api" | ||||||
| 	client "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" | 	client "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" | ||||||
| 	"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" |  | ||||||
| 	kubectlcmd "k8s.io/kubernetes/pkg/kubectl/cmd" | 	kubectlcmd "k8s.io/kubernetes/pkg/kubectl/cmd" | ||||||
| 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | ||||||
|  |  | ||||||
|   | |||||||
| @@ -60,8 +60,6 @@ filegroup( | |||||||
|     name = "all-srcs", |     name = "all-srcs", | ||||||
|     srcs = [ |     srcs = [ | ||||||
|         ":package-srcs", |         ":package-srcs", | ||||||
|         "//pkg/client/unversioned/auth:all-srcs", |  | ||||||
|         "//pkg/client/unversioned/clientcmd:all-srcs", |  | ||||||
|         "//pkg/client/unversioned/portforward:all-srcs", |         "//pkg/client/unversioned/portforward:all-srcs", | ||||||
|         "//pkg/client/unversioned/remotecommand:all-srcs", |         "//pkg/client/unversioned/remotecommand:all-srcs", | ||||||
|         "//pkg/client/unversioned/testclient/simple:all-srcs", |         "//pkg/client/unversioned/testclient/simple:all-srcs", | ||||||
|   | |||||||
| @@ -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"], |  | ||||||
| ) |  | ||||||
| @@ -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 |  | ||||||
| } |  | ||||||
| @@ -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) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| @@ -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"], |  | ||||||
| ) |  | ||||||
| @@ -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{} |  | ||||||
| } |  | ||||||
| @@ -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() |  | ||||||
| } |  | ||||||
| @@ -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) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| @@ -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 |  | ||||||
| } |  | ||||||
| @@ -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" |  | ||||||
| @@ -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)") |  | ||||||
| } |  | ||||||
| @@ -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 |  | ||||||
| } |  | ||||||
| @@ -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 |  | ||||||
| } |  | ||||||
| @@ -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 |  | ||||||
| } |  | ||||||
| @@ -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) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| @@ -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) |  | ||||||
| } |  | ||||||
| @@ -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 |  | ||||||
| } |  | ||||||
| @@ -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)) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| @@ -74,7 +74,6 @@ go_library( | |||||||
|         "//pkg/client/clientset_generated/internalclientset/typed/core/internalversion:go_default_library", |         "//pkg/client/clientset_generated/internalclientset/typed/core/internalversion:go_default_library", | ||||||
|         "//pkg/client/typed/discovery:go_default_library", |         "//pkg/client/typed/discovery:go_default_library", | ||||||
|         "//pkg/client/unversioned: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/portforward:go_default_library", | ||||||
|         "//pkg/client/unversioned/remotecommand:go_default_library", |         "//pkg/client/unversioned/remotecommand:go_default_library", | ||||||
|         "//pkg/kubectl: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/util/yaml", | ||||||
|         "//vendor:k8s.io/apimachinery/pkg/watch", |         "//vendor:k8s.io/apimachinery/pkg/watch", | ||||||
|         "//vendor:k8s.io/client-go/rest", |         "//vendor:k8s.io/client-go/rest", | ||||||
|  |         "//vendor:k8s.io/client-go/tools/clientcmd", | ||||||
|     ], |     ], | ||||||
| ) | ) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -20,7 +20,7 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"io" | 	"io" | ||||||
|  |  | ||||||
| 	"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	cmdconfig "k8s.io/kubernetes/pkg/kubectl/cmd/config" | 	cmdconfig "k8s.io/kubernetes/pkg/kubectl/cmd/config" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/cmd/rollout" | 	"k8s.io/kubernetes/pkg/kubectl/cmd/rollout" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/cmd/set" | 	"k8s.io/kubernetes/pkg/kubectl/cmd/set" | ||||||
|   | |||||||
| @@ -28,7 +28,6 @@ go_library( | |||||||
|     ], |     ], | ||||||
|     tags = ["automanaged"], |     tags = ["automanaged"], | ||||||
|     deps = [ |     deps = [ | ||||||
|         "//pkg/client/unversioned/clientcmd:go_default_library", |  | ||||||
|         "//pkg/kubectl:go_default_library", |         "//pkg/kubectl:go_default_library", | ||||||
|         "//pkg/kubectl/cmd/templates:go_default_library", |         "//pkg/kubectl/cmd/templates:go_default_library", | ||||||
|         "//pkg/kubectl/cmd/util:go_default_library", |         "//pkg/kubectl/cmd/util:go_default_library", | ||||||
| @@ -36,6 +35,7 @@ go_library( | |||||||
|         "//vendor:github.com/spf13/cobra", |         "//vendor:github.com/spf13/cobra", | ||||||
|         "//vendor:k8s.io/apimachinery/pkg/util/errors", |         "//vendor:k8s.io/apimachinery/pkg/util/errors", | ||||||
|         "//vendor:k8s.io/apimachinery/pkg/util/sets", |         "//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", | ||||||
|         "//vendor:k8s.io/client-go/tools/clientcmd/api/latest", |         "//vendor:k8s.io/client-go/tools/clientcmd/api/latest", | ||||||
|     ], |     ], | ||||||
| @@ -57,10 +57,10 @@ go_test( | |||||||
|     tags = ["automanaged"], |     tags = ["automanaged"], | ||||||
|     deps = [ |     deps = [ | ||||||
|         "//pkg/api:go_default_library", |         "//pkg/api:go_default_library", | ||||||
|         "//pkg/client/unversioned/clientcmd:go_default_library", |  | ||||||
|         "//pkg/kubectl/cmd/util:go_default_library", |         "//pkg/kubectl/cmd/util:go_default_library", | ||||||
|         "//pkg/util/flag:go_default_library", |         "//pkg/util/flag:go_default_library", | ||||||
|         "//vendor:k8s.io/apimachinery/pkg/util/diff", |         "//vendor:k8s.io/apimachinery/pkg/util/diff", | ||||||
|  |         "//vendor:k8s.io/client-go/tools/clientcmd", | ||||||
|         "//vendor:k8s.io/client-go/tools/clientcmd/api", |         "//vendor:k8s.io/client-go/tools/clientcmd/api", | ||||||
|     ], |     ], | ||||||
| ) | ) | ||||||
|   | |||||||
| @@ -23,7 +23,7 @@ import ( | |||||||
|  |  | ||||||
| 	"github.com/spf13/cobra" | 	"github.com/spf13/cobra" | ||||||
|  |  | ||||||
| 	"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | ||||||
| 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | ||||||
| ) | ) | ||||||
|   | |||||||
| @@ -27,9 +27,9 @@ import ( | |||||||
| 	"testing" | 	"testing" | ||||||
|  |  | ||||||
| 	"k8s.io/apimachinery/pkg/util/diff" | 	"k8s.io/apimachinery/pkg/util/diff" | ||||||
|  | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | ||||||
| 	"k8s.io/kubernetes/pkg/api" | 	"k8s.io/kubernetes/pkg/api" | ||||||
| 	"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" |  | ||||||
| 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | ||||||
| ) | ) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -26,8 +26,8 @@ import ( | |||||||
|  |  | ||||||
| 	"github.com/spf13/cobra" | 	"github.com/spf13/cobra" | ||||||
|  |  | ||||||
|  | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | ||||||
| 	"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" |  | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | ||||||
| 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | ||||||
| 	"k8s.io/kubernetes/pkg/util/flag" | 	"k8s.io/kubernetes/pkg/util/flag" | ||||||
|   | |||||||
| @@ -25,8 +25,8 @@ import ( | |||||||
|  |  | ||||||
| 	"github.com/spf13/cobra" | 	"github.com/spf13/cobra" | ||||||
|  |  | ||||||
|  | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | ||||||
| 	"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" |  | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | ||||||
| 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | ||||||
| 	"k8s.io/kubernetes/pkg/util/flag" | 	"k8s.io/kubernetes/pkg/util/flag" | ||||||
|   | |||||||
| @@ -23,8 +23,8 @@ import ( | |||||||
|  |  | ||||||
| 	"github.com/spf13/cobra" | 	"github.com/spf13/cobra" | ||||||
|  |  | ||||||
|  | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | ||||||
| 	"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" |  | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | ||||||
| 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | ||||||
| 	"k8s.io/kubernetes/pkg/util/flag" | 	"k8s.io/kubernetes/pkg/util/flag" | ||||||
|   | |||||||
| @@ -22,7 +22,7 @@ import ( | |||||||
|  |  | ||||||
| 	"github.com/spf13/cobra" | 	"github.com/spf13/cobra" | ||||||
|  |  | ||||||
| 	"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | ||||||
| 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | ||||||
| ) | ) | ||||||
|   | |||||||
| @@ -23,8 +23,8 @@ import ( | |||||||
| 	"strings" | 	"strings" | ||||||
| 	"testing" | 	"testing" | ||||||
|  |  | ||||||
|  | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | ||||||
| 	"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
| type currentContextTest struct { | type currentContextTest struct { | ||||||
|   | |||||||
| @@ -21,7 +21,7 @@ import ( | |||||||
| 	"io" | 	"io" | ||||||
|  |  | ||||||
| 	"github.com/spf13/cobra" | 	"github.com/spf13/cobra" | ||||||
| 	"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | ||||||
| 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | ||||||
| ) | ) | ||||||
|   | |||||||
| @@ -24,8 +24,8 @@ import ( | |||||||
| 	"reflect" | 	"reflect" | ||||||
| 	"testing" | 	"testing" | ||||||
|  |  | ||||||
|  | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | ||||||
| 	"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
| type deleteClusterTest struct { | type deleteClusterTest struct { | ||||||
|   | |||||||
| @@ -21,7 +21,7 @@ import ( | |||||||
| 	"io" | 	"io" | ||||||
|  |  | ||||||
| 	"github.com/spf13/cobra" | 	"github.com/spf13/cobra" | ||||||
| 	"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | ||||||
| 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | ||||||
| ) | ) | ||||||
|   | |||||||
| @@ -24,8 +24,8 @@ import ( | |||||||
| 	"reflect" | 	"reflect" | ||||||
| 	"testing" | 	"testing" | ||||||
|  |  | ||||||
|  | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | ||||||
| 	"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
| type deleteContextTest struct { | type deleteContextTest struct { | ||||||
|   | |||||||
| @@ -21,7 +21,7 @@ import ( | |||||||
| 	"io" | 	"io" | ||||||
|  |  | ||||||
| 	"github.com/spf13/cobra" | 	"github.com/spf13/cobra" | ||||||
| 	"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | ||||||
| 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | ||||||
| ) | ) | ||||||
|   | |||||||
| @@ -22,8 +22,8 @@ import ( | |||||||
| 	"os" | 	"os" | ||||||
| 	"testing" | 	"testing" | ||||||
|  |  | ||||||
|  | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | ||||||
| 	"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
| type getClustersTest struct { | type getClustersTest struct { | ||||||
|   | |||||||
| @@ -25,8 +25,8 @@ import ( | |||||||
| 	"github.com/spf13/cobra" | 	"github.com/spf13/cobra" | ||||||
| 	utilerrors "k8s.io/apimachinery/pkg/util/errors" | 	utilerrors "k8s.io/apimachinery/pkg/util/errors" | ||||||
| 	"k8s.io/apimachinery/pkg/util/sets" | 	"k8s.io/apimachinery/pkg/util/sets" | ||||||
|  | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | 	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" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | ||||||
| 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | ||||||
|   | |||||||
| @@ -22,8 +22,8 @@ import ( | |||||||
| 	"os" | 	"os" | ||||||
| 	"testing" | 	"testing" | ||||||
|  |  | ||||||
|  | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | ||||||
| 	"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
| type getContextsTest struct { | type getContextsTest struct { | ||||||
|   | |||||||
| @@ -26,7 +26,7 @@ import ( | |||||||
|  |  | ||||||
| 	"github.com/spf13/cobra" | 	"github.com/spf13/cobra" | ||||||
|  |  | ||||||
| 	"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | ||||||
| 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | ||||||
| 	"k8s.io/kubernetes/pkg/util/flag" | 	"k8s.io/kubernetes/pkg/util/flag" | ||||||
|   | |||||||
| @@ -25,7 +25,7 @@ import ( | |||||||
| 	"github.com/spf13/cobra" | 	"github.com/spf13/cobra" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | 	"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" | 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | ||||||
| ) | ) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -23,8 +23,8 @@ import ( | |||||||
|  |  | ||||||
| 	"github.com/spf13/cobra" | 	"github.com/spf13/cobra" | ||||||
|  |  | ||||||
|  | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | ||||||
| 	"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" |  | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | ||||||
| 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | ||||||
| ) | ) | ||||||
|   | |||||||
| @@ -23,9 +23,9 @@ import ( | |||||||
|  |  | ||||||
| 	"github.com/spf13/cobra" | 	"github.com/spf13/cobra" | ||||||
|  |  | ||||||
|  | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | ||||||
| 	"k8s.io/client-go/tools/clientcmd/api/latest" | 	"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" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | 	"k8s.io/kubernetes/pkg/kubectl/cmd/templates" | ||||||
| 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" | ||||||
|   | |||||||
| @@ -37,14 +37,12 @@ go_library( | |||||||
|         "//pkg/client/typed/discovery:go_default_library", |         "//pkg/client/typed/discovery:go_default_library", | ||||||
|         "//pkg/client/typed/dynamic:go_default_library", |         "//pkg/client/typed/dynamic:go_default_library", | ||||||
|         "//pkg/client/unversioned:go_default_library", |         "//pkg/client/unversioned:go_default_library", | ||||||
|         "//pkg/client/unversioned/clientcmd:go_default_library", |  | ||||||
|         "//pkg/controller:go_default_library", |         "//pkg/controller:go_default_library", | ||||||
|         "//pkg/kubectl:go_default_library", |         "//pkg/kubectl:go_default_library", | ||||||
|         "//pkg/kubectl/resource:go_default_library", |         "//pkg/kubectl/resource:go_default_library", | ||||||
|         "//pkg/registry/extensions/thirdpartyresourcedata:go_default_library", |         "//pkg/registry/extensions/thirdpartyresourcedata:go_default_library", | ||||||
|         "//pkg/util/exec:go_default_library", |         "//pkg/util/exec:go_default_library", | ||||||
|         "//pkg/util/flag:go_default_library", |         "//pkg/util/flag:go_default_library", | ||||||
|         "//pkg/util/homedir:go_default_library", |  | ||||||
|         "//pkg/util/strategicpatch:go_default_library", |         "//pkg/util/strategicpatch:go_default_library", | ||||||
|         "//vendor:github.com/emicklei/go-restful/swagger", |         "//vendor:github.com/emicklei/go-restful/swagger", | ||||||
|         "//vendor:github.com/evanphx/json-patch", |         "//vendor:github.com/evanphx/json-patch", | ||||||
| @@ -63,7 +61,9 @@ go_library( | |||||||
|         "//vendor:k8s.io/apimachinery/pkg/util/sets", |         "//vendor:k8s.io/apimachinery/pkg/util/sets", | ||||||
|         "//vendor:k8s.io/apimachinery/pkg/version", |         "//vendor:k8s.io/apimachinery/pkg/version", | ||||||
|         "//vendor:k8s.io/apimachinery/pkg/watch", |         "//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/rest", | ||||||
|  |         "//vendor:k8s.io/client-go/tools/clientcmd", | ||||||
|     ], |     ], | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @@ -91,7 +91,6 @@ go_test( | |||||||
|         "//pkg/client/restclient/fake:go_default_library", |         "//pkg/client/restclient/fake:go_default_library", | ||||||
|         "//pkg/client/testing/core:go_default_library", |         "//pkg/client/testing/core:go_default_library", | ||||||
|         "//pkg/client/typed/discovery:go_default_library", |         "//pkg/client/typed/discovery:go_default_library", | ||||||
|         "//pkg/client/unversioned/clientcmd:go_default_library", |  | ||||||
|         "//pkg/controller:go_default_library", |         "//pkg/controller:go_default_library", | ||||||
|         "//pkg/kubectl:go_default_library", |         "//pkg/kubectl:go_default_library", | ||||||
|         "//pkg/kubectl/resource: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/version", | ||||||
|         "//vendor:k8s.io/apimachinery/pkg/watch", |         "//vendor:k8s.io/apimachinery/pkg/watch", | ||||||
|         "//vendor:k8s.io/client-go/rest", |         "//vendor:k8s.io/client-go/rest", | ||||||
|  |         "//vendor:k8s.io/client-go/tools/clientcmd", | ||||||
|         "//vendor:k8s.io/client-go/tools/clientcmd/api", |         "//vendor:k8s.io/client-go/tools/clientcmd/api", | ||||||
|     ], |     ], | ||||||
| ) | ) | ||||||
|   | |||||||
| @@ -21,12 +21,12 @@ import ( | |||||||
|  |  | ||||||
| 	"k8s.io/apimachinery/pkg/runtime/schema" | 	"k8s.io/apimachinery/pkg/runtime/schema" | ||||||
| 	restclient "k8s.io/client-go/rest" | 	restclient "k8s.io/client-go/rest" | ||||||
|  | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	fedclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_internalclientset" | 	fedclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_internalclientset" | ||||||
| 	"k8s.io/kubernetes/pkg/api" | 	"k8s.io/kubernetes/pkg/api" | ||||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" | 	"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" | ||||||
| 	"k8s.io/kubernetes/pkg/client/typed/discovery" | 	"k8s.io/kubernetes/pkg/client/typed/discovery" | ||||||
| 	oldclient "k8s.io/kubernetes/pkg/client/unversioned" | 	oldclient "k8s.io/kubernetes/pkg/client/unversioned" | ||||||
| 	"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func NewClientCache(loader clientcmd.ClientConfig, discoveryClientFactory DiscoveryClientFactory) *ClientCache { | func NewClientCache(loader clientcmd.ClientConfig, discoveryClientFactory DiscoveryClientFactory) *ClientCache { | ||||||
|   | |||||||
| @@ -40,6 +40,7 @@ import ( | |||||||
| 	"k8s.io/apimachinery/pkg/runtime/serializer/json" | 	"k8s.io/apimachinery/pkg/runtime/serializer/json" | ||||||
| 	"k8s.io/apimachinery/pkg/watch" | 	"k8s.io/apimachinery/pkg/watch" | ||||||
| 	restclient "k8s.io/client-go/rest" | 	restclient "k8s.io/client-go/rest" | ||||||
|  | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	fedclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_internalclientset" | 	fedclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_internalclientset" | ||||||
| 	"k8s.io/kubernetes/pkg/api" | 	"k8s.io/kubernetes/pkg/api" | ||||||
| 	"k8s.io/kubernetes/pkg/api/v1" | 	"k8s.io/kubernetes/pkg/api/v1" | ||||||
| @@ -47,7 +48,6 @@ import ( | |||||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" | 	"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" | ||||||
| 	coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion" | 	coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion" | ||||||
| 	"k8s.io/kubernetes/pkg/client/typed/discovery" | 	"k8s.io/kubernetes/pkg/client/typed/discovery" | ||||||
| 	"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" |  | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl" | 	"k8s.io/kubernetes/pkg/kubectl" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/resource" | 	"k8s.io/kubernetes/pkg/kubectl/resource" | ||||||
| 	"k8s.io/kubernetes/pkg/registry/extensions/thirdpartyresourcedata" | 	"k8s.io/kubernetes/pkg/registry/extensions/thirdpartyresourcedata" | ||||||
|   | |||||||
| @@ -35,7 +35,9 @@ import ( | |||||||
| 	"k8s.io/apimachinery/pkg/api/meta" | 	"k8s.io/apimachinery/pkg/api/meta" | ||||||
| 	"k8s.io/apimachinery/pkg/runtime" | 	"k8s.io/apimachinery/pkg/runtime" | ||||||
| 	"k8s.io/apimachinery/pkg/runtime/schema" | 	"k8s.io/apimachinery/pkg/runtime/schema" | ||||||
|  | 	"k8s.io/client-go/pkg/util/homedir" | ||||||
| 	restclient "k8s.io/client-go/rest" | 	restclient "k8s.io/client-go/rest" | ||||||
|  | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	fedclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_internalclientset" | 	fedclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_internalclientset" | ||||||
| 	"k8s.io/kubernetes/pkg/api" | 	"k8s.io/kubernetes/pkg/api" | ||||||
| 	"k8s.io/kubernetes/pkg/api/service" | 	"k8s.io/kubernetes/pkg/api/service" | ||||||
| @@ -44,12 +46,10 @@ import ( | |||||||
| 	"k8s.io/kubernetes/pkg/apis/extensions" | 	"k8s.io/kubernetes/pkg/apis/extensions" | ||||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" | 	"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" | ||||||
| 	"k8s.io/kubernetes/pkg/client/typed/discovery" | 	"k8s.io/kubernetes/pkg/client/typed/discovery" | ||||||
| 	"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" |  | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl" | 	"k8s.io/kubernetes/pkg/kubectl" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/resource" | 	"k8s.io/kubernetes/pkg/kubectl/resource" | ||||||
| 	"k8s.io/kubernetes/pkg/registry/extensions/thirdpartyresourcedata" | 	"k8s.io/kubernetes/pkg/registry/extensions/thirdpartyresourcedata" | ||||||
| 	utilflag "k8s.io/kubernetes/pkg/util/flag" | 	utilflag "k8s.io/kubernetes/pkg/util/flag" | ||||||
| 	"k8s.io/kubernetes/pkg/util/homedir" |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
| type ring0Factory struct { | type ring0Factory struct { | ||||||
|   | |||||||
| @@ -37,6 +37,7 @@ import ( | |||||||
| 	"k8s.io/apimachinery/pkg/runtime" | 	"k8s.io/apimachinery/pkg/runtime" | ||||||
| 	"k8s.io/apimachinery/pkg/runtime/schema" | 	"k8s.io/apimachinery/pkg/runtime/schema" | ||||||
| 	"k8s.io/apimachinery/pkg/watch" | 	"k8s.io/apimachinery/pkg/watch" | ||||||
|  | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | ||||||
| 	"k8s.io/kubernetes/pkg/api" | 	"k8s.io/kubernetes/pkg/api" | ||||||
| 	"k8s.io/kubernetes/pkg/api/testapi" | 	"k8s.io/kubernetes/pkg/api/testapi" | ||||||
| @@ -46,7 +47,6 @@ import ( | |||||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake" | 	"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake" | ||||||
| 	manualfake "k8s.io/kubernetes/pkg/client/restclient/fake" | 	manualfake "k8s.io/kubernetes/pkg/client/restclient/fake" | ||||||
| 	testcore "k8s.io/kubernetes/pkg/client/testing/core" | 	testcore "k8s.io/kubernetes/pkg/client/testing/core" | ||||||
| 	"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" |  | ||||||
| 	"k8s.io/kubernetes/pkg/controller" | 	"k8s.io/kubernetes/pkg/controller" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl" | 	"k8s.io/kubernetes/pkg/kubectl" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/resource" | 	"k8s.io/kubernetes/pkg/kubectl/resource" | ||||||
|   | |||||||
| @@ -40,9 +40,9 @@ import ( | |||||||
| 	"k8s.io/apimachinery/pkg/runtime/schema" | 	"k8s.io/apimachinery/pkg/runtime/schema" | ||||||
| 	utilerrors "k8s.io/apimachinery/pkg/util/errors" | 	utilerrors "k8s.io/apimachinery/pkg/util/errors" | ||||||
| 	"k8s.io/apimachinery/pkg/util/sets" | 	"k8s.io/apimachinery/pkg/util/sets" | ||||||
|  | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	"k8s.io/kubernetes/pkg/api" | 	"k8s.io/kubernetes/pkg/api" | ||||||
| 	"k8s.io/kubernetes/pkg/apis/extensions" | 	"k8s.io/kubernetes/pkg/apis/extensions" | ||||||
| 	"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" |  | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl" | 	"k8s.io/kubernetes/pkg/kubectl" | ||||||
| 	"k8s.io/kubernetes/pkg/kubectl/resource" | 	"k8s.io/kubernetes/pkg/kubectl/resource" | ||||||
| 	utilexec "k8s.io/kubernetes/pkg/util/exec" | 	utilexec "k8s.io/kubernetes/pkg/util/exec" | ||||||
|   | |||||||
| @@ -64,7 +64,6 @@ filegroup( | |||||||
|         "//pkg/util/framer:all-srcs", |         "//pkg/util/framer:all-srcs", | ||||||
|         "//pkg/util/goroutinemap:all-srcs", |         "//pkg/util/goroutinemap:all-srcs", | ||||||
|         "//pkg/util/hash:all-srcs", |         "//pkg/util/hash:all-srcs", | ||||||
|         "//pkg/util/homedir:all-srcs", |  | ||||||
|         "//pkg/util/httpstream:all-srcs", |         "//pkg/util/httpstream:all-srcs", | ||||||
|         "//pkg/util/i18n:all-srcs", |         "//pkg/util/i18n:all-srcs", | ||||||
|         "//pkg/util/initsystem:all-srcs", |         "//pkg/util/initsystem:all-srcs", | ||||||
|   | |||||||
| @@ -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"], |  | ||||||
| ) |  | ||||||
| @@ -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") |  | ||||||
| } |  | ||||||
| @@ -18,7 +18,6 @@ go_library( | |||||||
|         "//pkg/client/leaderelection:go_default_library", |         "//pkg/client/leaderelection:go_default_library", | ||||||
|         "//pkg/client/leaderelection/resourcelock:go_default_library", |         "//pkg/client/leaderelection/resourcelock:go_default_library", | ||||||
|         "//pkg/client/record:go_default_library", |         "//pkg/client/record:go_default_library", | ||||||
|         "//pkg/client/unversioned/clientcmd:go_default_library", |  | ||||||
|         "//pkg/util/configz:go_default_library", |         "//pkg/util/configz:go_default_library", | ||||||
|         "//plugin/cmd/kube-scheduler/app/options:go_default_library", |         "//plugin/cmd/kube-scheduler/app/options:go_default_library", | ||||||
|         "//plugin/pkg/scheduler:go_default_library", |         "//plugin/pkg/scheduler:go_default_library", | ||||||
| @@ -34,6 +33,7 @@ go_library( | |||||||
|         "//vendor:k8s.io/apimachinery/pkg/runtime", |         "//vendor:k8s.io/apimachinery/pkg/runtime", | ||||||
|         "//vendor:k8s.io/apiserver/pkg/server/healthz", |         "//vendor:k8s.io/apiserver/pkg/server/healthz", | ||||||
|         "//vendor:k8s.io/client-go/rest", |         "//vendor:k8s.io/client-go/rest", | ||||||
|  |         "//vendor:k8s.io/client-go/tools/clientcmd", | ||||||
|     ], |     ], | ||||||
| ) | ) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -31,13 +31,13 @@ import ( | |||||||
| 	"k8s.io/apimachinery/pkg/runtime" | 	"k8s.io/apimachinery/pkg/runtime" | ||||||
| 	"k8s.io/apiserver/pkg/server/healthz" | 	"k8s.io/apiserver/pkg/server/healthz" | ||||||
| 	restclient "k8s.io/client-go/rest" | 	restclient "k8s.io/client-go/rest" | ||||||
|  | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	"k8s.io/kubernetes/pkg/api/v1" | 	"k8s.io/kubernetes/pkg/api/v1" | ||||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||||
| 	v1core "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/core/v1" | 	v1core "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/core/v1" | ||||||
| 	"k8s.io/kubernetes/pkg/client/leaderelection" | 	"k8s.io/kubernetes/pkg/client/leaderelection" | ||||||
| 	"k8s.io/kubernetes/pkg/client/leaderelection/resourcelock" | 	"k8s.io/kubernetes/pkg/client/leaderelection/resourcelock" | ||||||
| 	"k8s.io/kubernetes/pkg/client/record" | 	"k8s.io/kubernetes/pkg/client/record" | ||||||
| 	"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" |  | ||||||
| 	"k8s.io/kubernetes/pkg/util/configz" | 	"k8s.io/kubernetes/pkg/util/configz" | ||||||
| 	"k8s.io/kubernetes/plugin/cmd/kube-scheduler/app/options" | 	"k8s.io/kubernetes/plugin/cmd/kube-scheduler/app/options" | ||||||
| 	"k8s.io/kubernetes/plugin/pkg/scheduler" | 	"k8s.io/kubernetes/plugin/pkg/scheduler" | ||||||
|   | |||||||
| @@ -21,7 +21,6 @@ go_library( | |||||||
|     deps = [ |     deps = [ | ||||||
|         "//pkg/api:go_default_library", |         "//pkg/api:go_default_library", | ||||||
|         "//pkg/api/resource:go_default_library", |         "//pkg/api/resource:go_default_library", | ||||||
|         "//pkg/client/unversioned/clientcmd:go_default_library", |  | ||||||
|         "//vendor:cloud.google.com/go/compute/metadata", |         "//vendor:cloud.google.com/go/compute/metadata", | ||||||
|         "//vendor:github.com/golang/glog", |         "//vendor:github.com/golang/glog", | ||||||
|         "//vendor:github.com/hawkular/hawkular-client-go/metrics", |         "//vendor:github.com/hawkular/hawkular-client-go/metrics", | ||||||
| @@ -32,6 +31,7 @@ go_library( | |||||||
|         "//vendor:k8s.io/apimachinery/pkg/api/errors", |         "//vendor:k8s.io/apimachinery/pkg/api/errors", | ||||||
|         "//vendor:k8s.io/apiserver/pkg/admission", |         "//vendor:k8s.io/apiserver/pkg/admission", | ||||||
|         "//vendor:k8s.io/client-go/rest", |         "//vendor:k8s.io/client-go/rest", | ||||||
|  |         "//vendor:k8s.io/client-go/tools/clientcmd", | ||||||
|     ], |     ], | ||||||
| ) | ) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -32,7 +32,7 @@ import ( | |||||||
| 	"k8s.io/kubernetes/pkg/api" | 	"k8s.io/kubernetes/pkg/api" | ||||||
|  |  | ||||||
| 	restclient "k8s.io/client-go/rest" | 	restclient "k8s.io/client-go/rest" | ||||||
| 	"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| type hawkularSource struct { | type hawkularSource struct { | ||||||
|   | |||||||
| @@ -52,7 +52,6 @@ go_library( | |||||||
|         "//pkg/client/conditions:go_default_library", |         "//pkg/client/conditions:go_default_library", | ||||||
|         "//pkg/client/typed/discovery:go_default_library", |         "//pkg/client/typed/discovery:go_default_library", | ||||||
|         "//pkg/client/typed/dynamic: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/client/unversioned/remotecommand:go_default_library", | ||||||
|         "//pkg/cloudprovider:go_default_library", |         "//pkg/cloudprovider:go_default_library", | ||||||
|         "//pkg/cloudprovider/providers/gce: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/apimachinery/pkg/watch", | ||||||
|         "//vendor:k8s.io/client-go/kubernetes", |         "//vendor:k8s.io/client-go/kubernetes", | ||||||
|         "//vendor:k8s.io/client-go/rest", |         "//vendor:k8s.io/client-go/rest", | ||||||
|  |         "//vendor:k8s.io/client-go/tools/clientcmd", | ||||||
|         "//vendor:k8s.io/client-go/tools/clientcmd/api", |         "//vendor:k8s.io/client-go/tools/clientcmd/api", | ||||||
|     ], |     ], | ||||||
| ) | ) | ||||||
|   | |||||||
| @@ -23,8 +23,8 @@ import ( | |||||||
|  |  | ||||||
| 	"github.com/onsi/ginkgo/config" | 	"github.com/onsi/ginkgo/config" | ||||||
| 	"github.com/spf13/viper" | 	"github.com/spf13/viper" | ||||||
|  | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	"k8s.io/kubernetes/pkg/apis/componentconfig" | 	"k8s.io/kubernetes/pkg/apis/componentconfig" | ||||||
| 	"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" |  | ||||||
| 	"k8s.io/kubernetes/pkg/cloudprovider" | 	"k8s.io/kubernetes/pkg/cloudprovider" | ||||||
| ) | ) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -63,6 +63,7 @@ import ( | |||||||
| 	"k8s.io/apimachinery/pkg/util/wait" | 	"k8s.io/apimachinery/pkg/util/wait" | ||||||
| 	"k8s.io/apimachinery/pkg/watch" | 	"k8s.io/apimachinery/pkg/watch" | ||||||
| 	restclient "k8s.io/client-go/rest" | 	restclient "k8s.io/client-go/rest" | ||||||
|  | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | ||||||
| 	"k8s.io/kubernetes/pkg/api" | 	"k8s.io/kubernetes/pkg/api" | ||||||
| 	"k8s.io/kubernetes/pkg/api/v1" | 	"k8s.io/kubernetes/pkg/api/v1" | ||||||
| @@ -76,7 +77,6 @@ import ( | |||||||
| 	"k8s.io/kubernetes/pkg/client/conditions" | 	"k8s.io/kubernetes/pkg/client/conditions" | ||||||
| 	"k8s.io/kubernetes/pkg/client/typed/discovery" | 	"k8s.io/kubernetes/pkg/client/typed/discovery" | ||||||
| 	"k8s.io/kubernetes/pkg/client/typed/dynamic" | 	"k8s.io/kubernetes/pkg/client/typed/dynamic" | ||||||
| 	"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" |  | ||||||
| 	gcecloud "k8s.io/kubernetes/pkg/cloudprovider/providers/gce" | 	gcecloud "k8s.io/kubernetes/pkg/cloudprovider/providers/gce" | ||||||
| 	"k8s.io/kubernetes/pkg/controller" | 	"k8s.io/kubernetes/pkg/controller" | ||||||
| 	deploymentutil "k8s.io/kubernetes/pkg/controller/deployment/util" | 	deploymentutil "k8s.io/kubernetes/pkg/controller/deployment/util" | ||||||
|   | |||||||
| @@ -32,7 +32,6 @@ go_library( | |||||||
|         "//pkg/api/v1:go_default_library", |         "//pkg/api/v1:go_default_library", | ||||||
|         "//pkg/apis/extensions/v1beta1:go_default_library", |         "//pkg/apis/extensions/v1beta1:go_default_library", | ||||||
|         "//pkg/client/clientset_generated/clientset:go_default_library", |         "//pkg/client/clientset_generated/clientset:go_default_library", | ||||||
|         "//pkg/client/unversioned/clientcmd:go_default_library", |  | ||||||
|         "//pkg/util/intstr:go_default_library", |         "//pkg/util/intstr:go_default_library", | ||||||
|         "//test/e2e/common:go_default_library", |         "//test/e2e/common:go_default_library", | ||||||
|         "//test/e2e/framework: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/apis/meta/v1", | ||||||
|         "//vendor:k8s.io/apimachinery/pkg/util/wait", |         "//vendor:k8s.io/apimachinery/pkg/util/wait", | ||||||
|         "//vendor:k8s.io/client-go/rest", |         "//vendor:k8s.io/client-go/rest", | ||||||
|  |         "//vendor:k8s.io/client-go/tools/clientcmd", | ||||||
|         "//vendor:k8s.io/client-go/tools/clientcmd/api", |         "//vendor:k8s.io/client-go/tools/clientcmd/api", | ||||||
|     ], |     ], | ||||||
| ) | ) | ||||||
|   | |||||||
| @@ -20,9 +20,9 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
|  |  | ||||||
| 	"k8s.io/apimachinery/pkg/api/errors" | 	"k8s.io/apimachinery/pkg/api/errors" | ||||||
|  | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | ||||||
| 	"k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset" | 	"k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset" | ||||||
| 	"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" |  | ||||||
| 	"k8s.io/kubernetes/test/e2e/framework" | 	"k8s.io/kubernetes/test/e2e/framework" | ||||||
| 	fedframework "k8s.io/kubernetes/test/e2e_federation/framework" | 	fedframework "k8s.io/kubernetes/test/e2e_federation/framework" | ||||||
|  |  | ||||||
|   | |||||||
| @@ -26,13 +26,13 @@ import ( | |||||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||||
| 	"k8s.io/apimachinery/pkg/util/wait" | 	"k8s.io/apimachinery/pkg/util/wait" | ||||||
| 	restclient "k8s.io/client-go/rest" | 	restclient "k8s.io/client-go/rest" | ||||||
|  | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | ||||||
| 	federationapi "k8s.io/kubernetes/federation/apis/federation/v1beta1" | 	federationapi "k8s.io/kubernetes/federation/apis/federation/v1beta1" | ||||||
| 	fedclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset" | 	fedclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset" | ||||||
| 	"k8s.io/kubernetes/pkg/api" | 	"k8s.io/kubernetes/pkg/api" | ||||||
| 	"k8s.io/kubernetes/pkg/api/v1" | 	"k8s.io/kubernetes/pkg/api/v1" | ||||||
| 	kubeclientset "k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | 	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/common" | ||||||
| 	"k8s.io/kubernetes/test/e2e/framework" | 	"k8s.io/kubernetes/test/e2e/framework" | ||||||
| 	fedframework "k8s.io/kubernetes/test/e2e_federation/framework" | 	fedframework "k8s.io/kubernetes/test/e2e_federation/framework" | ||||||
|   | |||||||
| @@ -21,7 +21,6 @@ go_library( | |||||||
|         "//pkg/api/v1:go_default_library", |         "//pkg/api/v1:go_default_library", | ||||||
|         "//pkg/api/validation:go_default_library", |         "//pkg/api/validation:go_default_library", | ||||||
|         "//pkg/client/clientset_generated/clientset:go_default_library", |         "//pkg/client/clientset_generated/clientset:go_default_library", | ||||||
|         "//pkg/client/unversioned/clientcmd:go_default_library", |  | ||||||
|         "//test/e2e/framework:go_default_library", |         "//test/e2e/framework:go_default_library", | ||||||
|         "//vendor:github.com/onsi/ginkgo", |         "//vendor:github.com/onsi/ginkgo", | ||||||
|         "//vendor:github.com/onsi/gomega", |         "//vendor:github.com/onsi/gomega", | ||||||
| @@ -31,6 +30,7 @@ go_library( | |||||||
|         "//vendor:k8s.io/apimachinery/pkg/util/validation", |         "//vendor:k8s.io/apimachinery/pkg/util/validation", | ||||||
|         "//vendor:k8s.io/apimachinery/pkg/util/wait", |         "//vendor:k8s.io/apimachinery/pkg/util/wait", | ||||||
|         "//vendor:k8s.io/client-go/rest", |         "//vendor:k8s.io/client-go/rest", | ||||||
|  |         "//vendor:k8s.io/client-go/tools/clientcmd", | ||||||
|     ], |     ], | ||||||
| ) | ) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -27,13 +27,13 @@ import ( | |||||||
| 	validationutil "k8s.io/apimachinery/pkg/util/validation" | 	validationutil "k8s.io/apimachinery/pkg/util/validation" | ||||||
| 	"k8s.io/apimachinery/pkg/util/wait" | 	"k8s.io/apimachinery/pkg/util/wait" | ||||||
| 	restclient "k8s.io/client-go/rest" | 	restclient "k8s.io/client-go/rest" | ||||||
|  | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	federationapi "k8s.io/kubernetes/federation/apis/federation/v1beta1" | 	federationapi "k8s.io/kubernetes/federation/apis/federation/v1beta1" | ||||||
| 	"k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset" | 	"k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset" | ||||||
| 	"k8s.io/kubernetes/pkg/api" | 	"k8s.io/kubernetes/pkg/api" | ||||||
| 	"k8s.io/kubernetes/pkg/api/v1" | 	"k8s.io/kubernetes/pkg/api/v1" | ||||||
| 	"k8s.io/kubernetes/pkg/api/validation" | 	"k8s.io/kubernetes/pkg/api/validation" | ||||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||||
| 	"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" |  | ||||||
| 	"k8s.io/kubernetes/test/e2e/framework" | 	"k8s.io/kubernetes/test/e2e/framework" | ||||||
| ) | ) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -21,8 +21,8 @@ package kubectl | |||||||
| import ( | import ( | ||||||
| 	"testing" | 	"testing" | ||||||
|  |  | ||||||
|  | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | 	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/pkg/kubectl/cmd/util" | ||||||
| 	"k8s.io/kubernetes/test/integration/framework" | 	"k8s.io/kubernetes/test/integration/framework" | ||||||
| ) | ) | ||||||
|   | |||||||
| @@ -22,7 +22,6 @@ go_library( | |||||||
|         "//pkg/api:go_default_library", |         "//pkg/api:go_default_library", | ||||||
|         "//pkg/api/v1:go_default_library", |         "//pkg/api/v1:go_default_library", | ||||||
|         "//pkg/client/clientset_generated/clientset:go_default_library", |         "//pkg/client/clientset_generated/clientset:go_default_library", | ||||||
|         "//pkg/client/unversioned/clientcmd:go_default_library", |  | ||||||
|         "//pkg/util/intstr:go_default_library", |         "//pkg/util/intstr:go_default_library", | ||||||
|         "//test/e2e/framework:go_default_library", |         "//test/e2e/framework:go_default_library", | ||||||
|         "//vendor:github.com/golang/glog", |         "//vendor:github.com/golang/glog", | ||||||
| @@ -30,6 +29,7 @@ go_library( | |||||||
|         "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", |         "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", | ||||||
|         "//vendor:k8s.io/apimachinery/pkg/runtime", |         "//vendor:k8s.io/apimachinery/pkg/runtime", | ||||||
|         "//vendor:k8s.io/client-go/rest", |         "//vendor:k8s.io/client-go/rest", | ||||||
|  |         "//vendor:k8s.io/client-go/tools/clientcmd", | ||||||
|     ], |     ], | ||||||
| ) | ) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -33,10 +33,10 @@ import ( | |||||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||||
| 	"k8s.io/apimachinery/pkg/runtime" | 	"k8s.io/apimachinery/pkg/runtime" | ||||||
| 	restclient "k8s.io/client-go/rest" | 	restclient "k8s.io/client-go/rest" | ||||||
|  | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 	"k8s.io/kubernetes/pkg/api" | 	"k8s.io/kubernetes/pkg/api" | ||||||
| 	"k8s.io/kubernetes/pkg/api/v1" | 	"k8s.io/kubernetes/pkg/api/v1" | ||||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||||
| 	"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" |  | ||||||
| 	"k8s.io/kubernetes/pkg/util/intstr" | 	"k8s.io/kubernetes/pkg/util/intstr" | ||||||
| 	e2e "k8s.io/kubernetes/test/e2e/framework" | 	e2e "k8s.io/kubernetes/test/e2e/framework" | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 deads2k
					deads2k