From f397aac9819c8d923b54d353ae3861161c021ce5 Mon Sep 17 00:00:00 2001 From: jlanson Date: Thu, 16 Jan 2025 10:27:01 -0500 Subject: [PATCH] feat: add #env macro to policy file parsing Signed-off-by: jlanson --- hipcheck/src/policy/macros.rs | 23 ++++++++++++++++++- site/content/docs/guide/config/policy-file.md | 16 +++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/hipcheck/src/policy/macros.rs b/hipcheck/src/policy/macros.rs index 3aed011b..51ed01ed 100644 --- a/hipcheck/src/policy/macros.rs +++ b/hipcheck/src/policy/macros.rs @@ -31,6 +31,25 @@ fn rel(opt_var: Option<&str>, file_path: &Path) -> Result { Ok(path_node) } +/// Expects a non-None opt_var of format `""`. Parses to an environment variable name on +/// the current system and resolves to the value of that env var or returns an error if not found. +fn env(opt_var: Option<&str>) -> Result { + let Some(var) = opt_var else { + return Err(hc_error!("#env macro expects an argument")); + }; + + // Parse `" Result { let mut s = s.to_owned(); // @Note - continues working until all macros resolved. If a macro returns another @@ -41,11 +60,13 @@ pub fn preprocess_policy_file(s: &str, file_path: &Path) -> Result { let opt_parens = caps.get(2); // optional value in parentheses log::debug!("Handling macro: {}", macro_name.as_str()); + let opt_var = opt_parens.map(|x| x.as_str()); // Call the right macro function given the `macro_name`, and get the string // to replace `full` with. let replace = match macro_name.as_str() { - "rel" => rel(opt_parens.map(|x| x.as_str()), file_path)?, + "rel" => rel(opt_var, file_path)?, + "env" => env(opt_var)?, other => { return Err(hc_error!("Unknown policy file macro name '{}'", other)); } diff --git a/site/content/docs/guide/config/policy-file.md b/site/content/docs/guide/config/policy-file.md index 2b88b84e..1bea6e65 100644 --- a/site/content/docs/guide/config/policy-file.md +++ b/site/content/docs/guide/config/policy-file.md @@ -183,3 +183,19 @@ specific analyses such that if those analyses produce a failed result, the overall target of analysis is marked for further investigation regardless of the risk score. In this case, the risk score is still calculated and all other analyses are still run. + +## Macros + +The policy file parsing system supports a few simple macros to increase +flexibility. Macros start with a `#`, followed by a name of two or more +characters, and then an optional open and closed parentheses containing data. + +- `#rel("")` - The `#rel` macro takes a KDL string object as a parameter. + At parse time, the contained string is interpreted as a path, and that path + is interpreted as relative to the directory from which the policy file was + loaded. Without using `#rel()`, paths specified in policy files will be + interpreted as relative to the directory from which `hc` is run. Example: + `binary-file #rel("Binary.toml")` +- `#env("")` - The `#env` macro takes a KDL string object as a parameter + and allows for parse-time environment variable resolution. For instance, + `api-token #env("API_TOKEN")`