Skip to main content

devops_armory/logrotate/
parser.rs

1use std::collections::HashMap;
2use std::fs::File;
3use std::io::{self, Write};
4use std::path::PathBuf;
5use std::path::Path;
6
7use super::models::{
8    LogrotateConfig,
9    CreateSpec
10};
11
12pub type LogrotateFileMap = HashMap<PathBuf, LogrotateConfig>;
13
14/// Custom serializer for logrotate file 
15fn format_entry(path: &PathBuf, cfg: &LogrotateConfig) -> String {
16    let mut s = String::new();
17    s.push_str(&format!("{} {{\n", path.display()));
18
19    if let Some(f) = &cfg.frequency { s.push_str(&format!("    {}\n", f)); }
20    if let Some(r) = cfg.rotate { s.push_str(&format!("    rotate {}\n", r)); }
21    if cfg.compress { s.push_str("    compress\n"); }
22    if cfg.delaycompress { s.push_str("    delaycompress\n"); }
23    if cfg.missingok { s.push_str("    missingok\n"); }
24    if cfg.notifempty { s.push_str("    notifempty\n"); }
25    if let Some(create) = &cfg.create {
26        // format mode as octal with leading zeros (e.g. 0640)
27        s.push_str(&format!(
28            "    create {:04o} {} {}\n",
29            create.mode, create.owner, create.group
30        ));
31    }
32    if cfg.sharedscripts { s.push_str("    sharedscripts\n"); }
33    if let Some(post) = &cfg.postrotate {
34        s.push_str("    postrotate\n");
35        for line in post.lines() {
36            s.push_str("        ");
37            s.push_str(line);
38            s.push('\n');
39        }
40        s.push_str("    endscript\n");
41    }
42
43    s.push_str("}\n\n");
44    s
45}
46
47/// Function to write parsed data into file
48fn write_logrotate_file(path: &std::path::Path, map: &LogrotateFileMap) -> io::Result<()> {
49    let mut file = File::create(path)?;
50    // If ordering matters, iterate in a deterministic order:
51    let mut entries: Vec<_> = map.iter().collect();
52    entries.sort_by_key(|(p, _)| p.clone());
53    for (p, cfg) in entries {
54        let block = format_entry(p, cfg);
55        file.write_all(block.as_bytes())?;
56    }
57    Ok(())
58}
59
60/// Logrotate file creator
61/// Create logrotate conf file based on provided function parameters.
62pub fn logrotate_parser(
63    log_file: &str,
64    freq: Option<String>,
65    rotation: Option<u32>,
66    comp: bool,
67    delaycomp: bool,
68    missok: bool,
69    not_if_empty: bool,
70    create_mode: u32,
71    create_owner: String,
72    create_group: String,
73    shared_scripts: bool,
74    post_rotate: Option<String>, 
75    logrotate_file: &Path
76) -> io::Result<()> {
77    let mut m = LogrotateFileMap::new();
78    m.insert(
79        PathBuf::from(log_file),
80        LogrotateConfig {
81            frequency: freq,
82            rotate: rotation,
83            compress: comp,
84            delaycompress: delaycomp,
85            missingok: missok,
86            notifempty: not_if_empty,
87            create: Some(CreateSpec {
88                mode: create_mode,
89                owner: create_owner,
90                group: create_group,
91            }),
92            sharedscripts: shared_scripts,
93            postrotate: post_rotate,
94        },
95    );
96
97    write_logrotate_file(std::path::Path::new(logrotate_file), &m)
98}