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