ServiceSubnetsUseCase.cs 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. using RackPeek.Domain.Resources.Services.Networking;
  2. namespace RackPeek.Domain.Resources.Services.UseCases;
  3. public class ServiceSubnetsUseCase(IServiceRepository repo) : IUseCase
  4. {
  5. public async Task<ServiceSubnetsResult> ExecuteAsync(string? cidr, int? prefix, CancellationToken token)
  6. {
  7. var services = await repo.GetAllAsync();
  8. // If CIDR is provided → filter mode
  9. if (cidr is not null)
  10. {
  11. Cidr parsed;
  12. try
  13. {
  14. parsed = Cidr.Parse(cidr);
  15. }
  16. catch
  17. {
  18. return ServiceSubnetsResult.InvalidCidr(cidr);
  19. }
  20. var matches = services
  21. .Where(s => s.Network?.Ip != null)
  22. .Where(s => parsed.Contains(IpHelper.ToUInt32(s.Network!.Ip!)))
  23. .Select(s => new ServiceSummary(
  24. s.Name,
  25. s.Network!.Ip!,
  26. s.RunsOn))
  27. .ToList();
  28. return ServiceSubnetsResult.FromServices(matches, parsed.ToString());
  29. }
  30. // No CIDR → subnet discovery mode
  31. var effectivePrefix = prefix ?? 24;
  32. var mask = IpHelper.MaskFromPrefix(effectivePrefix);
  33. var groups = services
  34. .Where(s => s.Network?.Ip != null)
  35. .Select(s => IpHelper.ToUInt32(s.Network!.Ip!))
  36. .GroupBy(ip => ip & mask)
  37. .Select(g => new SubnetSummary(
  38. $"{IpHelper.ToIp(g.Key)}/{effectivePrefix}",
  39. g.Count()))
  40. .OrderBy(s => s.Cidr)
  41. .ToList();
  42. return ServiceSubnetsResult.FromSubnets(groups);
  43. }
  44. }
  45. public record SubnetSummary(string Cidr, int Count);
  46. public record ServiceSummary(string Name, string Ip, string? RunsOn);
  47. public class ServiceSubnetsResult
  48. {
  49. public bool IsInvalidCidr { get; private set; }
  50. public string? InvalidCidrValue { get; private set; }
  51. public string? FilteredCidr { get; private set; }
  52. public List<SubnetSummary> Subnets { get; private set; } = new();
  53. public List<ServiceSummary> Services { get; private set; } = new();
  54. public static ServiceSubnetsResult InvalidCidr(string cidr)
  55. {
  56. return new ServiceSubnetsResult { IsInvalidCidr = true, InvalidCidrValue = cidr };
  57. }
  58. public static ServiceSubnetsResult FromSubnets(List<SubnetSummary> subnets)
  59. {
  60. return new ServiceSubnetsResult { Subnets = subnets };
  61. }
  62. public static ServiceSubnetsResult FromServices(List<ServiceSummary> services, string cidr)
  63. {
  64. return new ServiceSubnetsResult { Services = services, FilteredCidr = cidr };
  65. }
  66. }