fluentd-ui 1.0.1 → 1.1.0

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 (67) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog.md +5 -0
  3. data/Gemfile.lock +1 -1
  4. data/app/controllers/api/settings_controller.rb +46 -16
  5. data/app/controllers/concerns/setting_concern.rb +1 -1
  6. data/app/controllers/fluentd/settings/filter_grep_controller.rb +9 -0
  7. data/app/controllers/fluentd/settings/filter_parser_controller.rb +9 -0
  8. data/app/controllers/fluentd/settings/filter_record_transformer_controller.rb +14 -0
  9. data/app/controllers/fluentd/settings/filter_stdout_controller.rb +9 -0
  10. data/app/javascript/packs/filter_grep_setting.js +39 -0
  11. data/app/javascript/packs/grep_container.js +53 -0
  12. data/app/javascript/packs/grep_pattern.js +43 -0
  13. data/app/javascript/packs/owned_plugin_form.js +9 -7
  14. data/app/javascript/packs/settings.js +34 -16
  15. data/app/models/concerns/fluentd/setting/configurable.rb +1 -0
  16. data/app/models/concerns/fluentd/setting/label.rb +11 -0
  17. data/app/models/concerns/fluentd/setting/plugin.rb +2 -0
  18. data/app/models/concerns/fluentd/setting/plugin_config.rb +34 -4
  19. data/app/models/concerns/fluentd/setting/section_config.rb +10 -2
  20. data/app/models/fluentd/agent/common.rb +97 -0
  21. data/app/models/fluentd/setting/config.rb +71 -0
  22. data/app/models/fluentd/setting/filter_grep.rb +38 -0
  23. data/app/models/fluentd/setting/filter_parser.rb +34 -0
  24. data/app/models/fluentd/setting/filter_record_transformer.rb +27 -0
  25. data/app/models/fluentd/setting/filter_stdout.rb +34 -0
  26. data/app/models/fluentd/setting/in_forward.rb +1 -0
  27. data/app/models/fluentd/setting/in_http.rb +1 -1
  28. data/app/models/fluentd/setting/in_monitor_agent.rb +1 -1
  29. data/app/models/fluentd/setting/in_syslog.rb +1 -1
  30. data/app/models/fluentd/setting/out_elasticsearch.rb +1 -0
  31. data/app/models/fluentd/setting/out_forward.rb +1 -1
  32. data/app/models/fluentd/setting/out_mongo.rb +1 -0
  33. data/app/models/fluentd/setting/out_s3.rb +1 -0
  34. data/app/models/fluentd/setting/out_stdout.rb +1 -1
  35. data/app/models/fluentd/setting/out_tdlog.rb +1 -1
  36. data/app/views/api/settings/_element.json.jbuilder +3 -1
  37. data/app/views/api/settings/index.json.jbuilder +10 -2
  38. data/app/views/api/settings/show.json.jbuilder +1 -1
  39. data/app/views/fluentd/settings/filter_grep/_form.html.haml +18 -0
  40. data/app/views/fluentd/settings/filter_record_transformer/_form.html.haml +20 -0
  41. data/app/views/fluentd/settings/in_tail/_form.html.haml +1 -0
  42. data/app/views/fluentd/settings/source_and_output.html.haml +46 -14
  43. data/app/views/shared/vue/_filter_grep_setting.html.haml +19 -0
  44. data/app/views/shared/vue/_grep_container.html.haml +32 -0
  45. data/app/views/shared/vue/_grep_pattern.html.haml +24 -0
  46. data/app/views/shared/vue/_setting.html.erb +2 -2
  47. data/config/locales/translation_en.yml +39 -10
  48. data/config/locales/translation_ja.yml +39 -10
  49. data/config/routes.rb +6 -0
  50. data/lib/fluentd-ui/version.rb +1 -1
  51. data/test/factories/fluentd.rb +4 -4
  52. data/test/factories/plugins.rb +2 -2
  53. data/test/factories/user.rb +2 -2
  54. data/test/fixtures/config/label.conf +15 -0
  55. data/test/fixtures/config/multi-label.conf +40 -0
  56. data/test/fixtures/config/simple.conf +12 -0
  57. data/test/models/fluentd/agent_common_test.rb +288 -0
  58. data/test/models/fluentd/setting/config_test.rb +98 -0
  59. data/test/support/configurable_daemon_settings.rb +1 -1
  60. data/test/system/fluentd/setting/filter_grep_test.rb +96 -0
  61. data/test/system/fluentd/setting/filter_parser_test.rb +13 -0
  62. data/test/system/fluentd/setting/filter_record_transformer_test.rb +30 -0
  63. data/test/system/fluentd/setting/filter_stdout_test.rb +13 -0
  64. data/test/system/source_and_output_test.rb +168 -19
  65. data/test/test_helper.rb +4 -0
  66. metadata +98 -55
  67. data/.rspec +0 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d6d045b90f722b9793cbf8e23abcfc7a9d78b00a898001bbdbd0c3c590a4de9a
4
- data.tar.gz: 0dc77c43a23e146587351f375c0aaa976fafbd5cefcf1c10e053f611f1efee42
3
+ metadata.gz: df6f137ac8e1059590ba4eab9a088b202cc722397be835af16284d4c6d088e73
4
+ data.tar.gz: e62688373e36af8d8ce2a1afb3fb29f71fe450a519962380891b223d58ea1341
5
5
  SHA512:
6
- metadata.gz: f79d69613ea99bc156ba20899c0334b6919238181b5635acde0f31e5119f7c33bd749a2a5aee8195923fe29b0bb9152074ab9e2b2c85eec87e6f30503e73d47d
7
- data.tar.gz: 49938a1d5aa8b4704deedc1c0a237b539a11661067a24a0c9fda5ca7e14dce96c504a3374257056d92e39bc13d1c1557b92f1c4aeecf80549a69d57ddb8f81eb
6
+ metadata.gz: fc05861a183d2d2eee8cda2e53b922b931145eb3087e0f11c323482762bf5ccff6e02c8efe1f0e939bd5b2bd03295750e09dea9bb7c0f63bb33e79748eaea2ca
7
+ data.tar.gz: 0140571fd3ceb851aea8ddc765811d17bf863c47276e3cff3ace9c4bf8a15a5852f2e130fe6477ac099f91a8b65a8dafe9c7953720b7d6f2edb65c9e9ce587ee
@@ -1,3 +1,8 @@
1
+ ## Release 1.1.0 - 2018/09/25
2
+
3
+ * [maintenance] Suppress JavaScript warnings [#265](https://github.com/fluent/fluentd-ui/pull/265)
4
+ * [improvement] Support filter plugins and label feature [#262](https://github.com/fluent/fluentd-ui/pull/262)
5
+
1
6
  ## Release 1.0.1 - 2018/09/14
2
7
 
3
8
  * [maintenance] Update rubyzip [#263](https://github.com/fluent/fluentd-ui/pull/263)
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- fluentd-ui (1.0.1)
4
+ fluentd-ui (1.1.0)
5
5
  addressable
6
6
  bootsnap (>= 1.1.0)
7
7
  bundler
@@ -2,7 +2,7 @@ class Api::SettingsController < ApplicationController
2
2
  before_action :login_required
3
3
  before_action :find_fluentd
4
4
  before_action :set_config
5
- before_action :set_section, only: [:show, :update, :destroy]
5
+ before_action :set_target_element, only: [:show, :update, :destroy]
6
6
  helper_method :element_id
7
7
 
8
8
  def index
@@ -12,26 +12,38 @@ class Api::SettingsController < ApplicationController
12
12
  end
13
13
 
14
14
  def update
15
+ label_name = params[:label]
15
16
  coming = Fluent::Config::V1Parser.parse(params[:content], @fluentd.config_file)
16
- current = @section
17
- index = @config.elements.index current
18
- unless index
17
+ coming_element = coming.elements.first
18
+
19
+ unless @target_element
19
20
  render_404
20
21
  return
21
22
  end
22
- @config.elements[index] = coming.elements.first
23
+
24
+ @target_element.elements = coming_element.elements
25
+ @target_element.merge(coming_element)
26
+
23
27
  @config.write_to_file
24
- redirect_to api_setting_path(id: element_id(coming.elements.first))
28
+ redirect_to api_setting_path(id: element_id(label_name, @target_element),
29
+ label: label_name,
30
+ pluginType: params[:pluginType])
25
31
  end
26
32
 
27
33
  def destroy
28
- unless @config.elements.index(@section)
34
+ if params[:label] == "ROOT" || params[:pluginType] == "source"
35
+ name = params[:pluginType]
36
+ arg = params[:arg]
37
+ else
38
+ name = "label"
39
+ arg = params[:label]
40
+ end
41
+ if @config.delete_element(name, arg, @target_element)
42
+ @config.write_to_file
43
+ head :no_content # 204
44
+ else
29
45
  render_404
30
- return
31
46
  end
32
- @config.elements.delete @section
33
- @config.write_to_file
34
- head :no_content # 204
35
47
  end
36
48
 
37
49
  private
@@ -40,17 +52,35 @@ class Api::SettingsController < ApplicationController
40
52
  @config = Fluentd::Setting::Config.new(@fluentd.config_file)
41
53
  end
42
54
 
43
- def set_section
44
- @section = @config.elements.find do |elm|
45
- element_id(elm) == params[:id]
55
+ def set_target_element
56
+ id = params[:id]
57
+ plugin_type = params[:pluginType]
58
+ label_name = params[:label]
59
+ return unless id
60
+ elements = @config.group_by_label.dig(label_name, element_type(plugin_type))
61
+ @target_element = elements.find do |elm|
62
+ element_id(label_name, elm) == id
46
63
  end
47
64
  end
48
65
 
49
- def element_id(element)
50
- index = @config.elements.index(element)
66
+ def element_id(label_name, element)
67
+ element_type = element_type(element.name)
68
+ elements = @config.group_by_label.dig(label_name, element_type)
69
+ index = elements.index(element)
51
70
  "#{"%06d" % index}#{Digest::MD5.hexdigest(element.to_s)}"
52
71
  end
53
72
 
73
+ def element_type(name)
74
+ case name
75
+ when "source"
76
+ :sources
77
+ when "filter"
78
+ :filters
79
+ when "match"
80
+ :matches
81
+ end
82
+ end
83
+
54
84
  def render_404
55
85
  render nothing: true, status: 404
56
86
  end
@@ -23,7 +23,7 @@ module SettingConcern
23
23
  return render "shared/settings/show"
24
24
  end
25
25
 
26
- @fluentd.agent.config_append @setting.to_config
26
+ @fluentd.agent.config_merge(@setting.to_config.to_s)
27
27
  if @fluentd.agent.running?
28
28
  unless @fluentd.agent.restart
29
29
  @setting.errors.add(:base, @fluentd.agent.log.tail(1).first)
@@ -0,0 +1,9 @@
1
+ class Fluentd::Settings::FilterGrepController < ApplicationController
2
+ include SettingConcern
3
+
4
+ private
5
+
6
+ def target_class
7
+ Fluentd::Setting::FilterGrep
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ class Fluentd::Settings::FilterParserController < ApplicationController
2
+ include SettingConcern
3
+
4
+ private
5
+
6
+ def target_class
7
+ Fluentd::Setting::FilterParser
8
+ end
9
+ end
@@ -0,0 +1,14 @@
1
+ class Fluentd::Settings::FilterRecordTransformerController < ApplicationController
2
+ include SettingConcern
3
+
4
+ private
5
+
6
+ def target_class
7
+ Fluentd::Setting::FilterRecordTransformer
8
+ end
9
+
10
+ def setting_params
11
+ permit_params = target_class.permit_params + [:record]
12
+ params.require(:setting).permit(*permit_params)
13
+ end
14
+ end
@@ -0,0 +1,9 @@
1
+ class Fluentd::Settings::FilterStdoutController < ApplicationController
2
+ include SettingConcern
3
+
4
+ private
5
+
6
+ def target_class
7
+ Fluentd::Setting::FilterStdout
8
+ end
9
+ end
@@ -0,0 +1,39 @@
1
+ /* global _ */
2
+ "use strict";
3
+ import "lodash/lodash";
4
+
5
+ import GrepContainer from "./grep_container";
6
+
7
+ $(document).ready(() => {
8
+ new Vue({
9
+ el: "#filter-grep-setting",
10
+ components: {
11
+ "grep-container": GrepContainer,
12
+ },
13
+ data: function() {
14
+ return {
15
+ containers: {
16
+ and: [true],
17
+ or: [true]
18
+ }
19
+ };
20
+ },
21
+ mounted: function() {
22
+ this.$on("add-grep-container", this.addGrepContainer);
23
+ this.$on("remove-grep-container", this.removeGrepContainer);
24
+ },
25
+ methods: {
26
+ addGrepContainer: function(containerType, index) {
27
+ const found = this.containers[containerType].indexOf(false);
28
+ if (found < 0) {
29
+ this.$set(this.containers[containerType], this.containers[containerType].length, true);
30
+ } else {
31
+ this.$set(this.containers[containerType], found, true);
32
+ }
33
+ },
34
+ removeGrepContainer: function(containerType, index) {
35
+ this.$set(this.containers[containerType], index, false);
36
+ }
37
+ }
38
+ });
39
+ });
@@ -0,0 +1,53 @@
1
+ /* global _ */
2
+ "use strict";
3
+ import "lodash/lodash";
4
+ import GrepPattern from "./grep_pattern";
5
+
6
+ const GrepContainer = {
7
+ template: "#vue-grep-container",
8
+ components: {
9
+ "grep-pattern": GrepPattern
10
+ },
11
+ props: [
12
+ "containerType", // and/or
13
+ "index",
14
+ ],
15
+ data: function() {
16
+ return {
17
+ grepType: "regexp",
18
+ patterns: [true],
19
+ }
20
+ },
21
+ filters: {
22
+ humanize: function(value) {
23
+ return _.capitalize(value.replace(/_/g, " "));
24
+ }
25
+ },
26
+ methods: {
27
+ add: function(event) {
28
+ this.$emit("add-grep-container", this.containerType, this.index);
29
+ },
30
+ remove: function(event) {
31
+ this.$emit("remove-grep-container", this.containerType, this.index);
32
+ },
33
+ addGrepPattern: function(grepType, index) {
34
+ const found = this.patterns.indexOf(false);
35
+ if (found < 0) {
36
+ this.$set(this.patterns, this.patterns.length, true);
37
+ } else {
38
+ this.$set(this.patterns, found, true);
39
+ }
40
+ },
41
+ removeGrepPattern: function(grepType, index) {
42
+ console.log(index);
43
+ console.log(this.patterns);
44
+ this.$set(this.patterns, index, false);
45
+ console.log(this.patterns);
46
+ },
47
+ inputName: function(index) {
48
+ return `setting[${this.containerType}[${this.index}]][grep_type]`;
49
+ }
50
+ }
51
+ };
52
+
53
+ export { GrepContainer as default };
@@ -0,0 +1,43 @@
1
+ /* global _ */
2
+ "use strict";
3
+ import "lodash/lodash";
4
+
5
+ const GrepPattern = {
6
+ template: "#vue-grep-pattern",
7
+ props: [
8
+ "containerType", // and/or
9
+ "grepType", // regexp/exclude
10
+ "index", // the index of and/or
11
+ "subIndex", // the index of regexp/exclude
12
+ ],
13
+ data: function() {
14
+ return {
15
+ key: null,
16
+ pattern: null,
17
+ }
18
+ },
19
+
20
+ filters: {
21
+ humanize: function(value) {
22
+ return _.capitalize(value.replace(/_/g, " "));
23
+ }
24
+ },
25
+
26
+ methods: {
27
+ add: function(event) {
28
+ this.$emit("add-grep-pattern", this.grepType, this.subIndex);
29
+ },
30
+ remove: function(event) {
31
+ this.$emit("remove-grep-pattern", this.grepType, this.subIndex);
32
+ },
33
+ inputId: function(name, index, subIndex) {
34
+ return `setting_${this.containerType}_${index}_${this.grepType}_${subIndex}__${name}`;
35
+ },
36
+
37
+ inputName: function(name, index, subIndex) {
38
+ return `setting[${this.containerType}[${index}]][${this.grepType}[${subIndex}]][${name}]`;
39
+ }
40
+ }
41
+ };
42
+
43
+ export { GrepPattern as default };
@@ -43,19 +43,21 @@ const OwnedPluginForm = {
43
43
  this.options = JSON.parse(this.optionsJson);
44
44
  this.initialParams = JSON.parse(this.initialParamsJson || "{}");
45
45
  this.pluginName = this.initialPluginName;
46
- this.$on("hook:updated", () => {
47
- console.log("hook:updated");
48
- this.$nextTick(() => {
49
- $("[data-toggle=tooltip]").tooltip("dispose");
50
- $("[data-toggle=tooltip]").tooltip("enable");
51
- });
52
- });
53
46
  this.$once("data-loaded", () => {
54
47
  this.updateSection();
55
48
  });
56
49
  this.$emit("data-loaded");
57
50
  },
58
51
 
52
+ updated: function() {
53
+ this.$nextTick(() => {
54
+ if ($("[data-toggle=tooltip]").tooltip) {
55
+ $("[data-toggle=tooltip]").tooltip("dispose");
56
+ $("[data-toggle=tooltip]").tooltip("enable");
57
+ }
58
+ });
59
+ },
60
+
59
61
  methods: {
60
62
  onChange: function() {
61
63
  this.updateSection();
@@ -6,11 +6,19 @@ import "lodash/lodash";
6
6
  $(document).ready(() => {
7
7
  const SettingSection = {
8
8
  template: "#vue-setting-section",
9
- props: ["initialId", "initialContent", "initialType", "initialName", "initialArg"],
9
+ props: [
10
+ "initialLabel",
11
+ "initialId",
12
+ "initialContent",
13
+ "initialType",
14
+ "initialName",
15
+ "initialArg"
16
+ ],
10
17
  data: function() {
11
18
  return {
12
19
  mode: "default",
13
20
  processing: false,
21
+ current_label: null,
14
22
  id: null,
15
23
  content: null,
16
24
  type: null,
@@ -20,6 +28,7 @@ $(document).ready(() => {
20
28
  },
21
29
  created: function() {
22
30
  this.initialState();
31
+ this.current_label = this.initialLabel;
23
32
  this.id = this.initialId;
24
33
  this.content = this.initialContent;
25
34
  this.type = this.initialType;
@@ -55,6 +64,8 @@ $(document).ready(() => {
55
64
  method: "POST",
56
65
  data: {
57
66
  _method: "PATCH",
67
+ label: this.current_label,
68
+ pluginType: this.name,
58
69
  id: this.id,
59
70
  content: this.content
60
71
  },
@@ -80,7 +91,10 @@ $(document).ready(() => {
80
91
  method: "POST",
81
92
  data: {
82
93
  _method: "DELETE",
83
- id: this.id
94
+ label: this.current_label,
95
+ pluginType: this.name,
96
+ arg: this.arg,
97
+ id: this.id,
84
98
  },
85
99
  headers: {
86
100
  "X-CSRF-Token": this.token
@@ -102,8 +116,11 @@ $(document).ready(() => {
102
116
  loaded: false,
103
117
  loading: false,
104
118
  sections: {
105
- sources: [],
106
- matches: []
119
+ "ROOT": {
120
+ sources: [],
121
+ filters: [],
122
+ matches: []
123
+ }
107
124
  }
108
125
  };
109
126
  },
@@ -115,20 +132,21 @@ $(document).ready(() => {
115
132
  methods: {
116
133
  update: function() {
117
134
  this.loading = true;
118
- $.getJSON(`${relativeUrlRoot}/api/settings`, (data)=> {
119
- var sources = [];
120
- var matches = [];
121
- data.forEach((v)=> {
122
- if(v.name === "source"){
123
- sources.push(v);
124
- }else{
125
- matches.push(v);
126
- }
135
+ $.getJSON(`${relativeUrlRoot}/api/settings`, (data) => {
136
+ console.log(data);
137
+ _.each(data, (elements, label) => {
138
+ this.$set(this.sections, label, elements);
127
139
  });
128
- this.sections.sources = sources;
129
- this.sections.matches = matches;
140
+ _.each(this.sections, (elements, label) => {
141
+ if (_.isEmpty(data[label])) {
142
+ this.$delete(this.sections, label);
143
+ }
144
+ })
145
+ if (_.isEmpty(data["ROOT"])) {
146
+ this.$set(this.sections, "ROOT", []);
147
+ }
130
148
  this.loaded = true;
131
- setTimeout(()=> {
149
+ setTimeout(() => {
132
150
  this.loading = false;
133
151
  }, 500);
134
152
  });