refactor: 枚举移入Models目录,命名空间更新为Rainbow.Entity.Models
大石头 authored at 2026-07-02 12:54:58
2.97 KiB
RainbowBridge
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; }
}