Compare commits
No commits in common. "55143dcad42b68a601697500ea15564fe2916892" and "29e74a2712de5747951b029b3fb07bcb630778b5" have entirely different histories.
55143dcad4
...
29e74a2712
7
Cargo.lock
generated
7
Cargo.lock
generated
@ -1577,7 +1577,6 @@ dependencies = [
|
|||||||
"serde-value",
|
"serde-value",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_yaml",
|
"serde_yaml",
|
||||||
"similar",
|
|
||||||
"temp-dir",
|
"temp-dir",
|
||||||
"temp-file",
|
"temp-file",
|
||||||
"tokio",
|
"tokio",
|
||||||
@ -4092,12 +4091,6 @@ dependencies = [
|
|||||||
"rand_core 0.6.4",
|
"rand_core 0.6.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "similar"
|
|
||||||
version = "2.7.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "simple_asn1"
|
name = "simple_asn1"
|
||||||
version = "0.6.3"
|
version = "0.6.3"
|
||||||
|
|||||||
47
Cargo.toml
47
Cargo.toml
@ -20,23 +20,34 @@ readme = "README.md"
|
|||||||
license = "GNU AGPL v3"
|
license = "GNU AGPL v3"
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
log = "0.4"
|
log = "0.4.22"
|
||||||
env_logger = "0.11"
|
env_logger = "0.11.5"
|
||||||
derive-new = "0.7"
|
derive-new = "0.7.0"
|
||||||
async-trait = "0.1"
|
async-trait = "0.1.82"
|
||||||
tokio = { version = "1.40", features = ["io-std", "fs", "macros", "rt-multi-thread"] }
|
tokio = { version = "1.40.0", features = [
|
||||||
|
"io-std",
|
||||||
|
"fs",
|
||||||
|
"macros",
|
||||||
|
"rt-multi-thread",
|
||||||
|
] }
|
||||||
cidr = { features = ["serde"], version = "0.2" }
|
cidr = { features = ["serde"], version = "0.2" }
|
||||||
russh = "0.45"
|
russh = "0.45.0"
|
||||||
russh-keys = "0.45"
|
russh-keys = "0.45.0"
|
||||||
rand = "0.8"
|
rand = "0.8.5"
|
||||||
url = "2.5"
|
url = "2.5.4"
|
||||||
kube = "0.98"
|
kube = "0.98.0"
|
||||||
k8s-openapi = { version = "0.24", features = ["v1_30"] }
|
k8s-openapi = { version = "0.24.0", features = ["v1_30"] }
|
||||||
serde_yaml = "0.9"
|
serde_yaml = "0.9.34"
|
||||||
serde-value = "0.7"
|
serde-value = "0.7.0"
|
||||||
http = "1.2"
|
http = "1.2.0"
|
||||||
inquire = "0.7"
|
inquire = "0.7.5"
|
||||||
convert_case = "0.8"
|
convert_case = "0.8.0"
|
||||||
chrono = "0.4"
|
chrono = "0.4"
|
||||||
similar = "2"
|
|
||||||
uuid = { version = "1.11", features = [ "v4", "fast-rng", "macro-diagnostics" ] }
|
[workspace.dependencies.uuid]
|
||||||
|
version = "1.11.0"
|
||||||
|
features = [
|
||||||
|
"v4", # Lets you generate random UUIDs
|
||||||
|
"fast-rng", # Use a faster (but still sufficiently random) RNG
|
||||||
|
"macro-diagnostics", # Enable better diagnostics for compile-time UUIDs
|
||||||
|
]
|
||||||
|
|||||||
@ -53,4 +53,3 @@ fqdn = { version = "0.4.6", features = [
|
|||||||
] }
|
] }
|
||||||
temp-dir = "0.1.14"
|
temp-dir = "0.1.14"
|
||||||
dyn-clone = "1.0.19"
|
dyn-clone = "1.0.19"
|
||||||
similar.workspace = true
|
|
||||||
|
|||||||
@ -10,6 +10,4 @@ lazy_static! {
|
|||||||
std::env::var("HARMONY_REGISTRY_URL").unwrap_or_else(|_| "hub.nationtech.io".to_string());
|
std::env::var("HARMONY_REGISTRY_URL").unwrap_or_else(|_| "hub.nationtech.io".to_string());
|
||||||
pub static ref REGISTRY_PROJECT: String =
|
pub static ref REGISTRY_PROJECT: String =
|
||||||
std::env::var("HARMONY_REGISTRY_PROJECT").unwrap_or_else(|_| "harmony".to_string());
|
std::env::var("HARMONY_REGISTRY_PROJECT").unwrap_or_else(|_| "harmony".to_string());
|
||||||
pub static ref DRY_RUN: bool =
|
|
||||||
std::env::var("HARMONY_DRY_RUN").map_or(true, |value| value.parse().unwrap_or(true));
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,11 +4,9 @@ use kube::{
|
|||||||
Api, Client, Config, Error, Resource,
|
Api, Client, Config, Error, Resource,
|
||||||
api::{Patch, PatchParams},
|
api::{Patch, PatchParams},
|
||||||
config::{KubeConfigOptions, Kubeconfig},
|
config::{KubeConfigOptions, Kubeconfig},
|
||||||
core::ErrorResponse,
|
|
||||||
};
|
};
|
||||||
use log::{debug, error, trace};
|
use log::{debug, error, trace};
|
||||||
use serde::de::DeserializeOwned;
|
use serde::de::DeserializeOwned;
|
||||||
use similar::TextDiff;
|
|
||||||
|
|
||||||
#[derive(new)]
|
#[derive(new)]
|
||||||
pub struct K8sClient {
|
pub struct K8sClient {
|
||||||
@ -50,79 +48,8 @@ impl K8sClient {
|
|||||||
.name
|
.name
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.expect("K8s Resource should have a name");
|
.expect("K8s Resource should have a name");
|
||||||
|
api.patch(name, &patch_params, &Patch::Apply(resource))
|
||||||
if *crate::config::DRY_RUN {
|
.await
|
||||||
match api.get(name).await {
|
|
||||||
Ok(current) => {
|
|
||||||
trace!("Received current value {current:#?}");
|
|
||||||
// The resource exists, so we calculate and display a diff.
|
|
||||||
println!("\nPerforming dry-run for resource: '{}'", name);
|
|
||||||
let mut current_yaml = serde_yaml::to_value(¤t)
|
|
||||||
.expect(&format!("Could not serialize current value : {current:#?}"));
|
|
||||||
if current_yaml.is_mapping() && current_yaml.get("status").is_some() {
|
|
||||||
let map = current_yaml.as_mapping_mut().unwrap();
|
|
||||||
let removed = map.remove_entry("status");
|
|
||||||
trace!("Removed status {:?}", removed);
|
|
||||||
} else {
|
|
||||||
trace!(
|
|
||||||
"Did not find status entry for current object {}/{}",
|
|
||||||
current.meta().namespace.as_ref().unwrap_or(&"".to_string()),
|
|
||||||
current.meta().name.as_ref().unwrap_or(&"".to_string())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
let current_yaml = serde_yaml::to_string(¤t_yaml)
|
|
||||||
.unwrap_or_else(|_| "Failed to serialize current resource".to_string());
|
|
||||||
let new_yaml = serde_yaml::to_string(resource)
|
|
||||||
.unwrap_or_else(|_| "Failed to serialize new resource".to_string());
|
|
||||||
|
|
||||||
if current_yaml == new_yaml {
|
|
||||||
println!("No changes detected.");
|
|
||||||
// Return the current resource state as there are no changes.
|
|
||||||
return Ok(current);
|
|
||||||
}
|
|
||||||
|
|
||||||
println!("Changes detected:");
|
|
||||||
let diff = TextDiff::from_lines(¤t_yaml, &new_yaml);
|
|
||||||
|
|
||||||
// Iterate over the changes and print them in a git-like diff format.
|
|
||||||
for change in diff.iter_all_changes() {
|
|
||||||
let sign = match change.tag() {
|
|
||||||
similar::ChangeTag::Delete => "-",
|
|
||||||
similar::ChangeTag::Insert => "+",
|
|
||||||
similar::ChangeTag::Equal => " ",
|
|
||||||
};
|
|
||||||
print!("{}{}", sign, change);
|
|
||||||
}
|
|
||||||
// In a dry run, we return the new resource state that would have been applied.
|
|
||||||
Ok(resource.clone())
|
|
||||||
}
|
|
||||||
Err(Error::Api(ErrorResponse { code: 404, .. })) => {
|
|
||||||
// The resource does not exist, so the "diff" is the entire new resource.
|
|
||||||
println!("\nPerforming dry-run for new resource: '{}'", name);
|
|
||||||
println!(
|
|
||||||
"Resource does not exist. It would be created with the following content:"
|
|
||||||
);
|
|
||||||
let new_yaml = serde_yaml::to_string(resource)
|
|
||||||
.unwrap_or_else(|_| "Failed to serialize new resource".to_string());
|
|
||||||
|
|
||||||
// Print each line of the new resource with a '+' prefix.
|
|
||||||
for line in new_yaml.lines() {
|
|
||||||
println!("+{}", line);
|
|
||||||
}
|
|
||||||
// In a dry run, we return the new resource state that would have been created.
|
|
||||||
Ok(resource.clone())
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
// Another API error occurred.
|
|
||||||
error!("Failed to get resource '{}': {}", name, e);
|
|
||||||
Err(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return api
|
|
||||||
.patch(name, &patch_params, &Patch::Apply(resource))
|
|
||||||
.await;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn apply_many<K>(&self, resource: &Vec<K>, ns: Option<&str>) -> Result<Vec<K>, Error>
|
pub async fn apply_many<K>(&self, resource: &Vec<K>, ns: Option<&str>) -> Result<Vec<K>, Error>
|
||||||
|
|||||||
@ -138,7 +138,6 @@ impl K8sTenantManager {
|
|||||||
"kind": "NetworkPolicy",
|
"kind": "NetworkPolicy",
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"name": format!("{}-network-policy", config.name),
|
"name": format!("{}-network-policy", config.name),
|
||||||
"namespace": self.get_namespace_name(config),
|
|
||||||
},
|
},
|
||||||
"spec": {
|
"spec": {
|
||||||
"podSelector": {},
|
"podSelector": {},
|
||||||
@ -220,29 +219,8 @@ impl K8sTenantManager {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
let ports: Option<Vec<NetworkPolicyPort>> =
|
|
||||||
c.1.as_ref().map(|spec| match &spec.data {
|
|
||||||
super::PortSpecData::SinglePort(port) => vec![NetworkPolicyPort {
|
|
||||||
port: Some(IntOrString::Int(port.clone().into())),
|
|
||||||
..Default::default()
|
|
||||||
}],
|
|
||||||
super::PortSpecData::PortRange(start, end) => vec![NetworkPolicyPort {
|
|
||||||
port: Some(IntOrString::Int(start.clone().into())),
|
|
||||||
end_port: Some(end.clone().into()),
|
|
||||||
protocol: None, // Not currently supported by Harmony
|
|
||||||
}],
|
|
||||||
|
|
||||||
super::PortSpecData::ListOfPorts(items) => items
|
|
||||||
.iter()
|
|
||||||
.map(|i| NetworkPolicyPort {
|
|
||||||
port: Some(IntOrString::Int(i.clone().into())),
|
|
||||||
..Default::default()
|
|
||||||
})
|
|
||||||
.collect(),
|
|
||||||
});
|
|
||||||
let rule = serde_json::from_value::<NetworkPolicyIngressRule>(json!({
|
let rule = serde_json::from_value::<NetworkPolicyIngressRule>(json!({
|
||||||
"from": cidr_list,
|
"from": cidr_list
|
||||||
"ports": ports,
|
|
||||||
}))
|
}))
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
ExecutorError::ConfigurationError(format!(
|
ExecutorError::ConfigurationError(format!(
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user