Skip to content

Commit 861f7f8

Browse files
committed
Add LinuxAdmin::NetworkInterface.list
Previously there wasn't a method for listing interfaces on the system, which was okay because we assumed an eth0 was available but as we move away from that and use the standard predictable network interface names it would be helpful to get a list.
1 parent 12c3933 commit 861f7f8

File tree

2 files changed

+59
-1
lines changed

2 files changed

+59
-1
lines changed

lib/linux_admin/network_interface.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,21 @@ def self.dist_class(clear_cache = false)
2020
end
2121
end
2222

23+
def self.list
24+
ip_link.pluck("ifname").map { |iface| new(iface) }
25+
rescue AwesomeSpawn::CommandResultError => e
26+
raise NetworkInterfaceError.new(e.message, e.result)
27+
end
28+
29+
private_class_method def self.ip_link
30+
require "json"
31+
32+
ip_link = Common.run!(Common.cmd("ip"), :params => ["--json", "link"])
33+
JSON.parse(ip_link.output)
34+
rescue AwesomeSpawn::CommandResultError, JSON::ParserError => e
35+
raise NetworkInterfaceError.new(e.message, e.result)
36+
end
37+
2338
# Creates an instance of the correct NetworkInterface subclass for the local distro
2439
def self.new(*args)
2540
self == LinuxAdmin::NetworkInterface ? dist_class.new(*args) : super

spec/network_interface_spec.rb

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,21 @@
5555
end
5656

5757
context "on all systems" do
58-
IP_SHOW_ARGS = [
58+
IP_LINK_ARGS = [
59+
LinuxAdmin::Common.cmd("ip"),
60+
:params => %w(--json link)
61+
]
62+
63+
IP_SHOW_ARGS = IP_SHOW_ETH0_ARGS = [
5964
LinuxAdmin::Common.cmd("ip"),
6065
:params => %w(addr show eth0)
6166
]
6267

68+
IP_SHOW_LO_ARGS = [
69+
LinuxAdmin::Common.cmd("ip"),
70+
:params => %w(addr show lo)
71+
]
72+
6373
IP_ROUTE_ARGS = [
6474
LinuxAdmin::Common.cmd("ip"),
6575
:params => ['-4', 'route']
@@ -80,6 +90,19 @@
8090
:params => ["eth0"]
8191
]
8292

93+
IP_LINK_OUT = <<~IP_OUT
94+
[{"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"]}]
95+
IP_OUT
96+
97+
IP_ADDR_LO_OUT = <<~IP_OUT
98+
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
99+
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
100+
inet 127.0.0.1/8 scope host lo
101+
valid_lft forever preferred_lft forever
102+
inet6 ::1/128 scope host
103+
valid_lft forever preferred_lft forever
104+
IP_OUT
105+
83106
IP_ADDR_OUT = <<-IP_OUT
84107
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
85108
link/ether 00:0c:29:ed:0e:8b brd ff:ff:ff:ff:ff:ff
@@ -115,6 +138,18 @@
115138
link/ether 52:54:00:ce:b4:f4 brd ff:ff:ff:ff:ff:ff
116139
IP_OUT
117140

141+
subject(:subj_list) do
142+
allow(LinuxAdmin::Distros).to receive(:local).and_return(LinuxAdmin::Distros.generic)
143+
described_class.dist_class(true)
144+
145+
allow(AwesomeSpawn).to receive(:run!).with(*IP_LINK_ARGS).and_return(result(IP_LINK_OUT, 0))
146+
allow(AwesomeSpawn).to receive(:run!).with(*IP_SHOW_LO_ARGS).and_return(result(IP_ADDR_LO_OUT, 0))
147+
allow(AwesomeSpawn).to receive(:run!).with(*IP_SHOW_ETH0_ARGS).and_return(result(IP_ADDR_OUT, 0))
148+
allow(AwesomeSpawn).to receive(:run!).with(*IP_ROUTE_ARGS).and_return(result(IP_ROUTE_OUT, 0))
149+
allow(AwesomeSpawn).to receive(:run!).with(*IP6_ROUTE_ARGS).and_return(result(IP6_ROUTE_OUT, 0))
150+
described_class.list
151+
end
152+
118153
subject(:subj) do
119154
allow(LinuxAdmin::Distros).to receive(:local).and_return(LinuxAdmin::Distros.generic)
120155
described_class.dist_class(true)
@@ -149,6 +184,14 @@ def result(output, exit_status)
149184
AwesomeSpawn::CommandResult.new("", output, "", nil, exit_status)
150185
end
151186

187+
describe ".list" do
188+
it "returns a list of NetworkInterface objects" do
189+
interfaces = subj_list
190+
expect(interfaces.count).to eq(2)
191+
expect(interfaces.map(&:interface)).to match_array(["eth0", "lo"])
192+
end
193+
end
194+
152195
describe "#reload" do
153196
it "returns false when ip addr show fails" do
154197
subj

0 commit comments

Comments
 (0)