Refactored subnet object methods and enhanced related documentation
This commit is contained in:
374
classlib/Helpers/RequestHelper.cs
Normal file
374
classlib/Helpers/RequestHelper.cs
Normal file
@@ -0,0 +1,374 @@
|
||||
namespace PS.IPAM.Helpers;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Management.Automation;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PS.IPAM;
|
||||
|
||||
public static class RequestHelper
|
||||
{
|
||||
// Handler for testing - allows injecting a mock HTTP handler
|
||||
public static HttpMessageHandler? TestHttpHandler { get; set; }
|
||||
|
||||
public static async Task<object?> InvokeRequest(
|
||||
string method,
|
||||
controllers controller,
|
||||
types? type = null,
|
||||
subcontrollers? subController = null,
|
||||
object? parameters = null,
|
||||
string[]? identifiers = null,
|
||||
bool ignoreSsl = false)
|
||||
{
|
||||
var tokenStatus = SessionManager.TestSession();
|
||||
if (tokenStatus == "NoToken")
|
||||
{
|
||||
throw new Exception("No session available!");
|
||||
}
|
||||
|
||||
if (tokenStatus == "Expired")
|
||||
{
|
||||
await UpdateSession();
|
||||
}
|
||||
|
||||
var session = SessionManager.CurrentSession;
|
||||
if (session == null)
|
||||
{
|
||||
throw new Exception("No session available!");
|
||||
}
|
||||
|
||||
var uri = $"{session.URL}/api/{session.AppID}/{controller}";
|
||||
if (subController != null)
|
||||
{
|
||||
uri += $"/{subController}";
|
||||
}
|
||||
if (identifiers != null && identifiers.Length > 0)
|
||||
{
|
||||
uri += $"/{string.Join("/", identifiers)}/";
|
||||
}
|
||||
|
||||
using var client = SessionManager.CreateHttpClient(ignoreSsl, TestHttpHandler);
|
||||
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
|
||||
|
||||
switch (session.AuthType)
|
||||
{
|
||||
case AuthType.credentials:
|
||||
client.DefaultRequestHeaders.Add("token", session.Token);
|
||||
break;
|
||||
case AuthType.token:
|
||||
client.DefaultRequestHeaders.Add("phpipam-token", session.Token);
|
||||
break;
|
||||
}
|
||||
|
||||
HttpResponseMessage? response = null;
|
||||
try
|
||||
{
|
||||
if (method == "GET")
|
||||
{
|
||||
response = await client.GetAsync(uri);
|
||||
}
|
||||
else if (method == "POST")
|
||||
{
|
||||
var jsonContent = parameters != null ? JsonConvert.SerializeObject(parameters) : "{}";
|
||||
var content = new StringContent(jsonContent, Encoding.UTF8, "application/json");
|
||||
response = await client.PostAsync(uri, content);
|
||||
}
|
||||
else if (method == "PATCH")
|
||||
{
|
||||
var jsonContent = parameters != null ? JsonConvert.SerializeObject(parameters) : "{}";
|
||||
var content = new StringContent(jsonContent, Encoding.UTF8, "application/json");
|
||||
var request = new HttpRequestMessage(new HttpMethod("PATCH"), uri)
|
||||
{
|
||||
Content = content
|
||||
};
|
||||
response = await client.SendAsync(request);
|
||||
}
|
||||
else if (method == "DELETE")
|
||||
{
|
||||
response = await client.DeleteAsync(uri);
|
||||
}
|
||||
|
||||
if (response == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var responseContent = await response.Content.ReadAsStringAsync();
|
||||
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
if (response.StatusCode == System.Net.HttpStatusCode.NotFound)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
throw new HttpRequestException($"Request failed with status {response.StatusCode}");
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(responseContent))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var jsonResponse = JsonConvert.DeserializeObject<dynamic>(responseContent);
|
||||
if (jsonResponse == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (type.HasValue)
|
||||
{
|
||||
return ConvertToTypedObjects(jsonResponse, type.Value);
|
||||
}
|
||||
|
||||
return jsonResponse.data;
|
||||
}
|
||||
catch (HttpRequestException ex)
|
||||
{
|
||||
if (ex.Message.Contains("404"))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private static object? ConvertToTypedObjects(dynamic jsonResponse, types type)
|
||||
{
|
||||
if (jsonResponse?.data == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var data = jsonResponse.data;
|
||||
if (data is JArray array)
|
||||
{
|
||||
return array.Select(item => ConvertSingleObject(item, type)).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
return ConvertSingleObject(data, type);
|
||||
}
|
||||
}
|
||||
|
||||
private static object? ConvertSingleObject(dynamic item, types type)
|
||||
{
|
||||
var jobject = item as JObject;
|
||||
if (jobject == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var customFields = new Dictionary<string, object>();
|
||||
foreach (var prop in jobject.Properties())
|
||||
{
|
||||
if (prop.Name.StartsWith("custom_"))
|
||||
{
|
||||
customFields[prop.Name] = prop.Value?.ToObject<object>() ?? new object();
|
||||
}
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case types.Address:
|
||||
return CreateAddress(jobject, customFields);
|
||||
case types.Vlan:
|
||||
return CreateVlan(jobject, customFields);
|
||||
case types.Subnetwork:
|
||||
return CreateSubnetwork(jobject, customFields);
|
||||
case types.Vrf:
|
||||
return CreateVrf(jobject, customFields);
|
||||
case types.Section:
|
||||
return CreateSection(jobject);
|
||||
case types.Tag:
|
||||
return CreateTag(jobject);
|
||||
case types.Nameserver:
|
||||
return CreateNameserver(jobject);
|
||||
case types.Domain:
|
||||
return CreateDomain(jobject);
|
||||
default:
|
||||
return jobject.ToObject<object>();
|
||||
}
|
||||
}
|
||||
|
||||
private static Address CreateAddress(JObject jobject, Dictionary<string, object> customFields)
|
||||
{
|
||||
return new Address(
|
||||
jobject["id"]?.ToObject<int>() ?? 0,
|
||||
jobject["subnetId"]?.ToObject<int>() ?? 0,
|
||||
jobject["ip"]?.ToString() ?? "",
|
||||
jobject["is_gateway"]?.ToObject<bool>() ?? false,
|
||||
jobject["description"]?.ToString() ?? "",
|
||||
jobject["hostname"]?.ToString() ?? "",
|
||||
jobject["mac"]?.ToString() ?? "",
|
||||
jobject["owner"]?.ToString() ?? "",
|
||||
jobject["tag"]?.ToObject<int>() ?? 0,
|
||||
jobject["deviceId"]?.ToObject<int>() ?? 0,
|
||||
jobject["location"]?.ToString() ?? "",
|
||||
jobject["port"]?.ToString() ?? "",
|
||||
jobject["note"]?.ToString() ?? "",
|
||||
jobject["lastSeen"]?.ToObject<DateTime?>(),
|
||||
jobject["excludePing"]?.ToObject<bool>() ?? false,
|
||||
jobject["PTRignore"]?.ToObject<bool>() ?? false,
|
||||
jobject["PTR"]?.ToObject<int>() ?? 0,
|
||||
jobject["firewallAddressObject"]?.ToString() ?? "",
|
||||
jobject["editDate"]?.ToObject<DateTime?>(),
|
||||
jobject["customer_id"]?.ToObject<int>() ?? 0,
|
||||
customFields.Count > 0 ? customFields : null
|
||||
);
|
||||
}
|
||||
|
||||
private static Vlan CreateVlan(JObject jobject, Dictionary<string, object> customFields)
|
||||
{
|
||||
return new Vlan(
|
||||
jobject["vlanId"]?.ToObject<int>() ?? 0,
|
||||
jobject["domainId"]?.ToObject<int>() ?? 0,
|
||||
jobject["name"]?.ToString() ?? "",
|
||||
jobject["number"]?.ToObject<int>() ?? 0,
|
||||
jobject["description"]?.ToString() ?? "",
|
||||
jobject["editDate"]?.ToObject<DateTime?>(),
|
||||
jobject["customer_id"]?.ToObject<int>() ?? 0,
|
||||
customFields.Count > 0 ? customFields : null
|
||||
);
|
||||
}
|
||||
|
||||
private static Subnetwork CreateSubnetwork(JObject jobject, Dictionary<string, object> customFields)
|
||||
{
|
||||
var props = jobject.Properties().ToList();
|
||||
return new Subnetwork(
|
||||
jobject["id"]?.ToObject<int>() ?? 0,
|
||||
jobject["subnet"]?.ToString() ?? "",
|
||||
jobject["mask"]?.ToObject<int>() ?? 0,
|
||||
jobject["sectionId"]?.ToObject<int>() ?? 0,
|
||||
jobject["description"]?.ToString() ?? "",
|
||||
jobject["linked_subnet"]?.ToString() ?? "",
|
||||
jobject["firewallAddressObject"]?.ToString() ?? "",
|
||||
jobject["vrfId"]?.ToObject<int>() ?? 0,
|
||||
jobject["masterSubnetId"]?.ToObject<int>() ?? 0,
|
||||
jobject["allowRequests"]?.ToObject<bool>() ?? false,
|
||||
jobject["vlanId"]?.ToObject<int>() ?? 0,
|
||||
jobject["showName"]?.ToObject<bool>() ?? false,
|
||||
jobject["deviceId"]?.ToObject<int>() ?? 0,
|
||||
jobject["permissions"]?.ToString() ?? "",
|
||||
jobject["pingSubnet"]?.ToObject<bool>() ?? false,
|
||||
jobject["discoverSubnet"]?.ToObject<bool>() ?? false,
|
||||
jobject["resolveDNS"]?.ToObject<bool>() ?? false,
|
||||
jobject["DNSrecursive"]?.ToObject<bool>() ?? false,
|
||||
jobject["DNSrecords"]?.ToObject<bool>() ?? false,
|
||||
jobject["nameserverId"]?.ToObject<int>() ?? 0,
|
||||
jobject["scanAgent"]?.ToObject<bool>() ?? false,
|
||||
jobject["isFolder"]?.ToObject<bool>() ?? false,
|
||||
jobject["isFull"]?.ToObject<bool>() ?? false,
|
||||
jobject["isPool"]?.ToObject<bool>() ?? false,
|
||||
jobject["state"]?.ToObject<int>() ?? 0,
|
||||
jobject["threshold"]?.ToObject<int>() ?? 0,
|
||||
jobject["location"]?.ToObject<int>() ?? 0,
|
||||
jobject["editDate"]?.ToObject<DateTime?>(),
|
||||
jobject["lastScan"]?.ToObject<DateTime?>(),
|
||||
jobject["lastDiscovery"]?.ToObject<DateTime?>(),
|
||||
jobject["calculation"]?.ToObject<object>() ?? new object(),
|
||||
customFields.Count > 0 ? customFields : null
|
||||
);
|
||||
}
|
||||
|
||||
private static Vrf CreateVrf(JObject jobject, Dictionary<string, object> customFields)
|
||||
{
|
||||
return new Vrf(
|
||||
jobject["id"]?.ToObject<int>() ?? 0,
|
||||
jobject["name"]?.ToString() ?? "",
|
||||
jobject["rd"]?.ToString() ?? "",
|
||||
jobject["description"]?.ToString() ?? "",
|
||||
jobject["sections"]?.ToString() ?? "",
|
||||
jobject["editDate"]?.ToObject<DateTime?>(),
|
||||
customFields.Count > 0 ? customFields : null
|
||||
);
|
||||
}
|
||||
|
||||
private static Section CreateSection(JObject jobject)
|
||||
{
|
||||
return new Section(
|
||||
jobject["id"]?.ToObject<int>() ?? 0,
|
||||
jobject["name"]?.ToString() ?? "",
|
||||
jobject["description"]?.ToString() ?? "",
|
||||
jobject["masterSection"]?.ToObject<int>() ?? 0,
|
||||
jobject["permissions"]?.ToString() ?? "",
|
||||
jobject["strictMode"]?.ToObject<bool>() ?? false,
|
||||
jobject["subnetOrdering"]?.ToString() ?? "",
|
||||
jobject["order"]?.ToObject<int>() ?? 0,
|
||||
jobject["editDate"]?.ToObject<DateTime?>(),
|
||||
jobject["showSubnet"]?.ToObject<bool>() ?? false,
|
||||
jobject["showVlan"]?.ToObject<bool>() ?? false,
|
||||
jobject["showVRF"]?.ToObject<bool>() ?? false,
|
||||
jobject["showSupernetOnly"]?.ToObject<bool>() ?? false,
|
||||
jobject["DNS"]?.ToObject<int>() ?? 0
|
||||
);
|
||||
}
|
||||
|
||||
private static Tag CreateTag(JObject jobject)
|
||||
{
|
||||
return new Tag(
|
||||
jobject["id"]?.ToObject<int>() ?? 0,
|
||||
jobject["type"]?.ToString() ?? "",
|
||||
jobject["showtag"]?.ToObject<bool>() ?? false,
|
||||
jobject["bgcolor"]?.ToString() ?? "",
|
||||
jobject["fgcolor"]?.ToString() ?? "",
|
||||
jobject["compress"]?.ToString() ?? "",
|
||||
jobject["locked"]?.ToString() ?? "",
|
||||
jobject["updateTag"]?.ToObject<bool>() ?? false
|
||||
);
|
||||
}
|
||||
|
||||
private static Nameserver CreateNameserver(JObject jobject)
|
||||
{
|
||||
return new Nameserver(
|
||||
jobject["id"]?.ToObject<int>() ?? 0,
|
||||
jobject["name"]?.ToString() ?? "",
|
||||
jobject["nameservers"]?.ToString() ?? "",
|
||||
jobject["description"]?.ToString() ?? "",
|
||||
jobject["permissions"]?.ToString() ?? "",
|
||||
jobject["editDate"]?.ToObject<DateTime?>()
|
||||
);
|
||||
}
|
||||
|
||||
private static Domain CreateDomain(JObject jobject)
|
||||
{
|
||||
return new Domain(
|
||||
jobject["id"]?.ToObject<int>() ?? 0,
|
||||
jobject["name"]?.ToString() ?? "",
|
||||
jobject["description"]?.ToString() ?? "",
|
||||
jobject["sections"]?.ToString() ?? ""
|
||||
);
|
||||
}
|
||||
|
||||
private static async Task UpdateSession()
|
||||
{
|
||||
var session = SessionManager.CurrentSession;
|
||||
if (session == null)
|
||||
{
|
||||
throw new Exception("No session available!");
|
||||
}
|
||||
|
||||
var tokenStatus = SessionManager.TestSession();
|
||||
if (tokenStatus == "Valid")
|
||||
{
|
||||
// Just refresh the token
|
||||
var result = await InvokeRequest("PATCH", controllers.user, null, null, null, null);
|
||||
// Token refresh doesn't return expires in the same format, so we'll skip updating expires
|
||||
return;
|
||||
}
|
||||
|
||||
if (tokenStatus == "Expired" && session.Credentials is PSCredential creds)
|
||||
{
|
||||
await SessionManager.CreateSessionWithCredentials(
|
||||
session.URL,
|
||||
session.AppID,
|
||||
creds,
|
||||
false
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user