pub(super) const SHIMMED: &[&str] = &["az", "gcloud", "oci"];
const CMD_OPERATORS: &[char] = &['&', '|', '<', '>', '^', '%', '"', '\n', '\r'];
const CMD_NOT_FOUND: i32 = 9009;
pub(super) const ENGINE_OVERRIDES: [&str; 2] = ["DOCKER_HOST", "DOCKER_CONTEXT"];
const CLOUD_BLIND: [&str; 2] = ["terraform", "tofu"];
const CLOUD_SETTINGS: [&str; 11] = [
"AWS_",
"ARM_",
"AZURE_",
"GOOGLE_",
"CLOUDSDK_",
"GCLOUD_",
"DIGITALOCEAN_",
"LINODE_",
"OCI_",
"TF_VAR_",
"TF_CLI_ARGS",
];
pub(super) fn withheld(program: &str, inherited: impl Iterator<Item = String>) -> Vec<String> {
if !CLOUD_BLIND.contains(&program) {
return Vec::new();
}
inherited.filter(|name| CLOUD_SETTINGS.iter().any(|p| name.starts_with(p))).collect()
}
pub(super) fn refused_arg<'a>(program: &str, args: &'a [String]) -> Option<&'a str> {
if !SHIMMED.contains(&program) {
return None;
}
args.iter().find(|a| a.contains(CMD_OPERATORS)).map(String::as_str)
}
pub(super) fn missing_behind_cmd(program: &str, code: Option<i32>) -> bool {
SHIMMED.contains(&program) && code == Some(CMD_NOT_FOUND)
}
pub(super) fn uses_engine(program: &str) -> bool {
program == "docker"
}
pub(super) fn strips_engine_overrides(cli_config: Option<&str>) -> bool {
cli_config
.and_then(|c| serde_json::from_str::<serde_json::Value>(c).ok())
.and_then(|v| v.get("currentContext").and_then(|c| c.as_str()).map(|c| !c.is_empty() && c != "default"))
.unwrap_or(false)
}
#[cfg(test)]
mod tests {
use super::*;
fn args(list: &[&str]) -> Vec<String> {
list.iter().map(|s| (*s).to_owned()).collect()
}
#[test]
fn a_cmd_operator_in_an_argument_is_refused() {
assert_eq!(refused_arg("gcloud", &args(&["auth", "list", "--filter=status:ACTIVE"])), None);
for bad in ["x & calc", "a|b", "out>f", "<in", "^x", "%PATH%", "say \"hi\"", "a\nb", "a\rb"] {
assert_eq!(refused_arg("az", &args(&["group", "create", "--name", bad])), Some(bad));
}
assert_eq!(refused_arg("docker", &args(&["a & b"])), None, "only the wrapped tools");
}
#[test]
fn a_wrapped_tool_cmd_cant_find_is_missing() {
for tool in ["az", "gcloud", "oci"] {
assert!(missing_behind_cmd(tool, Some(9009)) && !missing_behind_cmd(tool, Some(1)) && !missing_behind_cmd(tool, None));
}
assert!(!missing_behind_cmd("terraform", Some(9009)));
}
#[test]
fn terraform_inherits_no_cloud_setting_of_the_runners() {
let inherited = [
"PATH",
"HOME",
"AWS_PROFILE",
"AWS_REGION",
"ARM_SUBSCRIPTION_ID",
"GOOGLE_PROJECT",
"TF_VAR_region",
"TF_CLI_ARGS_apply",
"OCI_CLI_PROFILE",
"LINODE_TOKEN",
];
let names = || inherited.iter().map(|s| (*s).to_owned());
assert_eq!(
withheld("terraform", names()),
[
"AWS_PROFILE",
"AWS_REGION",
"ARM_SUBSCRIPTION_ID",
"GOOGLE_PROJECT",
"TF_VAR_region",
"TF_CLI_ARGS_apply",
"OCI_CLI_PROFILE",
"LINODE_TOKEN"
]
);
assert_eq!(withheld("tofu", names()).len(), 8);
assert!(withheld("aws", names()).is_empty(), "a cloud's own CLI reads its settings");
}
#[test]
fn engine_overrides_go_only_with_a_context_the_user_picked() {
assert!(strips_engine_overrides(Some(r#"{"currentContext":"desktop-linux"}"#)));
assert!(!strips_engine_overrides(Some(r#"{"currentContext":"default"}"#)));
assert!(!strips_engine_overrides(Some(r#"{"auths":{}}"#)));
assert!(!strips_engine_overrides(Some("not json")));
assert!(!strips_engine_overrides(None));
assert!(uses_engine("docker") && !uses_engine("vagrant"));
}
}