class Puffy::Puppet

Manage nodes rulesets as a tree of rules to serve via Puppet

Public Class Methods

new(path, parser) click to toggle source

Setup an environment to store firewall rules to disk

@param path [String] Root directory of the tree of firewall rules @param parser [Puffy::Parser] A parser with nodes and rules

# File lib/puffy/puppet.rb, line 12
def initialize(path, parser)
  @path = path
  @parser = parser

  @formatters = [
    Puffy::Formatters::Pf::Ruleset.new,
    Puffy::Formatters::Netfilter4::Ruleset.new,
    Puffy::Formatters::Netfilter6::Ruleset.new,
  ]
end

Public Instance Methods

diff() click to toggle source

Show differences between saved and generated rules

@return [void]

# File lib/puffy/puppet.rb, line 41
def diff
  each_fragment do |fragment_name, fragment_content|
    human_fragment_name = fragment_name.delete_prefix(@path).delete_prefix('/')
    IO.popen("diff -u1 -N --unidirectional-new-file --ignore-matching-lines='^#' --label a/#{human_fragment_name} #{fragment_name} --label b/#{human_fragment_name} -", 'r+') do |io|
      io.write(fragment_content)
      io.close_write
      out = io.read
      $stdout.write out
    end
  end
end
save() click to toggle source

Saves rules to disk

@return [void]

# File lib/puffy/puppet.rb, line 26
def save
  each_fragment do |fragment_name, fragment_content|
    FileUtils.mkdir_p(File.dirname(fragment_name))

    next unless fragment_changed?(fragment_name, fragment_content)

    File.open(fragment_name, 'w') do |f|
      f.write(fragment_content)
    end
  end
end

Private Instance Methods

each_fragment() { |filename, emit_ruleset| ... } click to toggle source
# File lib/puffy/puppet.rb, line 55
def each_fragment
  @parser.nodes.each do |hostname|
    rules = @parser.ruleset_for(hostname)
    policy = @parser.policy_for(hostname)

    @formatters.each do |formatter|
      filename = File.join(@path, hostname, formatter.filename_fragment)
      yield filename, formatter.emit_ruleset(rules, policy)
    end
  end
end
fragment_changed?(fragment_name, fragment_content) click to toggle source
# File lib/puffy/puppet.rb, line 67
def fragment_changed?(fragment_name, fragment_content)
  return true unless File.exist?(fragment_name)

  File.read(fragment_name).split("\n").reject { |l| l =~ /^#/ } != fragment_content.split("\n").reject { |l| l =~ /^#/ }
end