Skip to main content

unifly_api/command/
mod.rs

1// ── Command API ──
2//
3// All write operations flow through a unified `Command` enum.
4// The controller routes each variant to the appropriate API backend
5// (Integration API preferred, Session API for session-only operations).
6
7pub mod requests;
8
9use crate::core_error::CoreError;
10use crate::model::{
11    AclRule, Client, Device, DnsPolicy, EntityId, FirewallPolicy, FirewallZone, MacAddress,
12    Network, TrafficMatchingList, Voucher, WifiBroadcast,
13};
14
15pub use requests::{
16    CreateAclRuleRequest, CreateDnsPolicyRequest, CreateFirewallPolicyRequest,
17    CreateFirewallZoneRequest, CreateNatPolicyRequest, CreateNetworkRequest,
18    CreateRemoteAccessVpnServerRequest, CreateSiteToSiteVpnRequest,
19    CreateTrafficMatchingListRequest, CreateVouchersRequest, CreateVpnClientProfileRequest,
20    CreateWifiBroadcastRequest, CreateWireGuardPeerRequest, TrafficFilterSpec,
21    UpdateAclRuleRequest, UpdateDnsPolicyRequest, UpdateFirewallPolicyRequest,
22    UpdateFirewallZoneRequest, UpdateNetworkRequest, UpdateRemoteAccessVpnServerRequest,
23    UpdateSiteToSiteVpnRequest, UpdateTrafficMatchingListRequest, UpdateVpnClientProfileRequest,
24    UpdateWifiBroadcastRequest, UpdateWireGuardPeerRequest,
25};
26
27/// A command envelope sent through the command channel.
28/// Contains the command and a oneshot response channel.
29pub(crate) struct CommandEnvelope {
30    pub command: Command,
31    pub response_tx: tokio::sync::oneshot::Sender<Result<CommandResult, CoreError>>,
32}
33
34/// All possible write operations against a UniFi controller.
35#[derive(Debug, Clone)]
36pub enum Command {
37    // ── Device operations ────────────────────────────────────────────
38    AdoptDevice {
39        mac: MacAddress,
40        ignore_device_limit: bool,
41    },
42    RemoveDevice {
43        id: EntityId,
44    },
45    RestartDevice {
46        id: EntityId,
47    },
48    LocateDevice {
49        mac: MacAddress,
50        enable: bool,
51    },
52    UpgradeDevice {
53        mac: MacAddress,
54        firmware_url: Option<String>,
55    },
56    ProvisionDevice {
57        mac: MacAddress,
58    },
59    SpeedtestDevice,
60    PowerCyclePort {
61        device_id: EntityId,
62        port_idx: u32,
63    },
64
65    // ── Client operations ────────────────────────────────────────────
66    BlockClient {
67        mac: MacAddress,
68    },
69    UnblockClient {
70        mac: MacAddress,
71    },
72    KickClient {
73        mac: MacAddress,
74    },
75    ForgetClient {
76        mac: MacAddress,
77    },
78    AuthorizeGuest {
79        client_id: EntityId,
80        time_limit_minutes: Option<u32>,
81        data_limit_mb: Option<u64>,
82        rx_rate_kbps: Option<u64>,
83        tx_rate_kbps: Option<u64>,
84    },
85    UnauthorizeGuest {
86        client_id: EntityId,
87    },
88    SetClientFixedIp {
89        mac: MacAddress,
90        ip: std::net::Ipv4Addr,
91        network_id: EntityId,
92    },
93    RemoveClientFixedIp {
94        mac: MacAddress,
95        network_id: Option<EntityId>,
96    },
97
98    // ── Network CRUD ─────────────────────────────────────────────────
99    CreateNetwork(CreateNetworkRequest),
100    UpdateNetwork {
101        id: EntityId,
102        update: UpdateNetworkRequest,
103    },
104    DeleteNetwork {
105        id: EntityId,
106        force: bool,
107    },
108
109    // ── WiFi CRUD ────────────────────────────────────────────────────
110    CreateWifiBroadcast(CreateWifiBroadcastRequest),
111    UpdateWifiBroadcast {
112        id: EntityId,
113        update: UpdateWifiBroadcastRequest,
114    },
115    DeleteWifiBroadcast {
116        id: EntityId,
117        force: bool,
118    },
119
120    // ── Firewall ─────────────────────────────────────────────────────
121    CreateFirewallPolicy(CreateFirewallPolicyRequest),
122    UpdateFirewallPolicy {
123        id: EntityId,
124        update: UpdateFirewallPolicyRequest,
125    },
126    DeleteFirewallPolicy {
127        id: EntityId,
128    },
129    PatchFirewallPolicy {
130        id: EntityId,
131        enabled: Option<bool>,
132        logging: Option<bool>,
133    },
134    ReorderFirewallPolicies {
135        zone_pair: (EntityId, EntityId),
136        ordered_ids: Vec<EntityId>,
137        after_system: bool,
138    },
139    CreateFirewallZone(CreateFirewallZoneRequest),
140    UpdateFirewallZone {
141        id: EntityId,
142        update: UpdateFirewallZoneRequest,
143    },
144    DeleteFirewallZone {
145        id: EntityId,
146    },
147
148    // ── NAT ──────────────────────────────────────────────────────────
149    CreateNatPolicy(CreateNatPolicyRequest),
150    DeleteNatPolicy {
151        id: EntityId,
152    },
153
154    // ── VPN (Legacy) ────────────────────────────────────────────────
155    CreateSiteToSiteVpn(CreateSiteToSiteVpnRequest),
156    UpdateSiteToSiteVpn {
157        id: EntityId,
158        update: UpdateSiteToSiteVpnRequest,
159    },
160    DeleteSiteToSiteVpn {
161        id: EntityId,
162    },
163    CreateRemoteAccessVpnServer(CreateRemoteAccessVpnServerRequest),
164    UpdateRemoteAccessVpnServer {
165        id: EntityId,
166        update: UpdateRemoteAccessVpnServerRequest,
167    },
168    DeleteRemoteAccessVpnServer {
169        id: EntityId,
170    },
171    CreateVpnClientProfile(CreateVpnClientProfileRequest),
172    UpdateVpnClientProfile {
173        id: EntityId,
174        update: UpdateVpnClientProfileRequest,
175    },
176    DeleteVpnClientProfile {
177        id: EntityId,
178    },
179    CreateWireGuardPeer {
180        server_id: EntityId,
181        peer: CreateWireGuardPeerRequest,
182    },
183    UpdateWireGuardPeer {
184        server_id: EntityId,
185        peer_id: EntityId,
186        update: UpdateWireGuardPeerRequest,
187    },
188    DeleteWireGuardPeer {
189        server_id: EntityId,
190        peer_id: EntityId,
191    },
192    RestartVpnClientConnection {
193        id: EntityId,
194    },
195
196    // ── ACL ──────────────────────────────────────────────────────────
197    CreateAclRule(CreateAclRuleRequest),
198    UpdateAclRule {
199        id: EntityId,
200        update: UpdateAclRuleRequest,
201    },
202    DeleteAclRule {
203        id: EntityId,
204    },
205    ReorderAclRules {
206        ordered_ids: Vec<EntityId>,
207    },
208
209    // ── DNS ──────────────────────────────────────────────────────────
210    CreateDnsPolicy(CreateDnsPolicyRequest),
211    UpdateDnsPolicy {
212        id: EntityId,
213        update: UpdateDnsPolicyRequest,
214    },
215    DeleteDnsPolicy {
216        id: EntityId,
217    },
218
219    // ── Traffic matching lists ───────────────────────────────────────
220    CreateTrafficMatchingList(CreateTrafficMatchingListRequest),
221    UpdateTrafficMatchingList {
222        id: EntityId,
223        update: UpdateTrafficMatchingListRequest,
224    },
225    DeleteTrafficMatchingList {
226        id: EntityId,
227    },
228
229    // ── Hotspot / Vouchers ───────────────────────────────────────────
230    CreateVouchers(CreateVouchersRequest),
231    DeleteVoucher {
232        id: EntityId,
233    },
234    PurgeVouchers {
235        filter: String,
236    },
237
238    // ── Site settings (Session) ─────────────────────────────────────────
239    SetDpiEnabled {
240        enabled: bool,
241    },
242
243    // ── System (Session) ──────────────────────────────────────────────
244    ArchiveAlarm {
245        id: EntityId,
246    },
247    ArchiveAllAlarms,
248    CreateSite {
249        name: String,
250        description: String,
251    },
252    DeleteSite {
253        name: String,
254    },
255    CreateBackup,
256    DeleteBackup {
257        filename: String,
258    },
259    RebootController,
260    PoweroffController,
261    InviteAdmin {
262        name: String,
263        email: String,
264        role: String,
265    },
266    RevokeAdmin {
267        id: EntityId,
268    },
269    UpdateAdmin {
270        id: EntityId,
271        role: Option<String>,
272    },
273}
274
275/// Result of a command execution.
276#[derive(Debug)]
277pub enum CommandResult {
278    Ok,
279    Device(Device),
280    Client(Client),
281    Network(Network),
282    WifiBroadcast(WifiBroadcast),
283    FirewallPolicy(FirewallPolicy),
284    FirewallZone(FirewallZone),
285    AclRule(AclRule),
286    DnsPolicy(DnsPolicy),
287    Vouchers(Vec<Voucher>),
288    TrafficMatchingList(TrafficMatchingList),
289}