using Microsoft.AspNetCore.Mvc;
using NewLife;
using Rainbow.Services;
namespace Rainbow.Web.Controllers;
/// <summary>VLAN 管理 API。通过 ip link 管理 VLAN 接口</summary>
[ApiController]
[Route("api/vlan")]
public class VlanController : ControllerBase
{
private readonly ShellExecutor _shell;
/// <summary>实例化</summary>
public VlanController(ShellExecutor shell) => _shell = shell;
/// <summary>获取 VLAN 接口列表</summary>
[HttpGet]
public async Task<ActionResult> GetVlans()
{
var result = await _shell.ExecuteAsync("ip", "-d link show type vlan");
var vlans = new List<Object>();
if (result.Success && !result.Stdout.IsNullOrEmpty())
{
var lines = result.Stdout.Split('\n');
for (var i = 0; i < lines.Length; i++)
{
var line = lines[i].Trim();
if (!line.Contains("vlan")) continue;
var idx = line.IndexOf(':');
var ifName = idx > 0 ? line.Substring(0, idx).Trim() : "";
var vlanId = "";
var vlanIdx = line.IndexOf("id ");
if (vlanIdx > 0)
vlanId = line.Substring(vlanIdx + 3).Split(' ')[0].Trim();
vlans.Add(new { name = ifName, vlanId, raw = line });
}
}
return Ok(vlans);
}
/// <summary>创建 VLAN 接口</summary>
[HttpPost]
public async Task<ActionResult> CreateVlan([FromBody] VlanDto dto)
{
if (dto.ParentInterface.IsNullOrEmpty() || dto.VlanId <= 0)
return BadRequest(new { error = "父接口和 VLAN ID 为必填" });
var ifName = $"{dto.ParentInterface}.{dto.VlanId}";
var args = $"link add link {dto.ParentInterface} name {ifName} type vlan id {dto.VlanId}";
var result = await _shell.ExecuteAsync("ip", args);
if (!result.Success)
return BadRequest(new { error = result.Stderr ?? "创建 VLAN 失败" });
if (!dto.IpAddress.IsNullOrEmpty())
await _shell.ExecuteAsync("ip", $"addr add {dto.IpAddress} dev {ifName}");
await _shell.ExecuteAsync("ip", $"link set {ifName} up");
return Ok(new { success = true, name = ifName, vlanId = dto.VlanId });
}
/// <summary>删除 VLAN 接口</summary>
[HttpDelete("{name}")]
public async Task<ActionResult> DeleteVlan(String name)
{
if (name.IsNullOrEmpty()) return BadRequest(new { error = "接口名不能为空" });
await _shell.ExecuteAsync("ip", $"link set {name} down");
var result = await _shell.ExecuteAsync("ip", $"link delete {name}");
if (!result.Success)
return BadRequest(new { error = result.Stderr ?? "删除 VLAN 失败" });
return Ok(new { success = true });
}
}
/// <summary>VLAN 创建 DTO</summary>
public class VlanDto
{
public String ParentInterface { get; set; } = "";
public Int32 VlanId { get; set; }
public String? IpAddress { get; set; }
}
|