Skip to content

Commit c686568

Browse files
NickLarsenNZmaltesanderTechassi
committed
chore: Apply suggestions from code review
Co-authored-by: Malte Sander <malte.sander.it@gmail.com> Co-authored-by: Techassi <sascha.lautenschlaeger@stackable.tech>
1 parent d0ab020 commit c686568

File tree

1 file changed

+32
-28
lines changed

1 file changed

+32
-28
lines changed

crates/stackable-operator/src/utils/cluster_domain.rs

Lines changed: 32 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
use std::{env, path::Path, str::FromStr, sync::OnceLock};
1+
use std::{env, path::PathBuf, str::FromStr, sync::OnceLock};
22

3-
use snafu::{OptionExt, ResultExt, Snafu};
3+
use snafu::{ResultExt, Snafu};
44
use tracing::instrument;
55

66
use crate::commons::networking::DomainName;
@@ -11,11 +11,9 @@ const KUBERNETES_SERVICE_HOST_ENV: &str = "KUBERNETES_SERVICE_HOST";
1111
const KUBERNETES_CLUSTER_DOMAIN_DEFAULT: &str = "cluster.local";
1212
const RESOLVE_CONF_FILE_PATH: &str = "/etc/resolv.conf";
1313

14-
// TODO (@Techassi): Do we even need this many variants? Can we get rid of a bunch of variants and
15-
// fall back to defaults instead? Also trace the errors
1614
#[derive(Debug, Snafu)]
1715
pub enum Error {
18-
#[snafu(display("failed to read resolv config from {RESOLVE_CONF_FILE_PATH}"))]
16+
#[snafu(display("failed to read resolv config from {RESOLVE_CONF_FILE_PATH:?}"))]
1917
ReadResolvConfFile { source: std::io::Error },
2018

2119
#[snafu(display("failed to parse {cluster_domain:?} as domain name"))]
@@ -24,10 +22,10 @@ pub enum Error {
2422
cluster_domain: String,
2523
},
2624

27-
#[snafu(display("unable to find \"search\" entry"))]
25+
#[snafu(display(r#"unable to find "search" entry"#))]
2826
NoSearchEntry,
2927

30-
#[snafu(display("unable to find unambiguous domain in \"search\" entry"))]
28+
#[snafu(display(r#"unable to find unambiguous domain in "search" entry"#))]
3129
AmbiguousDomainEntries,
3230
}
3331

@@ -90,52 +88,58 @@ pub(crate) fn retrieve_cluster_domain() -> Result<DomainName, Error> {
9088

9189
tracing::info!(
9290
%cluster_domain,
93-
"Using Kubernetes cluster domain from {RESOLVE_CONF_FILE_PATH} file"
91+
"Using Kubernetes cluster domain from {RESOLVE_CONF_FILE_PATH:?} file"
9492
);
9593

9694
Ok(cluster_domain)
9795
}
9896
Err(_) => {
99-
let cluster_domain = DomainName::from_str(KUBERNETES_CLUSTER_DOMAIN_DEFAULT).context(
100-
ParseDomainNameSnafu {
101-
cluster_domain: KUBERNETES_CLUSTER_DOMAIN_DEFAULT,
102-
},
103-
)?;
97+
let cluster_domain = DomainName::from_str(KUBERNETES_CLUSTER_DOMAIN_DEFAULT)
98+
.expect("KUBERNETES_CLUSTER_DOMAIN_DEFAULT constant must a valid domain");
10499

105100
tracing::info!(
106101
%cluster_domain,
107102
"Could not determine Kubernetes cluster domain as the operator is not running within Kubernetes, assuming default Kubernetes cluster domain"
108103
);
104+
109105
Ok(cluster_domain)
110106
}
111107
}
112108
}
113109

114110
#[instrument]
115-
fn retrieve_cluster_domain_from_resolv_conf<P>(path: P) -> Result<String, Error>
116-
where
117-
P: std::fmt::Debug + AsRef<Path>,
118-
{
119-
let content = std::fs::read_to_string(path).context(ReadResolvConfFileSnafu)?;
120-
121-
let last = content
111+
fn retrieve_cluster_domain_from_resolv_conf(
112+
path: impl Into<PathBuf> + std::fmt::Debug,
113+
) -> Result<String, Error> {
114+
let path = path.into();
115+
let content = std::fs::read_to_string(&path)
116+
.inspect_err(|error| {
117+
tracing::error!(%error, path = %path.display(), "Cannot read resolv conf");
118+
})
119+
.context(ReadResolvConfFileSnafu)?;
120+
121+
// If there are multiple search directives, only the search
122+
// man 5 resolv.conf
123+
let Some(last_search_entry) = content
122124
.lines()
125+
.rev()
123126
.map(|l| l.trim())
124-
.filter(|l| l.starts_with("search"))
125-
.map(|l| l.trim_start_matches("search"))
126-
.last()
127-
.context(NoSearchEntrySnafu)?;
127+
.find(|&l| l.starts_with("search"))
128+
.map(|l| l.trim_start_matches("search").trim())
129+
else {
130+
return NoSearchEntrySnafu.fail();
131+
};
128132

129-
let shortest_entry = last
133+
let Some(shortest_entry) = last_search_entry
130134
.split_ascii_whitespace()
131135
.min_by_key(|item| item.len())
132-
.context(AmbiguousDomainEntriesSnafu)?;
136+
else {
137+
return AmbiguousDomainEntriesSnafu.fail();
138+
};
133139

134140
// NOTE (@Techassi): This is really sad and bothers me more than I would like to admit. This
135141
// clone could be removed by using the code directly in the calling function. But that would
136142
// remove the possibility to easily test the parsing.
137-
// NOTE (@maltesander): This is only executed once at the start of the operator, so we can
138-
// can live with that performance reduction :-)
139143
Ok(shortest_entry.to_owned())
140144
}
141145

0 commit comments

Comments
 (0)