1
- use std:: { env, path:: Path , str:: FromStr , sync:: OnceLock } ;
1
+ use std:: { env, path:: PathBuf , str:: FromStr , sync:: OnceLock } ;
2
2
3
- use snafu:: { OptionExt , ResultExt , Snafu } ;
3
+ use snafu:: { ResultExt , Snafu } ;
4
4
use tracing:: instrument;
5
5
6
6
use crate :: commons:: networking:: DomainName ;
@@ -11,11 +11,9 @@ const KUBERNETES_SERVICE_HOST_ENV: &str = "KUBERNETES_SERVICE_HOST";
11
11
const KUBERNETES_CLUSTER_DOMAIN_DEFAULT : & str = "cluster.local" ;
12
12
const RESOLVE_CONF_FILE_PATH : & str = "/etc/resolv.conf" ;
13
13
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
16
14
#[ derive( Debug , Snafu ) ]
17
15
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:? }" ) ) ]
19
17
ReadResolvConfFile { source : std:: io:: Error } ,
20
18
21
19
#[ snafu( display( "failed to parse {cluster_domain:?} as domain name" ) ) ]
@@ -24,10 +22,10 @@ pub enum Error {
24
22
cluster_domain : String ,
25
23
} ,
26
24
27
- #[ snafu( display( "unable to find \ " search\ " entry" ) ) ]
25
+ #[ snafu( display( r# "unable to find "search" entry"# ) ) ]
28
26
NoSearchEntry ,
29
27
30
- #[ snafu( display( "unable to find unambiguous domain in \ " search\ " entry" ) ) ]
28
+ #[ snafu( display( r# "unable to find unambiguous domain in "search" entry"# ) ) ]
31
29
AmbiguousDomainEntries ,
32
30
}
33
31
@@ -90,52 +88,58 @@ pub(crate) fn retrieve_cluster_domain() -> Result<DomainName, Error> {
90
88
91
89
tracing:: info!(
92
90
%cluster_domain,
93
- "Using Kubernetes cluster domain from {RESOLVE_CONF_FILE_PATH} file"
91
+ "Using Kubernetes cluster domain from {RESOLVE_CONF_FILE_PATH:? } file"
94
92
) ;
95
93
96
94
Ok ( cluster_domain)
97
95
}
98
96
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" ) ;
104
99
105
100
tracing:: info!(
106
101
%cluster_domain,
107
102
"Could not determine Kubernetes cluster domain as the operator is not running within Kubernetes, assuming default Kubernetes cluster domain"
108
103
) ;
104
+
109
105
Ok ( cluster_domain)
110
106
}
111
107
}
112
108
}
113
109
114
110
#[ 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
122
124
. lines ( )
125
+ . rev ( )
123
126
. 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
+ } ;
128
132
129
- let shortest_entry = last
133
+ let Some ( shortest_entry) = last_search_entry
130
134
. split_ascii_whitespace ( )
131
135
. min_by_key ( |item| item. len ( ) )
132
- . context ( AmbiguousDomainEntriesSnafu ) ?;
136
+ else {
137
+ return AmbiguousDomainEntriesSnafu . fail ( ) ;
138
+ } ;
133
139
134
140
// NOTE (@Techassi): This is really sad and bothers me more than I would like to admit. This
135
141
// clone could be removed by using the code directly in the calling function. But that would
136
142
// 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 :-)
139
143
Ok ( shortest_entry. to_owned ( ) )
140
144
}
141
145
0 commit comments