Skip to content

Commit

Permalink
Work in progress
Browse files Browse the repository at this point in the history
  • Loading branch information
amousset committed Oct 26, 2022
1 parent ff3b2da commit 63665c7
Show file tree
Hide file tree
Showing 15 changed files with 770 additions and 368 deletions.
196 changes: 144 additions & 52 deletions policies/Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion policies/resource-types/directory/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
= Template
# Template

Template resource type.

Expand Down
2 changes: 1 addition & 1 deletion policies/resource-types/template/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ serde = { version = "1", features = ["derive"] }
serde_json = "1"
# we want stable order in produced config files
# json and urlencode provide built-in filters
minijinja = { version = "0.23.0", features = ["preserve_order", "json", "urlencode"] }
minijinja = { version = "0.24.0", features = ["preserve_order", "json", "urlencode"] }
mustache = "0.9.0"
rudder_resource_type = { path = "../../rudder-resource-type" }

Expand Down
2 changes: 1 addition & 1 deletion policies/resource-types/template/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
= Directory
# Directory

Directory resource type.
2 changes: 1 addition & 1 deletion policies/rudderc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ license = "GPL-3.0-or-later"
anyhow = "1"
clap = { version = "4", features = ["derive"] }
colored = "2"
quick-xml = { version = "0.25", features = ["serialize"] }
quick-xml = { version = "0.26", features = ["serialize"] }
regex = "1"
fancy-regex = "0.10"
serde = { version = "1", features = ["derive"] }
Expand Down
2 changes: 2 additions & 0 deletions policies/rudderc/docs/examples/ntp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,5 @@ resources:
enforce: "true"
reporting:
enabled: true
files:
- ntp.conf.tpl
184 changes: 144 additions & 40 deletions policies/rudderc/src/backends/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,60 +4,79 @@
//! Generation of metadata.xml, shared by different backends
//!
//! Contains information about expected reports for the Rudder app
//!
//! WARNING: We do not implement the format exhaustively but only the parts we need to
//! generate our metadata file. There are parts that are probably optional, and others missing.

use crate::ir::resource::Id;
use anyhow::Result;
use quick_xml::{se::Serializer, Writer};
use serde::Serialize;

/*
<TECHNIQUE name="Audit config values">
<DESCRIPTION></DESCRIPTION>
<USEMETHODREPORTING>true</USEMETHODREPORTING>
<AGENT type="cfengine-community,cfengine-nova">
<BUNDLES>
<NAME>Audit_config_values</NAME>
</BUNDLES>
<FILES>
<FILE name="RUDDER_CONFIGURATION_REPOSITORY/techniques/ncf_techniques/Audit_config_values/1.0/technique.cf">
<INCLUDED>true</INCLUDED>
</FILE>
</FILES>
</AGENT>
<AGENT type="dsc">
<BUNDLES>
<NAME>Audit-Config-Values</NAME>
</BUNDLES>
<FILES>
<FILE name="RUDDER_CONFIGURATION_REPOSITORY/techniques/ncf_techniques/Audit_config_values/1.0/technique.ps1">
<INCLUDED>true</INCLUDED>
</FILE>
</FILES>
</AGENT>
<SECTIONS>
<SECTION component="true" multivalued="true" id="dcf1f0d5-80e5-42f6-8844-280822a9af17" name="Variable string from Augeas">
<REPORTKEYS>
<VALUE id="dcf1f0d5-80e5-42f6-8844-280822a9af17">key</VALUE>
</REPORTKEYS>
</SECTION>
<SECTION component="true" multivalued="true" id="ff4ca248-2e26-445c-9cfc-f49d9687c0c6" name="Variable string match">
<REPORTKEYS>
<VALUE id="ff4ca248-2e26-445c-9cfc-f49d9687c0c6">audit_ini.key</VALUE>
</REPORTKEYS>
</SECTION>
</SECTIONS>
</TECHNIQUE>
*/
use std::str::FromStr;

// metadata(policy: Policy)
pub fn metadata() -> Result<String> {
let mut buffer = Vec::new();
// FIXME indent does not seem to work
let writer = Writer::new_with_indent(&mut buffer, b' ', 2);
let mut ser = Serializer::with_root(writer, Some("TECHNIQUE"));
Technique {
name: "Configure NTP".into(),
description: Description {
value: "This is a description".into(),
},
use_method_reporting: UseMethodReporting {
value: true,
},
agent: vec![
Agent {
_type: "dsc".to_string(),
bundles: Bundles {
name: vec![Name {
value: "package_present".to_string(),
}],
},
files: Files {
file: vec![
File { name: "RUDDER_CONFIGURATION_REPOSITORY/techniques/ncf_techniques/Audit_config_values/1.0/technique.ps1".to_string(),
included: Included {value: true},
out_path: None,}
],
},
},
Agent {
_type: "cfengine-community,cfengine-nova".to_string(),
bundles: Bundles {
name: vec![Name {
value: "Package-Present".to_string(),
}],
},
files: Files {
file: vec![
File {
name: "RUDDER_CONFIGURATION_REPOSITORY/techniques/ncf_techniques/Audit_config_values/1.0/technique.cf".to_string(),
included: Included {value: true},
out_path: Some(
OutPath {
value: "CIS_5_OS_Services/1.0/resources/rudder-square.png".to_string()
}
)
}
],
},
},
],
sections: Sections {
section: vec![Section {
name: "Variable string match".to_string(),
id: Id::from_str("1e65ca00-6c33-4455-94b1-3a3c9f6eb36f").unwrap(),
component: true,
multivalued: true,
value: vec![ReportKey {
value: "key".to_string(), id: Id::from_str("5dbfb761-f15f-40b5-9f75-b3d88b81483e").unwrap(),
}],
}],
},
}
.serialize(&mut ser)?;
Ok(String::from_utf8(buffer.clone()).unwrap())
Expand All @@ -67,11 +86,96 @@ pub fn metadata() -> Result<String> {
struct Technique {
name: String,
description: Description,
#[serde(rename = "usemethodreporting")]
use_method_reporting: UseMethodReporting,
agent: Vec<Agent>,
sections: Sections,
}

#[derive(Debug, PartialEq, Serialize)]
struct Description {
#[serde(rename = "$value")]
value: String,
}

#[derive(Debug, PartialEq, Serialize)]
struct UseMethodReporting {
#[serde(rename = "$value")]
value: bool,
}

#[derive(Debug, PartialEq, Serialize)]
struct Agent {
#[serde(rename = "type")]
_type: String,
bundles: Bundles,
files: Files,
}

#[derive(Debug, PartialEq, Serialize)]
struct Files {
file: Vec<File>,
}

#[derive(Debug, PartialEq, Serialize)]
struct File {
name: String,
included: Included,
#[serde(rename = "outpath")]
out_path: Option<OutPath>,
}

#[derive(Debug, PartialEq, Serialize)]
struct Included {
#[serde(rename = "$value")]
value: bool,
}

#[derive(Debug, PartialEq, Serialize)]
struct OutPath {
#[serde(rename = "$value")]
value: String,
}

#[derive(Debug, PartialEq, Serialize)]
struct Bundles {
name: Vec<Name>,
}

#[derive(Debug, PartialEq, Serialize)]
struct Name {
#[serde(rename = "$value")]
value: String,
}

#[derive(Debug, PartialEq, Serialize)]
struct Sections {
section: Vec<Section>,
}

#[derive(Debug, PartialEq, Serialize)]
struct Section {
name: String,
id: Id,
component: bool,
multivalued: bool,
value: Vec<ReportKey>,
// FIXME allow subsections
/*
<SECTIONS>
<SECTION component="true" multivalued="true" name="Copy rootshell files and change permissions" reporting="weighted">
<SECTION component="true" multivalued="true" id="0f5c4ffd-d05c-4e41-9903-f32420677f41" name="Check /var/www/rootshell folder exist">
<REPORTKEYS>
<VALUE id="0f5c4ffd-d05c-4e41-9903-f32420677f41">/var/www/rootshell</VALUE>
</REPORTKEYS>
*/
}

#[derive(Debug, PartialEq, Serialize)]
struct ReportKey {
#[serde(rename = "$value")]
value: String,
id: Id,
}

#[cfg(test)]
Expand All @@ -84,7 +188,7 @@ mod tests {
fn it_computes_metadata_xml() {
assert_eq!(
metadata().unwrap(),
r#"<TECHNIQUE name="Configure NTP"><description value="This is a description"/>
r#"<TECHNIQUE name="Configure NTP"><description>This is a description</description><agent type="dsc"/><agent type="cfengine-community,cfengine-nova"/>
</TECHNIQUE>"#
);
}
Expand Down
64 changes: 32 additions & 32 deletions policies/rudderc/src/backends/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::{
cfengine::{bundle::Bundle, promise::Promise},
ncf::{method_call::MethodCall, technique::Technique},
},
ir::{self, resource::Resource},
ir::{self, resource::ResourceKind},
};

// TODO support macros at the policy or bundle level
Expand Down Expand Up @@ -41,9 +41,9 @@ impl Backend for Unix {
"${this.promise_dirname}/resources",
)]);

fn resolve_resource(r: Resource, context: &str) -> Result<Vec<MethodCall>> {
fn resolve_resource(r: ResourceKind, context: &str) -> Result<Vec<MethodCall>> {
match r {
Resource::BlockResource(r) => {
ResourceKind::BlockResource(r) => {
let mut result: Vec<MethodCall> = vec![];
for inner in r.resources {
result.extend(resolve_resource(
Expand All @@ -53,38 +53,38 @@ impl Backend for Unix {
}
Ok(result)
}
Resource::LeafResource(r) => {
ResourceKind::Method(r) => {
let mut branch_result: Vec<MethodCall> = vec![];
for state in r.states {
// sort the params in arbitrary order to make the tests more determinist
// must be removed when we the parameters ordering will be implemented
// Add quotes around the parameters as the bundle call expects them.
let method_params = {
let mut vec = state.params.values().cloned().collect::<Vec<String>>();
vec = vec
.iter()
.map(|x| format!("\"{}\"", x))
.collect::<Vec<String>>();
vec.sort();
vec
};
let method = MethodCall::new()
.id(state.id.clone())
.resource(r.resource_type.clone())
.state(state.state_type.clone())
.parameters(method_params)
.report_parameter(state.report_parameter.clone())
.report_component(state.name.clone())
.condition(format!("({}).({})", context, state.condition.clone()))
// assume everything is supported
.supported(true);
// serialize state source as yaml in comment
// TODO need to order output
//.source(serde_yaml::to_string(&state)?);
branch_result.push(method);
}
// sort the params in arbitrary order to make the tests more determinist
// must be removed when we the parameters ordering will be implemented
// Add quotes around the parameters as the bundle call expects them.
let method_params = {
let mut vec = r.params.values().cloned().collect::<Vec<String>>();
vec = vec
.iter()
.map(|x| format!("\"{}\"", x))
.collect::<Vec<String>>();
vec.sort();
vec
};
let method = MethodCall::new(r.method.clone())
.id(r.id.clone())
.parameters(method_params)
// FIXME get from method lib
.report_parameter("FIXME".to_string())
.report_component(r.name.clone())
.condition(format!("({}).({})", context, r.condition.clone()))
// assume everything is supported
// FIXME replace
.supported(true);
// serialize state source as yaml in comment
// TODO need to order output
//.source(serde_yaml::to_string(&state)?);
branch_result.push(method);

Ok(branch_result)
}
_ => todo!(),
}
}

Expand Down
Loading

0 comments on commit 63665c7

Please sign in to comment.