module Havox::Merlin
Constants
- BASENAME_REGEX
- ERROR_REGEX
- RULES_BLOCK_REGEX
- SEPARATOR_REGEX
Public Class Methods
compile(topology_file, policy_file, opts = {})
click to toggle source
# File lib/havox/modules/merlin.rb, line 65 def self.compile(topology_file, policy_file, opts = {}) rules = [] result = run(cmd.compile(topology_file, policy_file)) # Runs Merlin in the remote VM and retrieves its output. result = parse(result) # Parses the output into raw rules. result = Havox::RuleSanitizer.new(result).sanitized_rules # Removes unwanted rule snippets. result = Havox::RuleExpander.new(result).expanded_rules if opts[:expand] # Expands each raw rule in the parsed result. result.each { |raw_rule| rules << Havox::Rule.new(raw_rule, opts) } # Creates Rule instances for each raw rule. rules end
compile!(topology_file, policy_file, opts = {})
click to toggle source
# File lib/havox/modules/merlin.rb, line 75 def self.compile!(topology_file, policy_file, opts = {}) check_options(opts) policy_file = Havox::ModifiedPolicy.new(topology_file, policy_file).path if opts[:basic] if upload!(topology_file, opts[:dst]) && upload!(policy_file, opts[:dst]) topology_file = "#{opts[:dst]}#{basename(topology_file)}" policy_file = "#{opts[:dst]}#{basename(policy_file)}" compile(topology_file, policy_file, opts) end end
run(command)
click to toggle source
# File lib/havox/modules/merlin.rb, line 53 def self.run(command) output = nil ssh_connection { |ssh| output = ssh.exec!(command) } output end
upload!(file, dst = nil)
click to toggle source
# File lib/havox/modules/merlin.rb, line 59 def self.upload!(file, dst = nil) dst ||= "#{config.merlin_path}/examples/" ssh_connection { |ssh| ssh.scp.upload!(file, dst) } true end
Private Class Methods
basename(path)
click to toggle source
# File lib/havox/modules/merlin.rb, line 39 def basename(path) path.match(BASENAME_REGEX)[:name] end
check_for_errors(result)
click to toggle source
# File lib/havox/modules/merlin.rb, line 34 def check_for_errors(result) error_msg = result.scan(ERROR_REGEX).flatten.first raise Havox::Merlin::ParsingError, error_msg unless error_msg.nil? end
check_options(opts)
click to toggle source
# File lib/havox/modules/merlin.rb, line 43 def check_options(opts) opts[:dst] ||= "#{config.merlin_path}/examples/" # Sets the upload path in Merlin VM. opts[:force] ||= false # Forces Havox to ignore field conflicts. opts[:basic] ||= false # Instructs to append basic policies. opts[:expand] ||= false # Expands raw rules from VLAN-based to full predicates. opts[:output] ||= false # Switches Enqueue action for Output action. opts[:syntax] ||= :trema # Sets the output syntax for generated rules. end
cmd()
click to toggle source
# File lib/havox/modules/merlin.rb, line 15 def cmd Havox::Command end
config()
click to toggle source
# File lib/havox/modules/merlin.rb, line 11 def config Havox.configuration end
parse(result)
click to toggle source
# File lib/havox/modules/merlin.rb, line 25 def parse(result) result = result.tr("\n", '').tr("\t", ' ') # Removes line break and tab characters. check_for_errors(result) # Raises an error if Merlin has errored. result = result.scan(RULES_BLOCK_REGEX).flatten.first # Matches OpenFlow rules block. return [] if result.nil? # Returns an empty array if no rules were created. result = result.split(SEPARATOR_REGEX) # Splits the block into separated rules. result.map(&:to_s) # Converts NetSSH special string to string. end
ssh_connection() { |ssh| ... }
click to toggle source
# File lib/havox/modules/merlin.rb, line 19 def ssh_connection Net::SSH.start(config.merlin_host, config.merlin_user, password: config.merlin_password) do |ssh| yield(ssh) end end