regorus/
compiled_policy.rs1#![allow(
4 clippy::redundant_pub_crate,
5 clippy::missing_const_for_fn,
6 clippy::option_if_let_else,
7 clippy::pattern_type_mismatch
8)]
9
10use crate::ast::*;
11use crate::compiler::hoist::HoistedLoopsLookup;
12use crate::engine::Engine;
13use crate::scheduler::*;
14use crate::utils::*;
15use crate::*;
16
17use alloc::collections::BTreeMap;
18use anyhow::Result;
19
20#[cfg(feature = "azure_policy")]
21use crate::target::Target;
22
23pub(crate) type DefaultRuleInfo = (Ref<Rule>, Option<crate::String>);
24
25#[cfg(feature = "azure_policy")]
26pub(crate) type ResourceTypeInfo = (Rc<str>, Rc<Schema>);
27
28#[cfg(feature = "azure_policy")]
29pub(crate) type InferredResourceTypes = BTreeMap<Ref<Query>, ResourceTypeInfo>;
30
31#[derive(Debug, Clone)]
33pub struct CompiledPolicy {
34 pub(crate) inner: Rc<CompiledPolicyData>,
35}
36
37impl CompiledPolicy {
38 pub(crate) fn new(inner: Rc<CompiledPolicyData>) -> Self {
40 Self { inner }
41 }
42
43 pub fn get_rules(&self) -> &Map<String, Vec<Ref<Rule>>> {
45 &self.inner.rules
46 }
47
48 pub fn get_modules(&self) -> &Vec<Ref<Module>> {
50 self.inner.modules.as_ref()
51 }
52
53 pub fn is_rego_v0(&self) -> bool {
55 !self.inner.modules.iter().any(|module| module.rego_v1)
56 }
57}
58
59impl CompiledPolicy {
60 pub fn eval_with_input(&self, input: Value) -> Result<Value> {
69 let mut engine = Engine::new_from_compiled_policy(self.inner.clone());
70
71 engine.set_input(input);
73
74 #[cfg(feature = "azure_policy")]
76 if let Some(target_info) = self.inner.target_info.as_ref() {
77 return engine.eval_rule(target_info.effect_path.to_string());
78 }
79 engine.eval_rule(self.inner.rule_to_evaluate.to_string())
80 }
81
82 pub fn get_policy_info(&self) -> Result<crate::policy_info::PolicyInfo> {
133 let module_ids: Vec<Rc<str>> = self
135 .inner
136 .modules
137 .iter()
138 .enumerate()
139 .map(|(i, module)| {
140 let source_path = module.package.span.source.get_path();
142 if source_path.is_empty() {
143 format!("module_{}", i).into()
144 } else {
145 source_path.clone().into()
146 }
147 })
148 .collect();
149
150 #[cfg(feature = "azure_policy")]
152 let (target_name, effect_rule) = if let Some(target_info) = &self.inner.target_info {
153 (
154 Some(target_info.target.name.clone()),
155 Some(target_info.effect_name.clone()),
156 )
157 } else {
158 (None, None)
159 };
160
161 #[cfg(not(feature = "azure_policy"))]
162 let (target_name, effect_rule) = (None, None);
163
164 #[cfg(feature = "azure_policy")]
166 let applicable_resource_types: Vec<Rc<str>> =
167 if let Some(inferred_types) = &self.inner.inferred_resource_types {
168 inferred_types
169 .values()
170 .map(|(resource_type, _schema)| resource_type.clone())
171 .collect::<std::collections::BTreeSet<_>>() .into_iter()
173 .collect()
174 } else {
175 Vec::new()
176 };
177
178 #[cfg(not(feature = "azure_policy"))]
179 let applicable_resource_types: Vec<Rc<str>> = Vec::new();
180
181 #[cfg(feature = "azure_policy")]
183 let parameters = {
184 let temp_engine = crate::engine::Engine::new_from_compiled_policy(self.inner.clone());
186
187 temp_engine.get_policy_parameters()?
188 };
189
190 Ok(crate::policy_info::PolicyInfo {
191 module_ids,
192 target_name,
193 applicable_resource_types,
194 entrypoint_rule: self.inner.rule_to_evaluate.clone(),
195 effect_rule,
196 #[cfg(feature = "azure_policy")]
197 parameters,
198 })
199 }
200}
201
202#[cfg(feature = "azure_policy")]
203#[derive(Debug, Clone)]
204pub(crate) struct TargetInfo {
205 pub(crate) target: Rc<Target>,
206 pub(crate) package: String,
207 pub(crate) effect_schema: Rc<Schema>,
208 pub(crate) effect_name: Rc<str>,
209 pub(crate) effect_path: Rc<str>,
210}
211
212#[derive(Debug, Clone, Default)]
213pub(crate) struct CompiledPolicyData {
214 pub(crate) modules: Rc<Vec<Ref<Module>>>,
215 pub(crate) schedule: Option<Rc<Schedule>>,
216 pub(crate) rules: Map<String, Vec<Ref<Rule>>>,
217 pub(crate) default_rules: Map<String, Vec<DefaultRuleInfo>>,
218 pub(crate) imports: BTreeMap<String, Ref<Expr>>,
219 pub(crate) functions: FunctionTable,
220 pub(crate) rule_paths: Set<String>,
221 #[cfg(feature = "azure_policy")]
222 pub(crate) target_info: Option<TargetInfo>,
223 #[cfg(feature = "azure_policy")]
224 pub(crate) inferred_resource_types: Option<InferredResourceTypes>,
225
226 pub(crate) rule_to_evaluate: Rc<str>,
228
229 pub(crate) data: Option<Value>,
231
232 pub(crate) strict_builtin_errors: bool,
234
235 pub(crate) extensions: Map<String, (u8, Rc<Box<dyn Extension>>)>,
237
238 pub(crate) loop_hoisting_table: HoistedLoopsLookup,
240}