灵活扩展规则开发指南
更新时间:2025/06/12
在Gitcode上查看源码

本文档主要介绍如何灵活扩展模型检查规则。

概述

为便于用户维护自己的模型检查规则,BMC Studio支持用户自定义模型检查规则,工具将自动调用规则的代码完成模型检查。

规则定义

为模型检查定义规则,具体的操作方法如下:

  1. ~/bmc_studio/var/plugins/rule_definition路径下,打开grammar_check.json文件。

  2. 修改grammar_check.json文件进行自定义检查规则。以下为定义规则的样例,请结合实际情况进行配置:

    json
    {
         "oem_rule_csr_001": {
              "name": "CSR扩展规则查询样例",
              "category": "CSR",
              "description": "CSR自定义语法中expr的配置写法为expr(...),其中expr()为固定语法,...为计算表达式,计算表达式中左右括号个数必须匹配,三元运算符参数个数匹配。",
              "errorListTemplate": [
                   "表达式(1%)的左右括号个数不匹配。"
              ],
              "errorInfluence": "CSR扩展规则样例",
              "repairSugTemplate": [
                   "确保表达式中左右括号个数匹配。"
              ],
              "alarmLevel": "严重",
              "ciEnabled": false
         }
    }
    • oem_rule_csr_001:规则编号,满足oem_rule_{type}_{index},其中{type}为模型类型,取值包括csripmimdsintf_mappingresourcecustom_type{index}1~999的序号,全局唯一。
    • name:规则名称,长度为小于128的非空字符串,全局唯一。
    • category:模型分类,包括CSR、IPMI、MDS、接口映射、资源协作接口、自定义类型。
    • description:规则描述,长度小于1024的非空字符串。
    • errorListTemplate:错误提示,长度小于1024的非空字符串。
    • errorInfluence:错误影响,长度小于1024的非空字符串。
    • repairSugTemplate:修复建议,长度小于1024的非空字符串。
    • alarmLevel:错误级别,“提示”,“一般”,“严重”。

规则实现

规则定义完成后,须配置一个.py文件,用于实现规则。操作方法如下:

  1. ~/bmc_studio/var/plugins/src路径下创建.py文件。要求.py文件的名称与规则定义中的规则编号保持一致,例如,规则编号为:oem_rule_csr_001,则.py文件命名为:oem_rule_csr_001.py

  2. oem_rule_csr_001.py文件内配置相关规则,以下为定制规则的样例,请结合实际情况进行配置:

    说明
    BMC Studio提供框架代码,位于/usr/share/bmc_studio/server/tools/plugins/util,其中包括"GrammarRule"类和"Grammarlssue"类,用户可基于这两个类实现自己的定制规则。
    规则逻辑定义在类中,要求继承GrammarRule并实现validate函数。
    BMC Studio会自动创建__init__.py文件。

    python
    import re
    import importlib
    GrammarIssue = getattr(importlib.import_module("issue"), "GrammarIssue")
    GrammarRule = getattr(importlib.import_module("grammar_rule"), "GrammarRule")
    
    BASE_ERROR_TEMPLATE = "CSR文件(1%)中的(2%)对象存在如下问题:"
    BASE_SUGGESTION_TEMPLATE = "对CSR文件(1%)中的(2%)进行如下修改:"
    
    # 规则实现类应当继承GrammarRule基类
    class GrammarRuleCsrExample(GrammarRule):
         def __init__(self, config: dict):
              # init时第一个参数应与规则定时时的编号一致
              super().__init__("oem_rule_csr_001", config)
    
         # 框架调用入口,用户必须将检查逻辑实现在validate函数中
         # value: dict待检查文件的全部内容
         # model: str模型分类,创建GrammarIssue类时使用
         # file_path: str待检查文件路径
         # file_type: str文件类型
         # require_data: dict模型的依赖数据,包括MDB模型数据,资源协作接口数据等
         def validate(self, value: dict, model: str, file_path: str, file_type: str, require_date: dict):
              issues = []
              for object_key, object_val in value['Object'].item():
                   # 创建GrammarIssue对象
                   issue = GrammarIssue(self.rule_id, config=self.config, model=model,file_path=file_path, file_type=file_type)\
                        .err(BASE_ERROR_TEMPLATE, [file_path, object_key])\
                        .suggest(BASE_SUGGESTION_TEMPLATE, [file_path, object_key])
                   # 核心检查逻辑,用户根据自身需求编写此处代码
                   for _, prop_val in object_val,items():
                        if not isinstance(prop_val, str):
                             continue
                        if not self.checkExpr(prop_val):
                             print(prop_val)
                             # 如果检查到错误,通过err suggest函数调用来加入检查结果
                             issue = issue.err(self.error_list_template[0], [prop_val]).suggest(self.repair_sug_template[0])
                   # 如果调用过err suggest函数,框架会自动将need_append设置为ture
                   if issue.need_append:
                        # 调用issue.format_issue函数标准化报错信息,加入issues即可
                        issue.append(issue.format_issue(error_obj=object_key))
              return issues
    
         def checkExpr(self, expr: str):
              brackets = re.findall(r'[()]', expr)
              #使用栈来检查括号是否匹配
              stack = []
              for bracket in brackets:
                   if bracket == '(':
                        stack.append(bracket)
                   elif bracket == ')':
                        if not stack or stack[-1] != '(':
                             return False
                             stack.pop()
    
              return not stack

规则生效

重启BMC Studio,在模型检查界面,勾选对应检查规则即可。