Skip to content

Commit

Permalink
fix: Add new way to create cluster, create cluster from yaml file, to…
Browse files Browse the repository at this point in the history
… fix previously wrong ipFamily issue

This is the body of the commit: this fix addressed the issue of when
create clusters, the ipv6 cluster always has a ipFamily of ipv4 which is
wrong. In this commit, a new way of creating cluster is added which is
using created yaml file in a certain path. That way we can definite the
ipFamily for whether it is ipv6 or ipv4.

Fixed feedbacks

fixed build
  • Loading branch information
zongzhidanielhu committed Jan 14, 2025
1 parent 9c02930 commit b3bcb2e
Showing 1 changed file with 142 additions and 41 deletions.
183 changes: 142 additions & 41 deletions bottlerocket/agents/src/bin/eks-resource-agent/eks_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,19 @@ use resource_agent::provider::{
use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::env::temp_dir;
use std::fs::write;
use std::path::Path;
use std::process::Command;
use testsys_model::{Configuration, SecretName};

use std::fs::File;
use std::io::Write;

/// The default region for the cluster.
const DEFAULT_REGION: &str = "us-west-2";
/// The default cluster version.
const DEFAULT_VERSION: &str = "1.24";
const TEST_CLUSTER_CONFIG_PATH: &str = "/local/eksctl_config.yaml";
const CLUSTER_CONFIG_PATH: &str = "/local/cluster_config.yaml";

#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
Expand Down Expand Up @@ -115,7 +118,6 @@ impl AwsClients {
}
}
}

enum ClusterConfig {
Args {
cluster_name: String,
Expand All @@ -128,6 +130,123 @@ enum ClusterConfig {
region: String,
},
}
enum IPFamily {
IPv4,
IPv6,
}

fn get_family_string(family: IPFamily) -> &'static str {
match family {
IPFamily::IPv4 => "IPv4",
IPFamily::IPv6 => "IPv6",
}
}

#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
struct Config {
api_version: String,
kind: String,
metadata: Metadata,
availability_zones: Vec<String>,
kubernetes_network_config: KubernetesNetworkConfig,
addons: Vec<Addon>,
iam: IAMConfig,
managed_node_groups: Vec<ManagedNodeGroup>,
}

#[derive(Serialize)]
struct Metadata {
name: String,
region: String,
version: String,
}

#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
struct KubernetesNetworkConfig {
ip_family: String,
}

#[derive(Serialize)]
struct Addon {
name: String,
version: String,
}

#[derive(Serialize)]
#[allow(non_snake_case)]
struct IAMConfig {
withOIDC: bool,
}

#[derive(Serialize)]
struct ManagedNodeGroup {
name: String,
}

#[allow(clippy::unwrap_or_default)]
fn create_yaml(
cluster_name: &str,
region: &str,
version: &str,
zones: &Option<Vec<String>>,
) -> ProviderResult<()> {
let ip_family = if cluster_name.ends_with("ipv6") {
get_family_string(IPFamily::IPv6)
} else {
get_family_string(IPFamily::IPv4)
};

let cluster = Config {
api_version: "eksctl.io/v1alpha5".to_string(),
kind: "ClusterConfig".to_string(),
metadata: Metadata {
name: cluster_name.to_string(),
region: region.to_string(),
version: version.to_string(),
},
availability_zones: zones.clone().unwrap_or_else(Vec::new),
kubernetes_network_config: KubernetesNetworkConfig {
ip_family: ip_family.to_string(),
},
addons: vec![
Addon {
name: "vpc-cni".to_string(),
version: "latest".to_string(),
},
Addon {
name: "coredns".to_string(),
version: "latest".to_string(),
},
Addon {
name: "kube-proxy".to_string(),
version: "latest".to_string(),
},
],
iam: IAMConfig { withOIDC: true },
managed_node_groups: vec![ManagedNodeGroup {
name: "mng-1".to_string(),
}],
};

let yaml =
serde_yaml::to_string(&cluster).context(Resources::Clear, "Failed to serialize YAML");

let mut file = File::create(CLUSTER_CONFIG_PATH)
.context(Resources::Clear, "Failed to create yaml file")?;

file.write_all(yaml.unwrap().as_bytes()).context(
Resources::Clear,
format!(
"Unable to write eksctl configuration to '{}'",
CLUSTER_CONFIG_PATH
),
)?;
info!("YAML file has been created at /local/cluster_config.yaml");

Ok(())
}

impl ClusterConfig {
pub fn new(eksctl_config: EksctlConfig) -> ProviderResult<Self> {
Expand All @@ -144,15 +263,6 @@ impl ClusterConfig {
)?)
.context(Resources::Clear, "Unable to serialize eksctl config.")?;

let config_path = Path::new(TEST_CLUSTER_CONFIG_PATH);
write(config_path, decoded_config).context(
Resources::Clear,
format!(
"Unable to write eksctl configuration to '{}'",
config_path.display()
),
)?;

let (cluster_name, region) = config
.get("metadata")
.map(|metadata| {
Expand Down Expand Up @@ -193,9 +303,9 @@ impl ClusterConfig {
Ok(config)
}

/// Create a cluster with the given config.
// Create a cluster with the given config.
pub fn create_cluster(&self) -> ProviderResult<()> {
let status = match self {
let cluster_config_path = match self {
Self::Args {
cluster_name,
region,
Expand All @@ -206,41 +316,32 @@ impl ClusterConfig {
.as_ref()
.map(|version| version.major_minor_without_v())
.unwrap_or_else(|| DEFAULT_VERSION.to_string());
trace!("Calling eksctl create cluster");
let status = Command::new("eksctl")
.args([
"create",
"cluster",
"-r",
region,
"--zones",
&zones.clone().unwrap_or_default().join(","),
"--version",
&version_arg,
"-n",
cluster_name,
"--nodes",
"0",
"--managed=false",
])
.status()
.context(Resources::Clear, "Failed create cluster")?;
trace!("eksctl create cluster has completed");
status

create_yaml(cluster_name, region, &version_arg, zones)?;
info!(
"assigned create cluster yaml file path is {}",
CLUSTER_CONFIG_PATH
);
CLUSTER_CONFIG_PATH
}
Self::ConfigPath {
cluster_name: _,
region: _,
} => {
trace!("Calling eksctl create cluster with config file");
let status = Command::new("eksctl")
.args(["create", "cluster", "-f", TEST_CLUSTER_CONFIG_PATH])
.status()
.context(Resources::Clear, "Failed create cluster")?;
trace!("eksctl create cluster has completed");
status
info!(
"assigned create cluster yaml file path is {}",
TEST_CLUSTER_CONFIG_PATH
);
TEST_CLUSTER_CONFIG_PATH
}
};

trace!("Calling eksctl create cluster with config file");
let status = Command::new("eksctl")
.args(["create", "cluster", "-f", cluster_config_path])
.status()
.context(Resources::Clear, "Failed create cluster")?;
trace!("eksctl create cluster has completed");
if !status.success() {
return Err(ProviderError::new_with_context(
Resources::Clear,
Expand Down

0 comments on commit b3bcb2e

Please sign in to comment.