diff --git a/AS1024.GeoFeed.Core/GeoFeedProviders/NetBoxGeoFeedProvider.cs b/AS1024.GeoFeed.Core/GeoFeedProviders/NetBoxGeoFeedProvider.cs index 9e44f28..b5c7014 100644 --- a/AS1024.GeoFeed.Core/GeoFeedProviders/NetBoxGeoFeedProvider.cs +++ b/AS1024.GeoFeed.Core/GeoFeedProviders/NetBoxGeoFeedProvider.cs @@ -1,129 +1,14 @@ using AS1024.GeoFeed.Core.Interfaces; -using AS1024.GeoFeed.Models; -using System.Text.Json; -using System.Net.Http.Headers; -using System.Net.Sockets; -using System.Web; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; namespace AS1024.GeoFeed.Core.GeoFeedProviders { - public class NetBoxGeoFeedProvider : IGeoFeedProvider + public class NetBoxGeoFeedProvider : NetBoxGeoFeedProviderBase, IGeoFeedProvider { - private readonly IConfiguration configuration; - private readonly ILogger logger; - private readonly IList addressFamilies = new List() + public NetBoxGeoFeedProvider(IConfiguration configuration, ILogger logger, IHttpClientFactory httpClientFactory) + : base(configuration, logger, httpClientFactory) { - AddressFamily.InterNetwork, - AddressFamily.InterNetworkV6 - }; - private readonly IHttpClientFactory httpClientFactory; - - string IGeoFeedProvider.GeoFeedProviderName => "netbox"; - - public NetBoxGeoFeedProvider(IConfiguration configuration, - ILogger logger, - IHttpClientFactory httpClientFactory) - { - this.configuration = configuration; - this.logger = logger; - this.httpClientFactory = httpClientFactory; - } - - public async Task> GetGeoFeedData() - { - List geoFeed = []; - using HttpClient client = httpClientFactory.CreateClient(); - client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Token", configuration["APIKey"]); - client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); - - foreach (AddressFamily family in addressFamilies) - { - Uri uri = BuildNetBoxURI(family); - NetboxData? jsonData = null; - - while (true) - { - logger.LogDebug($"Making request to {uri}..."); - - using HttpResponseMessage result = await client.GetAsync(uri); - if (!result.IsSuccessStatusCode) - { - break; - } - string stringResult = await result.Content.ReadAsStringAsync(); - jsonData = JsonSerializer.Deserialize(stringResult, new JsonSerializerOptions - { - PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower - }); - - if (jsonData?.Results == null || jsonData.Results.Count == 0) - { - break; - } - - foreach (Result 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, - GeolocPostalCode = data.CustomFields.GeolocPostalCode - }); - } - 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) - { - System.Collections.Specialized.NameValueCollection queryParameters = HttpUtility.ParseQueryString(string.Empty); - queryParameters["cf_geoloc_has_location"] = "true"; - queryParameters["limit"] = "50"; - - 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; - } - - UriBuilder endUrl = new UriBuilder - { - Path = "api/ipam/prefixes/", - Query = queryParameters.ToString(), - Host = configuration["NetBoxHost"], - Scheme = "https" - }; - - return endUrl.Uri; } } } diff --git a/AS1024.GeoFeed.Core/GeoFeedProviders/NetBoxGeoFeedProviderBase.cs b/AS1024.GeoFeed.Core/GeoFeedProviders/NetBoxGeoFeedProviderBase.cs new file mode 100644 index 0000000..324273c --- /dev/null +++ b/AS1024.GeoFeed.Core/GeoFeedProviders/NetBoxGeoFeedProviderBase.cs @@ -0,0 +1,134 @@ +using AS1024.GeoFeed.Core.Interfaces; +using AS1024.GeoFeed.Models; +using System.Text.Json; +using System.Net.Http.Headers; +using System.Net.Sockets; +using System.Web; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; + +namespace AS1024.GeoFeed.Core.GeoFeedProviders +{ + public class NetBoxGeoFeedProviderBase : IGeoFeedProvider + { + protected readonly IConfiguration configuration; + protected readonly ILogger logger; + protected readonly IList addressFamilies = new List() + { + AddressFamily.InterNetwork, + AddressFamily.InterNetworkV6 + }; + protected readonly IHttpClientFactory httpClientFactory; + + string IGeoFeedProvider.GeoFeedProviderName => "netbox"; + + public NetBoxGeoFeedProviderBase(IConfiguration configuration, + ILogger logger, + IHttpClientFactory httpClientFactory) + { + this.configuration = configuration; + this.logger = logger; + this.httpClientFactory = httpClientFactory; + } + + public async Task> GetGeoFeedData() + { + List geoFeed = []; + using HttpClient client = httpClientFactory.CreateClient(); + client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Token", configuration["APIKey"]); + client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); + + foreach (AddressFamily family in addressFamilies) + { + Uri uri = BuildNetBoxURI(family); + NetboxData? jsonData = null; + + while (true) + { + logger.LogDebug($"Making request to {uri}..."); + + using HttpResponseMessage result = await client.GetAsync(uri); + if (!result.IsSuccessStatusCode) + { + break; + } + string stringResult = await result.Content.ReadAsStringAsync(); + jsonData = DeserializeJsonData(stringResult); + + if (jsonData?.Results == null || jsonData.Results.Count == 0) + { + break; + } + + foreach (Result 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, + GeolocPostalCode = data.CustomFields.GeolocPostalCode + }); + } + catch (Exception ex) + { + logger.LogError(ex.ToString()); + } + } + + if (!string.IsNullOrEmpty(jsonData.Next)) + { + uri = new Uri(jsonData.Next); + continue; + } + + break; + } + } + + return geoFeed; + } + + protected virtual NetboxData? DeserializeJsonData(string stringResult) + { + return JsonSerializer.Deserialize(stringResult, new JsonSerializerOptions + { + PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower + }); + } + + protected Uri BuildNetBoxURI(AddressFamily family) + { + System.Collections.Specialized.NameValueCollection queryParameters = HttpUtility.ParseQueryString(string.Empty); + queryParameters["cf_geoloc_has_location"] = "true"; + queryParameters["limit"] = "50"; + + 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; + } + + UriBuilder endUrl = new UriBuilder + { + Path = "api/ipam/prefixes/", + Query = queryParameters.ToString(), + Host = configuration["NetBoxHost"], + Scheme = "https" + }; + + return endUrl.Uri; + } + } +}