我想知道你是否可以指出我正确的方向。我想编写一个基于规则的系统来审计一组机器 - 例如
我正在努力解决的问题是为审计规则提出一个语法,这样我就不需要编码规则。我创建了一些简单的审计规则,但我正在努力想出一个通用的表单。
这是我目前的尝试。
首先,我目前使用单个模板表示配置参数和运行状态(由于缺乏想象力,我称之为audit-fact),因此我的审计语言可以同时适用于配置和状态。我使用域槽来指定配置与状态。
(deftemplate audit-fact
(slot domain (allowed-values config state)) ;; config vs. state
(slot machine) ;; machine to audit
(slot name) ;; parameter or state to check/audit
(slot value) ;; parameter value
(slot already-checked (default FALSE))
)
接下来,我编写了一个程序来读入并断言机器配置和状态为审计事实。以下是示例配置和状态审计事实
(assert (audit-fact
(domain config)
(machine drl-a-15_0)
(name os-version) (value 5.5))
)
(assert (audit-fact
(domain state)
(machine drl-a-15_0)
(name rpm) (value 5023))
)
这是我目前对审计语法/语言的尝试---
(deftemplate rule
(slot domain)
(slot name)
(slot constraint (default ?NONE) (allowed-values should-remain-at-default should-equal should-be-between ignore-if-ends-with))
(multislot values)
(multislot reasons)
(multislot references)
(slot criticality (allowed-values critical info suggestion warning))
(slot already-checked (default FALSE))
)
以下规则用于检查状态或参数是否在特定范围内
(assert (rule
(domain state)
(name rpm)
(constraint should-be-between)
(values 5000 5500)
(criticality critical)
(reasons "Low values could cause engine to stall. Prolonged high value could cause engine to heat up") )
)
接下来,我使用以下规则检查状态或参数是否等于特定值
(assert (rule
(domain config)
(name os-version)
(constraint should-equal)
(values 5.5)
(criticality critical)
(reasons "OS version must be at 5.5 – no other levels are currently certified.") )
)
以下规则实现了相等和检查之间的
(defrule rule-should-eq
(rule (domain ?d) (name ?n) (constraint should-equal) (values ?cv) (reasons ?r))
?p <- (audit-fact (domain ?d) (name ?n) (value ?v) (already-checked FALSE))
=>
(if (eq ?v ?cv)
then
(printout t "checking " ?d ": " ?n ". Passed " crlf)
else
(printout t "checking " ?d “: “ ?n " should be set to " ?cv ". " ?r ". Warning" crlf)
)
(modify ?p (already-checked TRUE))
)
(defrule rule-should-be-between
(rule (domain ?d) (name ?n) (constraint should-be-between) (values ?cv-low ?cv-high) (reasons ?r))
?p <- (audit-fact (domain ?d) (name ?n) (value ?v) (already-checked FALSE))
=>
(if (and (>= ?v ?cv-low) (<= ?v ?cv-high))
then
(printout t "checking " ?n ". Passed " crlf)
else
(printout t "checking " ?n " should be between " ?cv-low " and " ?cv-high ". " ?r ". Warning" crlf)
)
(modify ?p (already-checked TRUE))
)
使用上面的内容,我可以实现简单的检查 - 例如,必须设置,必须在之间,必须不相等,必须保持默认值,必须 - 高于,必须低于等等。
但是我想不出一种简单的方法可以让语法处理多个条件和/或等等。
问题---
提前致谢。
伯尼
答案 0 :(得分:1)
1)如果RHS上的陈述是代码气味:不要! 2)由于您没有修改这些事实,因此您不需要已经检查过的标记。
针对一个机器属性重写检查:
?p <- (Configuration (machine ?m)(param ?p)(value ?v))
(ConfigCheckRange (param ?p){?v < loBound || $v > hiBound})
(您可能需要其他变体,例如,ConfigCheckEnum在一个时间间隔内不允许使用值。)
检查参数值组合更加困难,因为您已选择通过单独的事实表示每个参数值。你必须
?p1 <- (Configuration (machine ?m)(param ?p1)(value ?v1))
?p2 <- (Configuration (machine ?m)(param ?p2)(value ?v2)
{?p2 != ?p1))
(ConfigCheckCombi (param1 ?p1)(param2 ?p2)
{lowBound1 <= ?v1 && ?v2 <= lowBound2}
{?v2 < loBound2 || $v2 > hiBound2})
右手边应该只是在(新的)事实中记录违规行为,让我们称之为调查结果。 One Findings包含机器的id和(违反的)ConfigCheck事实列表。
最后(使用低显着性规则),您可以找到Findings事实并在其上调用报告方法。 (使用一些合适的Java bean作为事实可能更方便。)
答案 1 :(得分:1)
这是一种从通用规则评估任意表达式的方法:
CLIPS>
(deffunction str-replace (?str ?rpl ?fnd)
(if (eq ?fnd "") then (return ?str))
(bind ?rv "")
(bind ?i (str-index ?fnd ?str))
(while ?i
(bind ?rv (str-cat ?rv (sub-string 1 (- ?i 1) ?str) ?rpl))
(bind ?str (sub-string (+ ?i (str-length ?fnd)) (str-length ?str) ?str))
(bind ?i (str-index ?fnd ?str)))
(bind ?rv (str-cat ?rv ?str)))
CLIPS>
(deftemplate audit-fact
(slot domain)
(slot machine)
(slot name)
(slot value))
CLIPS>
(deftemplate rule
(slot domain)
(slot name)
(slot constraint)
(multislot reasons)
(multislot references)
(slot criticality))
CLIPS>
(deffacts initial
(audit-fact
(domain config)
(machine drl-a-15_0)
(name os-version)
(value 5.4))
(audit-fact
(domain state)
(machine drl-a-15_0)
(name rpm)
(value 5023))
(rule
(domain state)
(name rpm)
(constraint "(and (>= ?v 5000) (<= ?v 5500))")
(criticality critical)
(reasons "Low values could cause engine to stall. Prolonged high value could cause engine to heat up."))
(rule
(domain config)
(name os-version)
(constraint "(eq ?v 5.5)")
(criticality critical)
(reasons "OS version must be at 5.5 – no other levels are currently certified.")))
CLIPS>
(defrule rule-check
(rule (domain ?d) (name ?n) (constraint ?constraint) (reasons ?r))
?p <- (audit-fact (domain ?d) (name ?n) (value ?v))
=>
(bind ?constraint (str-replace ?constraint ?v "?v"))
(if (eval ?constraint)
then
(printout t "checking " ?d ": " ?n " Passed" crlf)
else
(printout t "checking " ?d ": " ?n " Warning : " ?r crlf)))
CLIPS> (reset)
CLIPS> (run)
checking config: os-version Warning : OS version must be at 5.5 – no other levels are currently certified.
checking state: rpm Passed
CLIPS>