Added --context flag to specify the context to use to talk to the Kubernetes apiserver (#1743)

* Added --context flag to specify the context to use to talk to the Kubernetes apiserver
* Fix tests that are failing
* Updated context flag description

Signed-off-by: Darko Radisic <ffd2subroutine@users.noreply.github.com>
This commit is contained in:
Darko Radisic 2018-10-08 21:37:35 +02:00 committed by Kevin Lingerfelt
parent 69cebae1a2
commit 6fee0f3c2b
12 changed files with 20 additions and 15 deletions

View File

@ -87,6 +87,7 @@ func configureAndRunChecks(options *checkOptions) {
ControlPlaneNamespace: controlPlaneNamespace,
DataPlaneNamespace: options.namespace,
KubeConfig: kubeconfigPath,
KubeContext: kubeContext,
APIAddr: apiAddr,
VersionOverride: options.versionOverride,
RetryDeadline: time.Now().Add(options.wait),

View File

@ -52,7 +52,7 @@ func newCmdDashboard() *cobra.Command {
options.dashboardShow, showLinkerd, showGrafana, showURL)
}
kubernetesProxy, err := k8s.NewProxy(kubeconfigPath, options.dashboardProxyPort)
kubernetesProxy, err := k8s.NewProxy(kubeconfigPath, kubeContext, options.dashboardProxyPort)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to initialize proxy: %s\n", err)
os.Exit(1)

View File

@ -26,6 +26,7 @@ const (
var controlPlaneNamespace string
var apiAddr string // An empty value means "use the Kubernetes configuration"
var kubeconfigPath string
var kubeContext string
var verbose bool
var (
@ -64,6 +65,7 @@ var RootCmd = &cobra.Command{
func init() {
RootCmd.PersistentFlags().StringVarP(&controlPlaneNamespace, "linkerd-namespace", "l", defaultNamespace, "Namespace in which Linkerd is installed [$LINKERD_NAMESPACE]")
RootCmd.PersistentFlags().StringVar(&kubeconfigPath, "kubeconfig", "", "Path to the kubeconfig file to use for CLI requests")
RootCmd.PersistentFlags().StringVar(&kubeContext, "context", "", "Name of the kubeconfig context to use")
RootCmd.PersistentFlags().StringVar(&apiAddr, "api-addr", "", "Override kubeconfig and communicate directly with the control plane at host:port (mostly for testing)")
RootCmd.PersistentFlags().BoolVar(&verbose, "verbose", false, "Turn on debug logging")
@ -92,6 +94,7 @@ func validatedPublicAPIClient(retryDeadline time.Time) pb.ApiClient {
hc := healthcheck.NewHealthChecker(checks, &healthcheck.HealthCheckOptions{
ControlPlaneNamespace: controlPlaneNamespace,
KubeConfig: kubeconfigPath,
KubeContext: kubeContext,
APIAddr: apiAddr,
RetryDeadline: retryDeadline,
})

View File

@ -78,7 +78,7 @@ func newVersionClient() (pb.ApiClient, error) {
if apiAddr != "" {
return public.NewInternalClient(controlPlaneNamespace, apiAddr)
}
kubeAPI, err := k8s.NewAPI(kubeconfigPath)
kubeAPI, err := k8s.NewAPI(kubeconfigPath, kubeContext)
if err != nil {
return nil, err
}

View File

@ -87,6 +87,7 @@ type HealthCheckOptions struct {
ControlPlaneNamespace string
DataPlaneNamespace string
KubeConfig string
KubeContext string
APIAddr string
VersionOverride string
RetryDeadline time.Time
@ -139,7 +140,7 @@ func (hc *HealthChecker) addKubernetesAPIChecks() {
description: "can initialize the client",
fatal: true,
check: func() (err error) {
hc.kubeAPI, err = k8s.NewAPI(hc.KubeConfig)
hc.kubeAPI, err = k8s.NewAPI(hc.KubeConfig, hc.KubeContext)
return
},
})

View File

@ -144,8 +144,8 @@ func (kubeAPI *KubernetesAPI) getRequest(ctx context.Context, client *http.Clien
// NewAPI validates a Kubernetes config and returns a client for accessing the
// configured cluster
func NewAPI(configPath string) (*KubernetesAPI, error) {
config, err := getConfig(configPath)
func NewAPI(configPath, kubeContext string) (*KubernetesAPI, error) {
config, err := getConfig(configPath, kubeContext)
if err != nil {
return nil, fmt.Errorf("error configuring Kubernetes API client: %v", err)
}

View File

@ -11,7 +11,7 @@ func TestKubernetesApiUrlFor(t *testing.T) {
t.Run("Returns base config containing k8s endpoint listed in config.test", func(t *testing.T) {
expected := fmt.Sprintf("https://55.197.171.239/api/v1/namespaces/%s%s", namespace, extraPath)
api, err := NewAPI("testdata/config.test")
api, err := NewAPI("testdata/config.test", "")
if err != nil {
t.Fatalf("Unexpected error creating Kubernetes API: %+v", err)
}

View File

@ -58,12 +58,12 @@ func generateBaseKubernetesApiUrl(schemeHostAndPort string) (*url.URL, error) {
return url, nil
}
func getConfig(fpath string) (*rest.Config, error) {
func getConfig(fpath, kubeContext string) (*rest.Config, error) {
rules := clientcmd.NewDefaultClientConfigLoadingRules()
if fpath != "" {
rules.ExplicitPath = fpath
}
overrides := &clientcmd.ConfigOverrides{}
overrides := &clientcmd.ConfigOverrides{CurrentContext: kubeContext}
return clientcmd.
NewNonInteractiveDeferredLoadingClientConfig(rules, overrides).
ClientConfig()

View File

@ -60,7 +60,7 @@ func TestGenerateBaseKubernetesApiUrl(t *testing.T) {
func TestGetConfig(t *testing.T) {
t.Run("Gets host correctly form existing file", func(t *testing.T) {
config, err := getConfig("testdata/config.test")
config, err := getConfig("testdata/config.test", "")
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
@ -72,7 +72,7 @@ func TestGetConfig(t *testing.T) {
})
t.Run("Returns error if configuration cannot be found", func(t *testing.T) {
_, err := getConfig("/this/doest./not/exist.config")
_, err := getConfig("/this/doest./not/exist.config", "")
if err == nil {
t.Fatalf("Expecting error when config file doesnt exist, got nothing")
}

View File

@ -19,8 +19,8 @@ type KubernetesProxy struct {
// NewProxy returns a new KubernetesProxy object and starts listening on a
// network address.
func NewProxy(configPath string, proxyPort int) (*KubernetesProxy, error) {
config, err := getConfig(configPath)
func NewProxy(configPath, kubeContext string, proxyPort int) (*KubernetesProxy, error) {
config, err := getConfig(configPath, kubeContext)
if err != nil {
return nil, fmt.Errorf("error configuring Kubernetes API client: %v", err)
}

View File

@ -8,7 +8,7 @@ import (
func TestInitK8sProxy(t *testing.T) {
t.Run("Returns an initialized Kubernetes Proxy object", func(t *testing.T) {
kp, err := NewProxy( "testdata/config.test", 0)
kp, err := NewProxy("testdata/config.test", "", 0)
if err != nil {
t.Fatalf("Unexpected error creating Kubernetes API: %+v", err)
}
@ -24,7 +24,7 @@ func TestKubernetesProxyUrlFor(t *testing.T) {
const extraPath = "/some/extra/path"
t.Run("Returns proxy URL based on the initialized KubernetesProxy", func(t *testing.T) {
kp, err := NewProxy( "testdata/config.test", 0)
kp, err := NewProxy("testdata/config.test", "", 0)
if err != nil {
t.Fatalf("Unexpected error creating Kubernetes API: %+v", err)
}

View File

@ -203,7 +203,7 @@ func (h *KubernetesHelper) ParseNamespacedResource(resource string) (string, str
// tests can use for access to the given service. Note that the proxy remains
// running for the duration of the test.
func (h *KubernetesHelper) ProxyURLFor(namespace, service, port string) (string, error) {
proxy, err := k8s.NewProxy("", 0)
proxy, err := k8s.NewProxy("", "", 0)
if err != nil {
return "", err
}