junoser 0.5.5 → 0.6.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.
- checksums.yaml +4 -4
- data/.github/dependabot.yml +6 -0
- data/.github/workflows/test-linux.yaml +2 -2
- data/.pre-commit-config.yaml +1 -1
- data/CHANGELOG.md +23 -0
- data/Gemfile.lock +7 -7
- data/LICENSE.txt +1 -1
- data/README.md +1 -1
- data/Rakefile +14 -2
- data/lib/junoser/development.rb +1 -0
- data/lib/junoser/input.rb +21 -0
- data/lib/junoser/js_ruler.rb +5 -0
- data/lib/junoser/parser.rb +4949 -3662
- data/lib/junoser/rule_tree/node.rb +24 -0
- data/lib/junoser/rule_tree/parser.rb +66 -0
- data/lib/junoser/rule_tree.rb +2 -0
- data/lib/junoser/ruler.rb +12 -6
- data/lib/junoser/version.rb +1 -1
- data/sig/junoser/rule_tree/node.rbs +17 -0
- data/sig/junoser/rule_tree/parser.rbs +21 -0
- data/sig/junoser/ruler.rbs +9 -7
- metadata +9 -3
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module Junoser
|
|
2
|
+
module RuleTree
|
|
3
|
+
class Node
|
|
4
|
+
INDENT = ' '
|
|
5
|
+
attr_reader :name, :children
|
|
6
|
+
|
|
7
|
+
def initialize(name)
|
|
8
|
+
@name = name
|
|
9
|
+
@children = []
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def <<(child)
|
|
13
|
+
@children << child
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def print(level = 0)
|
|
17
|
+
puts INDENT * level + "- #{@name}"
|
|
18
|
+
@children.each do |child|
|
|
19
|
+
child.print level + 1
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
module Junoser
|
|
2
|
+
module RuleTree
|
|
3
|
+
class Parser
|
|
4
|
+
def initialize(content)
|
|
5
|
+
@content = content
|
|
6
|
+
@nodes = {}
|
|
7
|
+
@root = nil
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def print
|
|
11
|
+
parse
|
|
12
|
+
@nodes['configuration'].print 0
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def parse
|
|
16
|
+
rules = content.scan(/^rule\(:([a-z\d_]+)\) do\n(.*?)^end/m)
|
|
17
|
+
root_index = rules.index { |r| r[0] == 'configuration' }
|
|
18
|
+
primitives = rules.map(&:first)
|
|
19
|
+
.then { |r| r[0, root_index] } + %w[any]
|
|
20
|
+
|
|
21
|
+
validate_uniq rules[root_index..].map(&:first)
|
|
22
|
+
|
|
23
|
+
@nodes = Hash[rules[root_index..].map { |name, _| [name, Node.new(name)] }]
|
|
24
|
+
used = Set.new
|
|
25
|
+
|
|
26
|
+
rules[root_index..].map do |name, refs|
|
|
27
|
+
children = refs.split.map { |i| i.strip.gsub(/,$/, '') }
|
|
28
|
+
.reject { |i| primitives.include?(i) }
|
|
29
|
+
.uniq
|
|
30
|
+
used += children
|
|
31
|
+
children.each do |child|
|
|
32
|
+
raise %(Unknown rule: #{child}) unless @nodes[child]
|
|
33
|
+
@nodes[name] << @nodes[child]
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
validate_used @nodes.keys, used.to_a
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
|
|
42
|
+
def content
|
|
43
|
+
@_content ||= @content
|
|
44
|
+
.gsub(%r| */\*.*\*/|, '')
|
|
45
|
+
.gsub(/\.as\(:oneline\)/, '')
|
|
46
|
+
.gsub(/^(?!rule.*).*["#()].*\n/, '')
|
|
47
|
+
.gsub(/ *arg,?\n/, '')
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def validate_uniq(rules)
|
|
51
|
+
duplicates = rules.group_by(&:itself).select { |_, v| v.count > 1 }.keys
|
|
52
|
+
return if duplicates.empty?
|
|
53
|
+
|
|
54
|
+
raise %(Duplicated rules:\n - #{duplicates.join("\n - ")}) unless duplicates.empty?
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def validate_used(all, used)
|
|
58
|
+
unused = all - used - %w[configuration]
|
|
59
|
+
return if unused.empty?
|
|
60
|
+
|
|
61
|
+
$stderr.puts 'Warning: Unused rules:'
|
|
62
|
+
unused.each { |r| $stderr.puts " - #{r}" }
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
data/lib/junoser/ruler.rb
CHANGED
|
@@ -56,6 +56,7 @@ module Junoser
|
|
|
56
56
|
str.gsub! '"message" arg', '"message" (quote | arg)'
|
|
57
57
|
str.gsub! '"description" arg', '"description" (quote | arg)'
|
|
58
58
|
str.gsub! '"as-path-prepend" arg', '"as-path-prepend" (quote | arg)'
|
|
59
|
+
str.gsub! '"tcp-flags" arg', '"tcp-flags" (quote | arg)'
|
|
59
60
|
|
|
60
61
|
str.gsub!(/^(\s*)"as-path" arg \(\s*c\(\s*arg/) do
|
|
61
62
|
format(['"as-path" arg (',
|
|
@@ -223,10 +224,8 @@ module Junoser
|
|
|
223
224
|
str.gsub! '"*"', 'arg'
|
|
224
225
|
|
|
225
226
|
# Fix .xsd: "from-zone" arg is also required
|
|
226
|
-
str.gsub!(/^
|
|
227
|
-
format(['b(s("from-zone", arg, "to-zone", arg),',
|
|
228
|
-
' b("policy", policy_type',
|
|
229
|
-
], $1)
|
|
227
|
+
str.gsub!(/^ "policy" \(\s*s\(\s*arg,\s*"to-zone-name" arg,\s*(.*?)\s*\)\s*^ \),/m) do
|
|
228
|
+
format(['b(', ' s("from-zone", arg, "to-zone", arg),', " #$1", '),'], ' ')
|
|
230
229
|
end
|
|
231
230
|
|
|
232
231
|
# Fix .xsd: "members" accepts [ foo bar ]
|
|
@@ -245,8 +244,8 @@ module Junoser
|
|
|
245
244
|
str.gsub!(/^(rule\(:license_object\) do.*?"key") arg/m) { "#{$1} (quote | arg)" }
|
|
246
245
|
|
|
247
246
|
# Fix .xsd: "prefix-limit teardown"
|
|
248
|
-
str.gsub!(/^(\s*)"teardown" (\(.*?as\(:oneline\)\s*\)\s*\))/m) do
|
|
249
|
-
"#{$1}\"teardown\" arg #{$
|
|
247
|
+
str.gsub!(/^((\s*)"maximum" arg,)\s*"teardown" (\(.*?as\(:oneline\)\s*\)\s*\))/m) do
|
|
248
|
+
"#{$1}\n#{$2}\"teardown\" arg #{$3},\n#{$2}\"teardown\""
|
|
250
249
|
end
|
|
251
250
|
|
|
252
251
|
# Fix .xsd: faster interface speed support
|
|
@@ -270,6 +269,11 @@ module Junoser
|
|
|
270
269
|
# Fix .xsd: support "set policy-options policy-statement xxx from policy [expression]"
|
|
271
270
|
str.gsub!(/^rule\(:policy_algebra\) do(\s*)arg\.as\(:arg\)\send/) { "rule(:policy_algebra) do#{$1}any.as(:arg)\nend" }
|
|
272
271
|
|
|
272
|
+
# Fix .xsd: support "set interfaces xxx enable"
|
|
273
|
+
str.gsub!(/^(rule\(:interfaces_type\) do\s*[^\n]*\s*c\()(\s*)/m) do
|
|
274
|
+
%[#{$1}#{$2}"enable",#{$2}]
|
|
275
|
+
end
|
|
276
|
+
|
|
273
277
|
str
|
|
274
278
|
end
|
|
275
279
|
|
|
@@ -279,6 +283,8 @@ module Junoser
|
|
|
279
283
|
str.empty? ? '' : offset + str
|
|
280
284
|
when Array
|
|
281
285
|
str.map { |s| s.empty? ? '' : offset + s.to_s }.join("\n")
|
|
286
|
+
else
|
|
287
|
+
''
|
|
282
288
|
end
|
|
283
289
|
end
|
|
284
290
|
|
data/lib/junoser/version.rb
CHANGED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module Junoser
|
|
2
|
+
module RuleTree
|
|
3
|
+
class Node
|
|
4
|
+
INDENT: String
|
|
5
|
+
@children: Array[Node]
|
|
6
|
+
@name: String
|
|
7
|
+
|
|
8
|
+
attr_reader children: Array[Node]
|
|
9
|
+
attr_reader name: String
|
|
10
|
+
|
|
11
|
+
def initialize: (String name) -> void
|
|
12
|
+
|
|
13
|
+
def <<: (Node child) -> void
|
|
14
|
+
def print: (Numeric level) -> void
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Junoser
|
|
2
|
+
module RuleTree
|
|
3
|
+
class Parser
|
|
4
|
+
@_content: String
|
|
5
|
+
@content: String
|
|
6
|
+
@path: String
|
|
7
|
+
@nodes: Hash[String, Node]
|
|
8
|
+
@root: Node?
|
|
9
|
+
|
|
10
|
+
def initialize: (String content) -> void
|
|
11
|
+
|
|
12
|
+
def parse: -> void
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def content: -> String
|
|
17
|
+
def validate_uniq: (Array[String] rules)-> void
|
|
18
|
+
def validate_used: (Array[String], Array[String])-> untyped
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
data/sig/junoser/ruler.rbs
CHANGED
|
@@ -4,17 +4,19 @@
|
|
|
4
4
|
module Junoser
|
|
5
5
|
class Ruler
|
|
6
6
|
OFFSET: String
|
|
7
|
-
@rule:
|
|
7
|
+
@rule: String
|
|
8
|
+
|
|
9
|
+
def initialize: (String input) -> void
|
|
8
10
|
|
|
9
|
-
def initialize: (untyped input) -> void
|
|
10
11
|
def to_rule: -> String
|
|
11
|
-
def rule: ->
|
|
12
|
+
def rule: -> String
|
|
12
13
|
|
|
13
14
|
private
|
|
14
|
-
|
|
15
|
-
def
|
|
16
|
-
def
|
|
17
|
-
def
|
|
15
|
+
|
|
16
|
+
def remove_comments: (String str) -> String
|
|
17
|
+
def process_line: (String str) -> String
|
|
18
|
+
def process_reserved_element: (String str) -> String
|
|
19
|
+
def format: (Array[String?] | String str, ?String? offset) -> String
|
|
18
20
|
def rule_header: -> String
|
|
19
21
|
def rule_footer: -> String
|
|
20
22
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: junoser
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.6.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Shintaro Kojima
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2024-09-15 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: parslet
|
|
@@ -89,6 +89,7 @@ executables:
|
|
|
89
89
|
extensions: []
|
|
90
90
|
extra_rdoc_files: []
|
|
91
91
|
files:
|
|
92
|
+
- ".github/dependabot.yml"
|
|
92
93
|
- ".github/workflows/test-linux.yaml"
|
|
93
94
|
- ".gitignore"
|
|
94
95
|
- ".pre-commit-config.yaml"
|
|
@@ -115,6 +116,9 @@ files:
|
|
|
115
116
|
- lib/junoser/input.rb
|
|
116
117
|
- lib/junoser/js_ruler.rb
|
|
117
118
|
- lib/junoser/parser.rb
|
|
119
|
+
- lib/junoser/rule_tree.rb
|
|
120
|
+
- lib/junoser/rule_tree/node.rb
|
|
121
|
+
- lib/junoser/rule_tree/parser.rb
|
|
118
122
|
- lib/junoser/ruler.rb
|
|
119
123
|
- lib/junoser/squash.rb
|
|
120
124
|
- lib/junoser/transformer.rb
|
|
@@ -131,6 +135,8 @@ files:
|
|
|
131
135
|
- lib/junoser/xsd/simple_type.rb
|
|
132
136
|
- lib/junoser/xsd/union.rb
|
|
133
137
|
- lib/underscorable.rb
|
|
138
|
+
- sig/junoser/rule_tree/node.rbs
|
|
139
|
+
- sig/junoser/rule_tree/parser.rbs
|
|
134
140
|
- sig/junoser/ruler.rbs
|
|
135
141
|
homepage: https://github.com/codeout/junoser
|
|
136
142
|
licenses: []
|
|
@@ -150,7 +156,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
150
156
|
- !ruby/object:Gem::Version
|
|
151
157
|
version: '0'
|
|
152
158
|
requirements: []
|
|
153
|
-
rubygems_version: 3.
|
|
159
|
+
rubygems_version: 3.5.11
|
|
154
160
|
signing_key:
|
|
155
161
|
specification_version: 4
|
|
156
162
|
summary: PEG parser for JUNOS configuration.
|