class HAProxy::Parser
Responsible for reading an HAProxy
config file and building an HAProxy::Config
instance.
Constants
- Error
Raised when an error occurs during parsing.
- SERVER_ATTRIBUTE_NAMES
- SERVER_ATTRIBUTE_NAMES_1_3
haproxy 1.3
- SERVER_ATTRIBUTE_NAMES_1_4
Added in haproxy 1.4
- SERVER_ATTRIBUTE_NAMES_1_5
Added in haproxy 1.5
- SERVER_ATTRIBUTE_NAMES_1_6
Added in haproxy 1.6
- SERVER_ATTRIBUTE_NAMES_1_7
Added in haproxy 1.7
- SERVER_ATTRIBUTE_NAMES_1_8
- SERVER_ATTRIBUTE_NAMES_1_9
Attributes
options[RW]
parse_result[RW]
verbose[RW]
Public Class Methods
new(options = nil)
click to toggle source
# File lib/haproxy/parser.rb, line 52 def initialize(options = nil) options ||= {} options = {verbose: false}.merge(options) self.options = options self.verbose = options[:verbose] end
Public Instance Methods
parse(config_text)
click to toggle source
# File lib/haproxy/parser.rb, line 65 def parse(config_text) result = parse_config_text(config_text) self.parse_result = result build_config(result) end
parse_file(filename)
click to toggle source
# File lib/haproxy/parser.rb, line 60 def parse_file(filename) config_text = File.read(filename) parse(config_text) end
Protected Instance Methods
build_backend(bs)
click to toggle source
# File lib/haproxy/parser.rb, line 101 def build_backend(bs) Backend.new.tap do |b| b.name = try_send(bs.backend_header, :proxy_name, :content) b.options = options_hash_from_config_section(bs) b.config = config_hash_from_config_section(bs) b.servers = server_hash_from_config_section(bs) end end
build_config(result)
click to toggle source
# File lib/haproxy/parser.rb, line 80 def build_config(result) HAProxy::Config.new(result).tap do |config| config.global = config_hash_from_config_section(result.global) config.frontends += collect_frontends(result) config.backends += collect_backends(result) config.listeners += collect_listeners(result) config.defaults += collect_defaults(result) end end
build_default(ds)
click to toggle source
# File lib/haproxy/parser.rb, line 121 def build_default(ds) Default.new.tap do |d| d.name = try_send(ds.defaults_header, :proxy_name, :content) d.options = options_hash_from_config_section(ds) d.config = config_hash_from_config_section(ds) end end
build_frontend(fs)
click to toggle source
# File lib/haproxy/parser.rb, line 91 def build_frontend(fs) Frontend.new.tap do |f| f.name = try_send(fs.frontend_header, :proxy_name, :content) f.host = try_send(fs.frontend_header, :service_address, :host, :content) f.port = try_send(fs.frontend_header, :service_address, :port, :content) f.options = options_hash_from_config_section(fs) f.config = config_hash_from_config_section(fs) end end
build_listener(ls)
click to toggle source
# File lib/haproxy/parser.rb, line 110 def build_listener(ls) Listener.new.tap do |l| l.name = try_send(ls.listen_header, :proxy_name, :content) l.host = try_send(ls.listen_header, :service_address, :host, :content) l.port = try_send(ls.listen_header, :service_address, :port, :content) l.options = options_hash_from_config_section(ls) l.config = config_hash_from_config_section(ls) l.servers = server_hash_from_config_section(ls) end end
clean_parsed_server_attributes(pairs)
click to toggle source
Converts attributes with no values to true, and combines everything else into space- separated strings.
# File lib/haproxy/parser.rb, line 187 def clean_parsed_server_attributes(pairs) pairs.each do |k, v| pairs[k] = if v.empty? true else v.join(" ") end end end
collect_backends(result)
click to toggle source
# File lib/haproxy/parser.rb, line 133 def collect_backends(result) result.backends.map { |bs| build_backend(bs) } end
collect_defaults(result)
click to toggle source
# File lib/haproxy/parser.rb, line 141 def collect_defaults(result) result.defaults.map { |ds| build_default(ds) } end
collect_frontends(result)
click to toggle source
# File lib/haproxy/parser.rb, line 129 def collect_frontends(result) result.frontends.map { |fs| build_frontend(fs) } end
collect_listeners(result)
click to toggle source
# File lib/haproxy/parser.rb, line 137 def collect_listeners(result) result.listeners.map { |ls| build_listener(ls) } end
config_hash_from_config_section(cs)
click to toggle source
# File lib/haproxy/parser.rb, line 203 def config_hash_from_config_section(cs) cs.config_lines.reject {|l| l.keyword.content == "option"}.each_with_object({}) do |l, ch| ch[l.keyword.content] = l.value ? l.value.content : nil end end
options_hash_from_config_section(cs)
click to toggle source
# File lib/haproxy/parser.rb, line 197 def options_hash_from_config_section(cs) cs.option_lines.each_with_object({}) do |l, ch| ch[l.keyword.content] = l.value ? l.value.content : nil end end
parse_config_text(config_text)
click to toggle source
# File lib/haproxy/parser.rb, line 73 def parse_config_text(config_text) parser = HAProxy::Treetop::ConfigParser.new result = parser.parse(config_text) raise HAProxy::Parser::Error.new(parser.failure_reason) if result.nil? result end
parse_server_attributes(value)
click to toggle source
Parses server attributes from the server value. I couldn't manage to get treetop to do this.
Types of server attributes to support: ipv4, boolean, string, integer, time (us, ms, s, m, h, d), url, source attributes
BUG: If an attribute value matches an attribute name, the parser will assume that a new attribute value has started. I don't know how haproxy itself handles that situation.
# File lib/haproxy/parser.rb, line 168 def parse_server_attributes(value) parts = value.to_s.split(/\s/) current_name = nil pairs = parts.each_with_object({}) { |part, attrs| if SERVER_ATTRIBUTE_NAMES.include?(part) current_name = part attrs[current_name] = [] elsif current_name.nil? raise "Invalid server attribute: #{part}" else attrs[current_name] << part end } clean_parsed_server_attributes(pairs) end
server_hash_from_config_section(cs)
click to toggle source
# File lib/haproxy/parser.rb, line 153 def server_hash_from_config_section(cs) cs.servers.each_with_object({}) do |s, ch| value = try_send(s, :value, :content) ch[s.name] = Server.new(s.name, s.host, s.port, parse_server_attributes(value)) end end
try_send(node, *method_names)
click to toggle source
# File lib/haproxy/parser.rb, line 145 def try_send(node, *method_names) method_name = method_names.shift if node.respond_to?(method_name) next_node = node.send(method_name) method_names.empty? ? next_node : try_send(next_node, *method_names) end end