Предложения по грамматике для системы аудита

Мне было интересно, можете ли вы указать мне правильное направление. Я хотел бы написать систему на основе правил для аудита набора машин - например

  • Проверьте параметры конфигурации, чтобы убедиться, что они были установлены правильно
  • Проверьте состояние машин, чтобы убедиться, что они находятся в допустимых диапазонах.

То, с чем я борюсь, - это придумать грамматику для правил аудита, чтобы мне не приходилось кодировать defrules. Я создал несколько простых правил аудита, но не могу придумать общую форму.

Вот моя текущая попытка.

Во-первых, в настоящее время я представляю параметры конфигурации и состояние выполнения с помощью одного шаблона (из-за недостатка воображения я назвал его аудит-фактом), чтобы мой язык аудита мог работать как для конфигурации, так и для состояния. Я использую слот домена, чтобы указать конфигурацию и состояние.

(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))  
)       

Используя вышеизложенное, я могу реализовать простые проверки - например, должно быть установлено, должно быть между, должно быть не равно, должно оставаться при значении по умолчанию, должно быть выше, чем , должно быть ниже и т. д.

Но я не могу придумать простого способа заставить грамматику обрабатывать несколько условий с помощью и или или и т. Д.

Вопрос ---

  • есть ли документ, в котором описывается шаблон проектирования правил аудита, как указано выше. В настоящее время я изучаю wine.clp в примерах (CLIPS).
  • стоит ли мне отказаться и просто использовать простую грамматику для простых правил аудита и просто использовать defrules для чего-нибудь сложного - например, если config-A установлен на X, тогда проверьте пять других конфигураций, чтобы убедиться, что они также установлены правильно, а затем утверждать проверку государства. После утверждения проверьте, чтобы состояние находилось в определенном диапазоне.

Заранее спасибо.

Берни


person Bernie Wong    schedule 16.08.2017    source источник
comment
Боковое примечание: rule-should-eq можно опустить; используйте should-be-between с одинаковыми границами. Приукрашивайте сообщение об ошибке.   -  person laune    schedule 16.08.2017
comment
Вы исследовали разные подходы? Если у вас есть машинные данные в XML, вы можете использовать фасеты и утверждения в определении схемы XML, и проверяющий синтаксический анализатор сделает свое дело. - Вы также можете изучить аннотации Java для определения ограничений для значений полей. IIRC, существует более одной библиотеки.   -  person laune    schedule 16.08.2017
comment
Лауне - приятное предложение. Я хотел бы развить аудитора для более сложных проверок - например, если configA = xx, тогда проверьте, что configB ›n, configC = m и т.д. способ и состояние машин находятся в пределах безопасности. Кроме того, когда я сообщаю о проблемах, я хотел бы распечатать отсортированный список - например, по важности, а затем по имени параметра. CLIPS или JESS, кажется, дают мне гибкость. Но мне все же нравится ваше предложение. Спасибо.   -  person Bernie Wong    schedule 16.08.2017


Ответы (2)


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 содержит идентификатор машины и список (нарушенных) фактов ConfigCheck.

В конце (с помощью правила малой значимости) вы находите факты «Выводы» и вызываете для них метод отчета. (Возможно, будет удобнее использовать некоторые правильные Java-бины в качестве фактов.)

person laune    schedule 16.08.2017
comment
Лауне - еще раз спасибо. Я сделаю так, как вы предложили - а) разделю аудит на Конфигурацию и Состояние. б) Перенести чеки в LHS. в) Утвердить результаты (мне это нравится, потому что потом я могу распечатать отсортированный список результатов) - person Bernie Wong; 16.08.2017

Вот метод оценки произвольных выражений из общего правила:

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> 
person Gary Riley    schedule 17.08.2017