flueconf 0.0.1

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 9effe81389c67ea7f4b51c8683f99402fcc20cf5bc43a18f5200ea43a712b363
4
+ data.tar.gz: 697df4d11e65ecf85ec54427e5326e9231b6e75b320d2be589bd9ac3327bd872
5
+ SHA512:
6
+ metadata.gz: eb218202d17afbd5afb401ab713e83cfe4ad748f6429af6d34089426cdc95cfc17c2bfc13e0080aa3de81bfe6a6dafd46cf8cc946d705142335c8ee89508de51
7
+ data.tar.gz: 212ef5b7c85e2fd53c4ddb8401c2623d353644d74fa19f4e9103b058ee09460ebf533d1baae430b94300ed091a46489f0a3dc40b6d365e2d92336cc7a87a842a
@@ -0,0 +1,10 @@
1
+ module Flueconf
2
+ def build(*args, &block)
3
+ Flueconf::Builder.new(*args, &block)
4
+ end
5
+ module_function :build
6
+ end
7
+
8
+ require 'flueconf/builder'
9
+ require 'flueconf/serializer'
10
+ require 'flueconf/version'
@@ -0,0 +1,94 @@
1
+ require 'json'
2
+
3
+ class Flueconf::Builder
4
+ def initialize(options = {}, &block)
5
+ @attributes = {}
6
+ @current = @attributes
7
+ @context = nil
8
+
9
+ build(&block) if block_given?
10
+ end
11
+
12
+ def build(&block)
13
+ return unless block_given?
14
+
15
+ @context = eval('self', block.binding)
16
+
17
+ instance_eval(&block)
18
+
19
+ self
20
+ end
21
+
22
+ def label(*args, &block)
23
+ method = block_given? ? :label : :@label
24
+ add(method, *args, &block)
25
+ end
26
+
27
+ %i(type id).each do |method|
28
+ define_method method do |*args, &block|
29
+ add(:"@#{method}", *args, &block)
30
+ end
31
+ end
32
+
33
+ %i(source match filter system).each do |method|
34
+ define_method method do |*args, &block|
35
+ add(method, *args, &block)
36
+ end
37
+ end
38
+
39
+ def method_missing(method, *args, &block)
40
+ if @context and @context.respond_to?(method)
41
+ @context.send(method, *args, &block)
42
+ else
43
+ add(method, *args, &block)
44
+ end
45
+ end
46
+
47
+ def add(*args, &block)
48
+ if block_given?
49
+ obj = {}
50
+ k = args.first.to_sym
51
+
52
+ @current[k] = [] unless @current[k].is_a? Array
53
+ @current[k] << obj
54
+
55
+ c = obj
56
+ args[1..-1].each do |k|
57
+ obj = {}
58
+ c[k.to_sym] = obj
59
+ c = obj
60
+ end
61
+
62
+ previous = @current
63
+ @current = obj
64
+ instance_eval(&block)
65
+ @current = previous
66
+ elsif args.length >= 1
67
+ method = args.shift.to_sym
68
+
69
+ value = case args.length
70
+ when 0
71
+ nil
72
+ when 1
73
+ args.first
74
+ else
75
+ args
76
+ end
77
+ value = case value
78
+ when Hash
79
+ value.map { |k, v| v.nil? ? nil : "#{k}:#{v}" }.compact.join(',')
80
+ when Array
81
+ value.compact.join(',')
82
+ else
83
+ value
84
+ end
85
+ @current[method] = value
86
+ else
87
+ raise ArgumentError, "One key and at least one of values are required: #{args.join(',')}"
88
+ end
89
+ end
90
+
91
+ def to_fluent(*args)
92
+ Flueconf::Serializer.serialize(@attributes, *args)
93
+ end
94
+ end
@@ -0,0 +1,44 @@
1
+ require 'json'
2
+
3
+ class Flueconf::Serializer
4
+ class << self
5
+ def serialize(obj, options = {})
6
+ indent = options[:indent]
7
+ indent = 2 unless indent.is_a? Integer and indent >= 0
8
+
9
+ dump(obj, [], indent, 0)
10
+ end
11
+
12
+ private
13
+
14
+ def dump(obj, keys = [], indent = 0, depth = 0)
15
+ prefix = ' ' * indent * depth
16
+ key = keys.empty? ? nil : keys.join(' ')
17
+
18
+ case obj
19
+ when Array
20
+ obj.map do |v|
21
+ send(__method__, v, [key], indent, depth)
22
+ end.compact.join("\n")
23
+ when Hash
24
+ compacted = keys.empty? || (!obj.empty? && obj.values.all? { |v| v.is_a? Hash })
25
+
26
+ str = obj.map do |k, v|
27
+ k = k.to_s.strip
28
+
29
+ send(__method__, v, (compacted ? (keys + [k]) : [k]), indent, (compacted ? depth : depth + 1))
30
+ end.compact.join("\n")
31
+
32
+ compacted ? str : "#{prefix}<#{key}>\n" + (str.empty? ? '' : "#{str}\n") + "#{prefix}</#{keys.first}>"
33
+ when Numeric, TrueClass, FalseClass
34
+ (key ? "#{prefix}#{key} " : '') + obj.inspect
35
+ when NilClass
36
+ key ? "#{prefix}#{key}" : nil
37
+ when Regexp
38
+ (key ? "#{prefix}#{key} " : '') + obj.to_s
39
+ else
40
+ (key ? "#{prefix}#{key} " : '') + (/["#]/.match?(obj) ? obj.to_s.to_json : obj.to_s)
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,8 @@
1
+ module Flueconf
2
+ VERSION = '0.0.1'.freeze
3
+
4
+ def version
5
+ VERSION
6
+ end
7
+ module_function :version
8
+ end
@@ -0,0 +1,340 @@
1
+ describe Flueconf do
2
+ it 'can handle primitive types' do
3
+ fluent = Flueconf.build do
4
+ it_is_integer 1
5
+ it_is_negtive_integer -1
6
+ it_is_float 1.23
7
+ it_is_negtive_float -1.23
8
+ it_is_string 'foo'
9
+ it_is_special_string '#{Socket.gethostname}'
10
+ it_is_null nil
11
+ it_is_true true
12
+ it_is_false false
13
+ it_is_regexp /^.*$/
14
+ it_is_array [1, -2, 3.3, -4.4, 'bar', nil, true, false]
15
+ it_is_empty_array []
16
+ it_is_hash({ foo: 123, bar: 'aaa', null: nil })
17
+ it_is_empty_hash({})
18
+ end.to_fluent
19
+
20
+ expect(fluent).to eq <<~'EOF'.chomp
21
+ it_is_integer 1
22
+ it_is_negtive_integer -1
23
+ it_is_float 1.23
24
+ it_is_negtive_float -1.23
25
+ it_is_string foo
26
+ it_is_special_string "#{Socket.gethostname}"
27
+ it_is_null
28
+ it_is_true true
29
+ it_is_false false
30
+ it_is_regexp (?-mix:^.*$)
31
+ it_is_array 1,-2,3.3,-4.4,bar,true,false
32
+ it_is_empty_array
33
+ it_is_hash foo:123,bar:aaa
34
+ it_is_empty_hash
35
+ EOF
36
+ end
37
+
38
+ it 'can handle array object' do
39
+ fluent = Flueconf.build do
40
+ it_is_array_object do
41
+ foo 'bar'
42
+ end
43
+ end.to_fluent
44
+
45
+ expect(fluent).to eq <<~'EOF'.chomp
46
+ <it_is_array_object>
47
+ foo bar
48
+ </it_is_array_object>
49
+ EOF
50
+ end
51
+
52
+ it 'can handle empty array object' do
53
+ fluent = Flueconf.build do
54
+ it_is_array_object do
55
+ end
56
+ end.to_fluent
57
+
58
+ expect(fluent).to eq <<~'EOF'.chomp
59
+ <it_is_array_object>
60
+ </it_is_array_object>
61
+ EOF
62
+ end
63
+
64
+ it 'can handle object' do
65
+ fluent = Flueconf.build do
66
+ it_is_object 'obj' do
67
+ foo 'bar'
68
+ end
69
+ end.to_fluent
70
+
71
+ expect(fluent).to eq <<~'EOF'.chomp
72
+ <it_is_object obj>
73
+ foo bar
74
+ </it_is_object>
75
+ EOF
76
+ end
77
+
78
+ it 'can handle empty object' do
79
+ fluent = Flueconf.build do
80
+ it_is_object 'obj' do
81
+ end
82
+ end.to_fluent
83
+
84
+ expect(fluent).to eq <<~'EOF'.chomp
85
+ <it_is_object obj>
86
+ </it_is_object>
87
+ EOF
88
+ end
89
+
90
+ it 'can handle object with multiple keys' do
91
+ fluent = Flueconf.build do
92
+ it_is_object 'o', 'b', 'j' do
93
+ foo 'bar'
94
+ end
95
+ end.to_fluent
96
+
97
+ expect(fluent).to eq <<~'EOF'.chomp
98
+ <it_is_object o b j>
99
+ foo bar
100
+ </it_is_object>
101
+ EOF
102
+ end
103
+
104
+ it 'can handle nested data types' do
105
+ fluent = Flueconf.build do
106
+ foo 'bar'
107
+ obj 'nested', 'obj' do
108
+ obj 'obj', 'in', 'obj' do
109
+ float 3.14
110
+ arr do
111
+ int 123
112
+ end
113
+ arr do
114
+ bool true
115
+ arr_in_arr do
116
+ bool false
117
+ end
118
+ end
119
+ end
120
+ end
121
+ end.to_fluent
122
+
123
+ expect(fluent).to eq <<~'EOF'.chomp
124
+ foo bar
125
+ <obj nested obj>
126
+ <obj obj in obj>
127
+ float 3.14
128
+ <arr>
129
+ int 123
130
+ </arr>
131
+ <arr>
132
+ bool true
133
+ <arr_in_arr>
134
+ bool false
135
+ </arr_in_arr>
136
+ </arr>
137
+ </obj>
138
+ </obj>
139
+ EOF
140
+ end
141
+
142
+ it 'can handle multiple builds' do
143
+ builder = Flueconf.build do
144
+ obj do
145
+ first 1
146
+ end
147
+ end
148
+
149
+ fluent = builder.build do
150
+ second 2
151
+ end.to_fluent
152
+
153
+ expect(fluent).to eq <<~'EOF'.chomp
154
+ <obj>
155
+ first 1
156
+ </obj>
157
+ second 2
158
+ EOF
159
+ end
160
+
161
+ it 'can serialize with different indent' do
162
+ fluent = Flueconf.build do
163
+ foo 'bar'
164
+ obj 'nested', 'obj' do
165
+ obj 'obj', 'in', 'obj' do
166
+ float 3.14
167
+ arr do
168
+ int 123
169
+ end
170
+ arr do
171
+ bool true
172
+ end
173
+ end
174
+ end
175
+ end.to_fluent(indent: 4)
176
+
177
+ expect(fluent).to eq <<~'EOF'.chomp
178
+ foo bar
179
+ <obj nested obj>
180
+ <obj obj in obj>
181
+ float 3.14
182
+ <arr>
183
+ int 123
184
+ </arr>
185
+ <arr>
186
+ bool true
187
+ </arr>
188
+ </obj>
189
+ </obj>
190
+ EOF
191
+ end
192
+
193
+ it 'can handle method in different context' do
194
+ def bar
195
+ 'barbar'
196
+ end
197
+
198
+ fluent = Flueconf.build do
199
+ foo bar
200
+ end.to_fluent
201
+
202
+ expect(fluent).to eq <<~'EOF'.chomp
203
+ foo barbar
204
+ EOF
205
+ end
206
+
207
+ it 'can handle predefined types' do
208
+ fluent = Flueconf.build do
209
+ system do
210
+ dir_permission '0755'
211
+ end
212
+ source do
213
+ type 'forward'
214
+ id 'in_forward'
215
+ label '@outside'
216
+ port 24224
217
+ end
218
+ source do
219
+ type 'tail'
220
+ id 'in_tail_httpd_access'
221
+ path '/var/log/httpd-access.log'
222
+ pos_file '/var/log/td-agent/httpd-access.log.pos'
223
+ tag 'apache.access'
224
+ parse do
225
+ type 'apache2'
226
+ end
227
+ end
228
+ filter 'fluent.**' do
229
+ type 'record_transformer'
230
+ record do
231
+ level '${tag_parts[1]}'
232
+ end
233
+ end
234
+ filter '**' do
235
+ type 'record_transformer'
236
+ record do
237
+ hostname '#{Socket.gethostname}'
238
+ end
239
+ end
240
+ match 'fluent.**' do
241
+ type 'rewrite_tag_filter'
242
+ rule do
243
+ key 'message'
244
+ pattern /.*/
245
+ tag 'fluent'
246
+ end
247
+ end
248
+ match '**' do
249
+ type 'forward'
250
+ server do
251
+ host '192.0.2.1'
252
+ weight 100
253
+ end
254
+ server do
255
+ host '192.0.2.2'
256
+ weight 50
257
+ end
258
+ end
259
+ label '@outside' do
260
+ match '**' do
261
+ type 'forward'
262
+ server do
263
+ host '192.0.2.1'
264
+ weight 100
265
+ end
266
+ server do
267
+ host '192.0.2.2'
268
+ weight 50
269
+ end
270
+ end
271
+ end
272
+ end.to_fluent
273
+
274
+ expect(fluent).to eq <<~'EOF'.chomp
275
+ <system>
276
+ dir_permission 0755
277
+ </system>
278
+ <source>
279
+ @type forward
280
+ @id in_forward
281
+ @label @outside
282
+ port 24224
283
+ </source>
284
+ <source>
285
+ @type tail
286
+ @id in_tail_httpd_access
287
+ path /var/log/httpd-access.log
288
+ pos_file /var/log/td-agent/httpd-access.log.pos
289
+ tag apache.access
290
+ <parse>
291
+ @type apache2
292
+ </parse>
293
+ </source>
294
+ <filter fluent.**>
295
+ @type record_transformer
296
+ <record>
297
+ level ${tag_parts[1]}
298
+ </record>
299
+ </filter>
300
+ <filter **>
301
+ @type record_transformer
302
+ <record>
303
+ hostname "#{Socket.gethostname}"
304
+ </record>
305
+ </filter>
306
+ <match fluent.**>
307
+ @type rewrite_tag_filter
308
+ <rule>
309
+ key message
310
+ pattern (?-mix:.*)
311
+ tag fluent
312
+ </rule>
313
+ </match>
314
+ <match **>
315
+ @type forward
316
+ <server>
317
+ host 192.0.2.1
318
+ weight 100
319
+ </server>
320
+ <server>
321
+ host 192.0.2.2
322
+ weight 50
323
+ </server>
324
+ </match>
325
+ <label @outside>
326
+ <match **>
327
+ @type forward
328
+ <server>
329
+ host 192.0.2.1
330
+ weight 100
331
+ </server>
332
+ <server>
333
+ host 192.0.2.2
334
+ weight 50
335
+ </server>
336
+ </match>
337
+ </label>
338
+ EOF
339
+ end
340
+ end
@@ -0,0 +1 @@
1
+ require 'flueconf'
metadata ADDED
@@ -0,0 +1,94 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: flueconf
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Rianol Jou
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-08-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '12.3'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '12.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.8'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.8'
55
+ description: " Config fluentd in ruby. And featuring all programming features (variables,
56
+ iterators, functions, regexp, etc) in ruby.\n"
57
+ email:
58
+ - rianol.jou@gmail.com
59
+ executables: []
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - lib/flueconf.rb
64
+ - lib/flueconf/builder.rb
65
+ - lib/flueconf/serializer.rb
66
+ - lib/flueconf/version.rb
67
+ - spec/flueconf_spec.rb
68
+ - spec/spec_helper.rb
69
+ homepage: https://github.com/RiANOl/flueconf
70
+ licenses:
71
+ - MIT
72
+ metadata: {}
73
+ post_install_message:
74
+ rdoc_options: []
75
+ require_paths:
76
+ - lib
77
+ required_ruby_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '2.4'
82
+ required_rubygems_version: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ requirements: []
88
+ rubygems_version: 3.0.3
89
+ signing_key:
90
+ specification_version: 4
91
+ summary: Config fluentd in ruby.
92
+ test_files:
93
+ - spec/flueconf_spec.rb
94
+ - spec/spec_helper.rb