@sentriflow/core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +190 -0
- package/README.md +86 -0
- package/package.json +60 -0
- package/src/constants.ts +77 -0
- package/src/engine/RuleExecutor.ts +256 -0
- package/src/engine/Runner.ts +312 -0
- package/src/engine/SandboxedExecutor.ts +208 -0
- package/src/errors.ts +88 -0
- package/src/helpers/arista/helpers.ts +1220 -0
- package/src/helpers/arista/index.ts +12 -0
- package/src/helpers/aruba/helpers.ts +637 -0
- package/src/helpers/aruba/index.ts +13 -0
- package/src/helpers/cisco/helpers.ts +534 -0
- package/src/helpers/cisco/index.ts +11 -0
- package/src/helpers/common/helpers.ts +265 -0
- package/src/helpers/common/index.ts +5 -0
- package/src/helpers/common/validation.ts +280 -0
- package/src/helpers/cumulus/helpers.ts +676 -0
- package/src/helpers/cumulus/index.ts +12 -0
- package/src/helpers/extreme/helpers.ts +422 -0
- package/src/helpers/extreme/index.ts +12 -0
- package/src/helpers/fortinet/helpers.ts +892 -0
- package/src/helpers/fortinet/index.ts +12 -0
- package/src/helpers/huawei/helpers.ts +790 -0
- package/src/helpers/huawei/index.ts +11 -0
- package/src/helpers/index.ts +53 -0
- package/src/helpers/juniper/helpers.ts +756 -0
- package/src/helpers/juniper/index.ts +12 -0
- package/src/helpers/mikrotik/helpers.ts +722 -0
- package/src/helpers/mikrotik/index.ts +12 -0
- package/src/helpers/nokia/helpers.ts +856 -0
- package/src/helpers/nokia/index.ts +11 -0
- package/src/helpers/paloalto/helpers.ts +939 -0
- package/src/helpers/paloalto/index.ts +12 -0
- package/src/helpers/vyos/helpers.ts +429 -0
- package/src/helpers/vyos/index.ts +12 -0
- package/src/index.ts +30 -0
- package/src/json-rules/ExpressionEvaluator.ts +292 -0
- package/src/json-rules/HelperRegistry.ts +177 -0
- package/src/json-rules/JsonRuleCompiler.ts +339 -0
- package/src/json-rules/JsonRuleValidator.ts +371 -0
- package/src/json-rules/index.ts +97 -0
- package/src/json-rules/schema.json +350 -0
- package/src/json-rules/types.ts +303 -0
- package/src/pack-loader/PackLoader.ts +332 -0
- package/src/pack-loader/index.ts +17 -0
- package/src/pack-loader/types.ts +135 -0
- package/src/parser/IncrementalParser.ts +527 -0
- package/src/parser/Sanitizer.ts +104 -0
- package/src/parser/SchemaAwareParser.ts +504 -0
- package/src/parser/VendorSchema.ts +72 -0
- package/src/parser/vendors/arista-eos.ts +206 -0
- package/src/parser/vendors/aruba-aoscx.ts +123 -0
- package/src/parser/vendors/aruba-aosswitch.ts +113 -0
- package/src/parser/vendors/aruba-wlc.ts +173 -0
- package/src/parser/vendors/cisco-ios.ts +110 -0
- package/src/parser/vendors/cisco-nxos.ts +107 -0
- package/src/parser/vendors/cumulus-linux.ts +161 -0
- package/src/parser/vendors/extreme-exos.ts +154 -0
- package/src/parser/vendors/extreme-voss.ts +167 -0
- package/src/parser/vendors/fortinet-fortigate.ts +217 -0
- package/src/parser/vendors/huawei-vrp.ts +192 -0
- package/src/parser/vendors/index.ts +1521 -0
- package/src/parser/vendors/juniper-junos.ts +230 -0
- package/src/parser/vendors/mikrotik-routeros.ts +274 -0
- package/src/parser/vendors/nokia-sros.ts +251 -0
- package/src/parser/vendors/paloalto-panos.ts +264 -0
- package/src/parser/vendors/vyos-vyos.ts +454 -0
- package/src/types/ConfigNode.ts +72 -0
- package/src/types/DeclarativeRule.ts +158 -0
- package/src/types/IRule.ts +270 -0
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
// packages/rule-helpers/src/extreme/helpers.ts
|
|
2
|
+
// Extreme Networks (EXOS and VOSS) specific helper functions
|
|
3
|
+
|
|
4
|
+
import type { ConfigNode } from '../../types/ConfigNode';
|
|
5
|
+
import { hasChildCommand } from '../common/helpers';
|
|
6
|
+
|
|
7
|
+
// =============================================================================
|
|
8
|
+
// EXOS-specific helpers
|
|
9
|
+
// =============================================================================
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Check if node is an EXOS VLAN creation command
|
|
13
|
+
* @param node The ConfigNode to check
|
|
14
|
+
* @returns true if it's a "create vlan" command
|
|
15
|
+
*/
|
|
16
|
+
export const isExosVlanCreate = (node: ConfigNode): boolean => {
|
|
17
|
+
return /^create\s+vlan\s+/i.test(node.id);
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Extract VLAN name from EXOS VLAN command
|
|
22
|
+
* @param node The ConfigNode
|
|
23
|
+
* @returns The VLAN name or undefined
|
|
24
|
+
*/
|
|
25
|
+
export const getExosVlanName = (node: ConfigNode): string | undefined => {
|
|
26
|
+
const match = node.id.match(/^(?:create|configure)\s+vlan\s+["']?(\w+)["']?/i);
|
|
27
|
+
const vlanName = match?.[1];
|
|
28
|
+
return vlanName?.trim();
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Extract VLAN tag from EXOS VLAN command
|
|
33
|
+
* @param node The ConfigNode
|
|
34
|
+
* @returns The VLAN tag number or undefined
|
|
35
|
+
*/
|
|
36
|
+
export const getExosVlanTag = (node: ConfigNode): number | undefined => {
|
|
37
|
+
const match = node.id.match(/tag\s+(\d+)/i);
|
|
38
|
+
const vlanTag = match?.[1];
|
|
39
|
+
return vlanTag ? parseInt(vlanTag, 10) : undefined;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Check if EXOS command is a configure command
|
|
44
|
+
* @param node The ConfigNode
|
|
45
|
+
* @returns true if it's a configure command
|
|
46
|
+
*/
|
|
47
|
+
export const isExosConfigureCommand = (node: ConfigNode): boolean => {
|
|
48
|
+
return /^configure\s+/i.test(node.id);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Check if EXOS has SNMP sysname configured
|
|
53
|
+
* @param ast The full AST array
|
|
54
|
+
* @returns true if snmp sysname is configured
|
|
55
|
+
*/
|
|
56
|
+
export const hasExosSysname = (ast: ConfigNode[]): boolean => {
|
|
57
|
+
return ast.some((node) =>
|
|
58
|
+
/^configure\s+snmp\s+sysname\s+/i.test(node.id)
|
|
59
|
+
);
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Get EXOS sysname value
|
|
64
|
+
* @param ast The full AST array
|
|
65
|
+
* @returns The sysname or undefined
|
|
66
|
+
*/
|
|
67
|
+
export const getExosSysname = (ast: ConfigNode[]): string | undefined => {
|
|
68
|
+
const node = ast.find((n) => /^configure\s+snmp\s+sysname\s+/i.test(n.id));
|
|
69
|
+
if (!node) return undefined;
|
|
70
|
+
const match = node.id.match(/sysname\s+["']?([^"'\s]+)["']?/i);
|
|
71
|
+
const sysname = match?.[1];
|
|
72
|
+
return sysname?.trim();
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Check if EXOS has SNTP configured
|
|
77
|
+
* @param ast The full AST array
|
|
78
|
+
* @returns true if SNTP is configured
|
|
79
|
+
*/
|
|
80
|
+
export const hasExosSntp = (ast: ConfigNode[]): boolean => {
|
|
81
|
+
return ast.some((node) =>
|
|
82
|
+
/^configure\s+sntp-client\s+/i.test(node.id)
|
|
83
|
+
);
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Check if EXOS SNTP is enabled
|
|
88
|
+
* @param ast The full AST array
|
|
89
|
+
* @returns true if SNTP is enabled
|
|
90
|
+
*/
|
|
91
|
+
export const isExosSntpEnabled = (ast: ConfigNode[]): boolean => {
|
|
92
|
+
return ast.some((node) =>
|
|
93
|
+
/^enable\s+sntp-client/i.test(node.id)
|
|
94
|
+
);
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Check if EXOS has syslog configured
|
|
99
|
+
* @param ast The full AST array
|
|
100
|
+
* @returns true if syslog is configured
|
|
101
|
+
*/
|
|
102
|
+
export const hasExosSyslog = (ast: ConfigNode[]): boolean => {
|
|
103
|
+
return ast.some((node) =>
|
|
104
|
+
/^configure\s+syslog\s+/i.test(node.id) ||
|
|
105
|
+
/^configure\s+log\s+target\s+/i.test(node.id)
|
|
106
|
+
);
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Check if EXOS has SSH2 enabled
|
|
111
|
+
* @param ast The full AST array
|
|
112
|
+
* @returns true if SSH2 is configured
|
|
113
|
+
*/
|
|
114
|
+
export const hasExosSsh2 = (ast: ConfigNode[]): boolean => {
|
|
115
|
+
return ast.some((node) =>
|
|
116
|
+
/^enable\s+ssh2/i.test(node.id) ||
|
|
117
|
+
/^configure\s+ssh2\s+/i.test(node.id)
|
|
118
|
+
);
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Check if EXOS has RADIUS configured
|
|
123
|
+
* @param ast The full AST array
|
|
124
|
+
* @returns true if RADIUS is configured
|
|
125
|
+
*/
|
|
126
|
+
export const hasExosRadius = (ast: ConfigNode[]): boolean => {
|
|
127
|
+
return ast.some((node) =>
|
|
128
|
+
/^configure\s+radius\s+/i.test(node.id)
|
|
129
|
+
);
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Check if EXOS has TACACS configured
|
|
134
|
+
* @param ast The full AST array
|
|
135
|
+
* @returns true if TACACS is configured
|
|
136
|
+
*/
|
|
137
|
+
export const hasExosTacacs = (ast: ConfigNode[]): boolean => {
|
|
138
|
+
return ast.some((node) =>
|
|
139
|
+
/^configure\s+tacacs\s+/i.test(node.id)
|
|
140
|
+
);
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Check if EXOS LAG (sharing) is configured
|
|
145
|
+
* @param node The ConfigNode
|
|
146
|
+
* @returns true if it's an enable sharing command
|
|
147
|
+
*/
|
|
148
|
+
export const isExosLag = (node: ConfigNode): boolean => {
|
|
149
|
+
return /^enable\s+sharing\s+/i.test(node.id);
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Extract LAG master port from EXOS sharing command
|
|
154
|
+
* @param node The ConfigNode
|
|
155
|
+
* @returns The master port (e.g., "1:1") or undefined
|
|
156
|
+
*/
|
|
157
|
+
export const getExosLagMasterPort = (node: ConfigNode): string | undefined => {
|
|
158
|
+
const match = node.id.match(/^enable\s+sharing\s+(\d+:\d+)/i);
|
|
159
|
+
const masterPort = match?.[1];
|
|
160
|
+
return masterPort?.trim();
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Check if EXOS EAPS is configured
|
|
165
|
+
* @param ast The full AST array
|
|
166
|
+
* @returns true if EAPS is configured
|
|
167
|
+
*/
|
|
168
|
+
export const hasExosEaps = (ast: ConfigNode[]): boolean => {
|
|
169
|
+
return ast.some((node) =>
|
|
170
|
+
/^create\s+eaps\s+/i.test(node.id) ||
|
|
171
|
+
/^configure\s+eaps\s+/i.test(node.id)
|
|
172
|
+
);
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Check if EXOS stacking is enabled
|
|
177
|
+
* @param ast The full AST array
|
|
178
|
+
* @returns true if stacking is enabled
|
|
179
|
+
*/
|
|
180
|
+
export const hasExosStacking = (ast: ConfigNode[]): boolean => {
|
|
181
|
+
return ast.some((node) =>
|
|
182
|
+
/^enable\s+stacking$/i.test(node.id) ||
|
|
183
|
+
/^configure\s+stacking\s+/i.test(node.id)
|
|
184
|
+
);
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Check if EXOS MLAG is configured
|
|
189
|
+
* @param ast The full AST array
|
|
190
|
+
* @returns true if MLAG is configured
|
|
191
|
+
*/
|
|
192
|
+
export const hasExosMlag = (ast: ConfigNode[]): boolean => {
|
|
193
|
+
return ast.some((node) =>
|
|
194
|
+
/^create\s+mlag\s+peer\s+/i.test(node.id) ||
|
|
195
|
+
/^configure\s+mlag\s+peer\s+/i.test(node.id)
|
|
196
|
+
);
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
// =============================================================================
|
|
200
|
+
// VOSS-specific helpers
|
|
201
|
+
// =============================================================================
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Check if node is a VOSS VLAN creation command
|
|
205
|
+
* @param node The ConfigNode
|
|
206
|
+
* @returns true if it's a "vlan create" command
|
|
207
|
+
*/
|
|
208
|
+
export const isVossVlanCreate = (node: ConfigNode): boolean => {
|
|
209
|
+
return /^vlan\s+create\s+\d+/i.test(node.id);
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Extract VLAN ID from VOSS VLAN command
|
|
214
|
+
* @param node The ConfigNode
|
|
215
|
+
* @returns The VLAN ID or undefined
|
|
216
|
+
*/
|
|
217
|
+
export const getVossVlanId = (node: ConfigNode): number | undefined => {
|
|
218
|
+
const match = node.id.match(/^vlan\s+(?:create|members|i-sid)\s+(\d+)/i);
|
|
219
|
+
const vlanId = match?.[1];
|
|
220
|
+
return vlanId ? parseInt(vlanId, 10) : undefined;
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Check if VOSS has SPBM configured
|
|
225
|
+
* @param ast The full AST array
|
|
226
|
+
* @returns true if SPBM is configured
|
|
227
|
+
*/
|
|
228
|
+
export const hasVossSpbm = (ast: ConfigNode[]): boolean => {
|
|
229
|
+
return ast.some((node) =>
|
|
230
|
+
/^spbm\s+\d+/i.test(node.id) ||
|
|
231
|
+
/^router\s+isis[\s\S]*spbm/i.test(node.id)
|
|
232
|
+
);
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Check if VOSS has ISIS configured
|
|
237
|
+
* @param ast The full AST array
|
|
238
|
+
* @returns true if ISIS is configured
|
|
239
|
+
*/
|
|
240
|
+
export const hasVossIsis = (ast: ConfigNode[]): boolean => {
|
|
241
|
+
return ast.some((node) =>
|
|
242
|
+
/^router\s+isis/i.test(node.id)
|
|
243
|
+
);
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Check if VOSS has I-SID configured for VLAN
|
|
248
|
+
* @param ast The full AST array
|
|
249
|
+
* @param vlanId The VLAN ID to check
|
|
250
|
+
* @returns true if I-SID is configured for the VLAN
|
|
251
|
+
*/
|
|
252
|
+
export const hasVossVlanIsid = (ast: ConfigNode[], vlanId: number): boolean => {
|
|
253
|
+
return ast.some((node) =>
|
|
254
|
+
new RegExp(`^vlan\\s+i-sid\\s+${vlanId}\\s+\\d+`, 'i').test(node.id)
|
|
255
|
+
);
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Get I-SID for a VOSS VLAN
|
|
260
|
+
* @param ast The full AST array
|
|
261
|
+
* @param vlanId The VLAN ID
|
|
262
|
+
* @returns The I-SID or undefined
|
|
263
|
+
*/
|
|
264
|
+
export const getVossVlanIsid = (ast: ConfigNode[], vlanId: number): number | undefined => {
|
|
265
|
+
const node = ast.find((n) =>
|
|
266
|
+
new RegExp(`^vlan\\s+i-sid\\s+${vlanId}\\s+\\d+`, 'i').test(n.id)
|
|
267
|
+
);
|
|
268
|
+
if (!node) return undefined;
|
|
269
|
+
const match = node.id.match(/i-sid\s+\d+\s+(\d+)/i);
|
|
270
|
+
const isid = match?.[1];
|
|
271
|
+
return isid ? parseInt(isid, 10) : undefined;
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Check if VOSS interface is a GigabitEthernet
|
|
276
|
+
* @param node The ConfigNode
|
|
277
|
+
* @returns true if it's a GigabitEthernet interface
|
|
278
|
+
*/
|
|
279
|
+
export const isVossGigabitEthernet = (node: ConfigNode): boolean => {
|
|
280
|
+
return /^interface\s+GigabitEthernet\s+\d+\/\d+/i.test(node.id);
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Check if VOSS interface is an MLT (Multi-Link Trunk)
|
|
285
|
+
* @param node The ConfigNode
|
|
286
|
+
* @returns true if it's an MLT interface
|
|
287
|
+
*/
|
|
288
|
+
export const isVossMlt = (node: ConfigNode): boolean => {
|
|
289
|
+
return /^interface\s+mlt\s+\d+/i.test(node.id) ||
|
|
290
|
+
/^mlt\s+\d+/i.test(node.id);
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Get VOSS MLT ID
|
|
295
|
+
* @param node The ConfigNode
|
|
296
|
+
* @returns The MLT ID or undefined
|
|
297
|
+
*/
|
|
298
|
+
export const getVossMltId = (node: ConfigNode): number | undefined => {
|
|
299
|
+
const match = node.id.match(/(?:interface\s+)?mlt\s+(\d+)/i);
|
|
300
|
+
const mltId = match?.[1];
|
|
301
|
+
return mltId ? parseInt(mltId, 10) : undefined;
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Check if VOSS interface is shutdown
|
|
306
|
+
* @param node The interface ConfigNode
|
|
307
|
+
* @returns true if interface is shutdown
|
|
308
|
+
*/
|
|
309
|
+
export const isVossShutdown = (node: ConfigNode): boolean => {
|
|
310
|
+
const hasShutdown = node.children.some((child) =>
|
|
311
|
+
child.id.toLowerCase() === 'shutdown'
|
|
312
|
+
);
|
|
313
|
+
const hasNoShutdown = node.children.some((child) =>
|
|
314
|
+
child.id.toLowerCase() === 'no shutdown'
|
|
315
|
+
);
|
|
316
|
+
return hasShutdown && !hasNoShutdown;
|
|
317
|
+
};
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Check if VOSS has snmp-server name configured
|
|
321
|
+
* @param ast The full AST array
|
|
322
|
+
* @returns true if snmp-server name is configured
|
|
323
|
+
*/
|
|
324
|
+
export const hasVossSnmpName = (ast: ConfigNode[]): boolean => {
|
|
325
|
+
return ast.some((node) =>
|
|
326
|
+
/^snmp-server\s+name\s+/i.test(node.id)
|
|
327
|
+
);
|
|
328
|
+
};
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Get VOSS snmp-server name
|
|
332
|
+
* @param ast The full AST array
|
|
333
|
+
* @returns The name or undefined
|
|
334
|
+
*/
|
|
335
|
+
export const getVossSnmpName = (ast: ConfigNode[]): string | undefined => {
|
|
336
|
+
const node = ast.find((n) => /^snmp-server\s+name\s+/i.test(n.id));
|
|
337
|
+
if (!node) return undefined;
|
|
338
|
+
const match = node.id.match(/name\s+["']?([^"'\s]+)["']?/i);
|
|
339
|
+
const name = match?.[1];
|
|
340
|
+
return name?.trim();
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* Check if VOSS has NTP configured
|
|
345
|
+
* @param ast The full AST array
|
|
346
|
+
* @returns true if NTP is configured
|
|
347
|
+
*/
|
|
348
|
+
export const hasVossNtp = (ast: ConfigNode[]): boolean => {
|
|
349
|
+
return ast.some((node) =>
|
|
350
|
+
/^ntp\s+server\s+/i.test(node.id)
|
|
351
|
+
);
|
|
352
|
+
};
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* Check if VOSS has logging configured
|
|
356
|
+
* @param ast The full AST array
|
|
357
|
+
* @returns true if logging is configured
|
|
358
|
+
*/
|
|
359
|
+
export const hasVossLogging = (ast: ConfigNode[]): boolean => {
|
|
360
|
+
return ast.some((node) =>
|
|
361
|
+
/^logging\s+(host|server)\s+/i.test(node.id)
|
|
362
|
+
);
|
|
363
|
+
};
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* Check if VOSS has SSH enabled
|
|
367
|
+
* @param ast The full AST array
|
|
368
|
+
* @returns true if SSH is configured
|
|
369
|
+
*/
|
|
370
|
+
export const hasVossSsh = (ast: ConfigNode[]): boolean => {
|
|
371
|
+
return ast.some((node) =>
|
|
372
|
+
/^ssh\s+/i.test(node.id)
|
|
373
|
+
);
|
|
374
|
+
};
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* Check if VOSS has LACP configured on interface
|
|
378
|
+
* @param node The interface ConfigNode
|
|
379
|
+
* @returns true if LACP is configured
|
|
380
|
+
*/
|
|
381
|
+
export const hasVossLacp = (node: ConfigNode): boolean => {
|
|
382
|
+
return node.children.some((child) =>
|
|
383
|
+
/^lacp\s+(enable|key)/i.test(child.id)
|
|
384
|
+
);
|
|
385
|
+
};
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* Check if VOSS has DVR (Distributed Virtual Routing) configured
|
|
389
|
+
* @param ast The full AST array
|
|
390
|
+
* @returns true if DVR is configured
|
|
391
|
+
*/
|
|
392
|
+
export const hasVossDvr = (ast: ConfigNode[]): boolean => {
|
|
393
|
+
return ast.some((node) =>
|
|
394
|
+
/^dvr\s+(leaf|controller)/i.test(node.id)
|
|
395
|
+
);
|
|
396
|
+
};
|
|
397
|
+
|
|
398
|
+
/**
|
|
399
|
+
* Check if VOSS has CFM (Connectivity Fault Management) configured
|
|
400
|
+
* @param ast The full AST array
|
|
401
|
+
* @returns true if CFM is configured
|
|
402
|
+
*/
|
|
403
|
+
export const hasVossCfm = (ast: ConfigNode[]): boolean => {
|
|
404
|
+
return ast.some((node) =>
|
|
405
|
+
/^cfm\s+/i.test(node.id)
|
|
406
|
+
);
|
|
407
|
+
};
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* Get VOSS interface default VLAN
|
|
411
|
+
* @param node The interface ConfigNode
|
|
412
|
+
* @returns The default VLAN ID or undefined
|
|
413
|
+
*/
|
|
414
|
+
export const getVossDefaultVlan = (node: ConfigNode): number | undefined => {
|
|
415
|
+
const defaultVlan = node.children.find((child) =>
|
|
416
|
+
/^default-vlan-id\s+\d+/i.test(child.id)
|
|
417
|
+
);
|
|
418
|
+
if (!defaultVlan) return undefined;
|
|
419
|
+
const match = defaultVlan.id.match(/default-vlan-id\s+(\d+)/i);
|
|
420
|
+
const vlanId = match?.[1];
|
|
421
|
+
return vlanId ? parseInt(vlanId, 10) : undefined;
|
|
422
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// packages/rule-helpers/src/extreme/index.ts
|
|
2
|
+
// Re-export all Extreme Networks helpers
|
|
3
|
+
|
|
4
|
+
export * from './helpers';
|
|
5
|
+
|
|
6
|
+
// Also re-export commonly used common helpers for convenience
|
|
7
|
+
export {
|
|
8
|
+
hasChildCommand,
|
|
9
|
+
getChildCommand,
|
|
10
|
+
getChildCommands,
|
|
11
|
+
parseIp,
|
|
12
|
+
} from '../common/helpers';
|