Exemple #1
0
        /// <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");
        }