Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ source 'https://rubygems.org'

# Specify your gem's dependencies in linux_admin.gemspec
gemspec

gem "more_core_extensions", "=1.1.0", :git => "git://github.com/ManageIQ/more_core_extensions.git", :tag => "v1.1.0"
1 change: 1 addition & 0 deletions lib/linux_admin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

require 'linux_admin/service'
require 'linux_admin/disk'
require 'linux_admin/hosts'
require 'linux_admin/partition'
require 'linux_admin/distro'
require 'linux_admin/system'
Expand Down
73 changes: 73 additions & 0 deletions lib/linux_admin/hosts.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
class LinuxAdmin
class Hosts < LinuxAdmin
attr_accessor :filename
attr_accessor :raw_lines
attr_accessor :parsed_file

def initialize(filename = "/etc/hosts")
@filename = filename
self.reload
end

def reload
@raw_lines = File.read(@filename).split("\n")
parse_file
end

def save
cleanup_empty
@raw_lines = assemble_lines
File.write(@filename, @raw_lines.join("\n"))
end

def update_entry(address, hostname, comment = nil)
# Delete entries for this hostname first
@parsed_file.each {|i| i[:hosts].to_a.delete(hostname)}

# Add entry
line_number = @parsed_file.find_path(address).first

if line_number.blank?
@parsed_file.push({:address => address, :hosts => [hostname], :comment => comment})
else
new_hosts = @parsed_file.fetch_path(line_number, :hosts).to_a.push(hostname)
@parsed_file.store_path(line_number, :hosts, new_hosts)
@parsed_file.store_path(line_number, :comment, comment) if comment
end
end

private
def parse_file
@parsed_file = []
@raw_lines.each { |line| @parsed_file.push(parse_line(line.strip)) }
@parsed_file.delete_blank_paths
end

def parse_line(line)
data, comment = line.split("#", 2)
address, hosts = data.to_s.split(" ", 2)
hostnames = hosts.to_s.split(" ")

{ :address => address.to_s, :hosts => hostnames, :comment => comment.to_s.strip, :blank => line.blank?}
end

def cleanup_empty
@parsed_file.each do |h|
h.delete(:hosts) if h[:address].blank?
h.delete(:address) if h[:hosts].blank?
end

@parsed_file.delete_blank_paths
end

def assemble_lines
@parsed_file.each_with_object([]) { |l, a| a.push(l[:blank] ? "" : build_line(l[:address], l[:hosts], l[:comment])) }
end

def build_line(address, hosts, comment)
line = [address.to_s.ljust(16), hosts.to_a.uniq]
line.push("##{comment}") if comment
line.flatten.join(" ").strip
end
end
end
2 changes: 1 addition & 1 deletion linux_admin.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,6 @@ registration, updates, etc.

spec.add_dependency "activesupport", "< 4.0"
spec.add_dependency "inifile", "~> 2.0.2"
spec.add_dependency "more_core_extensions"
spec.add_dependency "more_core_extensions", "~> 1.1.0"
spec.add_dependency "nokogiri"
end
55 changes: 55 additions & 0 deletions spec/hosts_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
require 'spec_helper'

describe LinuxAdmin::Hosts do
etc_hosts = "\n #Some Comment\n127.0.0.1\tlocalhost localhost.localdomain # with a comment\n127.0.1.1 my.domain.local"
before do
File.stub(:read).and_return(etc_hosts)
@instance = LinuxAdmin::Hosts.new
end

describe "#reload" do
it "sets raw_lines" do
expected_array = ["", " #Some Comment", "127.0.0.1\tlocalhost localhost.localdomain # with a comment", "127.0.1.1 my.domain.local"]
expect(@instance.raw_lines).to eq(expected_array)
end

it "sets parsed_file" do
expected_hash = [{:blank=>true}, {:comment=>"Some Comment"}, {:address=>"127.0.0.1", :hosts=>["localhost", "localhost.localdomain"], :comment=>"with a comment"}, {:address=>"127.0.1.1", :hosts=>["my.domain.local"]}]
expect(@instance.parsed_file).to eq(expected_hash)
end
end

describe "#update_entry" do
it "removes an existing entry and creates a new one" do
expected_hash = [{:blank=>true}, {:comment=>"Some Comment"}, {:address=>"127.0.0.1", :hosts=>["localhost", "localhost.localdomain"], :comment=>"with a comment"}, {:address=>"127.0.1.1", :hosts=>[]}, {:address=>"1.2.3.4", :hosts=>["my.domain.local"], :comment=>nil}]
@instance.update_entry("1.2.3.4", "my.domain.local")
expect(@instance.parsed_file).to eq(expected_hash)
end

it "updates an existing entry" do
expected_hash = [{:blank=>true}, {:comment=>"Some Comment"}, {:address=>"127.0.0.1", :hosts=>["localhost", "localhost.localdomain", "new.domain.local"], :comment=>"with a comment"}, {:address=>"127.0.1.1", :hosts=>["my.domain.local"]}]
@instance.update_entry("127.0.0.1", "new.domain.local")
expect(@instance.parsed_file).to eq(expected_hash)
end
end

describe "#save" do
before do
File.stub(:write)
end

it "properly generates file with new content" do
expected_array = ["", "#Some Comment", "127.0.0.1 localhost localhost.localdomain #with a comment", "127.0.1.1 my.domain.local", "1.2.3.4 test"]
@instance.update_entry("1.2.3.4", "test")
@instance.save
expect(@instance.raw_lines).to eq(expected_array)
end

it "properly generates file with removed content" do
expected_array = ["", "#Some Comment", "127.0.0.1 localhost localhost.localdomain my.domain.local #with a comment"]
@instance.update_entry("127.0.0.1", "my.domain.local")
@instance.save
expect(@instance.raw_lines).to eq(expected_array)
end
end
end