public static void Update(this List <SnmpAccessPoint> accessPoints, List <BulkResult> results, Mibs.Mib mib) { foreach (var result in results) { var id = result.Mib.Replace($"{Mibs.GetValue(mib)}.", ""); var accessPoint = accessPoints.FirstOrDefault(c => c.Index == id); if (accessPoint == null) { // AccessPoint doesn't exist in this list yet switch (mib) { case Mibs.Mib.ApName: accessPoints.Add(new SnmpAccessPoint(id) { Name = result.Value }); break; case Mibs.Mib.ApBaseRadioMacAddress: accessPoints.Add(new SnmpAccessPoint(id) { BaseRadioMacAddress = result.Value }); break; case Mibs.Mib.ApEthernetMacAddress: accessPoints.Add(new SnmpAccessPoint(id) { EthernetMacAddress = result.Value }); break; case Mibs.Mib.ApIpAddress: accessPoints.Add(new SnmpAccessPoint(id) { IpAddress = result.Value }); break; case Mibs.Mib.ApLocation: accessPoints.Add(new SnmpAccessPoint(id) { Location = result.Value }); break; case Mibs.Mib.ApModel: accessPoints.Add(new SnmpAccessPoint(id) { Model = result.Value }); break; case Mibs.Mib.ApSerialNumber: accessPoints.Add(new SnmpAccessPoint(id) { SerialNumber = result.Value }); break; } } else { switch (mib) { case Mibs.Mib.ApName: accessPoint.Name = result.Value; break; case Mibs.Mib.ApBaseRadioMacAddress: accessPoint.BaseRadioMacAddress = result.Value; break; case Mibs.Mib.ApEthernetMacAddress: accessPoint.EthernetMacAddress = result.Value; break; case Mibs.Mib.ApIpAddress: accessPoint.IpAddress = result.Value; break; case Mibs.Mib.ApLocation: accessPoint.Location = result.Value; break; case Mibs.Mib.ApModel: accessPoint.Model = result.Value; break; case Mibs.Mib.ApSerialNumber: accessPoint.SerialNumber = result.Value; break; } } } }
public static void Update(this List <SnmpClient> clients, List <BulkResult> results, Mibs.Mib mib) { foreach (var result in results) { var id = result.Mib.Replace($"{Mibs.GetValue(mib)}.", ""); var client = clients.FirstOrDefault(c => c.Index == id); if (client == null) { // Client doesn't exist in this list yet switch (mib) { case Mibs.Mib.ClientApMacAddress: clients.Add(new SnmpClient(id) { ApMacAddress = result.Value }); break; case Mibs.Mib.ClientIpAddress: clients.Add(new SnmpClient(id) { IpAddress = result.Value }); break; case Mibs.Mib.ClientMacAddress: clients.Add(new SnmpClient(id) { MacAddress = result.Value }); break; case Mibs.Mib.ClientSsid: clients.Add(new SnmpClient(id) { Ssid = result.Value }); break; case Mibs.Mib.ClientUsername: clients.Add(new SnmpClient(id) { Username = result.Value }); break; case Mibs.Mib.ClientVlan: clients.Add(new SnmpClient(id) { Vlan = result.Value }); break; case Mibs.Mib.ClientWlanInterface: clients.Add(new SnmpClient(id) { Interface = result.Value }); break; } } else { switch (mib) { case Mibs.Mib.ClientApMacAddress: client.ApMacAddress = result.Value; break; case Mibs.Mib.ClientIpAddress: client.IpAddress = result.Value; break; case Mibs.Mib.ClientMacAddress: client.MacAddress = result.Value; break; case Mibs.Mib.ClientSsid: client.Ssid = result.Value; break; case Mibs.Mib.ClientUsername: client.Username = result.Value; break; case Mibs.Mib.ClientVlan: client.Vlan = result.Value; break; case Mibs.Mib.ClientWlanInterface: client.Interface = result.Value; break; } } } }
/// <summary> /// This method polls both the APs and the Clients, and updates the database /// </summary> public async Task UpdateDatabase() { _writer.WriteLine("Gathering details from SNMP..."); var macAddresses = GatherBulk(Mibs.GetValue(Mibs.Mib.ClientMacAddress), Connection.Host, Connection.Community); var ipAddresses = GatherBulk(Mibs.GetValue(Mibs.Mib.ClientIpAddress), Connection.Host, Connection.Community); var usernames = GatherBulk(Mibs.GetValue(Mibs.Mib.ClientUsername), Connection.Host, Connection.Community); var apMacAddresses = GatherBulk(Mibs.GetValue(Mibs.Mib.ClientApMacAddress), Connection.Host, Connection.Community); var ssids = GatherBulk(Mibs.GetValue(Mibs.Mib.ClientSsid), Connection.Host, Connection.Community); var wlanInterfaces = GatherBulk(Mibs.GetValue(Mibs.Mib.ClientWlanInterface), Connection.Host, Connection.Community); var vlans = GatherBulk(Mibs.GetValue(Mibs.Mib.ClientVlan), Connection.Host, Connection.Community); var apBaseRadioMac = GatherBulk(Mibs.GetValue(Mibs.Mib.ApBaseRadioMacAddress), Connection.Host, Connection.Community); var apEthernetMac = GatherBulk(Mibs.GetValue(Mibs.Mib.ApEthernetMacAddress), Connection.Host, Connection.Community); var apIpAddresses = GatherBulk(Mibs.GetValue(Mibs.Mib.ApIpAddress), Connection.Host, Connection.Community); var apNames = GatherBulk(Mibs.GetValue(Mibs.Mib.ApName), Connection.Host, Connection.Community); var apLocations = GatherBulk(Mibs.GetValue(Mibs.Mib.ApLocation), Connection.Host, Connection.Community); var apModels = GatherBulk(Mibs.GetValue(Mibs.Mib.ApModel), Connection.Host, Connection.Community); var apSerialNumbers = GatherBulk(Mibs.GetValue(Mibs.Mib.ApSerialNumber), Connection.Host, Connection.Community); _writer.WriteLine("Finished retrieving SNMP data"); var clients = new List <SnmpClient>(); clients.Update(macAddresses, Mibs.Mib.ClientMacAddress); clients.Update(ipAddresses, Mibs.Mib.ClientIpAddress); clients.Update(usernames, Mibs.Mib.ClientUsername); clients.Update(apMacAddresses, Mibs.Mib.ClientApMacAddress); clients.Update(ssids, Mibs.Mib.ClientSsid); clients.Update(wlanInterfaces, Mibs.Mib.ClientWlanInterface); clients.Update(vlans, Mibs.Mib.ClientVlan); _writer.WriteLine($"Pre-cleanup: {clients.Count} clients"); Stopwatch sw = new Stopwatch(); sw.Start(); clients.Cleanup(); sw.Stop(); _writer.WriteLine($"Post-cleanup: {clients.Count} clients"); _writer.WriteLine($"SNMP clients updated and cleaned up in {sw.Elapsed}"); var accessPoints = new List <SnmpAccessPoint>(); accessPoints.Update(apBaseRadioMac, Mibs.Mib.ApBaseRadioMacAddress); accessPoints.Update(apEthernetMac, Mibs.Mib.ApEthernetMacAddress); accessPoints.Update(apIpAddresses, Mibs.Mib.ApIpAddress); accessPoints.Update(apNames, Mibs.Mib.ApName); accessPoints.Update(apLocations, Mibs.Mib.ApLocation); accessPoints.Update(apModels, Mibs.Mib.ApModel); accessPoints.Update(apSerialNumbers, Mibs.Mib.ApSerialNumber); _writer.WriteLine("Database update started"); // Update AP Models var updateResult = await _database.UpdateAccessPointModels(accessPoints.Select(ap => ap.Model).Distinct().ToList()); _writer.WriteLine(!updateResult.Success ? $"Something went wrong updating access point models.. {updateResult.Message}" : $"Updated AP Models in {updateResult.TimeTaken}"); // Update SSIDs updateResult = await _database.UpdateSsids(clients.Select(c => c.Ssid).Distinct().ToList()); _writer.WriteLine(!updateResult.Success ? $"Something went wrong updating SSIDs.. {updateResult.Message}" : $"Updated SSIDs in {updateResult.TimeTaken}"); // Update VLANs updateResult = await _database.UpdateVlans(clients.Where(c => !string.IsNullOrEmpty(c.Vlan)).Select(c => c.Vlan).Distinct().ToList()); _writer.WriteLine(!updateResult.Success ? $"Something went wrong updating VLANs.. {updateResult.Message}" : $"Updated VLANs in {updateResult.TimeTaken}"); // Update interfaces updateResult = await _database.UpdateWlanInterfaces(clients.Where(c => !string.IsNullOrEmpty(c.Interface)).Select(c => c.Interface).Distinct().ToList()); _writer.WriteLine(!updateResult.Success ? $"Something went wrong updating WLC interfaces.. {updateResult.Message}" : $"Updated WLC interfaces in {updateResult.TimeTaken}"); // Update clients updateResult = await _database.UpdateClients(clients.Where(c => !string.IsNullOrEmpty(c.MacAddress)).Select(c => c.MacAddress.Replace(" ", "")).Distinct().ToList()); _writer.WriteLine(!updateResult.Success ? $"Something went wrong updating clients.. {updateResult.Message}" : $"Updated clients in {updateResult.TimeTaken}"); // Update IP Addresses updateResult = await _database.UpdateIpAddresses(clients.Where(c => !string.IsNullOrEmpty(c.IpAddress)).Select(c => c.IpAddress).Distinct().ToList()); _writer.WriteLine(!updateResult.Success ? $"Something went wrong updating IP addresses.. {updateResult.Message}" : $"Updated IP addresses in {updateResult.TimeTaken}"); var dbApModels = await _database.GetApModelsAsync(); // Build the list of access points that the database should contain var actualAps = accessPoints.Select(accessPoint => new AccessPoint { BaseRadioMacAddress = accessPoint.BaseRadioMacAddress, EthernetMacAddress = accessPoint.EthernetMacAddress, Location = accessPoint.Location, Name = accessPoint.Name, ModelId = dbApModels.First(m => m.Name == accessPoint.Model).Id, IpAddress = accessPoint.IpAddress }).ToList(); updateResult = await _database.UpdateAccessPoints(actualAps); _writer.WriteLine(!updateResult.Success ? $"Something went wrong updating access points.. {updateResult.Message}" : $"Updated APs in {updateResult.TimeTaken}"); // Return the records so that we can key them properly (i.e. can't insert without FKs) var apListTask = _database.GetAccessPointsAsync(); var clientListTask = _database.GetClientsAsync(); var ssidListTask = _database.GetSsidsAsync(); var vlanListTask = _database.GetVlansAsync(); var wlanInterfaceListTask = _database.GetWlanInterfacesAsync(); var ipAddressListTask = _database.GetIpAddressesAsync(); await Task.WhenAll(apListTask, clientListTask, ssidListTask, vlanListTask, wlanInterfaceListTask, ipAddressListTask); var apList = apListTask.Result; var clientList = clientListTask.Result; var ssidList = ssidListTask.Result; var vlanList = vlanListTask.Result; var wlanInterfaceList = wlanInterfaceListTask.Result; var ipAddressList = ipAddressListTask.Result; // Add client tracking records var clientTrackingList = new List <ClientTracking>(); var batchDate = DateTime.Now; foreach (var client in clients) { try { clientTrackingList.Add(new ClientTracking { ClientId = clientList.First(c => c.MacAddress == client.MacAddress.Replace(" ", "").ToUpper()).Id, AccessPointId = apList.First(ap => ap.BaseRadioMacAddress == client.ApMacAddress.Replace(" ", "").ToUpper()).Id, IpAddressId = ipAddressList.First(ip => ip.Value == client.IpAddress).Id, SsidId = ssidList.First(s => s.Value == client.Ssid).Id, Username = client.Username, VlanId = vlanList.First(v => v.Value == client.Vlan).Id, WlanInterfaceId = wlanInterfaceList.First(w => w.Value == client.Interface).Id, BatchDate = batchDate }); } catch (NullReferenceException nre) { _writer.WriteLine("Hit a null reference exception for the following client..."); _writer.WriteLine(client.ToString()); } catch (Exception ex) { _writer.WriteLine($"Threw an exception for the following client ({ex.Message})"); _writer.WriteLine(client.ToString()); } } _writer.WriteLine("Beginning main update block"); updateResult = await _database.AddClientTracking(clientTrackingList); _writer.WriteLine(!updateResult.Success ? $"Something went wrong adding client tracking.. {updateResult.Message}" : $"Main update block completed successfully in {updateResult.TimeTaken}"); _writer.WriteLine("Database update complete"); }