blob: 7247f3ff046033429ddbc12ad36b9015e2a01352 [file] [log] [blame]
David K. Bainbridgea677d4e2016-09-11 20:01:32 -07001#!/usr/bin/env python
2
3import sys
4import json
5import ethtool
6import shlex
David K. Bainbridge603ee542016-10-04 21:11:05 -07007import re
8
9def match_list(value, list):
10 if len(list) == 0:
11 return False
12
13 for exp in list:
14 if re.match(exp, value):
15 return True
16
17 return False
18
19def has_match(name, module_type, bus_type, name_list, module_type_list, bus_type_list):
20 return match_list(name, name_list) or \
21 match_list(module_type, module_type_list) or match_list(bus_type, bus_type_list)
David K. Bainbridgea677d4e2016-09-11 20:01:32 -070022
23# read the argument string from the arguments file
24args_file = sys.argv[1]
25args_data = file(args_file).read()
26
David K. Bainbridge603ee542016-10-04 21:11:05 -070027exclude_names=[]
28exclude_module_types=[]
29exclude_bus_types=[]
30include_names=[]
31include_module_types=[]
32include_bus_types=[]
33ignore_names=[]
34ignore_module_types=["tun", "bridge", "bonding", "veth"]
35ignore_bus_types=["^\W*$", "N/A", "tap"]
36debug_out = False
David K. Bainbridgea677d4e2016-09-11 20:01:32 -070037
38# parse the task options
39arguments = shlex.split(args_data)
40for arg in arguments:
David K. Bainbridge603ee542016-10-04 21:11:05 -070041 # exclude any arguments without an equals in it
David K. Bainbridgea677d4e2016-09-11 20:01:32 -070042 if "=" in arg:
43 (key, value) = arg.split("=")
David K. Bainbridgea677d4e2016-09-11 20:01:32 -070044
David K. Bainbridge603ee542016-10-04 21:11:05 -070045 if key == "exclude-names":
46 exclude_names = re.split("\W*,\W*", value)
47 elif key == "exclude-module-types":
48 exclude_module_types = re.split("\W*,\W*", value)
49 elif key == "exclude-bus-types":
50 exclude_bus_types = re.split("\W*,\W*", value)
51 elif key == "include-names":
52 include_names = re.split("\W*,\W*", value)
53 elif key == "include-module-types":
54 include_module_types = re.split("\W*,\W*", value)
55 elif key == "include-bus-types":
56 include_bus_types = re.split("\W*,\W*", value)
57 elif key == "ignore-names":
58 ignore_names = re.split("\W*,\W*", value)
59 elif key == "ignore-module-types":
60 ignore_module_types = re.split("\W*,\W*", value)
61 elif key == "ignore-bus-types":
62 ignore_bus_types = re.split("\W*,\W*", value)
63 elif key == "debug":
64 debug_out = value.lower() in ["true", "yes", "on", "t", "y", "1"]
65 elif key[0] != '_':
66 raise ValueError('Unknown option to task "%s"' % key)
67
68included = {}
69ignored = {}
70excluded = {}
71debug = []
72
73if debug_out:
74 debug.append("EXCLUDES: '%s', '%s', '%s'" % (exclude_names, exclude_module_types, exclude_bus_types))
75 debug.append("INCLUDE: '%s', '%s', '%s'" % (include_names, include_module_types, include_bus_types))
76 debug.append("IGNORE: '%s', '%s', '%s'" % (ignore_names, ignore_module_types, ignore_bus_types))
77
David K. Bainbridgea677d4e2016-09-11 20:01:32 -070078for i in ethtool.get_devices():
79 o = { "name": i }
80 try:
81 module = ethtool.get_module(i)
82 businfo = ethtool.get_businfo(i)
David K. Bainbridge603ee542016-10-04 21:11:05 -070083
84 # If it matches an ignore pattern then just ignore it.
85 if has_match(i, module, businfo, ignore_names, ignore_module_types, ignore_bus_types):
86 if debug_out: debug.append("IGNORE '%s' on ignore match" % i)
87 ignored[i] = {
88 "name": i,
89 "module": module,
90 }
David K. Bainbridgea677d4e2016-09-11 20:01:32 -070091 continue
David K. Bainbridge603ee542016-10-04 21:11:05 -070092
93 # If no include specifications have been set and the interface is not ignored
94 # it needs to be considered for inclusion
95 if len(include_names) + len(include_module_types) + len(include_bus_types) == 0:
96 # If it matches exclude list then exclude it, else include it
97 if has_match(i, module, businfo, exclude_names, exclude_module_types, exclude_bus_types):
98 if debug_out: debug.append("EXCLUDE '%s' with no include specifiers, but with exclude match" %i)
99 excluded[i] = {
100 "name": i,
101 "module": module,
102 }
103 continue
104 if debug_out: debug.append("INCLUDE '%s' with no include specifiers, but with no exclude match" % i)
105 included[i] = {
106 "name": i,
107 "module": module,
108 }
109 continue
110
111 # If any of the include specifications are set then the interface must match at least one
112 # to be added to the mached list.
113 if has_match(i, module, businfo, include_names, include_module_types, include_bus_types):
114 if debug_out: debug.append("MATCH '%s' has include match" % i)
115 # If it matches exclude list then exclude it, else include it
116 if has_match(i, module, businfo, exclude_names, exclude_module_types, exclude_bus_types):
117 if debug_out: debug.append("EXCLUDE '%s' with include match, but also with exclude match" % i)
118 excluded[i] = {
119 "name": i,
120 "module": module,
121 }
122 continue
123 if debug_out: debug.append("INCLUDE '%s' with include match and with no exclude match" % i)
124 included[i] = {
125 "name": i,
126 "module" : module,
127 }
128 continue
129
130 # Implicitly ignore
131 if debug_out: debug.append("IGNORE: '%s' implicitly" %i)
132 ignored[i] = {
David K. Bainbridgea677d4e2016-09-11 20:01:32 -0700133 "name": i,
David K. Bainbridge603ee542016-10-04 21:11:05 -0700134 "module": module,
David K. Bainbridgea677d4e2016-09-11 20:01:32 -0700135 }
David K. Bainbridge603ee542016-10-04 21:11:05 -0700136
David K. Bainbridgea677d4e2016-09-11 20:01:32 -0700137 except:
138 pass
139
David K. Bainbridge603ee542016-10-04 21:11:05 -0700140result = {
David K. Bainbridgea677d4e2016-09-11 20:01:32 -0700141 "changed" : False,
142 "ansible_facts" : {
David K. Bainbridge603ee542016-10-04 21:11:05 -0700143 "netinfo" : {
144 "included" : included,
145 "excluded" : excluded,
146 "ignored" : ignored,
147 },
David K. Bainbridgea677d4e2016-09-11 20:01:32 -0700148 },
David K. Bainbridge603ee542016-10-04 21:11:05 -0700149}
150
151if debug_out: result["ansible_facts"]["netinfo"]["debug"] = debug
152
153print json.dumps(result)