blob: 78eabe00c315c6f500ffe6476392fef914c7ed5e [file] [log] [blame]
David K. Bainbridgea677d4e2016-09-11 20:01:32 -07001#!/usr/bin/env python
2
Jonathan Hart93956f52017-08-22 13:12:42 -07003# Copyright 2017-present Open Networking Foundation
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
David K. Bainbridgea677d4e2016-09-11 20:01:32 -070017import sys
18import json
19import ethtool
20import shlex
David K. Bainbridge603ee542016-10-04 21:11:05 -070021import re
22
23def match_list(value, list):
24 if len(list) == 0:
25 return False
26
27 for exp in list:
28 if re.match(exp, value):
29 return True
30
31 return False
32
33def has_match(name, module_type, bus_type, name_list, module_type_list, bus_type_list):
34 return match_list(name, name_list) or \
35 match_list(module_type, module_type_list) or match_list(bus_type, bus_type_list)
David K. Bainbridgea677d4e2016-09-11 20:01:32 -070036
37# read the argument string from the arguments file
38args_file = sys.argv[1]
39args_data = file(args_file).read()
40
David K. Bainbridge603ee542016-10-04 21:11:05 -070041exclude_names=[]
42exclude_module_types=[]
43exclude_bus_types=[]
44include_names=[]
45include_module_types=[]
46include_bus_types=[]
47ignore_names=[]
48ignore_module_types=["tun", "bridge", "bonding", "veth"]
49ignore_bus_types=["^\W*$", "N/A", "tap"]
50debug_out = False
David K. Bainbridgea677d4e2016-09-11 20:01:32 -070051
52# parse the task options
53arguments = shlex.split(args_data)
54for arg in arguments:
David K. Bainbridge603ee542016-10-04 21:11:05 -070055 # exclude any arguments without an equals in it
David K. Bainbridgea677d4e2016-09-11 20:01:32 -070056 if "=" in arg:
57 (key, value) = arg.split("=")
David K. Bainbridgea677d4e2016-09-11 20:01:32 -070058
David K. Bainbridge603ee542016-10-04 21:11:05 -070059 if key == "exclude-names":
60 exclude_names = re.split("\W*,\W*", value)
61 elif key == "exclude-module-types":
62 exclude_module_types = re.split("\W*,\W*", value)
63 elif key == "exclude-bus-types":
64 exclude_bus_types = re.split("\W*,\W*", value)
65 elif key == "include-names":
66 include_names = re.split("\W*,\W*", value)
67 elif key == "include-module-types":
68 include_module_types = re.split("\W*,\W*", value)
69 elif key == "include-bus-types":
70 include_bus_types = re.split("\W*,\W*", value)
71 elif key == "ignore-names":
72 ignore_names = re.split("\W*,\W*", value)
73 elif key == "ignore-module-types":
74 ignore_module_types = re.split("\W*,\W*", value)
75 elif key == "ignore-bus-types":
76 ignore_bus_types = re.split("\W*,\W*", value)
77 elif key == "debug":
78 debug_out = value.lower() in ["true", "yes", "on", "t", "y", "1"]
79 elif key[0] != '_':
80 raise ValueError('Unknown option to task "%s"' % key)
81
82included = {}
83ignored = {}
84excluded = {}
85debug = []
86
87if debug_out:
88 debug.append("EXCLUDES: '%s', '%s', '%s'" % (exclude_names, exclude_module_types, exclude_bus_types))
89 debug.append("INCLUDE: '%s', '%s', '%s'" % (include_names, include_module_types, include_bus_types))
90 debug.append("IGNORE: '%s', '%s', '%s'" % (ignore_names, ignore_module_types, ignore_bus_types))
91
David K. Bainbridgea677d4e2016-09-11 20:01:32 -070092for i in ethtool.get_devices():
93 o = { "name": i }
94 try:
95 module = ethtool.get_module(i)
96 businfo = ethtool.get_businfo(i)
David K. Bainbridge603ee542016-10-04 21:11:05 -070097
98 # If it matches an ignore pattern then just ignore it.
99 if has_match(i, module, businfo, ignore_names, ignore_module_types, ignore_bus_types):
100 if debug_out: debug.append("IGNORE '%s' on ignore match" % i)
101 ignored[i] = {
102 "name": i,
103 "module": module,
104 }
David K. Bainbridgea677d4e2016-09-11 20:01:32 -0700105 continue
David K. Bainbridge603ee542016-10-04 21:11:05 -0700106
107 # If no include specifications have been set and the interface is not ignored
108 # it needs to be considered for inclusion
109 if len(include_names) + len(include_module_types) + len(include_bus_types) == 0:
110 # If it matches exclude list then exclude it, else include it
111 if has_match(i, module, businfo, exclude_names, exclude_module_types, exclude_bus_types):
112 if debug_out: debug.append("EXCLUDE '%s' with no include specifiers, but with exclude match" %i)
113 excluded[i] = {
114 "name": i,
115 "module": module,
116 }
117 continue
118 if debug_out: debug.append("INCLUDE '%s' with no include specifiers, but with no exclude match" % i)
119 included[i] = {
120 "name": i,
121 "module": module,
122 }
123 continue
124
125 # If any of the include specifications are set then the interface must match at least one
126 # to be added to the mached list.
127 if has_match(i, module, businfo, include_names, include_module_types, include_bus_types):
128 if debug_out: debug.append("MATCH '%s' has include match" % i)
129 # If it matches exclude list then exclude it, else include it
130 if has_match(i, module, businfo, exclude_names, exclude_module_types, exclude_bus_types):
131 if debug_out: debug.append("EXCLUDE '%s' with include match, but also with exclude match" % i)
132 excluded[i] = {
133 "name": i,
134 "module": module,
135 }
136 continue
137 if debug_out: debug.append("INCLUDE '%s' with include match and with no exclude match" % i)
138 included[i] = {
139 "name": i,
140 "module" : module,
141 }
142 continue
143
144 # Implicitly ignore
145 if debug_out: debug.append("IGNORE: '%s' implicitly" %i)
146 ignored[i] = {
David K. Bainbridgea677d4e2016-09-11 20:01:32 -0700147 "name": i,
David K. Bainbridge603ee542016-10-04 21:11:05 -0700148 "module": module,
David K. Bainbridgea677d4e2016-09-11 20:01:32 -0700149 }
David K. Bainbridge603ee542016-10-04 21:11:05 -0700150
David K. Bainbridgea677d4e2016-09-11 20:01:32 -0700151 except:
152 pass
153
David K. Bainbridge603ee542016-10-04 21:11:05 -0700154result = {
David K. Bainbridgea677d4e2016-09-11 20:01:32 -0700155 "changed" : False,
156 "ansible_facts" : {
David K. Bainbridge603ee542016-10-04 21:11:05 -0700157 "netinfo" : {
158 "included" : included,
159 "excluded" : excluded,
160 "ignored" : ignored,
161 },
David K. Bainbridgea677d4e2016-09-11 20:01:32 -0700162 },
David K. Bainbridge603ee542016-10-04 21:11:05 -0700163}
164
165if debug_out: result["ansible_facts"]["netinfo"]["debug"] = debug
166
167print json.dumps(result)