19
19
class IProute2 (InstanceModule ):
20
20
"""Test network configuration via iproute2 commands
21
21
22
- Optional arguments:
23
- - family: force iproute2 tools to use a specific protocol family
24
- - namespace: execute iproute2 tools inside the provided namespace
22
+ Currently supported:
23
+
24
+ * ip-address
25
+ * ip-link
26
+ * ip-route
27
+ * ip-rule
28
+ * ip-vrf
29
+ * ip-tunnel
30
+ * ip-netns
31
+ * bridge vlan
32
+ * bridge link
33
+ * bridge fdb
34
+ * bridge mdb
35
+
36
+ Optional module-level arguments can also be provided to contro; execution:
37
+
38
+ * family: force iproute2 tools to use a specific protocol family
39
+ >>> host.iproute2(family="inet").addresses()
40
+
41
+ * namespace: execute iproute2 tools inside the provided namespace
42
+ >>> host.iproute2(namespace="test").addresses()
25
43
26
44
"""
27
45
@@ -42,17 +60,68 @@ def _ip(self):
42
60
ip_cmd = f"{ ip_cmd } -f { self .family } "
43
61
return ip_cmd
44
62
63
+ @functools .cached_property
64
+ def _bridge (self ):
65
+ bridge_cmd = self .find_command ("bridge" )
66
+ if self .namespace is not None :
67
+ bridge_cmd = f"{ bridge_cmd } -n { self .namespace } "
68
+ return bridge_cmd
69
+
45
70
@property
46
71
def exists (self ):
72
+ """Returns True if ip -V succeeds
73
+
74
+ >>> host.iproute2.exists
75
+ True
76
+
77
+ """
47
78
return self .run_test ("{} -V" .format (self ._ip )).rc == 0
48
79
49
- def addresses (self , address = None , ifname = None , local = None ):
50
- """Return the addresses associated with interfaces
80
+ @property
81
+ def bridge_exists (self ):
82
+ """Returns True if bridge -V succeeds
83
+
84
+ >>> host.iproute2.bridge_exists
85
+ True
51
86
52
- Optionally, results can be filtered by:
53
- - address
54
- - ifname
55
- - local
87
+ """
88
+ return self .run_test ("{} -V" .format (self ._bridge )).rc == 0
89
+
90
+ def addresses (self , address = None , ifname = None , local = None ):
91
+ """Returns the addresses associated with interfaces
92
+
93
+ >>> host.iproute2.addresses()
94
+ [{'ifindex': 1,
95
+ 'ifname': 'lo',
96
+ 'flags': ['LOOPBACK', 'UP', 'LOWER_UP'],
97
+ 'mtu': 65536,
98
+ 'qdisc': 'noqueue',
99
+ 'operstate': 'UNKNOWN',
100
+ 'group': 'default',
101
+ 'txqlen': 1000,
102
+ 'link_type': 'loopback',
103
+ 'address': '00:00:00:00:00:00',
104
+ 'broadcast': '00:00:00:00:00:00',
105
+ 'addr_info': [{'family': 'inet',
106
+ 'local': '127.0.0.1',
107
+ 'prefixlen': 8,
108
+ 'scope': 'host',
109
+ 'label': 'lo',
110
+ 'valid_life_time': 4294967295,
111
+ 'preferred_life_time': 4294967295},
112
+ {'family': 'inet6',
113
+ 'local': '::1',
114
+ 'prefixlen': 128,
115
+ 'scope': 'host',
116
+ 'noprefixroute': True,
117
+ 'valid_life_time': 4294967295,
118
+ 'preferred_life_time': 4294967295}]}]
119
+
120
+ Optionally, results can be filtered with the following selectors:
121
+
122
+ * address
123
+ * ifname
124
+ * local
56
125
57
126
"""
58
127
cmd = f"{ self ._ip } --json address show"
@@ -74,26 +143,56 @@ def addresses(self, address=None, ifname=None, local=None):
74
143
return o
75
144
76
145
def links (self ):
77
- """Return links and their state"""
146
+ """Returns links and their state.
147
+
148
+ >>> host.iproute2.links()
149
+ [{'ifindex': 1,
150
+ 'ifname': 'lo',
151
+ 'flags': ['LOOPBACK', 'UP', 'LOWER_UP'],
152
+ 'mtu': 65536,
153
+ 'qdisc': 'noqueue',
154
+ 'operstate': 'UNKNOWN',
155
+ 'linkmode': 'DEFAULT',
156
+ 'group': 'default',
157
+ 'txqlen': 1000,
158
+ 'link_type': 'loopback',
159
+ 'address': '00:00:00:00:00:00',
160
+ 'broadcast': '00:00:00:00:00:00'}]
161
+
162
+ """
78
163
cmd = f"{ self ._ip } --json link show"
79
164
out = self .check_output (cmd )
80
165
return json .loads (out )
81
166
82
167
def routes (
83
168
self , table = "all" , device = None , scope = None , proto = None , src = None , metric = None
84
169
):
85
- """Returns the routes installed
86
-
87
- Optionally, routes returned can be filtered with the following
88
- selectors. This can be useful in busy routing tables.
89
-
90
- Selectors:
91
- - table
92
- - device (maps to ip-route's 'dev' selector)
93
- - scope
94
- - proto
95
- - src
96
- - metric
170
+ """Returns the routes installed in *all* routing tables.
171
+
172
+ >>> host.iproute2.routes()
173
+ [{'dst': '169.254.0.0/16',
174
+ 'dev': 'wlp4s0',
175
+ 'scope': 'link',
176
+ 'metric': 1000,
177
+ 'flags': []},
178
+ {'type': 'multicast',
179
+ 'dst': 'ff00::/8',
180
+ 'dev': 'wlp4s0',
181
+ 'table': 'local',
182
+ 'protocol': 'kernel',
183
+ 'metric': 256,
184
+ 'flags': [],
185
+ 'pref': 'medium'}]
186
+
187
+ Optionally, routes returned can be filtered with the following
188
+ selectors. This can be useful in busy routing tables.
189
+
190
+ * table
191
+ * device (maps to ip-route's 'dev' selector)
192
+ * scope
193
+ * proto
194
+ * src
195
+ * metric
97
196
98
197
"""
99
198
cmd = f"{ self ._ip } --json route show "
@@ -129,23 +228,28 @@ def rules(
129
228
sport = None ,
130
229
dport = None ,
131
230
):
132
- """Returns the rules our routing policy consists of
133
-
134
- Optionally, rules returned can be filtered with the following
135
- selectors. This can be useful in busy rulesets.
136
-
137
- Selectors:
138
- - src (maps to ip-rule's 'from' selector)
139
- - to
140
- - tos
141
- - fwmark
142
- - iif
143
- - oif
144
- - pref
145
- - uidrange
146
- - ipproto
147
- - sport
148
- - dport
231
+ """Returns the rules our routing policy consists of.
232
+
233
+ >>> host.iproute2.rules()
234
+ [{'priority': 0, 'src': 'all', 'table': 'local'},
235
+ {'priority': 32765, 'src': '1.2.3.4', 'table': '123'},
236
+ {'priority': 32766, 'src': 'all', 'table': 'main'},
237
+ {'priority': 32767, 'src': 'all', 'table': 'default'}]
238
+
239
+ Optionally, rules returned can be filtered with the following
240
+ selectors. This can be useful in busy rulesets.
241
+
242
+ * src (maps to ip-rule's 'from' selector)
243
+ * to
244
+ * tos
245
+ * fwmark
246
+ * iif
247
+ * oif
248
+ * pref
249
+ * uidrange
250
+ * ipproto
251
+ * sport
252
+ * dport
149
253
150
254
"""
151
255
cmd = f"{ self ._ip } --json rule show "
@@ -191,11 +295,16 @@ def rules(
191
295
def tunnels (self , ifname = None ):
192
296
"""Returns all configured tunnels
193
297
194
- Optionally, tunnels returned can be filtered with the interface name.
195
- This can be faster in busy tunnel installations.
298
+ >>> host.iproute2.tunnels()
299
+ [{'ifname': 'test1',
300
+ 'mode': 'ip/ip',
301
+ 'remote': '127.0.0.2',
302
+ 'local': '0.0.0.0'}]
303
+
304
+ Optionally, tunnels returned can be filtered with the interface name.
305
+ This can be faster in busy tunnel installations.
196
306
197
- Selectors:
198
- - ifname
307
+ * ifname
199
308
200
309
"""
201
310
cmd = f"{ self ._ip } --json tunnel show "
@@ -215,33 +324,62 @@ def vrfs(self):
215
324
return json .loads (out )
216
325
217
326
def netns (self ):
218
- """Returns all configured network namespaces"""
327
+ """Returns all configured network namespaces
328
+
329
+ >>> host.iproute2.netns()
330
+ [{'name': 'test'}]
331
+ """
332
+
219
333
cmd = f"{ self ._ip } --json netns show"
220
334
out = self .check_output (cmd )
221
335
if not out : # ip netns returns null instead of [] in json mode
222
336
return json .loads ("[]\n " )
223
337
return json .loads (out )
224
338
225
339
def bridge_vlan (self ):
226
- """Returns all configured vlans"""
340
+ """Returns all configured vlans
341
+
342
+ >>> host.iproute2.bridge_vlan()
343
+ []
344
+ """
345
+
227
346
cmd = f"{ self ._bridge } -json vlan show"
228
347
out = self .check_output (cmd )
229
348
return json .loads (out )
230
349
231
350
def bridge_fdb (self ):
232
- """Returns all configured fdb entries"""
351
+ """Returns all configured fdb entries
352
+
353
+ >>> host.iproute2.bridge_fdb()
354
+ [{'mac': '33:33:00:00:00:01',
355
+ 'ifname': 'enp0s31f6',
356
+ 'flags': ['self'],
357
+ 'state': 'permanent'}]
358
+ """
359
+
233
360
cmd = f"{ self ._bridge } -json fdb show"
234
361
out = self .check_output (cmd )
235
362
return json .loads (out )
236
363
237
364
def bridge_mdb (self ):
238
- """Returns all configured mdb entries"""
365
+ """Returns all configured mdb entries
366
+
367
+ >>> host.iproute2.bridge_mdb()
368
+ [{'mdb': [], 'router': {}}]
369
+
370
+ """
371
+
239
372
cmd = f"{ self ._bridge } -json mdb show"
240
373
out = self .check_output (cmd )
241
374
return json .loads (out )
242
375
243
376
def bridge_link (self ):
244
- """Returns all configured links"""
377
+ """Returns all configured links
378
+
379
+ >>> host.iproute2.bridge_link()
380
+ []
381
+ """
382
+
245
383
cmd = f"{ self ._bridge } -json link show"
246
384
out = self .check_output (cmd )
247
385
return json .loads (out )
0 commit comments