using Microsoft.AspNetCore.Mvc;
using NewLife;
using Rainbow.Entity;
using Rainbow.Services;
using XCode;
namespace Rainbow.Web.Controllers;
/// <summary>DHCP 服务管理 API</summary>
[ApiController]
[Route("api/dhcp")]
public class DhcpController : ControllerBase
{
private readonly DnsmasqManager _dnsmasqManager;
/// <summary>构造 DHCP 控制器</summary>
/// <param name="dnsmasqManager">Dnsmasq 配置管理器</param>
public DhcpController(DnsmasqManager dnsmasqManager) => _dnsmasqManager = dnsmasqManager;
/// <summary>获取所有地址池</summary>
[HttpGet("pool")]
public ActionResult<IList<DhcpPool>> GetPools([FromQuery] String? iface = null)
{
if (!iface.IsNullOrEmpty())
{
return Ok(DhcpPool.FindAll(
DhcpPool._.Interface == iface & DhcpPool._.Enable == true));
}
return Ok(DhcpPool.FindAllWithCache());
}
/// <summary>保存地址池(新增或更新)</summary>
[HttpPost("pool")]
public ActionResult SavePool([FromBody] DhcpPool pool)
{
var existing = DhcpPool.Find(DhcpPool._.Name == pool.Name);
if (existing != null)
{
existing.Netmask = pool.Netmask;
existing.RangeStart = pool.RangeStart;
existing.RangeEnd = pool.RangeEnd;
existing.Gateway = pool.Gateway;
existing.LeaseTime = pool.LeaseTime;
existing.DnsServers = pool.DnsServers;
existing.Interface = pool.Interface;
existing.Enable = pool.Enable;
existing.Update();
}
else
{
pool.Insert();
}
TryApplyDnsmasq();
return Ok(new { success = true });
}
/// <summary>为指定接口创建默认 DHCP 地址池</summary>
[HttpPost("pool/for-interface")]
public ActionResult CreatePoolForInterface([FromBody] InterfacePoolDto dto)
{
if (dto.Interface.IsNullOrEmpty())
return BadRequest(new { error = "接口名不能为空" });
// 检查是否已存在
var existing = DhcpPool.Find(DhcpPool._.Interface == dto.Interface);
if (existing != null)
return Ok(new { success = true, message = "已存在", pool = existing });
// 根据接口 IP 推断网段
var gateway = dto.Gateway.IsNullOrEmpty() ? "192.168.100.1" : dto.Gateway;
var parts = gateway.Split('.');
if (parts.Length == 4)
parts[3] = "100";
var rangeStart = dto.RangeStart.IsNullOrEmpty() ? String.Join(".", parts) : dto.RangeStart;
parts[3] = "200";
var rangeEnd = dto.RangeEnd.IsNullOrEmpty() ? String.Join(".", parts) : dto.RangeEnd;
var pool = new DhcpPool
{
Name = $"dhcp_{dto.Interface}",
Interface = dto.Interface,
Netmask = dto.Netmask.IsNullOrEmpty() ? "255.255.255.0" : dto.Netmask,
RangeStart = rangeStart,
RangeEnd = rangeEnd,
Gateway = gateway,
LeaseTime = dto.LeaseTime > 0 ? dto.LeaseTime : 86400,
DnsServers = dto.DnsServers.IsNullOrEmpty() ? gateway : dto.DnsServers,
Enable = true
};
pool.Insert();
TryApplyDnsmasq();
return Ok(new { success = true, pool });
}
/// <summary>尝试应用 dnsmasq 配置(最佳努力)</summary>
private void TryApplyDnsmasq()
{
_ = Task.Run(async () =>
{
try
{
await _dnsmasqManager.ApplyAsync();
}
catch { }
});
}
}
/// <summary>接口 DHCP 池请求</summary>
public class InterfacePoolDto
{
public String? Interface { get; set; }
public String? Gateway { get; set; }
public String? Netmask { get; set; }
public String? RangeStart { get; set; }
public String? RangeEnd { get; set; }
public Int32 LeaseTime { get; set; }
public String? DnsServers { get; set; }
}
|