Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Missing EKS get-token #980

Closed
2 tasks
subtil-next opened this issue Nov 29, 2023 · 7 comments
Closed
2 tasks

Missing EKS get-token #980

subtil-next opened this issue Nov 29, 2023 · 7 comments
Labels
feature-request A feature should be added or improved. high-level-library

Comments

@subtil-next
Copy link

Describe the feature

the aws_sdk_eks crate appears to be missing the get-token call.

https://docs.aws.amazon.com/cli/latest/reference/eks/get-token.html

Use Case

Get-Token is needed to auth into EKS clusters: https://docs.aws.amazon.com/eks/latest/userguide/create-kubeconfig.html

Proposed Solution

No response

Other Information

No response

Acknowledgements

  • I may be able to implement this feature request
  • This feature might incur a breaking change

A note for the community

Community Note

  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
  • Please do not leave "+1" or "me too" comments, they generate extra noise for issue followers and do not help prioritize the request
  • If you are interested in working on this issue, please leave a comment
@subtil-next subtil-next added feature-request A feature should be added or improved. needs-triage This issue or PR still needs to be triaged. labels Nov 29, 2023
@rcoh rcoh added high-level-library and removed needs-triage This issue or PR still needs to be triaged. labels Nov 29, 2023
@rcoh
Copy link
Contributor

rcoh commented Nov 29, 2023

I think that's a custom function exclusive to the CLI. Code here: https://github.com/aws/aws-cli/blob/00a26836b824deb9a07c8b9d06ddfddec084cafc/awscli/customizations/eks/get_token.py#L222

@subtil-next
Copy link
Author

Oh. Awesome. Thanks!

Copy link

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.

@subtil-next
Copy link
Author

If anyone comes across this and is looking for the implementation:

pub fn generate_token<'a>(
    region: &Region,
    headers: impl Iterator<Item = (&'a str, &'a str)>,
    credentials: &Credentials,
    duration: Option<Duration>,
    time: Option<SystemTime>,
) -> Result<String, SigningError> {
    let expiration = credentials.expiry();
    let region = region.to_string();
    let identity = Identity::new(credentials.clone(), expiration);
    let mut signing_settings = SigningSettings::default();
    signing_settings.signature_location = SignatureLocation::QueryParams;
    signing_settings.expires_in = duration.or(Some(Duration::from_secs(60))); // 1 minute

    let signing_params = aws_sigv4::sign::v4::SigningParams::builder()
        .identity(&identity)
        .region(&region)
        .name("sts")
        .time(time.unwrap_or(SystemTime::now()))
        .settings(signing_settings)
        .build()
        .unwrap();
    
    // Convert the HTTP request into a signable request
    let url =
        format!("https://sts.{region}.amazonaws.com/?Action=GetCallerIdentity&Version=2011-06-15");
    let signable_request =
        SignableRequest::new("GET", url.clone(), headers, SignableBody::Bytes(&[]))
            .expect("signable request");

    let (signing_instructions, _signature) = aws_sigv4::http_request::sign(
        signable_request,
        &aws_sigv4::http_request::SigningParams::V4(signing_params),
    )?
    .into_parts();
    let mut my_req = Request::builder().uri(url).body(()).unwrap();

    signing_instructions.apply_to_request_http0x(&mut my_req);
    let uri = my_req.uri().to_string();

    Ok(format!("k8s-aws-v1.{}", encode(uri)))
}

@MushiTheMoshi
Copy link

If anyone comes across this and is looking for the implementation:

pub fn generate_token<'a>(
    region: &Region,
    headers: impl Iterator<Item = (&'a str, &'a str)>,
    credentials: &Credentials,
    duration: Option<Duration>,
    time: Option<SystemTime>,
) -> Result<String, SigningError> {
    let expiration = credentials.expiry();
    let region = region.to_string();
    let identity = Identity::new(credentials.clone(), expiration);
    let mut signing_settings = SigningSettings::default();
    signing_settings.signature_location = SignatureLocation::QueryParams;
    signing_settings.expires_in = duration.or(Some(Duration::from_secs(60))); // 1 minute

    let signing_params = aws_sigv4::sign::v4::SigningParams::builder()
        .identity(&identity)
        .region(&region)
        .name("sts")
        .time(time.unwrap_or(SystemTime::now()))
        .settings(signing_settings)
        .build()
        .unwrap();
    
    // Convert the HTTP request into a signable request
    let url =
        format!("https://sts.{region}.amazonaws.com/?Action=GetCallerIdentity&Version=2011-06-15");
    let signable_request =
        SignableRequest::new("GET", url.clone(), headers, SignableBody::Bytes(&[]))
            .expect("signable request");

    let (signing_instructions, _signature) = aws_sigv4::http_request::sign(
        signable_request,
        &aws_sigv4::http_request::SigningParams::V4(signing_params),
    )?
    .into_parts();
    let mut my_req = Request::builder().uri(url).body(()).unwrap();

    signing_instructions.apply_to_request_http0x(&mut my_req);
    let uri = my_req.uri().to_string();

    Ok(format!("k8s-aws-v1.{}", encode(uri)))
}

Any idea how it should look like next part where you actually use this token?

@subtil-next
Copy link
Author

I use:

kube = "0.88.0"
k8s-openapi = { version = "0.21.0", features = ["latest", "v1_29"] }
pem = "3.0.3"

with something like:

use kube::{Client, Config};

 let mut config = Config::new(uri);

// URL_SAFE base64 decode the certificate
    let decoded = match decode(certificate) {
        Ok(s) => s,
        Err(d) => {
            warn!(
                "Failed to decode certificate. Unable to pull kubernetes information {:?}",
                d
            );
            return None;
        }
    };
// parse the certificates. 
    let decoded = pem::parse_many(decoded)
        .unwrap()
        .into_iter()
        .filter_map(|p| {
            if p.tag() == "CERTIFICATE" {
                Some(p.into_contents())
            } else {
                None
            }
        })
        .collect::<Vec<_>>();
    config.root_cert = Some(decoded);
    config.auth_info.token = Some(SecretString::new(token));

let client =  Client::try_from(config).expect("failed to create kube client")

@MushiTheMoshi
Copy link

thank you so much for your quick response!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature-request A feature should be added or improved. high-level-library
Projects
None yet
Development

No branches or pull requests

3 participants