commit - 58786c5f343a9270afe5ce81fb158379ccf27849
commit + c71cc900bed6be4372957b42316a516c75575bb1
blob - /dev/null
blob + e4e220b13c5171d236cbb61100ac24acf7d1438e (mode 644)
--- /dev/null
+++ crates/kops_eks/Cargo.toml
+[package]
+name = "kops_eks"
+version = "0.1.0"
+edition = "2024"
+
+[dependencies]
+anyhow = "1"
+aws-config = { version = "1", features = ["behavior-version-latest"] }
+aws-sdk-eks = "1"
+aws-credential-types = "1"
+aws-sigv4 = "1"
+http = "1"
+base64 = "0.22"
+kube = { version = "0.91", features = ["client", "rustls-tls"] }
+k8s-openapi = { version = "0.22", features = ["v1_30"] }
+tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
+aws-smithy-runtime-api = "1.9.2"
+rustls = { version = "0.23", default-features = false, features = ["ring"] }
+rustls-pemfile = "2"
+aws-sdk-sts = "1.94.0"
+urlencoding = "2.1"
+percent-encoding = "2.3"
+url = "2.5.7"
+pem = "3.0.6"
blob - /dev/null
blob + cc56ce3257a24b2db2485fb4ab0d4875dea69737 (mode 644)
--- /dev/null
+++ crates/kops_eks/src/main.rs
+#![allow(unused_imports, unused_variables, unused_mut)]
+use anyhow::{Context, Result, anyhow};
+use aws_config::BehaviorVersion;
+use aws_credential_types::provider::ProvideCredentials;
+use aws_sdk_eks as eks;
+use aws_sigv4::http_request::SignatureLocation;
+use aws_sigv4::http_request::{
+ SignableBody, SignableRequest, SigningParams, SigningSettings, sign,
+};
+use aws_sigv4::sign::v4;
+use aws_smithy_runtime_api::client::identity::Identity;
+use base64::Engine;
+use base64::engine::general_purpose::{STANDARD, URL_SAFE_NO_PAD};
+use http::Uri;
+use http::header;
+use k8s_openapi::api::core::v1::Pod;
+use kube::Api;
+use kube::config::{AuthInfo, Config as KubeConfig};
+use percent_encoding::{NON_ALPHANUMERIC, utf8_percent_encode};
+use rustls::crypto::aws_lc_rs;
+use rustls_pemfile::Item;
+use std::io::Cursor;
+use std::time::{Duration, SystemTime};
+
+#[tokio::main]
+async fn main() -> Result<()> {
+ aws_lc_rs::default_provider()
+ .install_default()
+ .expect("failed to install aws-lc provider");
+
+ let region = "us-east-1";
+ let cluster_name = "my-cluster";
+
+ let token = main2(cluster_name, region).await?;
+
+ let (eks_cluster_url, eks_cluster_cert) = eks_k8s_cluster_info(cluster_name).await?;
+
+ let kubeconfig = kube::Config {
+ cluster_url: eks_cluster_url,
+ default_namespace: "observability".to_string(),
+ auth_info: kube::config::AuthInfo {
+ token: Some(token.clone().into()),
+ ..Default::default()
+ },
+ root_cert: Some(eks_cluster_cert),
+ accept_invalid_certs: false,
+ connect_timeout: Some(Duration::from_secs(30)),
+ read_timeout: Some(Duration::from_secs(295)),
+ write_timeout: None,
+ proxy_url: None,
+ tls_server_name: None,
+ };
+
+ let client = kube::Client::try_from(kubeconfig)?;
+ let pods: Api<Pod> = Api::namespaced(client, "observability");
+ for p in pods.list(&Default::default()).await?.items {
+ println!("{}", p.metadata.name.unwrap_or_default());
+ }
+
+ Ok(())
+}
+
+pub async fn eks_k8s_cluster_info(cluster_name: &str) -> Result<(http::Uri, Vec<Vec<u8>>)> {
+ let sdk_config = aws_config::load_defaults(BehaviorVersion::latest()).await;
+ let client = eks::Client::new(&sdk_config);
+
+ let resp = client.describe_cluster().name(cluster_name).send().await?;
+
+ let cluster = resp.cluster().context("Unable to find cluster")?.to_owned();
+ let b64_cert = cluster
+ .certificate_authority()
+ .context("Unable to find certificate authority")?
+ .data()
+ .context("Unable to find certificate data")?;
+ let cert = pem::parse(STANDARD.decode(b64_cert)?)?.into_contents();
+ let endpoint = cluster
+ .endpoint()
+ .context("Unable to find endpoint")?
+ .parse::<http::Uri>()?;
+
+ Ok((endpoint, [cert].to_vec()))
+}
+
+pub async fn main2(cluster_name: &str, region: &str) -> Result<String> {
+ let sdk_config = aws_config::load_defaults(BehaviorVersion::latest()).await;
+ let credentials = sdk_config
+ .credentials_provider()
+ .ok_or_else(|| anyhow!("no credentials provider in sdk_config"))?
+ .provide_credentials()
+ .await
+ .context("failed to provide AWS credentials")?;
+
+ let mut signing_settings = SigningSettings::default();
+ signing_settings.expires_in = Some(Duration::from_secs(60));
+ signing_settings.signature_location = SignatureLocation::QueryParams;
+
+ let identity = Identity::from(credentials.clone());
+
+ let signing_params = match aws_sigv4::sign::v4::SigningParams::builder()
+ .identity(&identity)
+ .region(region)
+ .name("sts")
+ .time(SystemTime::now())
+ .settings(signing_settings)
+ .build()
+ {
+ Ok(params) => params,
+ Err(e) => {
+ return Err(anyhow!("Unable to create signing params: {:?}", e));
+ }
+ };
+
+ let url =
+ format!("https://sts.{region}.amazonaws.com/?Action=GetCallerIdentity&Version=2011-06-15");
+ let headers = vec![("x-k8s-aws-id", cluster_name)];
+ let signable_request = SignableRequest::new(
+ "GET",
+ url.clone(),
+ headers.into_iter(),
+ SignableBody::Bytes(&[]),
+ )?;
+
+ let (signing_instructions, _signature) = aws_sigv4::http_request::sign(
+ signable_request,
+ &aws_sigv4::http_request::SigningParams::V4(signing_params),
+ )?
+ .into_parts();
+
+ let mut fake_req = http::Request::builder()
+ .uri(url)
+ .body(())
+ .expect("empty body request should not fail");
+
+ signing_instructions.apply_to_request_http1x(&mut fake_req);
+ let uri = fake_req.uri().to_string();
+
+ Ok(format!("k8s-aws-v1.{}", &URL_SAFE_NO_PAD.encode(uri)))
+}