diff --git a/Sources/ContainerResource/Network/Attachment.swift b/Sources/ContainerResource/Network/Attachment.swift index ada29d9f5..9cc5224ce 100644 --- a/Sources/ContainerResource/Network/Attachment.swift +++ b/Sources/ContainerResource/Network/Attachment.swift @@ -51,4 +51,49 @@ public struct Attachment: Codable, Sendable { self.macAddress = macAddress self.mtu = mtu } + + enum CodingKeys: String, CodingKey { + case network + case hostname + case ipv4Address + case ipv4Gateway + case ipv6Address + case macAddress + // TODO: retain for deserialization compatibility for now, remove later + case address + case gateway + } + + /// Create a configuration from the supplied Decoder, initializing missing + /// values where possible to reasonable defaults. + public init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + + network = try container.decode(String.self, forKey: .network) + hostname = try container.decode(String.self, forKey: .hostname) + if let address = try? container.decode(CIDRv4.self, forKey: .ipv4Address) { + ipv4Address = address + } else { + ipv4Address = try container.decode(CIDRv4.self, forKey: .address) + } + if let gateway = try? container.decode(IPv4Address.self, forKey: .ipv4Gateway) { + ipv4Gateway = gateway + } else { + ipv4Gateway = try container.decode(IPv4Address.self, forKey: .gateway) + } + ipv6Address = try container.decodeIfPresent(CIDRv6.self, forKey: .ipv6Address) + macAddress = try container.decodeIfPresent(MACAddress.self, forKey: .macAddress) + } + + /// Encode the configuration to the supplied Encoder. + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + + try container.encode(network, forKey: .network) + try container.encode(hostname, forKey: .hostname) + try container.encode(ipv4Address, forKey: .ipv4Address) + try container.encode(ipv4Gateway, forKey: .ipv4Gateway) + try container.encodeIfPresent(ipv6Address, forKey: .ipv6Address) + try container.encodeIfPresent(macAddress, forKey: .macAddress) + } } diff --git a/Sources/ContainerResource/Network/NetworkConfiguration.swift b/Sources/ContainerResource/Network/NetworkConfiguration.swift index a5e277cae..930b9c3bb 100644 --- a/Sources/ContainerResource/Network/NetworkConfiguration.swift +++ b/Sources/ContainerResource/Network/NetworkConfiguration.swift @@ -80,7 +80,7 @@ public struct NetworkConfiguration: Codable, Sendable, Identifiable { case ipv6Subnet case labels case pluginInfo - // TODO: retain for deserialization compatability for now, remove later + // TODO: retain for deserialization compatibility for now, remove later case subnet } diff --git a/Sources/ContainerResource/Network/NetworkState.swift b/Sources/ContainerResource/Network/NetworkState.swift index db5ba7d64..2c219ea0d 100644 --- a/Sources/ContainerResource/Network/NetworkState.swift +++ b/Sources/ContainerResource/Network/NetworkState.swift @@ -39,6 +39,43 @@ public struct NetworkStatus: Codable, Sendable { self.ipv4Gateway = ipv4Gateway self.ipv6Subnet = ipv6Subnet } + + enum CodingKeys: String, CodingKey { + case ipv4Subnet + case ipv4Gateway + case ipv6Subnet + // TODO: retain for deserialization compatibility for now, remove later + case address + case gateway + } + + /// Create a configuration from the supplied Decoder, initializing missing + /// values where possible to reasonable defaults. + public init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + + if let address = try? container.decode(CIDRv4.self, forKey: .ipv4Subnet) { + ipv4Subnet = address + } else { + ipv4Subnet = try container.decode(CIDRv4.self, forKey: .address) + } + if let gateway = try? container.decode(IPv4Address.self, forKey: .ipv4Gateway) { + ipv4Gateway = gateway + } else { + ipv4Gateway = try container.decode(IPv4Address.self, forKey: .gateway) + } + ipv6Subnet = try container.decodeIfPresent(String.self, forKey: .ipv6Subnet) + .map { try CIDRv6($0) } + } + + /// Encode the configuration to the supplied Encoder. + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + + try container.encode(ipv4Subnet, forKey: .ipv4Subnet) + try container.encode(ipv4Gateway, forKey: .ipv4Gateway) + try container.encodeIfPresent(ipv6Subnet, forKey: .ipv6Subnet) + } } /// The configuration and runtime attributes for a network.