Skip to content

Commit

Permalink
Fixes #23851: first auto-bond implementation
Browse files Browse the repository at this point in the history
refs #23851
  • Loading branch information
Thomas-Gelf committed Jun 22, 2018
1 parent 1428846 commit 2a577f1
Show file tree
Hide file tree
Showing 9 changed files with 440 additions and 1 deletion.
1 change: 1 addition & 0 deletions app/models/host/discovered.rb
Expand Up @@ -143,6 +143,7 @@ def populate_discovery_fields_from_facts(facts)
self.discovery_attribute_set = DiscoveryAttributeSet.where(:host_id => id).first_or_create
self.discovery_attribute_set.update_attributes(import_from_facts)
# set additional discovery attributes
::ForemanDiscovery::HostConverter.eventually_make_bond(self) if Setting[:discovery_auto_bond]
primary_ip = self.primary_interface.ip
unless primary_ip.nil?
subnet = Subnet.subnet_for(primary_ip)
Expand Down
1 change: 1 addition & 0 deletions app/models/setting/discovered.rb
Expand Up @@ -17,6 +17,7 @@ def self.load_defaults
Setting.transaction do
[
self.set('discovery_fact', N_("Fact name to use for primary interface detection"), "discovery_bootif", N_("Interface fact")),
self.set('discovery_auto_bond', N_("Automatic bond interface (if another interface is detected on the same VLAN via LLDP)"), false, N_("Create bond interfaces")),
self.set('discovery_clean_facts', N_("Clean all reported facts during provisioning (except discovery facts)"), false, N_("Clean all facts")),
self.set('discovery_hostname', N_("List of facts to use for the hostname (separated by comma, first wins)"), "discovery_bootif", N_("Hostname facts")),
self.set('discovery_auto', N_("Automatically provision newly discovered hosts, according to the provisioning rules"), false, N_("Auto provisioning")),
Expand Down
37 changes: 37 additions & 0 deletions app/services/foreman_discovery/host_converter.rb
Expand Up @@ -19,6 +19,43 @@ def self.to_managed(original_host, set_managed = true, set_build = true, added_a
host
end

def self.eventually_make_bond(host)
primary = host.primary_interface
return if primary.nil?
return if primary.type == 'Nic::Bond'

neighbors = ::ForemanDiscovery::LldpNeighbors
.from_facts(host.facts_hash)
.get_neighbors_by_interface(primary.identifier)

return if neighbors.nil?

ip = primary.ip
mac = primary.mac
name = primary.name
primary.update(
:primary => false,
:provision => false,
:managed => false,
:name => nil,
:ip => nil
)

bond = Nic::Bond.create(
:identifier => "bond0",
:attached_devices => neighbors,
:primary => true,
:provision => true,
:name => name,
:ip => ip,
:mac => mac,
:host => host
)

bond.save!
host.interfaces.push(bond)
end

def self.set_build_clean_facts(host)
# fact cleaning
if Setting['discovery_clean_facts']
Expand Down
67 changes: 67 additions & 0 deletions app/services/foreman_discovery/lldp_neighbors.rb
@@ -0,0 +1,67 @@
module ForemanDiscovery
class LldpNeighbors
def set(iface, neighbor)
interfaces[iface] = neighbor
end

def get(iface)
interfaces[iface]
end

def list_by_pvid
list = {}
interfaces.each do |name, neighbor|
next unless neighbor.has_key? 'PVID'
vlan = neighbor['PVID']
list[vlan] = [] unless list.has_key? vlan
list[vlan].push name
end

list.each { |_, interfaces| interfaces.sort!}
list
end

def interfaces
@interfaces ||= {}
end

def get_neighbors_by_interface(ifname)
return nil unless interfaces.has_key? ifname

interface = get(ifname)
return nil unless interface.has_key? 'PVID'

list = []
interfaces.each do |name, neighbor|
next unless neighbor.has_key? 'PVID'
list.push name if neighbor['PVID'] == interface['PVID']
end

return if list.size < 2
list.sort
end

def self.from_facts(facts)
neighbors = self.new
interfaces = {}
facts.keys.each do |key|
key_s = key.to_s
next unless key_s.start_with? 'lldp_neighbor_'

property, iface = key_s[14..-1].split('_', 2)
if property == 'mngAddr'
protocol, iface = iface.split('_', 2)
property += '_' + protocol
end
interfaces[iface] = {} unless interfaces.has_key? iface
interfaces[iface][property] = facts[key]
end

interfaces.each do |name, properties|
neighbors.set name, properties
end

neighbors
end
end
end
1 change: 1 addition & 0 deletions test/test_helper_discovery.rb
Expand Up @@ -68,6 +68,7 @@ def set_default_settings
FactoryBot.create(:setting, :name => 'discovery_always_rebuild_dns', :value => true, :category => 'Setting::Discovered')
FactoryBot.create(:setting, :name => 'discovery_error_on_existing', :value => false, :category => 'Setting::Discovered')
FactoryBot.create(:setting, :name => 'discovery_naming', :value => 'Fact', :category => 'Setting::Discovered')
FactoryBot.create(:setting, :name => 'discovery_auto_bond', :value => false, :category => 'Setting::Discovered')
end

def setup_hostgroup(host)
Expand Down
107 changes: 107 additions & 0 deletions test/unit/facts_with_lldp.json
@@ -0,0 +1,107 @@
{
"name": "sinn1636.lan",
"facts": {
"processor3": "Intel(R) Xeon(R) CPU E5620 @ 2.40GHz",
"productname": "IBM System x -[7870K4G]-",
"kernelmajversion": "2.6",
"kernelversion": "2.6.32",
"macaddress_vnet0": "FE:54:00:1E:45:13",
"macaddress_br181": "E4:1F:13:CC:36:58",
"macaddress_usb0": "E6:1F:13:D0:43:A3",
"macaddress_vnet1": "FE:54:00:45:E5:3E",
"rubysitedir": "/usr/lib/ruby/site_ruby/1.8",
"macaddress_br182": "E4:1F:13:CC:36:58",
"processor4": "Intel(R) Xeon(R) CPU E5620 @ 2.40GHz",
"macaddress_vnet2": "FE:54:00:93:F5:56",
"macaddress_br183": "E4:1F:13:CC:36:58",
"ps": "ps -ef",
"processor5": "Intel(R) Xeon(R) CPU E5620 @ 2.40GHz",
"macaddress_vnet10": "FE:54:00:7D:F8:24",
"uniqueid": "230a021b",
"macaddress_vnet3": "FE:54:00:05:49:DE",
"lsbdistcodename": "Santiago",
"hardwareisa": "x86_64",
"lsbdistrelease": "6.2",
"processor6": "Intel(R) Xeon(R) CPU E5620 @ 2.40GHz",
"serialnumber": "abcdefg",
"processor7": "Intel(R) Xeon(R) CPU E5620 @ 2.40GHz",
"macaddress_vnet4": "FE:54:00:62:53:67",
"hostname": "h02",
"osfamily": "RedHat",
"gateway_if": "br180",
"lsbrelease": ":core-4.0-amd64:core-4.0-noarch:graphics-4.0-amd64:graphics-4.0-noarch:printing-4.0-amd64:printing-4.0-noarch",
"kernelrelease": "2.6.32-131.12.1.el6.x86_64",
"kernel": "Linux",
"facterversion": "1.6.2",
"uptime_seconds": "13651752",
"macaddress_vnet5": "FE:54:00:01:B9:9C",
"interfaces": "br180,br181,br182,br183,eth0,eth0_181,eth0_182,eth0_183,eth1,lo,usb0,vnet0,vnet1,vnet2,vnet3,vnet4,vnet5,vnet7,vnet10",
"macaddress_vnet7": "FE:54:00:D8:F9:38",
"netmask_br180": "255.255.255.192",
"macaddress_eth0": "E4:1F:13:CC:36:58",
"is_virtual": "false",
"macaddress": "E4:1F:13:CC:36:58",
"sshdsakey": "AAAAB3NzaC1kc3MAAACBAIbK60jlhYKSd4Nx6LCQPMUZcq/P1lTY3sQVrwpmfbF7d4JOGed2RWSoTBAzP3/Tjwlf+8DZ3Jd8a6Yhd6WuBzinE+owym8LXo2gDTvelhnzOVrTytM8hAi8uFEiBTGbnN1zka2y7qCPVxEu+kV20qC3mPODGxpV6y/4KOZ5Y4SHAAAAFQCyjeF+Jy9CDhiD2tfnmtMGAn1xzQAAAIBwtnUhhkB0r3ivPdQZgVy6qha8AJQG94I9FU9FnGJJEjkkfqlgNrj9SxV6Cg9EcrntnAKxZxk7PQhgvDesx69Lap9PAx3Ffb5Pl47cd7ilOXv2RJGKuxZQHNdKUF2445POwNjxSuhEkIB3/zpFXBB/zPMRfqUtlXJEwP9m6z9UFgAAAIAQDBpmcGChFP7i8T2RdMZo3hSMnU4y5lpEGhmwfbODoLSAX37wWQwUmwRP8byTEqFL0+5bp3hRbt/67EoD1O6n39/We19g/UqHkbUdZQqLqFjJfyzqfepq4HXtIIT8GbqW+FGJkH9x2fY5gtQrn9nVdmPDTwERFS98qU9glufbIw==",
"uptime": "158 days",
"manufacturer": "IBM",
"macaddress_eth1": "E4:1F:13:CC:36:5A",
"timezone": "GMT",
"fqdn": "a.server.b.domain",
"ipaddress_br180": "10.35.27.2",
"ipaddress_eth0": "10.35.27.3",
"ipaddress_eth1": "10.35.27.4",
"puppetversion": "2.6.12",
"path": "/root/.gem/bin:/root/.gem/ruby/1.8/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:/sbin:/usr/sbin:/root/scripts",
"hardwaremodel": "x86_64",
"macaddress_eth0_181": "E4:1F:13:CC:36:58",
"netmask_lo": "255.0.0.0",
"uptime_days": "158",
"virtual": "physical",
"operatingsystemrelease": "6.2",
"processorcount": "8",
"sshrsakey": "AAAAB3NzaC1xcEabbAABIwAAAQEAwXfnuA0+6C6G152kzCbSZvTyUBrMwc0PGnmZgFpC3x4SkcMgRmtayPNqmY1vyYwyka1lNUoyU9u3TXOUkd7WrodoNYBbDQXWCAVpUci5099zUuZ8RVLcokKwNmQO0d1URgSLt2TtuLiUDB7JU2mHkoOuW9n7ODq+UzYsd2wf+/TQrvgsuyi25MROH2Z3WfMO+fmsj77h34gkuaavwB4e6lNRynjZLuEc4POFvDEW6kGCYm1g/8kRwUlB/Z1Cu0egxtxnTjILFFwfYFQu2Ksig020q1gLX3o4YL9X/YZz+JQuAOLGpK3F0owQUL7Ie3vokDsVmz2AweuLDFeh54i2Bw==",
"macaddress_eth0_182": "E4:1F:13:CC:36:58",
"memorysize": "15.57 GB",
"ipaddress": "10.35.27.2",
"rubyversion": "1.8.7",
"macaddress_eth0_183": "E4:1F:13:CC:36:58",
"physicalprocessorcount": "1",
"network_lo": "127.0.0.0",
"gateway": "10.35.27.62",
"lsbdistid": "RedHatEnterpriseServer",
"network_br180": "10.35.27.0",
"lsbdistdescription": "Red Hat Enterprise Linux Server release 6.2 (Santiago)",
"swapsize": "17.70 GB",
"processor0": "Intel(R) Xeon(R) CPU E5620 @ 2.40GHz",
"processor1": "Intel(R) Xeon(R) CPU E5620 @ 2.40GHz",
"macaddress_br180": "E4:1F:13:CC:36:58",
"selinux": "false",
"domain": "server.b.domain",
"architecture": "x86_64",
"uptime_hours": "3792",
"memoryfree": "6.87 GB",
"augeasversion": "0.9.0",
"operatingsystem": "RedHat",
"ipaddress_lo": "127.0.0.1",
"processor2": "Intel(R) Xeon(R) CPU E5620 @ 2.40GHz",
"type": "Main Server Chassis",
"id": "root",
"vlans": "181,182,183",
"lsbmajdistrelease": "6",
"swapfree": "16.72 GB",
"netmask": "255.255.255.192",
"discovery_bootif": "E4:1F:13:CC:36:58",
"memorysize_mb": "742.13",
"blockdevice_sda_size": "214749184",
"lldp_neighbor_chassisID_eth1": "0c:27:24:2c:c5:04",
"lldp_neighbor_portID_eth1": "Eth170/1/3",
"lldp_neighbor_sysName_eth1": "DC2-A03-DR-01",
"lldp_neighbor_mngAddr_ipv4_eth1": "192.0.2.13",
"lldp_neighbor_PVID_eth1": "184",
"lldp_neighbor_chassisID_eth2": "e0:d1:73:38:5a:84",
"lldp_neighbor_portID_eth2": "Eth171/1/3",
"lldp_neighbor_sysName_eth2": "DC2-A04-DR-03",
"lldp_neighbor_mngAddr_ipv4_eth2": "192.0.2.13",
"lldp_neighbor_PVID_eth2": "182"
}
}
107 changes: 107 additions & 0 deletions test/unit/facts_with_lldp_bond_candidate.json
@@ -0,0 +1,107 @@
{
"name": "sinn1636.lan",
"facts": {
"processor3": "Intel(R) Xeon(R) CPU E5620 @ 2.40GHz",
"productname": "IBM System x -[7870K4G]-",
"kernelmajversion": "2.6",
"kernelversion": "2.6.32",
"macaddress_vnet0": "FE:54:00:1E:45:13",
"macaddress_br181": "E4:1F:13:CC:36:58",
"macaddress_usb0": "E6:1F:13:D0:43:A3",
"macaddress_vnet1": "FE:54:00:45:E5:3E",
"rubysitedir": "/usr/lib/ruby/site_ruby/1.8",
"macaddress_br182": "E4:1F:13:CC:36:58",
"processor4": "Intel(R) Xeon(R) CPU E5620 @ 2.40GHz",
"macaddress_vnet2": "FE:54:00:93:F5:56",
"macaddress_br183": "E4:1F:13:CC:36:58",
"ps": "ps -ef",
"processor5": "Intel(R) Xeon(R) CPU E5620 @ 2.40GHz",
"macaddress_vnet10": "FE:54:00:7D:F8:24",
"uniqueid": "230a021b",
"macaddress_vnet3": "FE:54:00:05:49:DE",
"lsbdistcodename": "Santiago",
"hardwareisa": "x86_64",
"lsbdistrelease": "6.2",
"processor6": "Intel(R) Xeon(R) CPU E5620 @ 2.40GHz",
"serialnumber": "abcdefg",
"processor7": "Intel(R) Xeon(R) CPU E5620 @ 2.40GHz",
"macaddress_vnet4": "FE:54:00:62:53:67",
"hostname": "h02",
"osfamily": "RedHat",
"gateway_if": "br180",
"lsbrelease": ":core-4.0-amd64:core-4.0-noarch:graphics-4.0-amd64:graphics-4.0-noarch:printing-4.0-amd64:printing-4.0-noarch",
"kernelrelease": "2.6.32-131.12.1.el6.x86_64",
"kernel": "Linux",
"facterversion": "1.6.2",
"uptime_seconds": "13651752",
"macaddress_vnet5": "FE:54:00:01:B9:9C",
"interfaces": "br180,br181,br182,br183,eth0,eth0_181,eth0_182,eth0_183,eth1,lo,usb0,vnet0,vnet1,vnet2,vnet3,vnet4,vnet5,vnet7,vnet10",
"macaddress_vnet7": "FE:54:00:D8:F9:38",
"netmask_br180": "255.255.255.192",
"macaddress_eth0": "E4:1F:13:CC:36:58",
"is_virtual": "false",
"macaddress": "E4:1F:13:CC:36:58",
"sshdsakey": "AAAAB3NzaC1kc3MAAACBAIbK60jlhYKSd4Nx6LCQPMUZcq/P1lTY3sQVrwpmfbF7d4JOGed2RWSoTBAzP3/Tjwlf+8DZ3Jd8a6Yhd6WuBzinE+owym8LXo2gDTvelhnzOVrTytM8hAi8uFEiBTGbnN1zka2y7qCPVxEu+kV20qC3mPODGxpV6y/4KOZ5Y4SHAAAAFQCyjeF+Jy9CDhiD2tfnmtMGAn1xzQAAAIBwtnUhhkB0r3ivPdQZgVy6qha8AJQG94I9FU9FnGJJEjkkfqlgNrj9SxV6Cg9EcrntnAKxZxk7PQhgvDesx69Lap9PAx3Ffb5Pl47cd7ilOXv2RJGKuxZQHNdKUF2445POwNjxSuhEkIB3/zpFXBB/zPMRfqUtlXJEwP9m6z9UFgAAAIAQDBpmcGChFP7i8T2RdMZo3hSMnU4y5lpEGhmwfbODoLSAX37wWQwUmwRP8byTEqFL0+5bp3hRbt/67EoD1O6n39/We19g/UqHkbUdZQqLqFjJfyzqfepq4HXtIIT8GbqW+FGJkH9x2fY5gtQrn9nVdmPDTwERFS98qU9glufbIw==",
"uptime": "158 days",
"manufacturer": "IBM",
"macaddress_eth1": "E4:1F:13:CC:36:5A",
"timezone": "GMT",
"fqdn": "a.server.b.domain",
"ipaddress_br180": "10.35.27.2",
"ipaddress_eth0": "10.35.27.3",
"ipaddress_eth1": "10.35.27.4",
"puppetversion": "2.6.12",
"path": "/root/.gem/bin:/root/.gem/ruby/1.8/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:/sbin:/usr/sbin:/root/scripts",
"hardwaremodel": "x86_64",
"macaddress_eth0_181": "E4:1F:13:CC:36:58",
"netmask_lo": "255.0.0.0",
"uptime_days": "158",
"virtual": "physical",
"operatingsystemrelease": "6.2",
"processorcount": "8",
"sshrsakey": "AAAAB3NzaC1xcEabbAABIwAAAQEAwXfnuA0+6C6G152kzCbSZvTyUBrMwc0PGnmZgFpC3x4SkcMgRmtayPNqmY1vyYwyka1lNUoyU9u3TXOUkd7WrodoNYBbDQXWCAVpUci5099zUuZ8RVLcokKwNmQO0d1URgSLt2TtuLiUDB7JU2mHkoOuW9n7ODq+UzYsd2wf+/TQrvgsuyi25MROH2Z3WfMO+fmsj77h34gkuaavwB4e6lNRynjZLuEc4POFvDEW6kGCYm1g/8kRwUlB/Z1Cu0egxtxnTjILFFwfYFQu2Ksig020q1gLX3o4YL9X/YZz+JQuAOLGpK3F0owQUL7Ie3vokDsVmz2AweuLDFeh54i2Bw==",
"macaddress_eth0_182": "E4:1F:13:CC:36:58",
"memorysize": "15.57 GB",
"ipaddress": "10.35.27.2",
"rubyversion": "1.8.7",
"macaddress_eth0_183": "E4:1F:13:CC:36:58",
"physicalprocessorcount": "1",
"network_lo": "127.0.0.0",
"gateway": "10.35.27.62",
"lsbdistid": "RedHatEnterpriseServer",
"network_br180": "10.35.27.0",
"lsbdistdescription": "Red Hat Enterprise Linux Server release 6.2 (Santiago)",
"swapsize": "17.70 GB",
"processor0": "Intel(R) Xeon(R) CPU E5620 @ 2.40GHz",
"processor1": "Intel(R) Xeon(R) CPU E5620 @ 2.40GHz",
"macaddress_br180": "E4:1F:13:CC:36:58",
"selinux": "false",
"domain": "server.b.domain",
"architecture": "x86_64",
"uptime_hours": "3792",
"memoryfree": "6.87 GB",
"augeasversion": "0.9.0",
"operatingsystem": "RedHat",
"ipaddress_lo": "127.0.0.1",
"processor2": "Intel(R) Xeon(R) CPU E5620 @ 2.40GHz",
"type": "Main Server Chassis",
"id": "root",
"vlans": "181,182,183",
"lsbmajdistrelease": "6",
"swapfree": "16.72 GB",
"netmask": "255.255.255.192",
"discovery_bootif": "E4:1F:13:CC:36:58",
"memorysize_mb": "742.13",
"blockdevice_sda_size": "214749184",
"lldp_neighbor_chassisID_eth1": "0c:27:24:2c:c5:04",
"lldp_neighbor_portID_eth1": "Eth170/1/3",
"lldp_neighbor_sysName_eth1": "DC2-A03-DR-01",
"lldp_neighbor_mngAddr_ipv4_eth1": "192.0.2.13",
"lldp_neighbor_PVID_eth1": "182",
"lldp_neighbor_chassisID_eth0": "e0:d1:73:38:5a:84",
"lldp_neighbor_portID_eth0": "Eth171/1/3",
"lldp_neighbor_sysName_eth0": "DC2-A04-DR-03",
"lldp_neighbor_mngAddr_ipv4_eth0": "192.0.2.13",
"lldp_neighbor_PVID_eth0": "182"
}
}

0 comments on commit 2a577f1

Please sign in to comment.