Class: Fluent::Auditify::PluginManager

Inherits:
Object
  • Object
show all
Includes:
Plugin
Defined in:
lib/fluent/auditify/plugin_manager.rb

Constant Summary

Constants included from Plugin

Fluent::Auditify::Plugin::ARTIFACT, Fluent::Auditify::Plugin::CHARGES, Fluent::Auditify::Plugin::CONF_REGISTRY, Fluent::Auditify::Plugin::DEFAULT_PLUGIN_PATH, Fluent::Auditify::Plugin::FLUENT_AUDITIFY_LIB_PATH, Fluent::Auditify::Plugin::REGISTRIES

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Plugin

artifact, charges, discard, guilty, polish, register_conf, registries

Constructor Details

#initialize(logger = nil, mask_only: false) ⇒ PluginManager

Returns a new instance of PluginManager.



11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/fluent/auditify/plugin_manager.rb', line 11

def initialize(logger = nil, mask_only: false)
  @logger = logger
  @plugins = []
  @mask_only = mask_only
  load
  Fluent::Auditify::Plugin.registries.each do |registry|
    registry.map.each do |sym, klass|
      @logger.debug("Instantiate #{klass} for <#{sym}> plugin") if @logger
      @plugins << klass.new
    end
  end
end

Class Method Details

.search(plugin_name, logger = nil) ⇒ Object

search plugin with prefix



25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/fluent/auditify/plugin_manager.rb', line 25

def self.search(plugin_name, logger = nil)
  # Find plugin and require it in advance

  # Lastly, load built-in plugins
  plugin_path = File.expand_path(File.join(FLUENT_AUDITIFY_LIB_PATH,
                                           'fluent/auditify/plugin/conf_',
                                           "#{plugin_name}.rb"))
  if File.exist?(plugin_path)
    logger.debug("Loading <#{plugin_path}>") if logger
    require plugin_path
    return
  end
end

Instance Method Details

#builtin_plugin_pathsObject



61
62
63
64
65
66
# File 'lib/fluent/auditify/plugin_manager.rb', line 61

def builtin_plugin_paths
  Dir.glob("#{DEFAULT_PLUGIN_PATH}/*.rb").select do |path|
    File.dirname(path) == DEFAULT_PLUGIN_PATH and
      File.basename(path).start_with?('conf_')
  end
end


130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/fluent/auditify/plugin_manager.rb', line 130

def collect_related_config_files(object)
  files = []
  object.each do |directive|
    if directive[:include]
      files << directive[:include_path].to_s
    elsif directive[:empty_line]
      next
    else
      directive[:body].each do |element|
        if element[:value] and element[:name].to_s == '@include'
          files << element[:value].to_s
        end
      end
    end
  end
  files
end

#dispatch(options = {}) ⇒ Object



169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/fluent/auditify/plugin_manager.rb', line 169

def dispatch(options={})
  evacuate(options)
  @plugins.each do |plugin|
    next if skip_plugin?(plugin)

    config_path = File.join(@workspace_dir, File.basename(options[:config]))
    unless supported_file_extension?(plugin, config_path)
      @logger.debug("<#{plugin.class}> is not applicable to <#{config_path}>")
      next
    end

    plugin.instance_variable_set(:@log, @logger)
    begin
      @logger.debug { "#{plugin.class}\#parse" }
      plugin.parse(config_path, options)

      if plugin.respond_to?(:transform)
        tree = plugin.transform(config_path, options)
        util = Fluent::Auditify::ParsletUtil.new
        util.export(tree, options)
        @logger.info("Configuration files were saved at: #{@workspace_dir}")
      end
    rescue => e
      @logger.error("#{e.message}")
    end
  end
end

#evacuate(options = {}) ⇒ Object



148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/fluent/auditify/plugin_manager.rb', line 148

def evacuate(options={})
  @workspace_dir = Dir.mktmpdir('fluent-auditify')
  @logger.debug("Create workspace under <#{@workspace_dir}>")
  @base_dir = File.dirname(options[:config])

  if options[:config].end_with?('.conf')
    parser = Fluent::Auditify::Parser::V1ConfigParser.new
    object = parser.parse(File.read(options[:config]))

    # copy configuration files into workspace
    touched = [options[:config]]
    touched << collect_related_config_files(object).collect { |v| File.join(@base_dir, v) }
    touched.flatten!
    @logger.debug("Copy configuration files: <#{touched}>")
    FileUtils.cp(touched, @workspace_dir)
  else
    @logger.debug("Copy configuration files: <#{options[:config]}>")
    FileUtils.cp(options[:config], @workspace_dir)
  end
end

#linux?Boolean

Returns:

  • (Boolean)


72
73
74
# File 'lib/fluent/auditify/plugin_manager.rb', line 72

def linux?
  RbConfig::CONFIG['host_os'].include?('linux')
end

#loadObject



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/fluent/auditify/plugin_manager.rb', line 39

def load
  builtin_plugin_paths.each do |plugin_path|
    @logger.debug("Loading <#{plugin_path}>") if @logger
    if @mask_only
      if plugin_path.include?('/lib/fluent/auditify/plugin/conf_mask_secrets.rb')
        require plugin_path
      end
    else
      require plugin_path
    end
  end

  Gem::Specification.each { |spec|
    if spec.name.start_with?('fluent-auditify-plugin-')
      Dir.glob("#{spec.full_gem_path}/lib/fluent/auditify/plugin/conf_*.rb") do |path|
        @logger.debug("Loading <#{path}>") if @logger
        require path
      end
    end
  }
end

#report(type) ⇒ Object



197
198
199
200
201
202
203
204
205
# File 'lib/fluent/auditify/plugin_manager.rb', line 197

def report(type)
  case type
  when :console
    reporter = Fluent::Auditify::Reporter::ConsoleReporter.new(@logger)
  when :json
    reporter Fluent::Auditify::Reporter::JsonReporter.new(@logger)
  end
  reporter.run(Plugin.charges)
end

#skip_plugin?(plugin) ⇒ Boolean

Returns:

  • (Boolean)


114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/fluent/auditify/plugin_manager.rb', line 114

def skip_plugin?(plugin)
  unless supported_plugin?(plugin)
    return true
  end
  unless plugin.respond_to?(:parse)
    return true
  end
  unless plugin.respond_to?(:supported_file_extension?)
    return true
  end
  unless plugin.respond_to?(:disabled?)
    return true
  end
  false
end

#supported_file_extension?(plugin, config) ⇒ Boolean

Returns:

  • (Boolean)


99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/fluent/auditify/plugin_manager.rb', line 99

def supported_file_extension?(plugin, config)
  unless plugin.respond_to?(:supported_file_extension?)
    @logger.info("Plugin: <#{plugin.class}> must implement supported_file_extension?")
    return false
  end
  if config.end_with?('.yml', '.yaml') and
    plugin.supported_file_extension?.include?(:yaml)
    return true
  elsif config.end_with?('.conf') and
       plugin.supported_file_extension?.include?(:conf)
    return true
  end
  false
end

#supported_plugin?(plugin) ⇒ Boolean

Returns:

  • (Boolean)


76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/fluent/auditify/plugin_manager.rb', line 76

def supported_plugin?(plugin)
  unless plugin.respond_to?(:supported_platform?)
    @logger.info("Plugin: <#{plugin.class}> must implement supported_platform?")
    return false
  end
  platform = plugin.supported_platform?
  case platform
  when :windows
    unless windows?
      @logger.debug("Plugin: <#{plugin.class}> does not support #{RbConfig::CONFIG['host_os']}")
      return false
    end
  when :linux
    unless linux?
      @logger.debug("Plugin: <#{plugin.class}> does not support #{RbConfig::CONFIG['host_os']}")
      return false
    end
  else
    # :any
    true
  end
end

#windows?Boolean

Returns:

  • (Boolean)


68
69
70
# File 'lib/fluent/auditify/plugin_manager.rb', line 68

def windows?
  %w(mswin mingw).any? { |v| RbConfig::CONFIG['host_os'].include?(v) }
end