GeoFeed/AS1024.GeoFeed/GeoFeedBuilder/NetBoxGeoFeedProvider.cs

123 lines
4.4 KiB
C#

using AS1024.GeoFeed.Interfaces;
using AS1024.GeoFeed.Models;
using Newtonsoft.Json;
using System.Net.Http.Headers;
using System.Net.Sockets;
using System.Web;
namespace AS1024.GeoFeed.GeoFeedBuilder
{
public class NetBoxGeoFeedProvider : IGeoFeedProvider
{
private readonly IConfiguration configuration;
private readonly ILogger<NetBoxGeoFeedProvider> logger;
private readonly IList<AddressFamily> addressFamilies = new List<AddressFamily>()
{
AddressFamily.InterNetwork,
AddressFamily.InterNetworkV6
};
private readonly IHttpClientFactory httpClientFactory;
string IGeoFeedProvider.GeoFeedProviderName => "netbox";
public NetBoxGeoFeedProvider(IConfiguration configuration,
ILogger<NetBoxGeoFeedProvider> logger,
IHttpClientFactory httpClientFactory)
{
this.configuration = configuration;
this.logger = logger;
this.httpClientFactory = httpClientFactory;
}
public async Task<List<IPGeoFeed>> GetGeoFeedData()
{
var geoFeed = new List<IPGeoFeed>();
using var client = httpClientFactory.CreateClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Token", configuration["APIKey"]);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
foreach (var family in addressFamilies)
{
Uri uri = BuildNetBoxURI(family);
NetboxData? jsonData = null;
while (true)
{
logger.LogDebug($"Making request to {uri}...");
using var result = await client.GetAsync(uri);
if (result.IsSuccessStatusCode)
{
var stringResult = await result.Content.ReadAsStringAsync();
jsonData = JsonConvert.DeserializeObject<NetboxData>(stringResult);
if (jsonData?.Results == null || jsonData.Results.Count == 0)
{
break;
}
foreach (var data in jsonData.Results)
{
try
{
geoFeed.Add(new IPGeoFeed
{
Prefix = data.Prefix,
GeolocCity = data.CustomFields.GeolocCity,
GeolocRegion = data.CustomFields.GeolocRegion,
GeolocCountry = data.CustomFields.GeolocCountry,
GeolocHasLocation = data.CustomFields.GeolocHasLocation
});
}
catch (Exception ex)
{
logger.LogError(ex.ToString());
}
}
if (!string.IsNullOrEmpty(jsonData.Next))
{
uri = new Uri(jsonData.Next);
continue;
}
}
break;
}
}
return geoFeed;
}
protected Uri BuildNetBoxURI(AddressFamily family)
{
var queryParameters = HttpUtility.ParseQueryString(string.Empty);
queryParameters["cf_geoloc_has_location"] = "true";
queryParameters["limit"] = "5";
switch (family)
{
case AddressFamily.InterNetwork:
queryParameters["mask_length__lte"] = "24";
queryParameters["family"] = "4";
break;
case AddressFamily.InterNetworkV6:
queryParameters["mask_length__lte"] = "48";
queryParameters["family"] = "6";
break;
}
var endUrl = new UriBuilder
{
Path = "api/ipam/prefixes/",
Query = queryParameters.ToString(),
Host = configuration["NetBoxHost"],
Scheme = "https"
};
return endUrl.Uri;
}
}
}