databricks / click

The "Command Line Interactive Controller for Kubernetes"
Apache License 2.0
1.49k stars 84 forks source link

AWS (EKS) clusters protected with aws-iam-authenticator are not accepted #89

Closed unthought closed 2 years ago

unthought commented 5 years ago

I'm having a problem with a working AWS EKS cluster context in click:

[Warning] Couldn't find/load context <<cluster-name>>, now no current context.  Error: Failed to get config: Invalid context <<cluster-name>>.  Each user must have either a token, a username AND password, or a client-certificate AND a client-key, or an auth-provider

This is the config:

apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: <<k8s control plane endpoint>>
  name: <<cluster-aws-arn (AWS global ID)>>
contexts:      
- context:
    cluster: <<cluster-aws-arn (AWS global ID)>>
    namespace: <<namespace>>
    user: <<cluster-aws-arn (AWS global ID)>>
  name: bci-dev-main
current-context: <<cluster-name>>
kind: Config
preferences: {}
users:
- name: <<cluster-aws-arn (AWS global ID)>>
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1alpha1
      args:
      - token
      - -i
      - <<cluster-name>>
      command: aws-iam-authenticator
      env: null

The only thing omitted are essentially identifiers, there are no credentials, tokens, or client certs in the config. Instead this configuration is using aws-iam-authenticator, which pulls the authentication token out of AWS specific environment variables. The access to the cluster is protected via multi-factor auth, so to actually start executing commands with kubectl (or click), I'm using aws-vault, which essentially lets me authenticate, forces the multi-factor auth, and then executes the command with the correct env vars set (to be picked up by aws-iam-authenticator). The commands for kubectl/click look therefore like this:

aws-vault exec <<aws-vault config profile>> -- kubectl ...

This particular config was generated in the AWS recommended way with aws cli:

aws eks update-kubeconfig

Since this is part of the guides on EKS AWS, I expect other users to run into this problem.

I assume this also affects other AWS clusters set up in a similar way with eg. kops.

slyoldfox commented 5 years ago

Pitty,

would have loved to try Click, but seeing the same issue:

[none] [none] [none] > contexts arn:aws:eks:eu-west-1:83473894738497:cluster/eks-acceptance arn:aws:eks:eu-west-1:83473894738497:cluster/eks-production [none] [none] [none] > context Context Api Server Address

arn:aws:eks:eu-west-1:83473894738497:cluster/eks-acceptance https://XXXXXXXXXXXXXXXXXXXXXXXXXXXXX.sk1.eu-west-1.eks.amazonaws.com arn:aws:eks:eu-west-1:83473894738497:cluster/eks-production https://XXXXXXXXXXXXXXXXXXXXXXXXXXXXX.yl4.eu-west-1.eks.amazonaws.com

[none] [none] [none] > context arn:aws:eks:eu-west-1:83473894738497:cluster/eks-acceptance [WARN] Couldn't find/load context arn:aws:eks:eu-west-1:83473894738497:cluster/eks-acceptance, now no current context. Error: Failed to get config: Invalid context arn:aws:eks:eu-west-1:83473894738497:cluster/eks-acceptance. Each user must have either a token, a username AND password, or a client-certificate AND a client-key, or an auth-provider

Config generated via the same command

aws eks update-kubeconfig

We are using aws-adfs via DUO to authenticate.

nicklan commented 5 years ago

Yep, there is actually an open PR to add this feature: #78. However it's not quite ready to merge. Since the original creator of the PR hasn't replied, I will try and find time to fix the issues and merge it.

Keramblock commented 5 years ago

Same problem

Keramblock commented 5 years ago

any news here?

slyoldfox commented 5 years ago

For what it's worth I checked out this PR and used cargo build

Running with RUST_BACKTRACE=1 ./target/debug/click I get:

[eks-cluster] [default] [none] > pods
thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', src/libcore/option.rs:345:21
stack backtrace:
   0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
             at src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:39
   1: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:71
   2: std::panicking::default_hook::{{closure}}
             at src/libstd/sys_common/backtrace.rs:59
             at src/libstd/panicking.rs:197
   3: std::panicking::default_hook
             at src/libstd/panicking.rs:211
   4: <std::panicking::begin_panic::PanicPayload<A> as core::panic::BoxMeUp>::get
             at src/libstd/panicking.rs:474
   5: std::panicking::continue_panic_fmt
             at src/libstd/panicking.rs:381
   6: std::panicking::try::do_call
             at src/libstd/panicking.rs:308
   7: <T as core::any::Any>::type_id
             at src/libcore/panicking.rs:85
   8: <T as core::any::Any>::type_id
             at src/libcore/panicking.rs:49
   9: core::option::Option<T>::unwrap
             at /rustc/3c235d5600393dfe6c36eeed34042efad8d4f26e/src/libcore/macros.rs:12
  10: click::config::Exec::generate_token
             at src/config.rs:143
  11: click::kube::Kluster::add_auth_header
             at src/kube.rs:476
  12: click::kube::Kluster::send_req
             at src/kube.rs:512
  13: click::kube::Kluster::get
             at src/kube.rs:536
  14: <click::cmd::Pods as click::cmd::Cmd>::exec::{{closure}}::{{closure}}
             at src/cmd.rs:876
  15: click::Env::run_on_kluster
             at src/main.rs:397
  16: <click::cmd::Pods as click::cmd::Cmd>::exec::{{closure}}
             at src/cmd.rs:876
  17: click::cmd::exec_match
             at src/cmd.rs:103
  18: <click::cmd::Pods as click::cmd::Cmd>::exec
             at src/cmd.rs:163
  19: click::main
             at src/main.rs:700
  20: std::rt::lang_start::{{closure}}
             at /rustc/3c235d5600393dfe6c36eeed34042efad8d4f26e/src/libstd/rt.rs:64
  21: std::panicking::try::do_call
             at src/libstd/rt.rs:49
             at src/libstd/panicking.rs:293
  22: panic_unwind::dwarf::eh::read_encoded_pointer
             at src/libpanic_unwind/lib.rs:87
  23: <std::panicking::begin_panic::PanicPayload<A> as core::panic::BoxMeUp>::get
             at src/libstd/panicking.rs:272
             at src/libstd/panic.rs:388
             at src/libstd/rt.rs:48
  24: std::rt::lang_start
             at /rustc/3c235d5600393dfe6c36eeed34042efad8d4f26e/src/libstd/rt.rs:64
  25: click::main

So unless I'm doing something wrong (I'm trying to wrap my head around this), this code doesn't seem to be working flawlessly.

slyoldfox commented 5 years ago

I have taken the PR from @ahmetrehaseker and updated it with the latest code from master. At the moment I can use click with latest awscli (bypassing aws-iam-authenticator`), configure your used like this:

- name: myekscluster
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1alpha1
      args:
      - --region
      - eu-west-1
      - eks
      - get-token
      - --cluster-name
      - myclustername
      command: aws
      env:
      - name: AWS_PROFILE
        value: myawsprofile

The aws eks get-token command is available since 1.16.156 of awscli