Skip to content

Commit

Permalink
Add ability to use only selected interfaces for machine type detection (
Browse files Browse the repository at this point in the history
#37)

* Add ability to use only selected interfaces for machine type detection

Co-authored-by: Andrea Ieri <[email protected]>
  • Loading branch information
agileshaw and aieri authored Mar 20, 2023
1 parent 8627a69 commit 5b6ec18
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 27 deletions.
17 changes: 11 additions & 6 deletions prometheus_juju_exporter/collector.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,20 +115,25 @@ def _get_machine_type(self, machine: Dict, machine_id: str) -> MachineType:
"""
self.logger.debug("Determining type of machine: %s", machine_id)
machine_type = MachineType.METAL
skip_interfaces = self.config["detection"]["skip_interfaces"].as_str_seq()
interface_filter = re.compile(r"|".join(skip_interfaces))
match_interfaces = self.config["detection"]["match_interfaces"].get()

for interface, properties in machine["network-interfaces"].items():
if skip_interfaces and interface_filter.search(interface) is not None:
# skip if match_interface is not empty and interface name doesn't match pattern
if match_interfaces and re.search(match_interfaces, interface) is None:
self.logger.debug(
"Disregarding interface %s. Matching filter: %s",
"Disregarding interface %s because it doesn't match filter: %s",
interface,
skip_interfaces,
match_interfaces,
)
continue

mac_address = properties["mac-address"]
self.logger.debug("Considering interface %s with MAC: %s", interface, mac_address)
self.logger.debug(
"Considering interface %s matching filter: %s. MAC: %s",
interface,
match_interfaces,
mac_address,
)
if mac_address.startswith(tuple(self.virt_mac_prefixes)):
machine_type = MachineType.KVM
break
Expand Down
2 changes: 1 addition & 1 deletion prometheus_juju_exporter/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def validate_config_options(self) -> None:
"detection": OrderedDict(
[
("virt_macs", confuse.StrSeq()),
("skip_interfaces", confuse.StrSeq()),
("match_interfaces", str),
]
),
"debug": bool,
Expand Down
19 changes: 9 additions & 10 deletions prometheus_juju_exporter/config_default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,14 @@ exporter:
collect_interval: 15

detection: # parameters affecting the detection algorithm
skip_interfaces: []
# This option can be used to exclude interfaces that might confuse the detection algorithm.
# Takes a list of regexps as input. Any interface name matching any of the provided expressions will be skipped.
# For example: skip_interfaces: ["br.*", "tap-.*"]
virt_macs:
- "52:54:00"
- "fa:16:3e"
- "06:f1:3a"
- "00:0d:3a" # Microsoft
- "00:50:56" # VMware
match_interfaces: ''
# Interface names that should be considered when detecting machine type.
# Takes a single regexp string as input. Only interface names matching
# the provided expression will be considered. The default value '' is
# equivalent to '.*' and tells the detection algorithm to look through all interfaces.
# Example: match_interfaces: ^(en[os]|eth)\d+|enp\d+s\d+|enx[0-9a-f]+
virt_macs: []
# The list of MAC address prefixes to be considered as virtual machines.
# Example: virt_macs: ["52:54:00", "fa:16:3e", "06:f1:3a", "00:0d:3a", "00:50:56"]

debug: False
2 changes: 1 addition & 1 deletion tests/unit/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ exporter:
collect_interval: 15

detection:
skip_interfaces: []
match_interfaces: ^(en[os]|eth)\d+|enp\d+s\d+|enx[0-9a-f]+
virt_macs:
- "52:54:00"
- "fa:16:3e"
Expand Down
20 changes: 11 additions & 9 deletions tests/unit/test_collector.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,19 +159,21 @@ def test_get_machine_type(self, collector_daemon, mac_address, expect_machine_ty
assert machine_type.value == expect_machine_type

@pytest.mark.parametrize(
"skip_interfaces, expected_type",
"match_interfaces, expected_type",
[
([r"^virbr\d*", r"^tap-"], MachineType.METAL),
([], MachineType.KVM),
(r"^(en[os]|eth)\d+|enp\d+s\d+|enx[0-9a-f]+", MachineType.METAL),
(r".*", MachineType.KVM),
(r"", MachineType.KVM),
],
)
def test_get_machine_type_interface_skip(
self, skip_interfaces, expected_type, collector_daemon
def test_get_machine_type_interface_match(
self, match_interfaces, expected_type, collector_daemon
):
"""Test that blacklisted interfaces are not used to detect machine type.
"""Test that only whitelisted interfaces are used to detect machine type.
There are two scenarios to this test:
* Without setting 'skip_interfaces', the machine should be marked as KVM
There are three scenarios to this test:
* Without setting 'match_interfaces', the machine should be marked as KVM
* Setting 'match_interfaces' to match all, the machine should be marked as KVM
* With right interfaces skipped, the machine should be marked as METAL
"""
statsd = collector_daemon()
Expand All @@ -197,7 +199,7 @@ def test_get_machine_type_interface_skip(
}

statsd.config["detection"]["virt_macs"].set([kvm_prefix, tap_prefix])
statsd.config["detection"]["skip_interfaces"].set(skip_interfaces)
statsd.config["detection"]["match_interfaces"].set(match_interfaces)

assert statsd._get_machine_type(machine, "dummy-0") == expected_type

Expand Down

0 comments on commit 5b6ec18

Please sign in to comment.