use testcontainers::{
core::{ContainerPort, WaitFor},
Image,
};
const NAME: &str = "registry.k8s.io/kwok/cluster";
const TAG: &str = "v0.5.2-k8s.v1.29.2";
const DEFAULT_WAIT: u64 = 3000;
pub const KWOK_CLUSTER_PORT: ContainerPort = ContainerPort::Tcp(8080);
#[derive(Debug, Default, Clone)]
pub struct KwokCluster;
impl Image for KwokCluster {
fn name(&self) -> &str {
NAME
}
fn tag(&self) -> &str {
TAG
}
fn ready_conditions(&self) -> Vec<WaitFor> {
vec![
WaitFor::message_on_stdout("Starting to serve on [::]:8080"),
WaitFor::millis(DEFAULT_WAIT),
]
}
fn expose_ports(&self) -> &[ContainerPort] {
&[KWOK_CLUSTER_PORT]
}
}
#[cfg(test)]
mod test {
use k8s_openapi::api::core::v1::Namespace;
use kube::{
api::ListParams,
client::Client,
config::{AuthInfo, Cluster, KubeConfigOptions, Kubeconfig, NamedAuthInfo, NamedCluster},
Api, Config,
};
use rustls::crypto::CryptoProvider;
use testcontainers::core::IntoContainerPort;
use crate::{kwok::KwokCluster, testcontainers::runners::AsyncRunner};
const CLUSTER_NAME: &str = "kwok-kwok";
const CONTEXT_NAME: &str = "kwok-kwok";
const CLUSTER_USER: &str = "kwok-kwok";
#[tokio::test]
async fn test_kwok_image() -> Result<(), Box<dyn std::error::Error + 'static>> {
if CryptoProvider::get_default().is_none() {
rustls::crypto::ring::default_provider()
.install_default()
.expect("Error initializing rustls provider");
}
let node = KwokCluster.start().await?;
let host_port = node.get_host_port_ipv4(8080.tcp()).await?;
let kubeconfig = Kubeconfig {
clusters: vec![NamedCluster {
name: String::from(CLUSTER_NAME),
cluster: Some(Cluster {
server: Some(format!("http://localhost:{host_port}")), ..Default::default()
}),
}],
contexts: vec![kube::config::NamedContext {
name: CONTEXT_NAME.to_string(),
context: Option::from(kube::config::Context {
cluster: CLUSTER_NAME.to_string(),
user: String::from(CLUSTER_USER),
..Default::default()
}),
}],
auth_infos: vec![NamedAuthInfo {
name: String::from(CLUSTER_USER),
auth_info: Some(AuthInfo {
token: None,
..Default::default()
}),
}],
current_context: Some(CONTEXT_NAME.to_string()),
..Default::default()
};
let kubeconfigoptions = KubeConfigOptions {
context: Some(CONTEXT_NAME.to_string()),
cluster: Some(CLUSTER_NAME.to_string()),
user: None,
};
let config = Config::from_custom_kubeconfig(kubeconfig, &kubeconfigoptions)
.await
.unwrap();
let client = Client::try_from(config).unwrap();
let api: Api<Namespace> = Api::all(client);
let namespaces = api.list(&ListParams::default()).await.unwrap();
assert_eq!(namespaces.items.len(), 4);
let namespace_names: Vec<&str> = namespaces
.items
.iter()
.map(|namespace| namespace.metadata.name.as_deref().unwrap())
.collect();
assert_eq!(
namespace_names,
vec!["default", "kube-node-lease", "kube-public", "kube-system"]
);
Ok(())
}
}