Skip to content

Commit

Permalink
Merge pull request #249 from agrare/add_network_interface_list
Browse files Browse the repository at this point in the history
Add LinuxAdmin::NetworkInterface.list
  • Loading branch information
Fryguy committed Aug 5, 2024
2 parents 75b7abc + 5204709 commit ae97093
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 12 deletions.
15 changes: 15 additions & 0 deletions lib/linux_admin/network_interface.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,21 @@ def self.dist_class(clear_cache = false)
end
end

def self.list
ip_link.pluck("ifname").map { |iface| new(iface) }
rescue AwesomeSpawn::CommandResultError => e
raise NetworkInterfaceError.new(e.message, e.result)
end

private_class_method def self.ip_link
require "json"

result = Common.run!(Common.cmd("ip"), :params => ["--json", "link"])
JSON.parse(result.output)
rescue AwesomeSpawn::CommandResultError, JSON::ParserError => e
raise NetworkInterfaceError.new(e.message, e.result)
end

# Creates an instance of the correct NetworkInterface subclass for the local distro
def self.new(*args)
self == LinuxAdmin::NetworkInterface ? dist_class.new(*args) : super
Expand Down
61 changes: 49 additions & 12 deletions spec/network_interface_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,19 @@
end

context "on all systems" do
let(:ip_show_args) { [LinuxAdmin::Common.cmd("ip"), {:params => %w[addr show eth0]}] }
let(:ip_route_args) { [LinuxAdmin::Common.cmd("ip"), {:params => ['-4', 'route']}] }
let(:ip6_route_args) { [LinuxAdmin::Common.cmd("ip"), {:params => ['-6', 'route']}] }
let(:ifup_args) { [LinuxAdmin::Common.cmd("ifup"), {:params => ["eth0"]}] }
let(:ifdown_args) { [LinuxAdmin::Common.cmd("ifdown"), {:params => ["eth0"]}] }
let(:ip_addr_out) do
let(:ip_link_args) { [LinuxAdmin::Common.cmd("ip"), {:params => %w[--json link]}] }
let(:ip_show_eth0_args) { [LinuxAdmin::Common.cmd("ip"), {:params => %w[addr show eth0]}] }
let(:ip_show_lo_args) { [LinuxAdmin::Common.cmd("ip"), {:params => %w[addr show lo]}] }
let(:ip_route_args) { [LinuxAdmin::Common.cmd("ip"), {:params => ['-4', 'route']}] }
let(:ip6_route_args) { [LinuxAdmin::Common.cmd("ip"), {:params => ['-6', 'route']}] }
let(:ifup_args) { [LinuxAdmin::Common.cmd("ifup"), {:params => ["eth0"]}] }
let(:ifdown_args) { [LinuxAdmin::Common.cmd("ifdown"), {:params => ["eth0"]}] }
let(:ip_link_out) do
<<~IP_OUT
[{"ifindex":1,"ifname":"lo","flags":["LOOPBACK","UP","LOWER_UP"],"mtu":65536,"qdisc":"noqueue","operstate":"UNKNOWN","linkmode":"DEFAULT","group":"default","txqlen":1000,"link_type":"loopback","address":"00:00:00:00:00:00","broadcast":"00:00:00:00:00:00"},{"ifindex":2,"ifname":"eth0","flags":["BROADCAST","MULTICAST","UP","LOWER_UP"],"mtu":1500,"qdisc":"fq_codel","operstate":"UP","linkmode":"DEFAULT","group":"default","txqlen":1000,"link_type":"ether","address":"52:54:00:e8:67:81","broadcast":"ff:ff:ff:ff:ff:ff","altnames":["enp0s2","ens2"]}]
IP_OUT
end
let(:ip_addr_eth0_out) do
<<~IP_OUT
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:ed:0e:8b brd ff:ff:ff:ff:ff:ff
Expand All @@ -72,6 +79,16 @@
valid_lft forever preferred_lft forever
IP_OUT
end
let(:ip_addr_lo_out) do
<<~IP_OUT
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
IP_OUT
end
let(:ip6_addr_out) do
<<~IP_OUT
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
Expand Down Expand Up @@ -102,11 +119,23 @@
IP_OUT
end

subject(:subj_list) do
allow(LinuxAdmin::Distros).to receive(:local).and_return(LinuxAdmin::Distros.generic)
described_class.dist_class(true)

allow(AwesomeSpawn).to receive(:run!).with(*ip_link_args).and_return(result(ip_link_out, 0))
allow(AwesomeSpawn).to receive(:run!).with(*ip_show_lo_args).and_return(result(ip_addr_lo_out, 0))
allow(AwesomeSpawn).to receive(:run!).with(*ip_show_eth0_args).and_return(result(ip_addr_eth0_out, 0))
allow(AwesomeSpawn).to receive(:run!).with(*ip_route_args).and_return(result(ip_route_out, 0))
allow(AwesomeSpawn).to receive(:run!).with(*ip6_route_args).and_return(result(ip6_route_out, 0))
described_class.list
end

subject(:subj) do
allow(LinuxAdmin::Distros).to receive(:local).and_return(LinuxAdmin::Distros.generic)
described_class.dist_class(true)

allow(AwesomeSpawn).to receive(:run!).with(*ip_show_args).and_return(result(ip_addr_out, 0))
allow(AwesomeSpawn).to receive(:run!).with(*ip_show_eth0_args).and_return(result(ip_addr_eth0_out, 0))
allow(AwesomeSpawn).to receive(:run!).with(*ip_route_args).and_return(result(ip_route_out, 0))
allow(AwesomeSpawn).to receive(:run!).with(*ip6_route_args).and_return(result(ip6_route_out, 0))
described_class.new(device_name)
Expand All @@ -116,7 +145,7 @@
allow(LinuxAdmin::Distros).to receive(:local).and_return(LinuxAdmin::Distros.generic)
described_class.dist_class(true)

allow(AwesomeSpawn).to receive(:run!).with(*ip_show_args).and_return(result(ip6_addr_out, 0))
allow(AwesomeSpawn).to receive(:run!).with(*ip_show_eth0_args).and_return(result(ip6_addr_out, 0))
allow(AwesomeSpawn).to receive(:run!).with(*ip_route_args).and_return(result(ip_route_out, 0))
allow(AwesomeSpawn).to receive(:run!).with(*ip6_route_args).and_return(result(ip6_route_out, 0))
described_class.new(device_name)
Expand All @@ -126,7 +155,7 @@
allow(LinuxAdmin::Distros).to receive(:local).and_return(LinuxAdmin::Distros.generic)
described_class.dist_class(true)

allow(AwesomeSpawn).to receive(:run!).with(*ip_show_args).and_return(result(ip_none_addr_out, 0))
allow(AwesomeSpawn).to receive(:run!).with(*ip_show_eth0_args).and_return(result(ip_none_addr_out, 0))
allow(AwesomeSpawn).to receive(:run!).with(*ip_route_args).and_return(result(ip_route_out, 0))
allow(AwesomeSpawn).to receive(:run!).with(*ip6_route_args).and_return(result(ip6_route_out, 0))
described_class.new(device_name)
Expand All @@ -136,26 +165,34 @@ def result(output, exit_status)
AwesomeSpawn::CommandResult.new("", output, "", nil, exit_status)
end

describe ".list" do
it "returns a list of NetworkInterface objects" do
interfaces = subj_list
expect(interfaces.count).to eq(2)
expect(interfaces.map(&:interface)).to match_array(["eth0", "lo"])
end
end

describe "#reload" do
it "returns false when ip addr show fails" do
subj
awesome_error = AwesomeSpawn::CommandResultError.new("", nil)
allow(AwesomeSpawn).to receive(:run!).with(*ip_show_args).and_raise(awesome_error)
allow(AwesomeSpawn).to receive(:run!).with(*ip_show_eth0_args).and_raise(awesome_error)
expect(subj.reload).to eq(false)
end

it "raises when ip route fails" do
subj
awesome_error = AwesomeSpawn::CommandResultError.new("", nil)
allow(AwesomeSpawn).to receive(:run!).with(*ip_show_args).and_return(result(ip_addr_out, 0))
allow(AwesomeSpawn).to receive(:run!).with(*ip_show_eth0_args).and_return(result(ip_addr_eth0_out, 0))
allow(AwesomeSpawn).to receive(:run!).with(*ip_route_args).and_raise(awesome_error)
allow(AwesomeSpawn).to receive(:run!).with(*ip6_route_args).and_raise(awesome_error)
expect { subj.reload }.to raise_error(LinuxAdmin::NetworkInterfaceError)
end

it "doesn't blow up when given only ipv6 addresses" do
subj6
allow(AwesomeSpawn).to receive(:run!).with(*ip_show_args).and_return(result(ip6_addr_out, 0))
allow(AwesomeSpawn).to receive(:run!).with(*ip_show_eth0_args).and_return(result(ip6_addr_out, 0))
allow(AwesomeSpawn).to receive(:run!).with(*ip_route_args).and_return(result(ip_route_out, 0))
allow(AwesomeSpawn).to receive(:run!).with(*ip6_route_args).and_return(result(ip6_route_out, 0))
expect { subj.reload }.to_not raise_error
Expand Down

0 comments on commit ae97093

Please sign in to comment.