Skip to main content

rustfs_config/constants/
env.rs

1// Copyright 2024 RustFS Team
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15pub const DEFAULT_DELIMITER: &str = "_";
16pub const ENV_PREFIX: &str = "RUSTFS_";
17pub const ENV_WORD_DELIMITER: &str = "_";
18
19pub const EVENT_DEFAULT_DIR: &str = "/opt/rustfs/events"; // Default directory for event store
20pub const AUDIT_DEFAULT_DIR: &str = "/opt/rustfs/audit"; // Default directory for audit store
21pub const DEFAULT_LIMIT: u64 = 100000; // Default store limit
22
23pub const RUSTFS_WEBHOOK_SKIP_TLS_VERIFY_DEFAULT: bool = false;
24
25/// Standard config keys and values.
26pub const ENABLE_KEY: &str = "enable";
27pub const COMMENT_KEY: &str = "comment";
28
29/// Global switch for enabling the audit module.
30pub const ENV_AUDIT_ENABLE: &str = "RUSTFS_AUDIT_ENABLE";
31/// Global switch for enabling the notify module.
32pub const ENV_NOTIFY_ENABLE: &str = "RUSTFS_NOTIFY_ENABLE";
33/// Default global audit switch (disabled by default).
34pub const DEFAULT_AUDIT_ENABLE: bool = false;
35/// Default global notify switch (disabled by default).
36pub const DEFAULT_NOTIFY_ENABLE: bool = false;
37/// Canonical ILM process boundary env key (seconds).
38pub const ENV_ILM_PROCESS_TIME: &str = "RUSTFS_ILM_PROCESS_TIME";
39/// Deprecated ILM process boundary env key kept for compatibility.
40pub const ENV_ILM_PROCESS_TIME_DEPRECATED: &str = "_RUSTFS_ILM_PROCESS_TIME";
41/// Default ILM process boundary in seconds (24h).
42pub const DEFAULT_ILM_PROCESS_TIME_SECS: i32 = 86400;
43
44/// **TEST/DEBUG ONLY** — lifecycle "day" length override, in seconds.
45///
46/// Modeled on Ceph RGW's `rgw_lc_debug_interval`. When set to a positive
47/// integer `N`, lifecycle rule evaluation treats one Days-based "day" as `N`
48/// seconds instead of [`DEFAULT_ILM_DAY_SECS`] (86400), so `Days`-based
49/// expiration/transition/noncurrent rules become exercisable in seconds under
50/// test. When unset (or set to `0`/an invalid value), behavior is byte-for-byte
51/// identical to production.
52///
53/// This accelerates data deletion and MUST NEVER be set in a production
54/// deployment. Enabling it emits a `WARN` log. It only rescales relative
55/// `Days` deadlines; absolute `Date`-based rules are unaffected.
56pub const ENV_ILM_DEBUG_DAY_SECS: &str = "RUSTFS_ILM_DEBUG_DAY_SECS";
57
58/// Number of seconds in one lifecycle "day" (86400) used as the default when
59/// [`ENV_ILM_DEBUG_DAY_SECS`] is unset.
60pub const DEFAULT_ILM_DAY_SECS: u32 = 86400;
61
62/// Medium-drawn lines separator
63/// This is used to separate words in environment variable names.
64pub const ENV_WORD_DELIMITER_DASH: &str = "-";
65
66#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
67pub enum EnableState {
68    True,
69    False,
70    #[default]
71    Empty,
72    Yes,
73    No,
74    On,
75    Off,
76    Enabled,
77    Disabled,
78    Ok,
79    NotOk,
80    Success,
81    Failure,
82    Active,
83    Inactive,
84    One,
85    Zero,
86}
87impl std::fmt::Display for EnableState {
88    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
89        f.write_str(self.as_str())
90    }
91}
92impl std::str::FromStr for EnableState {
93    type Err = ();
94    fn from_str(s: &str) -> Result<Self, Self::Err> {
95        match s.trim() {
96            s if s.eq_ignore_ascii_case("true") => Ok(EnableState::True),
97            s if s.eq_ignore_ascii_case("false") => Ok(EnableState::False),
98            "" => Ok(EnableState::Empty),
99            s if s.eq_ignore_ascii_case("yes") => Ok(EnableState::Yes),
100            s if s.eq_ignore_ascii_case("no") => Ok(EnableState::No),
101            s if s.eq_ignore_ascii_case("on") => Ok(EnableState::On),
102            s if s.eq_ignore_ascii_case("off") => Ok(EnableState::Off),
103            s if s.eq_ignore_ascii_case("enabled") => Ok(EnableState::Enabled),
104            s if s.eq_ignore_ascii_case("disabled") => Ok(EnableState::Disabled),
105            s if s.eq_ignore_ascii_case("ok") => Ok(EnableState::Ok),
106            s if s.eq_ignore_ascii_case("not_ok") => Ok(EnableState::NotOk),
107            s if s.eq_ignore_ascii_case("success") => Ok(EnableState::Success),
108            s if s.eq_ignore_ascii_case("failure") => Ok(EnableState::Failure),
109            s if s.eq_ignore_ascii_case("active") => Ok(EnableState::Active),
110            s if s.eq_ignore_ascii_case("inactive") => Ok(EnableState::Inactive),
111            "1" => Ok(EnableState::One),
112            "0" => Ok(EnableState::Zero),
113            _ => Err(()),
114        }
115    }
116}
117
118impl EnableState {
119    /// Returns the default value for the enum.
120    pub fn get_default() -> Self {
121        Self::default()
122    }
123    /// Returns the string representation of the enum.
124    pub fn as_str(&self) -> &str {
125        match self {
126            EnableState::True => "true",
127            EnableState::False => "false",
128            EnableState::Empty => "",
129            EnableState::Yes => "yes",
130            EnableState::No => "no",
131            EnableState::On => "on",
132            EnableState::Off => "off",
133            EnableState::Enabled => "enabled",
134            EnableState::Disabled => "disabled",
135            EnableState::Ok => "ok",
136            EnableState::NotOk => "not_ok",
137            EnableState::Success => "success",
138            EnableState::Failure => "failure",
139            EnableState::Active => "active",
140            EnableState::Inactive => "inactive",
141            EnableState::One => "1",
142            EnableState::Zero => "0",
143        }
144    }
145
146    /// is_enabled checks if the state represents an enabled condition.
147    pub fn is_enabled(self) -> bool {
148        matches!(
149            self,
150            EnableState::True
151                | EnableState::Yes
152                | EnableState::On
153                | EnableState::Enabled
154                | EnableState::Ok
155                | EnableState::Success
156                | EnableState::Active
157                | EnableState::One
158        )
159    }
160
161    /// is_disabled checks if the state represents a disabled condition.
162    pub fn is_disabled(self) -> bool {
163        matches!(
164            self,
165            EnableState::False
166                | EnableState::No
167                | EnableState::Off
168                | EnableState::Disabled
169                | EnableState::NotOk
170                | EnableState::Failure
171                | EnableState::Inactive
172                | EnableState::Zero
173                | EnableState::Empty
174        )
175    }
176}
177
178#[cfg(test)]
179mod tests {
180    use super::*;
181    use std::str::FromStr;
182    #[test]
183    fn test_enable_state_display_and_fromstr() {
184        let cases = [
185            (EnableState::True, "true"),
186            (EnableState::False, "false"),
187            (EnableState::Empty, ""),
188            (EnableState::Yes, "yes"),
189            (EnableState::No, "no"),
190            (EnableState::On, "on"),
191            (EnableState::Off, "off"),
192            (EnableState::Enabled, "enabled"),
193            (EnableState::Disabled, "disabled"),
194            (EnableState::Ok, "ok"),
195            (EnableState::NotOk, "not_ok"),
196            (EnableState::Success, "success"),
197            (EnableState::Failure, "failure"),
198            (EnableState::Active, "active"),
199            (EnableState::Inactive, "inactive"),
200            (EnableState::One, "1"),
201            (EnableState::Zero, "0"),
202        ];
203        for (variant, string) in cases.iter() {
204            assert_eq!(&variant.to_string(), string);
205            assert_eq!(EnableState::from_str(string).unwrap(), *variant);
206        }
207        // Test invalid string
208        assert!(EnableState::from_str("invalid").is_err());
209    }
210    #[test]
211    fn test_enable_state_enum() {
212        let cases = [
213            (EnableState::True, "true"),
214            (EnableState::False, "false"),
215            (EnableState::Empty, ""),
216            (EnableState::Yes, "yes"),
217            (EnableState::No, "no"),
218            (EnableState::On, "on"),
219            (EnableState::Off, "off"),
220            (EnableState::Enabled, "enabled"),
221            (EnableState::Disabled, "disabled"),
222            (EnableState::Ok, "ok"),
223            (EnableState::NotOk, "not_ok"),
224            (EnableState::Success, "success"),
225            (EnableState::Failure, "failure"),
226            (EnableState::Active, "active"),
227            (EnableState::Inactive, "inactive"),
228            (EnableState::One, "1"),
229            (EnableState::Zero, "0"),
230        ];
231        for (variant, string) in cases.iter() {
232            assert_eq!(variant.to_string(), *string);
233        }
234    }
235
236    #[test]
237    fn test_enable_state_enum_from_str() {
238        let cases = [
239            ("true", EnableState::True),
240            ("false", EnableState::False),
241            ("", EnableState::Empty),
242            ("yes", EnableState::Yes),
243            ("no", EnableState::No),
244            ("on", EnableState::On),
245            ("off", EnableState::Off),
246            ("enabled", EnableState::Enabled),
247            ("disabled", EnableState::Disabled),
248            ("ok", EnableState::Ok),
249            ("not_ok", EnableState::NotOk),
250            ("success", EnableState::Success),
251            ("failure", EnableState::Failure),
252            ("active", EnableState::Active),
253            ("inactive", EnableState::Inactive),
254            ("1", EnableState::One),
255            ("0", EnableState::Zero),
256        ];
257        for (string, variant) in cases.iter() {
258            assert_eq!(EnableState::from_str(string).unwrap(), *variant);
259        }
260    }
261
262    #[test]
263    fn test_enable_state_default() {
264        let default_state = EnableState::get_default();
265        assert_eq!(default_state, EnableState::Empty);
266        assert_eq!(default_state.as_str(), "");
267    }
268
269    #[test]
270    fn test_enable_state_as_str() {
271        let cases = [
272            (EnableState::True, "true"),
273            (EnableState::False, "false"),
274            (EnableState::Empty, ""),
275            (EnableState::Yes, "yes"),
276            (EnableState::No, "no"),
277            (EnableState::On, "on"),
278            (EnableState::Off, "off"),
279            (EnableState::Enabled, "enabled"),
280            (EnableState::Disabled, "disabled"),
281            (EnableState::Ok, "ok"),
282            (EnableState::NotOk, "not_ok"),
283            (EnableState::Success, "success"),
284            (EnableState::Failure, "failure"),
285            (EnableState::Active, "active"),
286            (EnableState::Inactive, "inactive"),
287            (EnableState::One, "1"),
288            (EnableState::Zero, "0"),
289        ];
290        for (variant, string) in cases.iter() {
291            assert_eq!(variant.as_str(), *string);
292        }
293    }
294
295    #[test]
296    fn test_enable_state_is_enabled() {
297        let enabled_states = [
298            EnableState::True,
299            EnableState::Yes,
300            EnableState::On,
301            EnableState::Enabled,
302            EnableState::Ok,
303            EnableState::Success,
304            EnableState::Active,
305            EnableState::One,
306        ];
307        for state in enabled_states.iter() {
308            assert!(state.is_enabled());
309        }
310
311        let disabled_states = [
312            EnableState::False,
313            EnableState::No,
314            EnableState::Off,
315            EnableState::Disabled,
316            EnableState::NotOk,
317            EnableState::Failure,
318            EnableState::Inactive,
319            EnableState::Zero,
320            EnableState::Empty,
321        ];
322        for state in disabled_states.iter() {
323            assert!(state.is_disabled());
324        }
325    }
326
327    #[test]
328    fn test_global_audit_notify_switch_constants() {
329        assert_eq!(ENV_AUDIT_ENABLE, "RUSTFS_AUDIT_ENABLE");
330        assert_eq!(ENV_NOTIFY_ENABLE, "RUSTFS_NOTIFY_ENABLE");
331    }
332}