Skip to content

Commit

Permalink
Fixes #23835: Do the same for Blocks
Browse files Browse the repository at this point in the history
  • Loading branch information
Félix Dallidet committed Dec 5, 2023
1 parent 28dc74a commit 79fd607
Show file tree
Hide file tree
Showing 9 changed files with 511 additions and 39 deletions.
23 changes: 18 additions & 5 deletions policies/rudderc/src/backends/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@
use std::path::Path;

use anyhow::Result;

use tracing::trace;

use super::Backend;
use crate::{
backends::unix::{
cfengine::{bundle::Bundle, promise::Promise},
ncf::{method_call::method_call, technique::Technique},
ncf::{dry_run_mode, method_call::method_call, technique::Technique},
},
ir::{
self,
Expand Down Expand Up @@ -77,21 +78,33 @@ impl Backend for Unix {
r: ItemKind,
context: Condition,
technique_id: &Id,
) -> Result<Vec<(Promise, Bundle)>> {
) -> Result<Vec<(Promise, Option<Bundle>)>> {
match r {
ItemKind::Block(r) => {
let mut calls: Vec<(Promise, Bundle)> = vec![];
let mut calls: Vec<(Promise, Option<Bundle>)> = vec![];
if let Some(x) = dry_run_mode::push_policy_mode(
r.policy_mode,
format!("push_policy_mode_for_block_{}", r.id),
) {
calls.push((x, None))
}
for inner in r.items {
calls.extend(resolve_module(
inner,
context.and(&r.condition),
technique_id,
)?);
}
if let Some(x) = dry_run_mode::pop_policy_mode(
r.policy_mode,
format!("pop_policy_mode_for_block_{}", r.id),
) {
calls.push((x, None))
}
Ok(calls)
}
ItemKind::Method(r) => {
let method: Vec<(Promise, Bundle)> =
let method: Vec<(Promise, Option<Bundle>)> =
vec![method_call(technique_id, r, context)?];
Ok(method)
}
Expand Down Expand Up @@ -140,7 +153,7 @@ impl Backend for Unix {
.name(technique.name)
.version(technique.version)
.bundle(main_bundle)
.bundles(call_bundles);
.bundles(call_bundles.into_iter().flatten().collect());
trace!("Generated policy:\n{:#?}", cf_technique);
Ok(if standalone {
format!(
Expand Down
1 change: 1 addition & 0 deletions policies/rudderc/src/backends/unix/ncf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@
//! Once we get rid of these, we will be able to make things more general, but for now,
//! let's stick with what the webapp generates.

pub mod dry_run_mode;
pub mod method_call;
pub mod technique;
29 changes: 29 additions & 0 deletions policies/rudderc/src/backends/unix/ncf/dry_run_mode.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use rudder_commons::PolicyMode;

use crate::backends::unix::cfengine::{promise::Promise, quoted};

pub fn push_policy_mode(op: Option<PolicyMode>, promiser: String) -> Option<Promise> {
op.map(|p| {
Promise::usebundle(
"push_dry_run_mode",
None,
Some(&promiser),
vec![match p {
PolicyMode::Enforce => quoted("false").to_string(),
PolicyMode::Audit => quoted("true").to_string(),
}],
)
})
}
pub fn pop_policy_mode(op: Option<PolicyMode>, promiser: String) -> Option<Promise> {
if op.is_some() {
Some(Promise::usebundle(
"pop_dry_run_mode",
None,
Some(&promiser),
vec![],
))
} else {
None
}
}
40 changes: 12 additions & 28 deletions policies/rudderc/src/backends/unix/ncf/method_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@
//! signature, type, and constraints).

use anyhow::{bail, Result};
use rudder_commons::{canonify, methods::method::Agent, PolicyMode};
use rudder_commons::{canonify, methods::method::Agent};

use crate::{
backends::unix::cfengine::{
bundle::Bundle, cfengine_escape, expanded, promise::Promise, quoted,
backends::unix::{
cfengine::{bundle::Bundle, cfengine_escape, expanded, promise::Promise, quoted},
ncf::dry_run_mode,
},
ir::{
condition::Condition,
Expand All @@ -33,7 +34,7 @@ pub fn method_call(
technique_id: &Id,
m: Method,
condition: Condition,
) -> Result<(Promise, Bundle)> {
) -> Result<(Promise, Option<Bundle>)> {
assert!(!m.name.is_empty());

let info = m.info.unwrap();
Expand Down Expand Up @@ -102,27 +103,8 @@ pub fn method_call(
info.bundle_name
);

let push_policy_mode = m.policy_mode.map(|p| {
Promise::usebundle(
"push_dry_run_mode",
Some(&report_component),
Some(unique),
vec![match p {
PolicyMode::Enforce => quoted("false").to_string(),
PolicyMode::Audit => quoted("true").to_string(),
}],
)
});
let pop_policy_mode = if m.policy_mode.is_some() {
Some(Promise::usebundle(
"pop_dry_run_mode",
Some(&report_component),
Some(unique),
vec![],
))
} else {
None
};
let push_policy_mode = dry_run_mode::push_policy_mode(m.policy_mode, unique.clone());
let pop_policy_mode = dry_run_mode::pop_policy_mode(m.policy_mode, unique.clone());

let mut promises = match (&condition, is_supported) {
(Condition::Expression(_), true) => vec![
Expand Down Expand Up @@ -207,8 +189,10 @@ pub fn method_call(
method_parameters.append(&mut specific_parameters);
Ok((
bundle_call,
Bundle::agent(bundle_name)
.parameters(method_parameters)
.promise_group(bundle_content),
Some(
Bundle::agent(bundle_name)
.parameters(method_parameters)
.promise_group(bundle_content),
),
))
}
33 changes: 27 additions & 6 deletions policies/rudderc/src/backends/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,11 @@ struct WindowsMethod {
policy_mode: Option<PolicyMode>,
}

fn method_call(m: Method, condition: Condition) -> Result<WindowsMethod> {
fn method_call(
m: Method,
condition: Condition,
policy_mode_context: Option<PolicyMode>,
) -> Result<WindowsMethod> {
let Some(report_parameter) = m.params.get(&m.info.unwrap().class_parameter) else {
bail!("Missing parameter {}", m.info.unwrap().class_parameter)
};
Expand Down Expand Up @@ -207,7 +211,15 @@ fn method_call(m: Method, condition: Condition) -> Result<WindowsMethod> {
args,
name: filters::dsc_case(&m.info.as_ref().unwrap().bundle_name).unwrap(),
is_supported,
policy_mode: m.policy_mode,
policy_mode: if let Some(x) = policy_mode_context {
if m.policy_mode.is_none() {
Some(x)
} else {
m.policy_mode
}
} else {
m.policy_mode
},
})
}

Expand All @@ -222,17 +234,26 @@ impl Windows {

fn technique(src: Technique, resources: &Path) -> Result<String> {
// Extract methods
fn resolve_module(r: ItemKind, context: Condition) -> Result<Vec<WindowsMethod>> {
fn resolve_module(
r: ItemKind,
context: Condition,
policy_mode_context: Option<PolicyMode>,
) -> Result<Vec<WindowsMethod>> {
match r {
ItemKind::Block(r) => {
let mut calls: Vec<WindowsMethod> = vec![];
for inner in r.items {
calls.extend(resolve_module(inner, context.and(&r.condition))?);
calls.extend(resolve_module(
inner,
context.and(&r.condition),
r.policy_mode,
)?);
}
Ok(calls)
}
ItemKind::Method(r) => {
let method: Vec<WindowsMethod> = vec![method_call(r, context)?];
let method: Vec<WindowsMethod> =
vec![method_call(r, context, policy_mode_context)?];
Ok(method)
}
_ => todo!(),
Expand All @@ -241,7 +262,7 @@ impl Windows {

let mut methods = vec![];
for item in src.items {
for call in resolve_module(item, Condition::Defined)? {
for call in resolve_module(item, Condition::Defined, None)? {
methods.push(call);
}
}
Expand Down
64 changes: 64 additions & 0 deletions policies/rudderc/tests/cases/general/policy_mode/metadata.xml
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,69 @@
</VALUE>
</REPORTKEYS>
</SECTION>
<SECTION id="57f54359-2b2e-49f9-ab61-a77705615302" name="A block in audit mode" reporting="weighted" component="true" multivalued="true">
<SECTION name="Resolve to audit" id="ea274579-40fc-4545-b384-8d5576a7c69b" component="true" multivalued="true">
<REPORTKEYS>
<VALUE id="ea274579-40fc-4545-b384-8d5576a7c69b">
/tmp/1
</VALUE>
</REPORTKEYS>
</SECTION>
<SECTION name="Resolve to enforce" id="85659b7e-968c-458c-b566-c90108c50833" component="true" multivalued="true">
<REPORTKEYS>
<VALUE id="85659b7e-968c-458c-b566-c90108c50833">
/tmp/1
</VALUE>
</REPORTKEYS>
</SECTION>
<SECTION name="Resolve to audit" id="d8def455-cd43-441f-8dba-1ebae3a29389" component="true" multivalued="true">
<REPORTKEYS>
<VALUE id="d8def455-cd43-441f-8dba-1ebae3a29389">
/tmp/1
</VALUE>
</REPORTKEYS>
</SECTION>
</SECTION>
<SECTION id="1ff82fc2-38fc-4324-92ab-3de5fafcdc14" name="A block in enforce mode" reporting="weighted" component="true" multivalued="true">
<SECTION name="Resolve to audit" id="f9417d97-3a18-4db6-85c3-72e28618bff1" component="true" multivalued="true">
<REPORTKEYS>
<VALUE id="f9417d97-3a18-4db6-85c3-72e28618bff1">
/tmp/1
</VALUE>
</REPORTKEYS>
</SECTION>
<SECTION name="Resolve to enforce" id="c4b4faa1-85e5-4922-b713-c198bf99226e" component="true" multivalued="true">
<REPORTKEYS>
<VALUE id="c4b4faa1-85e5-4922-b713-c198bf99226e">
/tmp/1
</VALUE>
</REPORTKEYS>
</SECTION>
<SECTION name="Resolve to enforce" id="cce62a59-bd17-4858-ba06-6ae41f39b15a" component="true" multivalued="true">
<REPORTKEYS>
<VALUE id="cce62a59-bd17-4858-ba06-6ae41f39b15a">
/tmp/1
</VALUE>
</REPORTKEYS>
</SECTION>
</SECTION>
<SECTION id="7def389a-78d2-4104-b6fc-19c74f14fe93" name="An audit block" reporting="weighted" component="true" multivalued="true">
<SECTION id="9fca6ca8-ccaa-4688-a5fc-e2a0d9d60165" name="A nested block in audit" reporting="weighted" component="true" multivalued="true">
<SECTION name="Resolve to audit" id="0a4299dd-0902-48b2-85ee-13dfe6fc3af6" component="true" multivalued="true">
<REPORTKEYS>
<VALUE id="0a4299dd-0902-48b2-85ee-13dfe6fc3af6">
/tmp/1
</VALUE>
</REPORTKEYS>
</SECTION>
</SECTION>
<SECTION name="Resolve to enforce" id="3b8352df-1329-4956-a019-bb9c072bc830" component="true" multivalued="true">
<REPORTKEYS>
<VALUE id="3b8352df-1329-4956-a019-bb9c072bc830">
/tmp/1
</VALUE>
</REPORTKEYS>
</SECTION>
</SECTION>
</SECTIONS>
</TECHNIQUE>
Loading

0 comments on commit 79fd607

Please sign in to comment.