fluentd-ui 1.0.0.alpha.3 → 1.0.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of fluentd-ui might be problematic. Click here for more details.

Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/.eslintrc.js +45 -0
  3. data/.travis.yml +17 -3
  4. data/Gemfile +2 -2
  5. data/Gemfile.lock +62 -63
  6. data/README.md +11 -0
  7. data/app/controllers/api/config_definitions_controller.rb +41 -17
  8. data/app/controllers/concerns/setting_concern.rb +0 -4
  9. data/app/controllers/fluentd/settings/in_tail_controller.rb +1 -1
  10. data/app/form_builders/fluentd_form_builder.rb +18 -6
  11. data/app/javascript/packs/application.js +20 -20
  12. data/app/javascript/packs/aws_credential.js +61 -0
  13. data/app/javascript/packs/codemirror.js +33 -37
  14. data/app/javascript/packs/config_field.js +93 -0
  15. data/app/javascript/packs/fluent_log.js +10 -9
  16. data/app/javascript/packs/in_tail_parse.js +77 -76
  17. data/app/javascript/packs/nested_settings.js +17 -16
  18. data/app/javascript/packs/notification.js +14 -14
  19. data/app/javascript/packs/out_forward_setting.js +14 -0
  20. data/app/javascript/packs/out_s3_setting.js +14 -0
  21. data/app/javascript/packs/owned_plugin_form.js +60 -57
  22. data/app/javascript/packs/parser_multiline_form.js +15 -14
  23. data/app/javascript/packs/plugin_setting.js +13 -13
  24. data/app/javascript/packs/settings.js +23 -18
  25. data/app/javascript/packs/transport_config.js +62 -0
  26. data/app/javascript/packs/transport_section.js +72 -0
  27. data/app/javascript/packs/treeview.js +11 -10
  28. data/app/models/concerns/fluentd/setting/configurable.rb +1 -3
  29. data/app/models/concerns/fluentd/setting/plugin.rb +29 -1
  30. data/app/models/concerns/fluentd/setting/plugin_config.rb +32 -8
  31. data/app/models/concerns/fluentd/setting/plugin_parameter.rb +74 -21
  32. data/app/models/concerns/fluentd/setting/registry_loader.rb +38 -0
  33. data/app/models/concerns/fluentd/setting/section_config.rb +52 -0
  34. data/app/models/concerns/fluentd/setting/section_parser.rb +25 -18
  35. data/app/models/fluentd/setting/in_forward.rb +29 -10
  36. data/app/models/fluentd/setting/in_syslog.rb +6 -6
  37. data/app/models/fluentd/setting/out_forward.rb +15 -3
  38. data/app/models/fluentd/setting/out_mongo.rb +0 -11
  39. data/app/models/fluentd/setting/out_s3.rb +17 -3
  40. data/app/models/fluentd/setting/out_tdlog.rb +3 -2
  41. data/app/models/fluentd/setting/section.rb +4 -0
  42. data/app/models/fluentd/setting/type/object.rb +17 -0
  43. data/app/views/fluentd/settings/in_forward/_form.html.haml +5 -3
  44. data/app/views/fluentd/settings/out_forward/_form.html.haml +18 -0
  45. data/app/views/fluentd/settings/out_s3/_form.html.haml +18 -0
  46. data/app/views/shared/settings/_form.html.haml +14 -10
  47. data/app/views/shared/settings/show.html.haml +2 -2
  48. data/app/views/shared/vue/_aws_credential.html.haml +22 -0
  49. data/app/views/shared/vue/_config_field.html.haml +49 -0
  50. data/app/views/shared/vue/_out_forward_setting.html.haml +13 -0
  51. data/app/views/shared/vue/_out_s3_setting.html.haml +19 -0
  52. data/app/views/shared/vue/_owned_plugin_form.html.haml +8 -48
  53. data/app/views/shared/vue/_transport_config.html.haml +20 -0
  54. data/app/views/shared/vue/_transport_section.html.haml +30 -0
  55. data/config/initializers/dig.rb +8 -0
  56. data/config/initializers/dummy_logger.rb +1 -0
  57. data/config/initializers/types.rb +2 -1
  58. data/config/locales/translation_ja.yml +2 -2
  59. data/fluentd-ui.gemspec +1 -0
  60. data/gemfiles/ruby2.2.gemfile +28 -0
  61. data/lib/dummy_logger.rb +13 -0
  62. data/lib/fluentd-ui/version.rb +1 -1
  63. data/package.json +5 -0
  64. data/spec/features/fluentd/setting/in_forward_spec.rb +1 -2
  65. data/spec/features/fluentd/setting/in_http_spec.rb +1 -2
  66. data/spec/features/fluentd/setting/in_monitor_agent_spec.rb +1 -2
  67. data/spec/features/fluentd/setting/out_forward_spec.rb +3 -5
  68. data/spec/features/fluentd/setting/out_stdout_spec.rb +1 -2
  69. data/spec/features/out_elasticsearch_spec.rb +3 -3
  70. data/spec/features/out_forward_spec.rb +6 -5
  71. data/spec/features/out_tdlog_spec.rb +3 -2
  72. data/spec/features/shared_examples/configurable_daemon_settings.rb +2 -2
  73. data/spec/features/source_and_output_spec.rb +2 -0
  74. data/spec/models/fluentd/setting/in_forward_spec.rb +65 -9
  75. data/spec/models/fluentd/setting/in_syslog_spec.rb +12 -7
  76. data/spec/models/fluentd/setting/in_tail_spec.rb +6 -0
  77. data/spec/models/fluentd/setting/out_mongo_spec.rb +2 -3
  78. data/spec/models/fluentd/setting/out_tdlog_spec.rb +1 -2
  79. data/spec/spec_helper.rb +5 -0
  80. data/yarn.lock +466 -12
  81. metadata +90 -39
  82. data/app/helpers/settings_helper.rb +0 -144
  83. data/app/models/concerns/fluentd/setting/section_validator.rb +0 -21
  84. data/app/views/fluentd/settings/_form.html.haml +0 -43
@@ -0,0 +1,62 @@
1
+ /* global _ */
2
+ "use strict";
3
+
4
+ import "lodash/lodash";
5
+ import ConfigField from "./config_field";
6
+
7
+ const TransportConfig = {
8
+ template: "#vue-transport-config",
9
+ components: {
10
+ "config-field": ConfigField
11
+ },
12
+ props: [
13
+ "pluginType",
14
+ "pluginName"
15
+ ],
16
+ data: function() {
17
+ return {
18
+ transportType: "tcp",
19
+ options: ["tcp", "tls"],
20
+ tlsOptions: []
21
+ };
22
+ },
23
+ computed: {
24
+ token: function() {
25
+ return Rails.csrfToken();
26
+ }
27
+ },
28
+ filters: {
29
+ toUpper: function(value) {
30
+ return _.toUpper(value);
31
+ }
32
+ },
33
+ mounted: function() {
34
+ },
35
+ methods: {
36
+ onChange: function() {
37
+ console.log(this.pluginType, this.pluginName, this.transportType);
38
+ this.updateSection();
39
+ },
40
+
41
+ updateSection: function() {
42
+ if (this.transportType === "tcp") {
43
+ return;
44
+ }
45
+ $.ajax({
46
+ method: "GET",
47
+ url: "/api/config_definitions",
48
+ headers: {
49
+ "X-CSRF-Token": this.token
50
+ },
51
+ data: {
52
+ type: this.pluginType,
53
+ name: this.pluginName
54
+ }
55
+ }).then((data) => {
56
+ this.tlsOptions = data.tlsOptions;
57
+ });
58
+ }
59
+ }
60
+ };
61
+
62
+ export { TransportConfig as default };
@@ -0,0 +1,72 @@
1
+ /* global _ */
2
+ "use strict";
3
+ import "lodash/lodash";
4
+
5
+ import ConfigField from "./config_field";
6
+
7
+ $(document).ready(() => {
8
+ new Vue({
9
+ el: "#transport-section",
10
+ components: {
11
+ "config-field": ConfigField
12
+ },
13
+ filters: {
14
+ toUpper: function(value) {
15
+ return _.toUpper(value);
16
+ }
17
+ },
18
+ props: {
19
+ "transportType": {
20
+ default: "tcp",
21
+ type: String
22
+ }
23
+ },
24
+ data: function() {
25
+ return {
26
+ pluginType: null,
27
+ pluginName: null,
28
+ options: ["tcp", "tls"],
29
+ commonOptions: [],
30
+ advancedOptions: []
31
+
32
+ };
33
+ },
34
+ computed: {
35
+ token: function() {
36
+ return Rails.csrfToken();
37
+ }
38
+ },
39
+ beforeMount: function() {
40
+ this.pluginType = this.$el.attributes.pluginType.nodeValue;
41
+ this.pluginName = this.$el.attributes.pluginName.nodeValue;
42
+ },
43
+ mounted: function() {
44
+ },
45
+ methods: {
46
+ onChange: function() {
47
+ console.log(this.pluginType, this.pluginName, this.transportType);
48
+ this.updateSection();
49
+ },
50
+
51
+ updateSection: function() {
52
+ if (this.transportType === "tcp") {
53
+ return;
54
+ }
55
+ $.ajax({
56
+ method: "GET",
57
+ url: "/api/config_definitions",
58
+ headers: {
59
+ "X-CSRF-Token": this.token
60
+ },
61
+ data: {
62
+ type: this.pluginType,
63
+ name: this.pluginName
64
+ }
65
+ }).then((data) => {
66
+ this.commonOptions = data.transport.commonOptions;
67
+ this.advancedOptions = data.transport.advancedOptions;
68
+ });
69
+ }
70
+ }
71
+ });
72
+ });
@@ -1,5 +1,6 @@
1
- 'use strict';
2
- import 'lodash/lodash';
1
+ /* global _ */
2
+ "use strict";
3
+ import "lodash/lodash";
3
4
  $(document).ready(() => {
4
5
  new Vue({
5
6
  el: "#treeview",
@@ -15,14 +16,6 @@ $(document).ready(() => {
15
16
  paths: []
16
17
  },
17
18
 
18
- mounted: function(){
19
- console.log(this.initialPath);
20
- this.path = this.initialPath;
21
- this.fetchTree();
22
- this.$watch("path", this.fetchTree);
23
- this.$watch("path", this.fetchPreview);
24
- },
25
-
26
19
  computed: {
27
20
  selected: function(){
28
21
  var self = this;
@@ -55,6 +48,14 @@ $(document).ready(() => {
55
48
  }
56
49
  },
57
50
 
51
+ mounted: function(){
52
+ console.log(this.initialPath);
53
+ this.path = this.initialPath;
54
+ this.fetchTree();
55
+ this.$watch("path", this.fetchTree);
56
+ this.$watch("path", this.fetchPreview);
57
+ },
58
+
58
59
  methods: {
59
60
  isAncestor: function(target) {
60
61
  return this.path.indexOf(target) === 0;
@@ -64,11 +64,9 @@ class Fluentd
64
64
  self._built_in_params << name
65
65
  unless name == "type"
66
66
  attribute(name, type, **options.slice(:precision, :limit, :scale))
67
- validates(name, presence: true) if options[:required]
68
67
  end
69
68
  else
70
69
  attribute(name, type, **options.slice(:precision, :limit, :scale))
71
- validates(name, presence: true) if options[:required]
72
70
  end
73
71
  self._types[name] = type
74
72
  self._descriptions[name] = options[:desc] if options.key?(:desc)
@@ -100,7 +98,7 @@ class Fluentd
100
98
  end
101
99
 
102
100
  def config_argument(name, type = ActiveModel::Type::Value.new, **options)
103
- config_param(name, **options)
101
+ config_param(name, type, **options)
104
102
  self._argument_name = name
105
103
  end
106
104
 
@@ -1,4 +1,10 @@
1
1
  require "fluent/plugin"
2
+ require "fluent/test/log"
3
+ require "fluent/test/driver/input"
4
+ require "fluent/test/driver/output"
5
+ require "fluent/test/driver/filter"
6
+ require "fluent/test/driver/parser"
7
+ require "fluent/test/driver/formatter"
2
8
 
3
9
  class Fluentd
4
10
  module Setting
@@ -11,7 +17,6 @@ class Fluentd
11
17
  include Fluentd::Setting::PluginConfig
12
18
  include Fluentd::Setting::SectionParser
13
19
  include Fluentd::Setting::PluginParameter
14
- include Fluentd::Setting::SectionValidator
15
20
 
16
21
  included do
17
22
  cattr_accessor :plugin_type, :plugin_name, :config_definition
@@ -61,6 +66,29 @@ class Fluentd
61
66
  @plugin_class ||= plugin_instance.class
62
67
  end
63
68
 
69
+ def create_driver(config)
70
+ case plugin_type
71
+ when "input"
72
+ if plugin_class.class_variable_defined?(:@@pos_file_paths)
73
+ plugin_class.class_variable_set(:@@pos_file_paths, {})
74
+ end
75
+ Fluent::Test::Driver::Input.new(plugin_class).configure(config)
76
+ when "output"
77
+ if Fluent::Plugin::FileBuffer.class_variable_defined?(:@@buffer_paths)
78
+ Fluent::Plugin::FileBuffer.class_variable_set(:@@buffer_paths, {})
79
+ end
80
+ Fluent::Test::Driver::Output.new(plugin_class).configure(config)
81
+ when "filter"
82
+ Fluent::Test::Driver::Filter.new(plugin_class).configure(config)
83
+ when "parser"
84
+ Fluent::Test::Driver::Parser.new(plugin_class).configure(config)
85
+ when "formatter"
86
+ FLuent::Test::Driver::Formatter.new(plugin_class).configure(config)
87
+ else
88
+ nil
89
+ end
90
+ end
91
+
64
92
  def plugin_helpers
65
93
  @plugin_helpers ||= if plugin_instance.respond_to?(:plugin_helpers)
66
94
  plugin_instance.plugin_helpers
@@ -3,6 +3,21 @@ class Fluentd
3
3
  module PluginConfig
4
4
  extend ActiveSupport::Concern
5
5
 
6
+ included do
7
+ validate :validate_configuration
8
+ end
9
+
10
+ def validate_configuration
11
+ original_log = $log
12
+ $log = DummyLogger.logger
13
+ config = to_config.to_s.lines[1..-2].join
14
+ self.class.create_driver(config)
15
+ rescue Fluent::ConfigError => ex
16
+ errors.add(:base, :invalid, message: ex.message)
17
+ ensure
18
+ $log = original_log
19
+ end
20
+
6
21
  def to_config
7
22
  name = case plugin_type
8
23
  when "input"
@@ -44,16 +59,25 @@ class Fluentd
44
59
  end
45
60
  elements = []
46
61
  sections.to_h.each do |key, section_params|
47
- if %w(parse format buffer storage).include?(key)
48
- section_params["0"] = { "@type" => self.attributes["#{key}_type"] }.merge(section_params["0"])
49
- end
50
62
  next if section_params.blank?
51
- section_params.each do |index, _section_params|
52
- sub_attrs, sub_elements = parse_attributes(_section_params)
53
- elements << config_element(key, "", sub_attrs, sub_elements)
63
+ section_class = self._sections[key.to_sym]
64
+ if %w(parse format buffer storage).include?(key)
65
+ if section_params && section_params.key?("0")
66
+ section_params["0"] = { "type" => self.attributes["#{key}_type"] }.merge(section_params["0"])
67
+ else
68
+ section_params = {
69
+ "0" => { "type" => self.attributes["#{key}_type"] }
70
+ }
71
+ end
54
72
  end
73
+ elements = section_params.map do |index, _section_params|
74
+ section_class.new(_section_params).to_config
75
+ end.compact
76
+ end
77
+ attrs = params.to_h.reject do |key, value|
78
+ skip?(key.to_sym, value)
55
79
  end
56
- return params.to_h.reject{|key, value| skip?(key.to_sym, value) }, elements
80
+ return attrs, elements
57
81
  end
58
82
 
59
83
  # copy from Fluent::Test::Helpers#config_element
@@ -64,7 +88,7 @@ class Fluentd
64
88
  def skip?(key, value)
65
89
  return true if value.blank?
66
90
  if self._defaults.key?(key)
67
- reformat_value(key, self._defaults[key]) == reformat_value(key, value)
91
+ self.class.reformat_value(key, self._defaults[key]) == self.class.reformat_value(key, value)
68
92
  else
69
93
  false
70
94
  end
@@ -6,19 +6,19 @@ class Fluentd
6
6
  include Fluentd::Setting::Configurable
7
7
 
8
8
  def column_type(name)
9
- self.class._types[name]
9
+ self.class.column_type(name)
10
10
  end
11
11
 
12
12
  def list_of(name)
13
- self.class._list[name]
13
+ self.class.list_of(name)
14
14
  end
15
15
 
16
16
  def desc(name)
17
- self.class._descriptions[name]
17
+ self.class.desc(name)
18
18
  end
19
19
 
20
20
  def default(name)
21
- reformat_value(name, self.class._defaults[name])
21
+ self.class.reformat_value(name, self.class.default(name))
22
22
  end
23
23
 
24
24
  def common_options
@@ -38,19 +38,19 @@ class Fluentd
38
38
  end
39
39
 
40
40
  def have_buffer_section?
41
- self.class._sections.key?(:buffer)
41
+ self.class.have_buffer_section?
42
42
  end
43
43
 
44
44
  def have_storage_section?
45
- self.class._sections.key?(:storage)
45
+ self.class.have_storage_section?
46
46
  end
47
47
 
48
48
  def have_parse_section?
49
- self.class._sections.key?(:parse)
49
+ self.class.have_parse_section?
50
50
  end
51
51
 
52
52
  def have_format_section?
53
- self.class._sections.key?(:format)
53
+ self.class.have_format_section?
54
54
  end
55
55
 
56
56
  def create_buffer
@@ -77,19 +77,6 @@ class Fluentd
77
77
  formatter_class.new(format["0"].except("type"))
78
78
  end
79
79
 
80
- def reformat_value(name, value)
81
- type = column_type(name)
82
- return value if type.nil? # name == :time_key
83
- return value if type == :enum
84
- return value if type == :regexp
85
- type_name = if type.is_a?(Fluentd::Setting::Type::Time)
86
- :time
87
- else
88
- type
89
- end
90
- Fluent::Config::REFORMAT_VALUE.call(type_name, value)
91
- end
92
-
93
80
  module ClassMethods
94
81
  def column_type(name)
95
82
  self._types[name]
@@ -99,12 +86,61 @@ class Fluentd
99
86
  self._list[name]
100
87
  end
101
88
 
89
+ def desc(name)
90
+ self._descriptions[name]
91
+ end
92
+
93
+ def default(name)
94
+ reformat_value(name, self._defaults[name])
95
+ end
96
+
97
+ def have_buffer_section?
98
+ self._sections.key?(:buffer)
99
+ end
100
+
101
+ def have_storage_section?
102
+ self._sections.key?(:storage)
103
+ end
104
+
105
+ def have_parse_section?
106
+ self._sections.key?(:parse)
107
+ end
108
+
109
+ def have_format_section?
110
+ self._sections.key?(:format)
111
+ end
112
+
113
+ def initial_params
114
+ new # ensure to load attributes
115
+ params = {}
116
+ self._defaults.each do |key, value|
117
+ if key.to_s.start_with?("@")
118
+ params[key.to_s[1..-1].to_sym] = value
119
+ else
120
+ params[key] = value
121
+ end
122
+ end
123
+ self._sections.each do |key, section|
124
+ next if section.initial_params.blank?
125
+ params[key] = {
126
+ "0" => section.initial_params.stringify_keys
127
+ }
128
+ end
129
+ params
130
+ end
131
+
102
132
  def permit_params
103
133
  self.new # init
104
134
  keys = self._types.keys
105
135
  self._sections.each do |key, section|
106
136
  keys << _permit_section(key, section)
107
137
  end
138
+
139
+ keys << :buffer_type if have_buffer_section?
140
+ keys << :storage_type if have_storage_section?
141
+ keys << :parse_type if have_parse_section?
142
+ keys << :format_type if have_format_section?
143
+
108
144
  keys
109
145
  end
110
146
 
@@ -115,6 +151,23 @@ class Fluentd
115
151
  end
116
152
  keys
117
153
  end
154
+
155
+ def reformat_value(name, value)
156
+ type = column_type(name)
157
+ return value if type.nil? # name == :time_key
158
+ return value.to_sym if type == :enum
159
+ return value if type == :regexp
160
+ type_name = if type.is_a?(Fluentd::Setting::Type::Time)
161
+ :time
162
+ else
163
+ type
164
+ end
165
+ begin
166
+ Fluent::Config::REFORMAT_VALUE.call(type_name, value.dup)
167
+ rescue TypeError
168
+ Fluent::Config::REFORMAT_VALUE.call(type_name, value)
169
+ end
170
+ end
118
171
  end
119
172
  end
120
173
  end