Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 46 additions & 38 deletions hack/dummy_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,45 +29,54 @@ etcd_endpoint: localhost:2379
extend_expiration: true
force_expire: false
hostname: test.hostname
ip:
- 192.168.126.99
- 2001:db8::99
# proxy: http://registry.kni-qe-0.lab.eng.rdu2.redhat.com:3128|http://registry.kni-qe-0.lab.eng.rdu2.redhat.com:3130|.cluster.local,.kni-qe-2.lab.eng.rdu2.redhat.com,.svc,127.0.0.1,2620:52:0:11c::/64,2620:52:0:11c::1,2620:52:0:11c::10,2620:52:0:11c::11,2620:52:0:199::/64,api-int.kni-qe-2.lab.eng.rdu2.redhat.com,fd01::/48,fd02::/112,localhost|http://registry.kni-qe-0.lab.eng.rdu2.redhat.com:3128|http://registry.kni-qe-0.lab.eng.rdu2.redhat.com:3130|.cluster.local,.kni-qe-2.lab.eng.rdu2.redhat.com,.svc,127.0.0.1,2620:52:0:11c::/64,2620:52:0:11c::1,2620:52:0:11c::10,2620:52:0:11c::11,2620:52:0:199::/64,api-int.kni-qe-2.lab.eng.rdu2.redhat.com,fd01::/48,fd02::/112,localhost,moreproxy
install_config: |
additionalTrustBundlePolicy: Proxyonly
apiVersion: v1
baseDomain: ibo0.redhat.com
bootstrapInPlace:
installationDisk: /dev/disk/by-path/pci-0000:04:00.0
compute:
- architecture: amd64
hyperthreading: Enabled
name: worker
platform: {}
replicas: 0
controlPlane:
architecture: amd64
hyperthreading: Enabled
name: master
platform: {}
replicas: 1
metadata:
creationTimestamp: null
name: seed
networking:
clusterNetwork:
- cidr: 10.128.0.0/14
hostPrefix: 23
machineNetwork:
- cidr: 192.168.126.0/24
networkType: OVNKubernetes
serviceNetwork:
- 172.30.0.0/16
platform:
none: {}
publish: External
pullSecret: ""
sshKey: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDThIOETj6iTvbCaNv15tZg121nWLcwtJuZofc1QS5iAdw8C8fN2R39cSW/ambikl2Fr6YNBBVR3znbtmattOyWyxAOFUfdY0aw0MqZb4LWLf04q6X0KsWIYWaV3ol0KxTzgvX38i/IU42XQfJwMYFE8dQ15TZ7l+FTKKi3SUPXLuy/9CXRfaCDZ2dKMcCkelkTr0KR1HdjiKQ86rMfk9JUbAf7D29aAQq4h1WNnHMM9vnbqN7MW9L8ebn/lCTJjGQ56r0UmurgyIEMt0P+CGp1e4AUNKYsPoYFB0GNwUkr/rB8LeuCOaZcoWdYXlUJaN45GjtCDon56+AoMA9V8tYkV6HqyFwGQjoGKI1cRCHXDJnGyAbMd9OK94TWJmNvtdHkbSURHyw2G7otZpAkRuEvMP0C7R+3JmuxrDA8yaUgWvgccqGcmFl1krClksW6KrAXNlwhZ4QOAMhDrXwwPfOOQoG82zPpg+g9gZQIhkro1Cje4bmWz5z5fiuDloTq1vc=
root@edge-01.edge.lab.eng.rdu2.redhat.com
ip: 192.168.126.99
kubeadmin_password_hash: $2a$10$20Q4iRLy7cWZkjn/D07bF.RZQZonKwstyRGH0qiYbYRkx5Pe4Ztyi
additionalTrustBundlePolicy: Proxyonly
apiVersion: v1
baseDomain: ibo0.redhat.com
bootstrapInPlace:
installationDisk: /dev/disk/by-path/pci-0000:04:00.0
compute:
- architecture: amd64
hyperthreading: Enabled
name: worker
platform: {}
replicas: 0
controlPlane:
architecture: amd64
hyperthreading: Enabled
name: master
platform: {}
replicas: 1
metadata:
creationTimestamp: null
name: seed
networking:
clusterNetwork:
- cidr: 10.128.0.0/14
hostPrefix: 23
- cidr: fd01::/48
hostPrefix: 64
machineNetwork:
- cidr: 192.168.128.0/24
- cidr: 1001:db8::/120
networkType: OVNKubernetes
serviceNetwork:
- 172.30.0.0/16
- fd02::/112
platform:
none: {}
publish: External
pullSecret: ""
sshKey: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDThIOETj6iTvbCaNv15tZg121nWLcwtJuZofc1QS5iAdw8C8fN2R39cSW/ambikl2Fr6YNBBVR3znbtmattOyWyxAOFUfdY0aw0MqZb4LWLf04q6X0KsWIYWaV3ol0KxTzgvX38i/IU42XQfJwMYFE8dQ15TZ7l+FTKKi3SUPXLuy/9CXRfaCDZ2dKMcCkelkTr0KR1HdjiKQ86rMfk9JUbAf7D29aAQq4h1WNnHMM9vnbqN7MW9L8ebn/lCTJjGQ56r0UmurgyIEMt0P+CGp1e4AUNKYsPoYFB0GNwUkr/rB8LeuCOaZcoWdYXlUJaN45GjtCDon56+AoMA9V8tYkV6HqyFwGQjoGKI1cRCHXDJnGyAbMd9OK94TWJmNvtdHkbSURHyw2G7otZpAkRuEvMP0C7R+3JmuxrDA8yaUgWvgccqGcmFl1krClksW6KrAXNlwhZ4QOAMhDrXwwPfOOQoG82zPpg+g9gZQIhkro1Cje4bmWz5z5fiuDloTq1vc=
root@edge-01.edge.lab.eng.rdu2.redhat.com
machine_network_cidr:
- 192.168.128.0/24
- 1001:db8::/120
kubeadmin_password_hash: "$2a$10$20Q4iRLy7cWZkjn/D07bF.RZQZonKwstyRGH0qiYbYRkx5Pe4Ztyi"
# proxy_trusted_ca_bundle: 'user-ca-bundle:'
# user_ca_bundle: |
# # Foo
Expand All @@ -92,7 +101,6 @@ kubeadmin_password_hash: $2a$10$20Q4iRLy7cWZkjn/D07bF.RZQZonKwstyRGH0qiYbYRkx5Pe
# 42TI0UzcqRV4CWDoARMSV8yMLajZ0g1eEreUprwmFcOy17V7KCeV6E8lKb21OU8M
# Ad9q3H0iXjct
# -----END CERTIFICATE-----
machine_network_cidr: 192.168.127.0/24
postprocess_only: false
pull_secret: '{"auths":{"empty_registry":{"username":"empty","password":"empty","auth":"ZW1wdHk6ZW1wdHk=","email":""}}}'
summary_file: summary.yaml
Expand Down
54 changes: 40 additions & 14 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,15 @@ pub(crate) struct ClusterCustomizations {
pub(crate) files: Vec<ConfigPath>,
pub(crate) cluster_rename: Option<ClusterNamesRename>,
pub(crate) hostname: Option<String>,
pub(crate) ip: Option<String>,
pub(crate) ip_addresses: Vec<String>,
pub(crate) proxy: Option<Proxy>,
pub(crate) install_config: Option<String>,
pub(crate) kubeadmin_password_hash: Option<String>,
#[serde(serialize_with = "redact")]
pub(crate) pull_secret: Option<String>,
pub(crate) user_ca_bundle: Option<String>,
pub(crate) proxy_trusted_ca_bundle: Option<ProxyAdditionalTrustBundle>,
pub(crate) machine_network_cidr: Option<String>,
pub(crate) machine_network_cidrs: Vec<String>,
pub(crate) chrony_config: Option<String>,
}

Expand Down Expand Up @@ -155,12 +155,12 @@ impl RecertConfig {
files: vec![],
cluster_rename: None,
hostname: None,
ip: None,
ip_addresses: vec![],
kubeadmin_password_hash: None,
pull_secret: None,
proxy: None,
install_config: None,
machine_network_cidr: None,
machine_network_cidrs: vec![],
user_ca_bundle: None,
proxy_trusted_ca_bundle: None,
chrony_config: None,
Expand Down Expand Up @@ -222,9 +222,20 @@ impl RecertConfig {
Some(value) => Some(value.as_str().context("hostname must be a string")?.to_string()),
None => None,
};
let ip = match value.remove("ip") {
Some(value) => Some(value.as_str().context("ip must be a string")?.to_string()),
None => None,
let ip_addresses: Vec<String> = match value.remove("ip") {
Some(serde_json::Value::Array(array)) => {
ensure!(array.len() <= 2, "ip array must up to 2 elements");
array
.iter()
.map(|v| -> Result<String, anyhow::Error> { Ok(v.as_str().context("ip array element must be a string")?.to_string()) })
.collect::<Result<Vec<_>, _>>()?
}
Some(serde_json::Value::String(single_ip)) => {
// Handle single IP for backward compatibility
vec![single_ip.to_string()]
}
None => vec![],
_ => anyhow::bail!("ip must be a string or an array of strings"),
};
let pull_secret = match value.remove("pull_secret") {
Some(value) => Some(value.as_str().context("pull_secret must be a string")?.to_string()),
Expand Down Expand Up @@ -260,9 +271,24 @@ impl RecertConfig {
),
None => None,
};
let machine_network_cidr = match value.remove("machine_network_cidr") {
Some(value) => Some(value.as_str().context("machine_network_cidr must be a string")?.to_string()),
None => None,
let machine_network_cidrs = match value.remove("machine_network_cidr") {
Some(serde_json::Value::Array(array)) => {
ensure!(array.len() <= 2, "machine_network_cidr array must up to 2 elements");
array
.iter()
.map(|v| -> Result<String, anyhow::Error> {
Ok(v.as_str()
.context("machine_network_cidr array element must be a string")?
.to_string())
})
.collect::<Result<Vec<_>, _>>()?
}
Some(serde_json::Value::String(single_cidr)) => {
// Handle single CIDR for backward compatibility
vec![single_cidr.to_string()]
}
None => vec![],
_ => anyhow::bail!("machine_network_cidr must be a string or an array of strings"),
};
let chrony_config = match value.remove("chrony_config") {
Some(value) => Some(value.as_str().context("chrony_config must be a string")?.to_string()),
Expand Down Expand Up @@ -338,14 +364,14 @@ impl RecertConfig {
files: cluster_customization_files,
cluster_rename,
hostname,
ip,
ip_addresses,
kubeadmin_password_hash: set_kubeadmin_password_hash,
pull_secret,
user_ca_bundle,
proxy_trusted_ca_bundle,
proxy,
install_config,
machine_network_cidr,
machine_network_cidrs,
chrony_config,
};

Expand Down Expand Up @@ -429,14 +455,14 @@ impl RecertConfig {
},
cluster_rename: cli.cluster_rename,
hostname: cli.hostname,
ip: cli.ip,
ip_addresses: cli.ip,
proxy: cli.proxy,
install_config: cli.install_config,
kubeadmin_password_hash: cli.kubeadmin_password_hash,
pull_secret: cli.pull_secret,
user_ca_bundle: cli.user_ca_bundle,
proxy_trusted_ca_bundle: cli.proxy_trusted_ca_bundle,
machine_network_cidr: cli.machine_network_cidr,
machine_network_cidrs: cli.machine_network_cidr,
chrony_config: cli.chrony_config,
},
encryption_customizations: EncryptionCustomizations {
Expand Down
9 changes: 5 additions & 4 deletions src/config/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,9 @@ pub(crate) struct Cli {
pub(crate) hostname: Option<String>,

/// If given, the cluster resources that include the IP address will be modified to use this
/// one instead.
/// one instead. For dual stack, provide multiple IP addresses (IPv4 first).
#[clap(long)]
pub(crate) ip: Option<String>,
pub(crate) ip: Vec<String>,

/// If given, the cluster's HTTP proxy configuration will be modified to use this one instead.
#[clap(long, value_parser = Proxy::parse)]
Expand Down Expand Up @@ -150,10 +150,11 @@ pub(crate) struct Cli {

/// The CIDR of the machine network. If given, the machine network CIDR which appears in the
/// install-config found in the cluster-config-v1 configmaps will be modified to use this
/// machine CIDR. WARNING: If a different machine network CIDR is stated in the
/// machine CIDR. For dual stack, provide multiple IPv4 and IPv6 CIDRs (IPv4 first).
/// WARNING: If a different machine network CIDR is stated in the
/// --install-config parameter, it might overwrite the one given here.
#[clap(long)]
pub(crate) machine_network_cidr: Option<String>,
pub(crate) machine_network_cidr: Vec<String>,

/// If given, the cluster resources that include chrony.config be modified to have this value.
#[clap(long)]
Expand Down
4 changes: 3 additions & 1 deletion src/etcd_encoding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use super::protobuf_gen::{
admissionregistration::v1::{MutatingWebhookConfiguration, ValidatingWebhookConfiguration},
apps::v1::{ControllerRevision, DaemonSet, Deployment, StatefulSet},
batch::v1::{CronJob, Job},
core::v1::{ConfigMap, Secret},
core::v1::{ConfigMap, Node, Secret},
},
apimachinery::pkg::runtime::{TypeMeta, Unknown},
},
Expand Down Expand Up @@ -56,6 +56,7 @@ k8s_type!(JobWithMeta, Job);
k8s_type!(CronJobWithMeta, CronJob);
k8s_type!(StatefulSetWithMeta, StatefulSet);
k8s_type!(ConfigMapWithMeta, ConfigMap);
k8s_type!(NodeWithMeta, Node);
k8s_type!(SecretWithMeta, Secret);
k8s_type!(ValidatingWebhookConfigurationWithMeta, ValidatingWebhookConfiguration);
k8s_type!(MutatingWebhookConfigurationWithMeta, MutatingWebhookConfiguration);
Expand Down Expand Up @@ -86,6 +87,7 @@ pub(crate) async fn decode(data: &[u8]) -> Result<Vec<u8>> {
"StatefulSet" => serde_json::to_vec(&StatefulSetWithMeta::try_from(unknown)?)?,
"DaemonSet" => serde_json::to_vec(&DaemonsSetWithMeta::try_from(unknown)?)?,
"ConfigMap" => serde_json::to_vec(&ConfigMapWithMeta::try_from(unknown)?)?,
"Node" => serde_json::to_vec(&NodeWithMeta::try_from(unknown)?)?,
"Secret" => serde_json::to_vec(&SecretWithMeta::try_from(unknown)?)?,
"ValidatingWebhookConfiguration" => serde_json::to_vec(&ValidatingWebhookConfigurationWithMeta::try_from(unknown)?)?,
"MutatingWebhookConfiguration" => serde_json::to_vec(&MutatingWebhookConfigurationWithMeta::try_from(unknown)?)?,
Expand Down
37 changes: 33 additions & 4 deletions src/ocp_postprocess.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,19 @@ async fn run_cluster_customizations(
.context("renaming cluster")?;
}

if let Some(ip) = &cluster_customizations.ip {
ip_rename(in_memory_etcd_client, ip, dirs, files).await.context("renaming IP")?;
let ips = &cluster_customizations.ip_addresses;
if ips.len() == 1 {
log::info!("Processing single IP: {}", ips[0]);
ip_rename(in_memory_etcd_client, &ips[0], dirs, files)
.await
.context(format!("renaming IP {}", ips[0]))?;
} else if ips.len() == 2 {
log::info!("Processing dual-stack IPs: {}", ips.join(", "));
ip_rename_dual_stack(in_memory_etcd_client, ips, dirs, files)
.await
.context("renaming dual-stack IPs")?;
} else if ips.is_empty() {
log::info!("No IPs were provided, skipping IP rename");
}

if let Some(hostname) = &cluster_customizations.hostname {
Expand Down Expand Up @@ -196,8 +207,11 @@ async fn run_cluster_customizations(
.await
.context("renaming additional trust bundle")?;

if let Some(machine_network_cidr) = &cluster_customizations.machine_network_cidr {
fix_machine_network_cidr(in_memory_etcd_client, machine_network_cidr, dirs, files)
let machine_network_cidrs = &cluster_customizations.machine_network_cidrs;
if !machine_network_cidrs.is_empty() {
let combined_cidrs = machine_network_cidrs.join(",");
log::info!("Processing machine network CIDRs: {}", combined_cidrs);
fix_machine_network_cidr(in_memory_etcd_client, &combined_cidrs, dirs, files)
.await
.context("fixing machine network CIDR")?;
}
Expand Down Expand Up @@ -913,6 +927,21 @@ pub(crate) async fn ip_rename(
Ok(())
}

pub(crate) async fn ip_rename_dual_stack(
in_memory_etcd_client: &Arc<InMemoryK8sEtcd>,
ips: &[String],
dirs: &[ConfigPath],
files: &[ConfigPath],
) -> Result<()> {
let etcd_client = in_memory_etcd_client;

ip_rename::rename_all_dual_stack(etcd_client, ips, dirs, files)
.await
.context("renaming all dual stack")?;

Ok(())
}

pub(crate) async fn pull_secret_rename(
in_memory_etcd_client: &Arc<InMemoryK8sEtcd>,
pull_secret: &str,
Expand Down
Loading