Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #23851: first auto-bond implementation #439

Merged
merged 1 commit into from Jul 10, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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::LldpNeighbors.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
104 changes: 104 additions & 0 deletions app/services/foreman_discovery/lldp_neighbors.rb
@@ -0,0 +1,104 @@
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.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.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"
}
}