1
- require 'ipaddr'
2
-
3
1
module LinuxAdmin
4
2
class NetworkInterface
3
+ require "ipaddr"
4
+ require "json"
5
+
5
6
# Cached class instance variable for what distro we are running on
6
7
@dist_class = nil
7
8
@@ -60,14 +61,16 @@ def reload
60
61
return false
61
62
end
62
63
63
- parse_ip4 ( ip_output )
64
- parse_ip6 ( ip_output , :global )
65
- parse_ip6 ( ip_output , :link )
64
+ addr_info = ip_output [ "addr_info" ]
65
+
66
+ parse_ip4 ( addr_info )
67
+ parse_ip6 ( addr_info , "global" )
68
+ parse_ip6 ( addr_info , "link" )
66
69
67
- @network_conf [ :mac ] = parse_ip_output ( ip_output , %r{link/ether} , 1 )
70
+ @network_conf [ :mac ] = ip_output [ "address" ]
68
71
69
72
[ 4 , 6 ] . each do |version |
70
- @network_conf [ "gateway#{ version } " . to_sym ] = parse_ip_output ( ip_route ( version ) , /^ default/ , 2 )
73
+ @network_conf [ "gateway#{ version } " . to_sym ] = ip_route ( version , " default" ) &. dig ( "gateway" )
71
74
end
72
75
true
73
76
end
@@ -168,23 +171,13 @@ def stop
168
171
169
172
private
170
173
171
- # Parses the output of `ip addr show`
172
- #
173
- # @param output [String] The command output
174
- # @param regex [Regexp] Regular expression to match the desired output line
175
- # @param col [Fixnum] The whitespace delimited column to be returned
176
- # @return [String] The parsed data
177
- def parse_ip_output ( output , regex , col )
178
- the_line = output . split ( "\n " ) . detect { |l | l =~ regex }
179
- the_line . nil? ? nil : the_line . strip . split ( ' ' ) [ col ]
180
- end
181
-
182
174
# Runs the command `ip addr show <interface>`
183
175
#
184
176
# @return [String] The command output
185
177
# @raise [NetworkInterfaceError] if the command fails
186
178
def ip_show
187
- Common . run! ( Common . cmd ( "ip" ) , :params => [ "addr" , "show" , @interface ] ) . output
179
+ output = Common . run! ( Common . cmd ( "ip" ) , :params => [ "--json" , "addr" , "show" , @interface ] ) . output
180
+ JSON . parse ( output ) . first
188
181
rescue AwesomeSpawn ::CommandResultError => e
189
182
raise NetworkInterfaceError . new ( e . message , e . result )
190
183
end
@@ -194,35 +187,34 @@ def ip_show
194
187
# @param version [Fixnum] Version of IP protocol (4 or 6)
195
188
# @return [String] The command output
196
189
# @raise [NetworkInterfaceError] if the command fails
197
- def ip_route ( version )
198
- Common . run! ( Common . cmd ( "ip" ) , :params => [ "-#{ version } " , 'route' ] ) . output
190
+ def ip_route ( version , route = "default" )
191
+ output = Common . run! ( Common . cmd ( "ip" ) , :params => [ "--json" , "-#{ version } " , "route" , "show" , route ] ) . output
192
+ JSON . parse ( output ) . first
199
193
rescue AwesomeSpawn ::CommandResultError => e
200
194
raise NetworkInterfaceError . new ( e . message , e . result )
201
195
end
202
196
203
197
# Parses the IPv4 information from the output of `ip addr show <device>`
204
198
#
205
199
# @param ip_output [String] The command output
206
- def parse_ip4 ( ip_output )
207
- cidr_ip = parse_ip_output ( ip_output , /inet / , 1 )
208
- return unless cidr_ip
200
+ def parse_ip4 ( addr_info )
201
+ inet = addr_info . detect { | addr | addr [ "family" ] == "inet" }
202
+ return if inet . nil?
209
203
210
- parts = cidr_ip . split ( '/' )
211
- @network_conf [ :address ] = parts [ 0 ]
212
- @network_conf [ :prefix ] = parts [ 1 ] . to_i
204
+ @network_conf [ :address ] = inet [ "local" ]
205
+ @network_conf [ :prefix ] = inet [ "prefixlen" ]
213
206
end
214
207
215
208
# Parses the IPv6 information from the output of `ip addr show <device>`
216
209
#
217
210
# @param ip_output [String] The command output
218
211
# @param scope [Symbol] The IPv6 scope (either `:global` or `:local`)
219
- def parse_ip6 ( ip_output , scope )
220
- cidr_ip = parse_ip_output ( ip_output , / inet6 .* scope #{ scope } / , 1 )
221
- return unless cidr_ip
212
+ def parse_ip6 ( addr_info , scope )
213
+ inet6 = addr_info . detect { | addr | addr [ "family" ] == " inet6" && addr [ " scope" ] == scope }
214
+ return if inet6 . nil?
222
215
223
- parts = cidr_ip . split ( '/' )
224
- @network_conf [ "address6_#{ scope } " . to_sym ] = parts [ 0 ]
225
- @network_conf [ "prefix6_#{ scope } " . to_sym ] = parts [ 1 ] . to_i
216
+ @network_conf [ "address6_#{ scope } " . to_sym ] = inet6 [ "local" ]
217
+ @network_conf [ "prefix6_#{ scope } " . to_sym ] = inet6 [ "prefixlen" ]
226
218
end
227
219
end
228
220
end
0 commit comments