Skip to content

Commit

Permalink
feat: add #env macro to policy file parsing
Browse files Browse the repository at this point in the history
Signed-off-by: jlanson <[email protected]>
  • Loading branch information
j-lanson authored and mchernicoff committed Jan 16, 2025
1 parent f6e250c commit f397aac
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 1 deletion.
23 changes: 22 additions & 1 deletion hipcheck/src/policy/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,25 @@ fn rel(opt_var: Option<&str>, file_path: &Path) -> Result<String> {
Ok(path_node)
}

/// Expects a non-None opt_var of format `"<ENV_VAR>"`. 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<String> {
let Some(var) = opt_var else {
return Err(hc_error!("#env macro expects an argument"));
};

// Parse `"<PATH"` to a KdlValue and extract contained string
let entry = kdl::KdlEntry::parse(var).map_err(|e| hc_error!("{}", e))?;
let kdl::KdlValue::String(s) = entry.value() else {
return Err(hc_error!("Content of #env macro must be a string!"));
};

let val = std::env::var(s)
.map_err(|_| hc_error!("#env macro failed to resolve '{}' to a value", s))?;

Ok(format!("\"{val}\""))
}

pub fn preprocess_policy_file(s: &str, file_path: &Path) -> Result<String> {
let mut s = s.to_owned();
// @Note - continues working until all macros resolved. If a macro returns another
Expand All @@ -41,11 +60,13 @@ pub fn preprocess_policy_file(s: &str, file_path: &Path) -> Result<String> {
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));
}
Expand Down
16 changes: 16 additions & 0 deletions site/content/docs/guide/config/policy-file.md
Original file line number Diff line number Diff line change
Expand Up @@ -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("<PATH>")` - 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("<VAR>")` - 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")`

0 comments on commit f397aac

Please sign in to comment.