Skip to content

Commit 3bab784

Browse files
Bogdan IrimieFilipovici-Andrei
authored andcommitted
(FACT-2864) Added support for secondary ips and vlans on linux platforms
2 parents 7245bc3 + c3164f4 commit 3bab784

File tree

244 files changed

+1719
-1296
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

244 files changed

+1719
-1296
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,5 @@ build-iPhoneSimulator/
5555
.rspec_status
5656
Gemfile.lock
5757
Gemfile.local
58+
acceptance/vendor
59+
.beaker

.rubocop_todo.yml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ RSpec/FilePath:
2828
- 'spec/custom_facts/util/normalization_spec.rb'
2929
- 'spec/custom_facts/util/parser_spec.rb'
3030
- 'spec/custom_facts/util/resolution_spec.rb'
31-
- 'spec/facter/facts_utils/uptime_parser_spec.rb'
32-
- 'spec/facter/facts_utils/windows_release_finder_spec.rb'
33-
- 'spec/facter/facts_utils/virtual_detector_spec.rb'
31+
- 'spec/facter/util/facts/uptime_parser_spec.rb'
32+
- 'spec/facter/util/facts/windows_release_finder_spec.rb'
33+
- 'spec/facter/util/facts/virtual_detector_spec.rb'
3434
- 'spec/facter/model/fact_collection_spec.rb'
3535
- 'spec/facter/model/resolved_fact_spec.rb'
3636
- 'spec/facter/resolvers/aix/architecture_resolver_spec.rb'
@@ -54,7 +54,7 @@ RSpec/FilePath:
5454
- 'spec/facter/resolvers/system_profile_resolver_spec.rb'
5555
- 'spec/facter/resolvers/utils/aix/odm_query_spec.rb'
5656
- 'spec/facter/resolvers/utils/macosx/filesystem_helper_spec.rb'
57-
- 'spec/facter/resolvers/utils/windows/win32ole_spec.rb'
57+
- 'spec/facter/util/windows/win32ole_spec.rb'
5858
- 'spec/facter/resolvers/windows/dmi_bios_resolver_spec.rb'
5959
- 'spec/facter/resolvers/windows/dmi_computersystem_resolver_spec.rb'
6060
- 'spec/facter/resolvers/windows/hardware_architecture_resolver_spec.rb'
@@ -104,7 +104,7 @@ RSpec/LeakyConstantDeclaration:
104104
- 'spec/custom_facts/shared_contexts/platform.rb'
105105
- 'spec/custom_facts/util/collection_spec.rb'
106106
- 'spec/facter/resolvers/macosx/mountpoints_resolver_spec.rb'
107-
- 'spec/facter/resolvers/utils/windows/network_utils_spec.rb'
107+
- 'spec/facter/util/windows/network_utils_spec.rb'
108108

109109
# Offense count: 93
110110
# Configuration parameters: EnforcedStyle.
@@ -159,7 +159,7 @@ RSpec/MessageSpies:
159159
- 'spec/facter/facts/windows/processors/physicalcount_spec.rb'
160160
- 'spec/facter/facts/windows/ruby/platform_spec.rb'
161161
- 'spec/facter/facts/windows/ruby/sitedir_spec.rb'
162-
- 'spec/facter/resolvers/utils/aix/odm_query_spec.rb'
162+
- 'spec/facter/util/aix/odm_query_spec.rb'
163163

164164
# Offense count: 26
165165
RSpec/SubjectStub:
@@ -208,8 +208,8 @@ RSpec/VerifiedDoubles:
208208
- 'spec/facter/resolvers/freebsd/ffi_helper_spec.rb'
209209
- 'spec/facter/resolvers/macosx/mountpoints_resolver_spec.rb'
210210
- 'spec/facter/resolvers/mountpoints_resolver_spec.rb'
211-
- 'spec/facter/resolvers/utils/windows/network_utils_spec.rb'
212-
- 'spec/facter/resolvers/utils/windows/win32ole_spec.rb'
211+
- 'spec/facter/util/windows/network_utils_spec.rb'
212+
- 'spec/facter/util/windows/win32ole_spec.rb'
213213
- 'spec/facter/resolvers/windows/dmi_bios_resolver_spec.rb'
214214
- 'spec/facter/resolvers/windows/dmi_computersystem_resolver_spec.rb'
215215
- 'spec/facter/resolvers/windows/hardware_architecture_resolver_spec.rb'

acceptance/tests/facts/networking_facts.rb

Lines changed: 44 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,90 +1,96 @@
11
test_name 'C59029: networking facts should be fully populated' do
22
tag 'risk:high'
33

4-
#
5-
# This test is intended to ensure that networking facts resolves
6-
# as expected across supported platforms.
7-
#
4+
#
5+
# This test is intended to ensure that networking facts resolve
6+
# as expected across supported platforms.
7+
#
88

99
@ip_regex = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/
1010
@netmask_regex = /^(((128|192|224|240|248|252|254)\.0\.0\.0)|(255\.(0|128|192|224|240|248|252|254)\.0\.0)|(255\.255\.(0|128|192|224|240|248|252|254)\.0)|(255\.255\.255\.(0|128|192|224|240|248|252|254)))$/
1111

1212
expected_networking = {
13-
"networking.dhcp" => agent['platform'] =~ /fedora-32|el-8-aarch64/ ? '' : @ip_regex, # https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/426
14-
"networking.ip" => @ip_regex,
15-
"networking.ip6" => /[a-f0-9]+:+/,
16-
"networking.mac" => /[a-f0-9]{2}:/,
17-
"networking.mtu" => /\d+/,
18-
"networking.netmask" => @netmask_regex,
19-
"networking.netmask6" => /[a-f0-9]+:/,
20-
"networking.network" => @ip_regex,
21-
"networking.network6" => /([a-f0-9]+)?:([a-f0-9]+)?/
13+
%w[networking dhcp] => agent['platform'] =~ /fedora-32|el-8-aarch64/ ? '' : @ip_regex, # https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/426
14+
%w[networking ip] => @ip_regex,
15+
%w[networking ip6] => /[a-f0-9]+:+/,
16+
%w[networking mac] => /[a-f0-9]{2}:/,
17+
%w[networking mtu] => /\d+/,
18+
%w[networking netmask] => @netmask_regex,
19+
%w[networking netmask6] => /[a-f0-9]+:/,
20+
%w[networking network] => @ip_regex,
21+
%w[networking network6] => /([a-f0-9]+)?:([a-f0-9]+)?/,
22+
%w[networking scope6] => /link|host|site|global|compat/
2223
}
2324

2425
agents.each do |agent|
2526
primary_interface = fact_on(agent, 'networking.primary')
2627
refute_empty(primary_interface)
2728

2829
expected_bindings = {
29-
"networking.interfaces.#{primary_interface}.bindings.0.address" => @ip_regex,
30-
"networking.interfaces.#{primary_interface}.bindings.0.netmask" => @netmask_regex,
31-
"networking.interfaces.#{primary_interface}.bindings.0.network" => @ip_regex,
32-
"networking.interfaces.#{primary_interface}.bindings6.0.address" => /[a-f0-9:]+/,
33-
"networking.interfaces.#{primary_interface}.bindings6.0.netmask" => /[a-f0-9:]+/,
34-
"networking.interfaces.#{primary_interface}.bindings6.0.network" => /[a-f0-9:]+/
30+
['networking', 'interfaces', primary_interface, 'bindings', 0, 'address'] => @ip_regex,
31+
['networking', 'interfaces', primary_interface, 'bindings', 0, 'netmask'] => @netmask_regex,
32+
['networking', 'interfaces', primary_interface, 'bindings', 0, 'network'] => @ip_regex,
33+
['networking', 'interfaces', primary_interface, 'bindings6', 0, 'address'] => /[a-f0-9:]+/,
34+
['networking', 'interfaces', primary_interface, 'bindings6', 0, 'netmask'] => /[a-f0-9:]+/,
35+
['networking', 'interfaces', primary_interface, 'bindings6', 0, 'network'] => /[a-f0-9:]+/,
36+
['networking', 'interfaces', primary_interface, 'bindings6', 0, 'scope6'] => /link|host|site|global|compat/
3537
}
3638

3739
if agent['platform'] =~ /eos|solaris|aix|cisco/
3840
#remove the invalid networking facts on eccentric platforms
39-
expected_networking.delete("networking.ip6")
40-
expected_networking.delete("networking.netmask6")
41-
expected_networking.delete("networking.network6")
41+
expected_networking.delete(%w[networking ip6])
42+
expected_networking.delete(%w[networking netmask6])
43+
expected_networking.delete(%w[networking network6])
44+
expected_networking.delete(%w[networking scope6])
4245

4346
#remove invalid bindings for the primary networking interface eccentric platforms
44-
expected_bindings.delete("networking.interfaces.#{primary_interface}.bindings6.0.address")
45-
expected_bindings.delete("networking.interfaces.#{primary_interface}.bindings6.0.netmask")
46-
expected_bindings.delete("networking.interfaces.#{primary_interface}.bindings6.0.network")
47+
expected_bindings.delete(['networking', 'interfaces', primary_interface, 'bindings6', 0, 'address'])
48+
expected_bindings.delete(['networking', 'interfaces', primary_interface, 'bindings6', 0, 'netmask'])
49+
expected_bindings.delete(['networking', 'interfaces', primary_interface, 'bindings6', 0, 'network'])
50+
expected_bindings.delete(['networking', 'interfaces', primary_interface, 'bindings6', 0, 'scope6'])
4751
end
4852

4953
if agent['platform'] =~ /aix|sparc|cisco|huawei|sles|s390x/
5054
# some of our testing platforms do not use DHCP
51-
expected_networking.delete("networking.dhcp")
55+
expected_networking.delete(%w[networking dhcp])
5256
end
5357

5458
if agent['platform'] =~ /cisco/
5559
# Cisco main interface does not define netmask or network
56-
expected_networking.delete("networking.network")
57-
expected_networking.delete("networking.netmask")
60+
expected_networking.delete(%w[networking network])
61+
expected_networking.delete(%w[networking netmask])
5862

5963
#remove invalid bindings for Cisco's primary networking interface
60-
expected_bindings.delete("networking.interfaces.#{primary_interface}.bindings.0.netmask")
61-
expected_bindings.delete("networking.interfaces.#{primary_interface}.bindings.0.network")
64+
expected_bindings.delete(['networking', 'interfaces', primary_interface, 'bindings', 0, 'netmask'])
65+
expected_bindings.delete(['networking', 'interfaces', primary_interface, 'bindings', 0, 'network'])
6266
end
6367

68+
networking_facts = JSON.parse(on(agent, facter('networking --json')).stdout)
69+
6470
step "Ensure the Networking fact resolves with reasonable values for at least one interface" do
65-
expected_networking.each do |fact, value|
66-
assert_match(value, fact_on(agent, fact).to_s)
71+
expected_networking.each do |fact_tokens, regex|
72+
assert_match(regex, networking_facts.dig(*fact_tokens).to_s)
6773
end
6874
end
6975

7076
step "Ensure bindings for the primary networking interface are present" do
71-
expected_bindings.each do |fact, value|
72-
assert_match(value, fact_on(agent, fact).to_s)
77+
expected_bindings.each do |fact_tokens, regex|
78+
assert_match(regex, networking_facts.dig(*fact_tokens).to_s)
7379
end
7480
end
7581
end
7682

7783
# Verify that IP Address v6 and network v6 is retrieved correctly and does not contain the interface identifier
7884
agents.each do |agent|
7985
if agent['platform'] =~ /windows/
80-
step("verify that ipaddress6 is retrieved correctly") do
81-
on(agent, facter("ipaddress6")) do |facter_result|
86+
step "verify that ipaddress6 is retrieved correctly" do
87+
on(agent, facter('ipaddress6')) do |facter_result|
8288
assert_match(/^[a-fA-F0-9:]+$/, facter_result.stdout.chomp)
8389
end
8490
end
8591

86-
step("verify that network6 is retrieved correctly") do
87-
on(agent, facter("network6")) do |facter_result|
92+
step "verify that network6 is retrieved correctly" do
93+
on(agent, facter('network6')) do |facter_result|
8894
assert_match(/([a-fA-F0-9:]+)?:([a-fA-F0-9:]+)?$/, facter_result.stdout.chomp)
8995
end
9096
end
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
test_name 'networking facts with secondary ip' do
2+
tag 'risk:high'
3+
4+
#
5+
# This test is intended to ensure that networking facts resolve secondary ips
6+
# as expected across supported platforms.
7+
#
8+
9+
@ip_regex = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/
10+
@netmask_regex = /^(((128|192|224|240|248|252|254)\.0\.0\.0)|(255\.(0|128|192|224|240|248|252|254)\.0\.0)|(255\.255\.(0|128|192|224|240|248|252|254)\.0)|(255\.255\.255\.(0|128|192|224|240|248|252|254)))$/
11+
12+
def expected_interfaces(interface, count)
13+
expected_interfaces = {}
14+
(1..count).each do |index|
15+
expected_interfaces.merge!(expected_bindings(ip_name(interface, index), 1))
16+
expected_interfaces.merge!(
17+
{
18+
['networking', 'interfaces', "#{ip_name(interface, index)}", 'ip'] => @ip_regex,
19+
['networking', 'interfaces', "#{ip_name(interface, index)}", 'netmask'] => @netmask_regex,
20+
['networking', 'interfaces', "#{ip_name(interface, index)}", 'network'] => @ip_regex
21+
}
22+
)
23+
end
24+
expected_interfaces
25+
end
26+
27+
def expected_bindings(interface, count)
28+
expected_bindings = {}
29+
(1..count).each do |index|
30+
expected_bindings.merge!(
31+
{
32+
['networking', 'interfaces', "#{interface}", 'bindings', index - 1, 'address'] => @ip_regex,
33+
['networking', 'interfaces', "#{interface}", 'bindings', index - 1, 'netmask'] => @netmask_regex,
34+
['networking', 'interfaces', "#{interface}", 'bindings', index - 1, 'network'] => @ip_regex
35+
}
36+
)
37+
end
38+
expected_bindings
39+
end
40+
41+
def ip_name(interface, index)
42+
"#{interface}:#{index}"
43+
end
44+
45+
agents.each do |agent|
46+
interface = fact_on(agent, 'networking.primary')
47+
48+
step "Add secondary ip without labels" do
49+
on(agent, "ip addr add 11.0.0.0/24 dev #{interface}")
50+
end
51+
52+
step "Add two secondary ips with label" do
53+
on(agent, "ip addr add 11.0.0.1/24 dev #{interface} label #{ip_name(interface, 1)}")
54+
on(agent, "ip addr add 11.0.0.2/24 dev #{interface} label #{ip_name(interface, 2)}")
55+
end
56+
57+
networking_facts = JSON.parse(on(agent, facter('networking --json')).stdout)
58+
59+
step "Check secondary interfaces are found" do
60+
expected_interfaces(interface, 2).each do |fact_tokens, regex|
61+
assert_match(regex, networking_facts.dig(*fact_tokens).to_s)
62+
end
63+
end
64+
65+
step "Check secondary interfaces are inside the bindings of the primary interface" do
66+
expected_bindings(interface, 4).each do |fact_tokens, regex|
67+
assert_match(regex, networking_facts.dig(*fact_tokens).to_s)
68+
end
69+
end
70+
71+
teardown do
72+
on(agent, "ip addr flush dev #{interface}")
73+
end
74+
end
75+
end
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
test_name 'networking facts with vlans' do
2+
tag 'risk:high'
3+
4+
#
5+
# This test is intended to ensure that networking facts resolve vlans
6+
# as expected across supported platforms.
7+
#
8+
9+
@ip_regex = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/
10+
@netmask_regex = /^(((128|192|224|240|248|252|254)\.0\.0\.0)|(255\.(0|128|192|224|240|248|252|254)\.0\.0)|(255\.255\.(0|128|192|224|240|248|252|254)\.0)|(255\.255\.255\.(0|128|192|224|240|248|252|254)))$/
11+
12+
def vlan(interface, index)
13+
"#{interface}.#{index}"
14+
end
15+
16+
def expected_bindings(interface, count)
17+
expected_bindings = {}
18+
(1..count).each do |index|
19+
expected_bindings.merge!(
20+
{
21+
['networking', 'interfaces', vlan(interface, index).to_s, 'bindings', 0, 'address'] => @ip_regex,
22+
['networking', 'interfaces', vlan(interface, index).to_s, 'bindings', 0, 'netmask'] => @netmask_regex,
23+
['networking', 'interfaces', vlan(interface, index).to_s, 'bindings', 0, 'network'] => @ip_regex,
24+
%W[networking interfaces #{vlan(interface, index)} ip] => @ip_regex,
25+
%W[networking interfaces #{vlan(interface, index)} mac] => /[a-f0-9]{2}:/,
26+
%W[networking interfaces #{vlan(interface, index)} mtu] => /\d+/,
27+
%W[networking interfaces #{vlan(interface, index)} netmask] => @netmask_regex,
28+
%W[networking interfaces #{vlan(interface, index)} network] => @ip_regex
29+
}
30+
)
31+
end
32+
expected_bindings
33+
end
34+
35+
agents.each do |agent|
36+
interface = fact_on(agent, 'networking.primary')
37+
38+
step "Add two vlans" do
39+
on(agent, "ip link add link #{interface} name #{vlan(interface, 1)} type vlan id 1")
40+
on(agent, "ip addr add 11.0.0.1/24 dev #{vlan(interface, 1)}")
41+
on(agent, "ip link add link #{interface} name #{vlan(interface, 2)} type vlan id 2")
42+
on(agent, "ip addr add 11.0.0.2/24 dev #{vlan(interface, 2)}")
43+
end
44+
45+
step "Check vlans are found" do
46+
networking_facts = JSON.parse(on(agent, facter('networking --json')).stdout)
47+
48+
expected_bindings(interface, 2).each do |fact_tokens, regex|
49+
assert_match(regex, networking_facts.dig(*fact_tokens).to_s)
50+
end
51+
end
52+
53+
teardown do
54+
on(agent, "ip link delete #{vlan(interface, 1)}")
55+
on(agent, "ip link delete #{vlan(interface, 2)}")
56+
end
57+
end
58+
end

lib/facter/facts/aix/memory/swap/available.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class Available
1111
def call_the_resolver
1212
fact_value = Facter::Resolvers::Aix::Memory.resolve(:swap)
1313
if fact_value
14-
fact_value = Facter::FactsUtils::UnitConverter.bytes_to_human_readable(fact_value[:available_bytes])
14+
fact_value = Facter::Util::Facts::UnitConverter.bytes_to_human_readable(fact_value[:available_bytes])
1515
end
1616
[Facter::ResolvedFact.new(FACT_NAME, fact_value), Facter::ResolvedFact.new(ALIASES, fact_value, :legacy)]
1717
end

lib/facter/facts/aix/memory/swap/available_bytes.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ def call_the_resolver
1313
fact_value = fact_value[:available_bytes] if fact_value
1414

1515
[Facter::ResolvedFact.new(FACT_NAME, fact_value),
16-
Facter::ResolvedFact.new(ALIASES, Facter::FactsUtils::UnitConverter.bytes_to_mb(fact_value), :legacy)]
16+
Facter::ResolvedFact.new(ALIASES, Facter::Util::Facts::UnitConverter.bytes_to_mb(fact_value), :legacy)]
1717
end
1818
end
1919
end

lib/facter/facts/aix/memory/swap/total.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class Total
1111
def call_the_resolver
1212
fact_value = Facter::Resolvers::Aix::Memory.resolve(:swap)
1313
if fact_value
14-
fact_value = Facter::FactsUtils::UnitConverter.bytes_to_human_readable(fact_value[:total_bytes])
14+
fact_value = Facter::Util::Facts::UnitConverter.bytes_to_human_readable(fact_value[:total_bytes])
1515
end
1616
[Facter::ResolvedFact.new(FACT_NAME, fact_value), Facter::ResolvedFact.new(ALIASES, fact_value, :legacy)]
1717
end

lib/facter/facts/aix/memory/swap/total_bytes.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ def call_the_resolver
1313
fact_value = fact_value[:total_bytes] if fact_value
1414

1515
[Facter::ResolvedFact.new(FACT_NAME, fact_value),
16-
Facter::ResolvedFact.new(ALIASES, Facter::FactsUtils::UnitConverter.bytes_to_mb(fact_value), :legacy)]
16+
Facter::ResolvedFact.new(ALIASES, Facter::Util::Facts::UnitConverter.bytes_to_mb(fact_value), :legacy)]
1717
end
1818
end
1919
end

lib/facter/facts/aix/memory/swap/used.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ class Used
1010
def call_the_resolver
1111
fact_value = Facter::Resolvers::Aix::Memory.resolve(:swap)
1212
if fact_value
13-
fact_value = Facter::FactsUtils::UnitConverter.bytes_to_human_readable(fact_value[:used_bytes])
13+
fact_value = Facter::Util::Facts::UnitConverter.bytes_to_human_readable(fact_value[:used_bytes])
1414
end
1515
Facter::ResolvedFact.new(FACT_NAME, fact_value)
1616
end

0 commit comments

Comments
 (0)