68 lines
2.4 KiB
Swift
68 lines
2.4 KiB
Swift
// SPDX-FileCopyrightText: 2026 Kaede Akino
|
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
|
|
import Foundation
|
|
import TermindDomain
|
|
|
|
import struct TermindDomain.Host
|
|
|
|
/// Platform-neutral effects required after a remote Vault snapshot changes
|
|
/// connection-defining Host fields.
|
|
public nonisolated struct VaultRemoteChangePlan: Sendable {
|
|
public nonisolated struct HostChange: Sendable {
|
|
public let id: Host.ID
|
|
public let isRemoved: Bool
|
|
public let routeChanged: Bool
|
|
}
|
|
|
|
public let hosts: [HostChange]
|
|
public let forwardingRuleIDs: [PortForwardingRule.ID]
|
|
|
|
public static func make(
|
|
currentHosts: [Host],
|
|
snapshot: VaultSnapshot,
|
|
changedKeys: Set<VaultRecordKey>
|
|
) -> VaultRemoteChangePlan {
|
|
let current = Dictionary(uniqueKeysWithValues: currentHosts.map { ($0.id, $0) })
|
|
let next = Dictionary(uniqueKeysWithValues: snapshot.hosts.map { ($0.id, $0) })
|
|
let hosts = changedKeys.compactMap { key -> HostChange? in
|
|
guard key.kind == .host, let old = current[key.id] else { return nil }
|
|
let updated = next[key.id]
|
|
return HostChange(
|
|
id: key.id,
|
|
isRemoved: updated == nil,
|
|
routeChanged: updated.map { !old.hasSameConnectionRoute(as: $0) } ?? true
|
|
)
|
|
}
|
|
return VaultRemoteChangePlan(
|
|
hosts: hosts,
|
|
forwardingRuleIDs: changedKeys.filter { $0.kind == .portForwarding }.map(\.id)
|
|
)
|
|
}
|
|
}
|
|
|
|
extension Host {
|
|
public nonisolated func hasSameSSHConnectionRoute(as other: Host) -> Bool {
|
|
host == other.host
|
|
&& sshEnabled == other.sshEnabled
|
|
&& sshPort == other.sshPort
|
|
&& sshIdentityID == other.sshIdentityID
|
|
&& sshCharset == other.sshCharset
|
|
&& jumpHostID == other.jumpHostID
|
|
&& proxy == other.proxy
|
|
}
|
|
|
|
public nonisolated func hasSameTelnetConnection(as other: Host) -> Bool {
|
|
host == other.host
|
|
&& telnetEnabled == other.telnetEnabled
|
|
&& telnetPort == other.telnetPort
|
|
&& telnetIdentityID == other.telnetIdentityID
|
|
&& telnetCharset == other.telnetCharset
|
|
&& telnetProxy == other.telnetProxy
|
|
}
|
|
|
|
public nonisolated func hasSameConnectionRoute(as other: Host) -> Bool {
|
|
hasSameSSHConnectionRoute(as: other)
|
|
}
|
|
}
|