Skip to Content
APIRule Engine API: Evaluate Network Configuration Rules

Rule Engine API

The rule engine evaluates validation rules against parsed configuration nodes. This page covers the API for running rules programmatically.

Installation

npm install @sentriflow/core npm install @sentriflow/rules-default # Optional: default rules

Basic Usage

import { SchemaAwareParser, RuleEngine } from '@sentriflow/core'; import { allRules } from '@sentriflow/rules-default'; const config = ` hostname Router1 interface GigabitEthernet0/0 ip address 192.168.1.1 255.255.255.0 `; const parser = new SchemaAwareParser(); const nodes = parser.parse(config); const engine = new RuleEngine(); const results = engine.run(nodes, allRules); for (const result of results) { if (!result.passed) { console.log(`[${result.level}] ${result.ruleId}: ${result.message}`); } }

SchemaAwareParser

The SchemaAwareParser class parses configuration text into an array of ConfigNode objects.

Signature

class SchemaAwareParser { parse(config: string): ConfigNode[] }

Example

import { SchemaAwareParser } from '@sentriflow/core'; const config = loadConfig('./router.conf'); const parser = new SchemaAwareParser(); const nodes = parser.parse(config); console.log(`Parsed ${nodes.length} configuration nodes`);

RuleEngine

The RuleEngine class evaluates rules against parsed configuration nodes.

Constructor

const engine = new RuleEngine();

run()

Evaluate rules against parsed configuration nodes.

Signature

class RuleEngine { run(nodes: ConfigNode[], rules: IRule[]): RuleResult[] }

Parameters

ParameterTypeRequiredDescription
nodesConfigNode[]YesParsed configuration nodes
rulesIRule[]YesRules to evaluate

Returns

Returns an array of RuleResult objects.

Example

import { SchemaAwareParser, RuleEngine } from '@sentriflow/core'; import { allRules, getRulesByVendor } from '@sentriflow/rules-default'; const config = loadConfig('./router.conf'); const parser = new SchemaAwareParser(); const nodes = parser.parse(config); const engine = new RuleEngine(); // Evaluate all rules const allResults = engine.run(nodes, allRules); // Evaluate only Cisco rules const ciscoRules = getRulesByVendor('cisco-ios'); const ciscoResults = engine.run(nodes, ciscoRules);

RuleResult Interface

interface RuleResult { /** Whether the rule check passed */ passed: boolean; /** Result message */ message: string; /** Rule ID that generated this result */ ruleId: string; /** Node ID that was checked */ nodeId: string; /** Severity level */ level: 'error' | 'warning' | 'info'; /** Optional remediation text */ remediation?: string; /** Source location */ loc?: { startLine: number; endLine: number; }; }

Working with Rules

Using Default Rules

import { allRules, getRulesByVendor } from '@sentriflow/rules-default'; // All built-in rules console.log(`Total rules: ${allRules.length}`); // Filter rules by vendor const ciscoRules = getRulesByVendor('cisco-ios'); const juniperRules = getRulesByVendor('juniper');

Custom Rule Definition

Define custom rules programmatically:

import { SchemaAwareParser, RuleEngine } from '@sentriflow/core'; import type { IRule } from '@sentriflow/core'; const customRule: IRule = { id: 'ORG-SEC-001', selector: 'interface', vendor: 'cisco-ios', metadata: { level: 'warning', obu: 'Security', owner: 'security@example.com', description: 'Custom security check', }, check(node) { // Validation logic return { passed: true, /* ... */ }; }, }; const parser = new SchemaAwareParser(); const nodes = parser.parse(config); const engine = new RuleEngine(); const results = engine.run(nodes, [customRule]);

Combining Rules

import { SchemaAwareParser, RuleEngine } from '@sentriflow/core'; import { allRules } from '@sentriflow/rules-default'; import type { IRule } from '@sentriflow/core'; const customRules: IRule[] = [ // Your custom rules here ]; const parser = new SchemaAwareParser(); const nodes = parser.parse(config); const engine = new RuleEngine(); const results = engine.run(nodes, [...allRules, ...customRules]);

Rule Packs

Load rules from rule packs:

import { loadRulePack, SchemaAwareParser, RuleEngine } from '@sentriflow/core'; // Load from file const pack = await loadRulePack('./custom-rules.json'); // Use with engine const parser = new SchemaAwareParser(); const nodes = parser.parse(config); const engine = new RuleEngine(); const results = engine.run(nodes, pack.rules);

Complete Example

import { SchemaAwareParser, RuleEngine } from '@sentriflow/core'; import { allRules, getRulesByVendor } from '@sentriflow/rules-default'; import * as fs from 'fs'; // Load configuration const config = fs.readFileSync('./router.conf', 'utf-8'); // Parse configuration const parser = new SchemaAwareParser(); const nodes = parser.parse(config); // Get vendor-specific rules const ciscoRules = getRulesByVendor('cisco-ios'); // Evaluate rules const engine = new RuleEngine(); const results = engine.run(nodes, ciscoRules); // Process results const failures = results.filter(r => !r.passed); const errors = failures.filter(r => r.level === 'error'); const warnings = failures.filter(r => r.level === 'warning'); console.log(`Found ${errors.length} errors, ${warnings.length} warnings`); for (const result of failures) { console.log(`[${result.level}] ${result.ruleId}: ${result.message}`); if (result.loc) { console.log(` at lines ${result.loc.startLine}-${result.loc.endLine}`); } if (result.remediation) { console.log(` fix: ${result.remediation}`); } }

Performance Tips

  1. Filter rules by vendor before evaluation using getRulesByVendor()
  2. Only include rules you need - smaller rule sets evaluate faster
  3. Reuse parser and engine instances when processing multiple configurations

Next Steps

Last updated on