Skip to content
Open
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
1 change: 1 addition & 0 deletions crates/api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -844,6 +844,7 @@ impl Display for PolicyReloadError {
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct PolicyChanges {
pub changes: Vec<(String, PolicyChange)>,
pub warnings: Vec<String>,
}

#[derive(Deserialize, Serialize, Debug, Clone)]
Expand Down
8 changes: 8 additions & 0 deletions crates/cli/src/commands/policy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,14 @@ impl Policy {
reset = ansi::RESET
);
}

if !res.warnings.is_empty() {
println!();
}

for w in res.warnings {
println!("{}WARNING{}: {w}", ansi::YELLOW, ansi::RESET);
}
}
}
Ok(())
Expand Down
7 changes: 7 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,8 @@ fn main() -> ExitCode {
}
}

let mut warnings = Vec::new();

// Load all policies.
let mut updates = Vec::new();
let res = policy::reload_all(
Expand All @@ -232,8 +234,13 @@ fn main() -> ExitCode {
|name, _| {
updates.push(name.clone());
},
&mut warnings,
);

for w in warnings {
warn!("{w}");
}

if let Err(err) = res {
error!("Cascade couldn't load all policies: {err}");
return ExitCode::FAILURE;
Expand Down
24 changes: 15 additions & 9 deletions src/policy/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use domain::base::Name;
use domain::base::Ttl;
use domain::tsig::KeyName;
use serde::{Deserialize, Serialize};
use tracing::{debug, error, info, warn};
use tracing::info;

use crate::tsig::TsigStore;
use crate::{api::PolicyReloadError, config::Config};
Expand Down Expand Up @@ -61,8 +61,9 @@ pub fn reload_all(
config: &Config,
tsig_store: &TsigStore,
mut on_change: impl FnMut(&Box<str>, PolicyChange),
warnings: &mut Vec<String>,
) -> Result<(), PolicyReloadError> {
let new_versions = load_all(policies, config, tsig_store)?;
let new_versions = load_all(policies, config, tsig_store, warnings)?;

let mut new_policies = foldhash::HashMap::default();

Expand Down Expand Up @@ -96,9 +97,9 @@ pub fn reload_all(
for (name, policy) in policies.drain() {
// If any zones are using this policy, keep it.
if !policy.zones.is_empty() {
error!(
warnings.push(format!(
"The file backing policy '{name}' has been removed, but some zones are still using it; Cascade will preserve its internal copy"
);
));
let prev = new_policies.insert(name, policy);
assert!(
prev.is_none(),
Expand Down Expand Up @@ -131,6 +132,7 @@ pub fn load_all(
policies: &foldhash::HashMap<Box<str>, Policy>,
config: &Config,
tsig_store: &TsigStore,
warnings: &mut Vec<String>,
) -> Result<foldhash::HashMap<Box<str>, PolicyVersion>, PolicyReloadError> {
// Write the loaded policies to a new hashmap, so policies that no longer
// exist can be detected easily.
Expand All @@ -145,10 +147,10 @@ pub fn load_all(

// Filter for UTF-8 paths.
let Ok(path) = Utf8PathBuf::from_path_buf(entry.path()) else {
warn!(
warnings.push(format!(
"Ignoring potential policy '{}' as the path is non-UTF-8",
entry.path().display()
);
));
continue;
};

Expand All @@ -158,7 +160,7 @@ pub fn load_all(
.expect("this path has a known parent directory")
.starts_with('.')
{
debug!("Ignoring hidden file '{path}' among policies");
warnings.push(format!("Ignoring hidden file '{path}' among policies"));
continue;
}

Expand All @@ -167,7 +169,9 @@ pub fn load_all(
.extension()
.is_none_or(|e| !e.eq_ignore_ascii_case("toml"))
{
warn!("Ignoring potential policy '{path}'; policies must end in '.toml'");
warnings.push(format!(
"Ignoring potential policy '{path}'; policies must end in '.toml'"
));
continue;
}

Expand All @@ -179,7 +183,9 @@ pub fn load_all(
Ok(spec) => spec,
// Ignore a directory ending in '.toml'.
Err(err) if err.kind() == io::ErrorKind::IsADirectory => {
warn!("Ignoring potential policy '{path}'; policies must be files");
warnings.push(format!(
"Ignoring potential policy '{path}'; policies must be files"
));
continue;
}
Err(err) => return Err(PolicyReloadError::Io(path, err.to_string())),
Expand Down
4 changes: 3 additions & 1 deletion src/units/http_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -905,6 +905,7 @@ impl HttpServer {
.collect::<foldhash::HashMap<_, _>>();
let mut changed = false;
let mut updates = Vec::new();
let mut warnings = Vec::new();
let res = crate::policy::reload_all(
&mut state.policies,
&center.config,
Expand All @@ -923,6 +924,7 @@ impl HttpServer {

updates.push((name.clone(), change));
},
&mut warnings,
);

if let Err(err) = res {
Expand Down Expand Up @@ -971,7 +973,7 @@ impl HttpServer {
changes.into_iter().map(|(p, c)| (p.into(), c)).collect();
changes.sort_unstable_by(|l, r| l.0.cmp(&r.0));

Json(Ok(PolicyChanges { changes }))
Json(Ok(PolicyChanges { changes, warnings }))
}

async fn policy_show(
Expand Down
Loading