fluent-auditify 0.2.0 → 0.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6e234cfa52ee9302d33cad2f099be103df74ee3d34d58130be1ab8a540e2baed
4
- data.tar.gz: 0241bb9816a27f16304248198ba9186e72d504819a63abe1fb2131cf9a0023e2
3
+ metadata.gz: 0e823faccd2bd005e3878da8342af95d5ee2943bc019d7b961a76464ce1f138b
4
+ data.tar.gz: 877ea6a2fd26b975c72421228ab97d1d5287f04f64fcef7bd8dd1e542cd7f851
5
5
  SHA512:
6
- metadata.gz: d78ad3f05f6d5c3d9a6cde0c8791ab39ae3b65801a8d918b464486822b857486197cd2bbf6b3061a116473cfb35664ce4de2e5e432753b03f6a58e70fd72f5ba
7
- data.tar.gz: 1e10a6072de19e430828550bc33c7fe3b426344bc8c838fc544d1e4a71291739bdba5276d8ad602b1e44ed99e197200a965ca301bda39d65b0f7544dfc59b09c
6
+ metadata.gz: 76ae20f1d2c181edd3bb9aa708ad348e84d61e0a371bfbcbfabd01c5bced5c331e34b53ca155e45ce05d6960831d2d447b344d4dc66a29c782fe4dc644bbf393
7
+ data.tar.gz: 56df65aeb54848dfe60961bd8581ab0776d14b3a6fade5be889d35e37ae4473549f205f9cf1a719e701095c861d1df4255947f9ef6c896a965bec4bf17dddf0f
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.3.0] - 2025-11-23
4
+
5
+ * Fixed a bug that included .conf can't be exported correctly.
6
+ * Change the scope of parser methods.
7
+
3
8
  ## [0.2.0] - 2025-11-15
4
9
 
5
10
  * Support to load 3rd party plugin.
@@ -33,6 +33,7 @@ module Fluent
33
33
  else
34
34
  test_parse_content_with_debug(path_or_content, klass)
35
35
  end
36
+ object
36
37
  end
37
38
 
38
39
  def test_parse_content_with_debug(content, klass: Fluent::Auditify::Parser::V1ConfigParser)
@@ -95,7 +95,7 @@ module Fluent
95
95
  # match is reserved word
96
96
  rule(:match_directive) do
97
97
  space? >> str('<match').as(:match) >> space? >> pattern?.as(:pattern) >> str('>') >> space_or_newline >>
98
- (comment | key_value | empty_line.as(:empty_line) | section).repeat.as(:body) >>
98
+ (comment | key_value | empty_line.as(:empty_line) | key_line | section).repeat.as(:body) >>
99
99
  space? >> str('</match>') >> eof?
100
100
  end
101
101
  rule(:label) do
@@ -109,46 +109,25 @@ module Fluent
109
109
  root :conf
110
110
 
111
111
  # expand @include directive
112
- def self.eval(object, base_dir: "", path: "", include: true)
112
+ def eval(object, options={})
113
+ base_dir = options[:base_dir] || ''
114
+ path = options[:path] || ''
113
115
  modified = []
114
- object.each_with_index do |element, index|
115
- element[:__BASE__] = base_dir
116
- element[:__PATH__] = path
117
- unless element[:include]
118
- if element[:empty_line]
119
- modified << element
120
- elsif element[:body].collect { |v| v[:name].to_s }.any?('@include')
121
- # include section
122
- modified_body = []
123
- element[:body].each do |body_element|
124
- if body_element[:name].to_s == '@include'
125
- parser = Fluent::Auditify::Parser::V1ConfigSectionParser.new
126
- parsed = parser.parse(File.read(File.join(base_dir, body_element[:value])))
127
- parsed.each do |elem|
128
- elem[:__PATH__] = body_element[:value].to_s
129
- modified_body << elem
130
- end
131
- else
132
- modified_body << body_element
133
- end
134
- end
135
- element[:body] = modified_body
136
- modified << element
116
+ object.each do |directive|
117
+ directive[:__BASE__] = base_dir
118
+ directive[:__PATH__] = path
119
+ unless directive[:include]
120
+ if directive[:body]
121
+ modified << eval_body(directive, options)
137
122
  else
138
- modified << element
123
+ modified << directive
139
124
  end
140
125
  next
141
126
  end
142
- parser = Fluent::Auditify::Parser::V1ConfigParser.new
143
- pattern = File.expand_path(element[:include_path].to_s, base_dir)
144
- Dir.glob(pattern).sort.each do |path|
145
- included = parser.parse(File.read(path))
146
- included.each do |child|
147
- child[:__PATTERN__] = element[:include_path].to_s
148
- child[:__PATH__] = Pathname.new(path).relative_path_from(base_dir).to_s
149
- child[:__BASE__] = base_dir
150
- modified << child
151
- end
127
+ # top-level @include
128
+ eval_include(directive, options).each do |child|
129
+ child[:__PARENT__] = path
130
+ modified << child
152
131
  end
153
132
  end
154
133
  modified
@@ -166,6 +145,65 @@ module Fluent
166
145
  end
167
146
  nil
168
147
  end
148
+
149
+ private
150
+
151
+ def eval_body(directive, options={})
152
+ base_dir = options[:base_dir] || ''
153
+ # include section
154
+ modified_body = []
155
+ directive[:body].each do |body_element|
156
+ if body_element[:name].to_s == '@include'
157
+ parser = Fluent::Auditify::Parser::V1ConfigSectionParser.new
158
+ pattern = File.expand_path(body_element[:value].to_s, base_dir)
159
+ Dir.glob(pattern).sort.each do |path|
160
+ object = parser.parse(File.read(path))
161
+ object.each do |element|
162
+ element[:__PATTERN__] = body_element[:value].to_s
163
+ element[:__PATH__] = File.basename(path)
164
+ if element[:section]
165
+ element[:body] = eval_body(element, options)[:body]
166
+ modified_body << element
167
+ else
168
+ modified_body << element
169
+ end
170
+ end
171
+ end
172
+ elsif body_element[:section]
173
+ section_body = []
174
+ body_element[:body].each do |child|
175
+ child[:__PATH__] = body_element[:__PATH__]
176
+ section_body << child
177
+ end
178
+ body_element[:body] = section_body
179
+ modified_body << body_element
180
+ else
181
+ body_element[:__PATH__] = directive[:__PATH__]
182
+ modified_body << body_element
183
+ end
184
+ end
185
+ directive[:body] = modified_body
186
+ directive
187
+ end
188
+
189
+ def eval_include(directive, options={})
190
+ base_dir = options[:base_dir] || ''
191
+ parser = Fluent::Auditify::Parser::V1ConfigParser.new
192
+ pattern = File.expand_path(directive[:include_path].to_s, base_dir)
193
+ modified = []
194
+ Dir.glob(pattern).sort.each do |path|
195
+ included = parser.parse(File.read(path))
196
+ included.each do |included_directive|
197
+ included_directive[:__PATTERN__] = directive[:include_path].to_s
198
+ included_directive[:__PATH__] = Pathname.new(path).relative_path_from(base_dir).to_s
199
+ included_directive[:__BASE__] = base_dir
200
+ included_directive[:body] = eval_body(included_directive, options)[:body]
201
+ modified << included_directive
202
+ end
203
+ end
204
+ modified
205
+ end
206
+
169
207
  end
170
208
  end
171
209
  end
@@ -13,11 +13,25 @@ module Fluent
13
13
  @content = StringIO.new
14
14
  end
15
15
 
16
+ def handler_key(object, parent = nil)
17
+ if object[:__BASE__] and object[:__PATH__]
18
+ # directive
19
+ File.join(object[:__BASE__], object[:__PATH__])
20
+ elsif parent and parent[:__BASE__] and object[:__PATH__]
21
+ # section, body
22
+ File.join(parent[:__BASE__], object[:__PATH__])
23
+ elsif parent and parent[:__BASE__] and parent[:__PATH__]
24
+ File.join(parent[:__BASE__], parent[:__PATH__])
25
+ else
26
+ nil
27
+ end
28
+ end
29
+
16
30
  def collect_file_handlers(object)
17
31
  handlers = {}
18
32
  object.each do |directive|
19
33
  if directive[:empty_line]
20
- key = directive[:__PATH__]
34
+ key = handler_key(directive, object)
21
35
  unless key and handlers.key?(key)
22
36
  if key
23
37
  handlers[key] = File.open(key, 'w+')
@@ -25,14 +39,14 @@ module Fluent
25
39
  end
26
40
  elsif directive[:source] or directive[:match] or
27
41
  directive[:system] or directive[:filter]
28
- key = directive[:__PATH__]
42
+ key = handler_key(directive, object)
29
43
  unless key and handlers.key?(key)
30
44
  if key
31
45
  handlers[key] = File.open(key, 'w+')
32
46
  end
33
47
  end
34
48
  directive[:body].each do |body|
35
- key = body[:__PATH__]
49
+ key = handler_key(body, directive)
36
50
  unless key and handlers.key?(key)
37
51
  if key
38
52
  handlers[key] = File.open(key, 'w+')
@@ -47,55 +61,109 @@ module Fluent
47
61
  def export(object, options={})
48
62
  # setup rewrite file handles
49
63
  @handlers = collect_file_handlers(object)
64
+ @include_flushed = {}
50
65
  object.each do |directive|
51
- io = @handlers[directive[:__PATH__]]
66
+ key = handler_key(directive, object)
52
67
  if directive[:system]
53
- io.puts("#{' ' * @align * @indent_level}#{directive[:system].to_s}") if io
68
+ export_line(key, directive[:system].to_s)
54
69
  export_body(directive)
55
- io.puts('</system>') if io
70
+ export_line(key, '</system>')
56
71
  elsif directive[:source]
57
- io.puts "#{' ' * @align * @indent_level}#{directive[:source].to_s}" if io
72
+ export_line(key, directive[:source].to_s)
58
73
  export_body(directive)
59
- io.puts('</source>') if io
74
+ export_line(key, '</source>')
75
+ if directive[:__PATTERN__] and directive[:__PARENT__]
76
+ key = File.join(directive[:__BASE__], directive[:__PARENT__])
77
+ unless @include_flushed[key]
78
+ export_line(key, "@include #{directive[:__PATTERN__]}")
79
+ @include_flushed[key] = true
80
+ end
81
+ end
60
82
  elsif directive[:filter]
61
- io.puts "#{' ' * @align * @indent_level}#{directive[:filter].to_s}" if io
83
+ export_line(key, directive[:filter].to_s)
62
84
  export_body(directive)
63
- io.puts('</filter>') if io
85
+ export_line(key, '</filter>')
86
+ if directive[:__PATTERN__] and directive[:__PARENT__]
87
+ key = File.join(directive[:__BASE__], directive[:__PARENT__])
88
+ unless @include_flushed[key]
89
+ export_line(key, "@include #{directive[:__PATTERN__]}")
90
+ @include_flushed[key] = true
91
+ end
92
+ end
64
93
  elsif directive[:match]
65
- io.puts "#{' ' * @align * @indent_level}#{directive[:match].to_s}"
94
+ if directive[:pattern]
95
+ export_line(key, "#{directive[:match].to_s} #{directive[:pattern]}>")
96
+ else
97
+ export_line(key, "#{directive[:match].to_s}>")
98
+ end
66
99
  export_body(directive)
67
- io.puts('</match>') if io
100
+ export_line(key, '</match>')
101
+ elsif directive[:empty_line]
102
+ export_line(key, '')
68
103
  end
69
104
  end
105
+ @handlers.each do |path, io|
106
+ io.flush
107
+ io.fsync
108
+ io.close
109
+ end
110
+ @handlers = []
111
+ end
112
+
113
+ def export_section(section, directive)
114
+ key = handler_key(section, directive)
115
+ export_line(key, "<#{section[:section][:name].to_s}>")
116
+ @indent_level += 1
117
+ section[:body].each do |kv|
118
+ key = handler_key(kv, directive)
119
+ if kv[:value]
120
+ export_line(key, "#{kv[:name].to_s} #{kv[:value].to_s}")
121
+ else
122
+ export_line(key, "#{kv[:name].to_s}")
123
+ end
124
+ end
125
+ @indent_level -= 1
126
+ export_line(key, "</#{section[:name].to_s}>")
127
+ export_at_include(section, directive)
128
+ end
129
+
130
+ def export_at_include(object, parent)
131
+ pattern = object[:__PATTERN__]
132
+ if pattern
133
+ unless @include_flushed[pattern]
134
+ key = handler_key(parent, parent)
135
+ export_line(key, "@include #{pattern}")
136
+ @include_flushed[pattern] = true
137
+ end
138
+ end
139
+ end
140
+
141
+ def export_line(key, message)
142
+ io = @handlers[key]
143
+ if io
144
+ io.puts("#{' ' * @align * @indent_level}#{message}")
145
+ end
70
146
  end
71
147
 
72
148
  def export_body(directive)
149
+ @indent_level += 1
73
150
  directive[:body].each do |child|
74
151
  if child[:section]
152
+ export_section(child, directive)
75
153
  elsif child[:empty_line]
76
- if child[:__PATH__]
77
- io = @handlers[child[:__PATH__]]
78
- if io
79
- io.puts
80
- end
81
- else
82
- io = @handlers[directive[:__PATH__]]
83
- if io
84
- io.puts
85
- end
86
- end
154
+ key = handler_key(child, directive)
155
+ export_line(key, "")
87
156
  elsif child[:value]
88
- io = @handlers[child[:__PATH__]]
89
- if io
90
- io.puts("#{' ' * @align * @indent_level}#{child[:name].to_s} #{child[:value].to_s}")
91
- end
157
+ key = handler_key(child, directive)
158
+ export_line(key, "#{child[:name].to_s} #{child[:value].to_s}")
159
+ export_at_include(child, directive)
92
160
  elsif child[:name]
93
- io = @handlers[child[:__PATH__]]
94
- if io
95
- io.puts("#{' ' * @align * @indent_level}#{child[:name].to_s}")
96
- end
161
+ key = handler_key(child, directive)
162
+ export_line(key, child[:name].to_s)
163
+ export_at_include(child, directive)
97
164
  end
98
165
  end
166
+ @indent_level -= 1
99
167
  end
100
168
 
101
169
  def to_s(object, options={})
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Fluent
4
4
  module Auditify
5
- VERSION = "0.2.0"
5
+ VERSION = "0.3.0"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-auditify
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kentaro Hayashi