From 59e015acd1eca08b0e87bd18e80e2f392a278581 Mon Sep 17 00:00:00 2001 From: J Logan Date: Thu, 4 Jun 2026 13:03:29 -0700 Subject: [PATCH] Use `name` instead of `id` in `NetworkConfiguration`. (#1648) - Closes #1647. - `id` will become a system assigned (Docker-like) identifier for the managed resource, and `configuration.name` is the user-assigned name. --- Sources/APIServer/APIServer+Start.swift | 2 +- .../Network/NetworkCreate.swift | 2 +- .../Network/NetworkConfiguration.swift | 24 ++++++++++++------- .../Network/NetworkResource.swift | 6 ++--- .../NetworkVmnetHelper+Start.swift | 2 +- .../Server/Networks/NetworksService.swift | 6 ++--- .../NetworkConfigurationTest.swift | 8 +++---- 7 files changed, 29 insertions(+), 21 deletions(-) diff --git a/Sources/APIServer/APIServer+Start.swift b/Sources/APIServer/APIServer+Start.swift index 5be105d4..21a0dcbe 100644 --- a/Sources/APIServer/APIServer+Start.swift +++ b/Sources/APIServer/APIServer+Start.swift @@ -334,7 +334,7 @@ extension APIServer { if defaultNetwork == nil { // FIXME: default network should be configurable elsewhere let config = try NetworkConfiguration( - id: NetworkClient.defaultNetworkName, + name: NetworkClient.defaultNetworkName, mode: .nat, ipv4Subnet: containerSystemConfig.network.subnet, ipv6Subnet: containerSystemConfig.network.subnetv6, diff --git a/Sources/ContainerCommands/Network/NetworkCreate.swift b/Sources/ContainerCommands/Network/NetworkCreate.swift index 170cbaf3..2278fb38 100644 --- a/Sources/ContainerCommands/Network/NetworkCreate.swift +++ b/Sources/ContainerCommands/Network/NetworkCreate.swift @@ -67,7 +67,7 @@ extension Application { let parsedOptions = Utility.parseKeyValuePairs(options) let mode: NetworkMode = hostOnly ? .hostOnly : .nat let config = try NetworkConfiguration( - id: self.name, + name: self.name, mode: mode, ipv4Subnet: ipv4Subnet, ipv6Subnet: ipv6Subnet, diff --git a/Sources/ContainerResource/Network/NetworkConfiguration.swift b/Sources/ContainerResource/Network/NetworkConfiguration.swift index be1bbaf7..7678c471 100644 --- a/Sources/ContainerResource/Network/NetworkConfiguration.swift +++ b/Sources/ContainerResource/Network/NetworkConfiguration.swift @@ -20,8 +20,11 @@ import Foundation /// Configuration parameters for network creation. public struct NetworkConfiguration: Codable, Sendable, Identifiable { - /// A unique identifier for the network - public let id: String + /// The name of the network. + public let name: String + + /// The unique identifier for the network. Identical to ``name``. + public var id: String { name } /// The network type public let mode: NetworkMode @@ -47,7 +50,7 @@ public struct NetworkConfiguration: Codable, Sendable, Identifiable { /// Creates a network configuration public init( - id: String, + name: String, mode: NetworkMode, ipv4Subnet: CIDRv4? = nil, ipv6Subnet: CIDRv6? = nil, @@ -55,7 +58,7 @@ public struct NetworkConfiguration: Codable, Sendable, Identifiable { plugin: String, options: [String: String] = [:] ) throws { - self.id = id + self.name = name self.creationDate = Date() self.mode = mode self.ipv4Subnet = ipv4Subnet @@ -67,6 +70,9 @@ public struct NetworkConfiguration: Codable, Sendable, Identifiable { } enum CodingKeys: String, CodingKey { + case name + // Deprecated: As of 1.0.0. Use ``name`` instead of ``id``. + // Note: Will be removed in a later release. case id case creationDate case mode @@ -85,7 +91,9 @@ public struct NetworkConfiguration: Codable, Sendable, Identifiable { public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - id = try container.decode(String.self, forKey: .id) + name = + try container.decodeIfPresent(String.self, forKey: .name) + ?? container.decode(String.self, forKey: .id) creationDate = try container.decodeIfPresent(Date.self, forKey: .creationDate) ?? Date(timeIntervalSince1970: 0) mode = try container.decode(NetworkMode.self, forKey: .mode) let subnetText = @@ -119,7 +127,7 @@ public struct NetworkConfiguration: Codable, Sendable, Identifiable { public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) - try container.encode(id, forKey: .id) + try container.encode(name, forKey: .name) try container.encode(creationDate, forKey: .creationDate) try container.encode(mode, forKey: .mode) try container.encodeIfPresent(ipv4Subnet, forKey: .ipv4Subnet) @@ -130,8 +138,8 @@ public struct NetworkConfiguration: Codable, Sendable, Identifiable { } private func validate() throws { - guard NetworkResource.nameValid(id) else { - throw ContainerizationError(.invalidArgument, message: "invalid network ID: \(id)") + guard NetworkResource.nameValid(name) else { + throw ContainerizationError(.invalidArgument, message: "invalid network name: \(name)") } } } diff --git a/Sources/ContainerResource/Network/NetworkResource.swift b/Sources/ContainerResource/Network/NetworkResource.swift index 9699a390..249c6069 100644 --- a/Sources/ContainerResource/Network/NetworkResource.swift +++ b/Sources/ContainerResource/Network/NetworkResource.swift @@ -35,11 +35,11 @@ public struct NetworkResource: ManagedResource { // MARK: ManagedResource - /// The unique identifier for this network. Identical to ``configuration/id``. - public var id: String { configuration.id } + /// The unique identifier for this network. Identical to ``configuration/name``. + public var id: String { configuration.name } /// The user-assigned name for this network. For networks, name and ID are the same. - public var name: String { configuration.id } + public var name: String { configuration.name } /// The time at which this network was created. public var creationDate: Date { configuration.creationDate } diff --git a/Sources/Plugins/NetworkVmnet/NetworkVmnetHelper+Start.swift b/Sources/Plugins/NetworkVmnet/NetworkVmnetHelper+Start.swift index 99493348..7d67f1f3 100644 --- a/Sources/Plugins/NetworkVmnet/NetworkVmnetHelper+Start.swift +++ b/Sources/Plugins/NetworkVmnet/NetworkVmnetHelper+Start.swift @@ -84,7 +84,7 @@ extension NetworkVmnetHelper { let ipv6Subnet = try self.ipv6Subnet.map { try CIDRv6($0) } let configuration = try NetworkConfiguration( - id: id, + name: id, mode: mode, ipv4Subnet: ipv4Subnet, ipv6Subnet: ipv6Subnet, diff --git a/Sources/Services/ContainerAPIService/Server/Networks/NetworksService.swift b/Sources/Services/ContainerAPIService/Server/Networks/NetworksService.swift index 92655d22..ac21b524 100644 --- a/Sources/Services/ContainerAPIService/Server/Networks/NetworksService.swift +++ b/Sources/Services/ContainerAPIService/Server/Networks/NetworksService.swift @@ -91,7 +91,7 @@ public actor NetworksService { if let updatedLabels { let updatedConfiguration = try NetworkConfiguration( - id: configuration.id, + name: configuration.name, mode: configuration.mode, ipv4Subnet: configuration.ipv4Subnet, ipv6Subnet: configuration.ipv6Subnet, @@ -114,7 +114,7 @@ public actor NetworksService { let finalConfiguration = updatedLabels.flatMap { labels in try? NetworkConfiguration( - id: configuration.id, + name: configuration.name, mode: configuration.mode, ipv4Subnet: configuration.ipv4Subnet, ipv6Subnet: configuration.ipv6Subnet, @@ -195,7 +195,7 @@ public actor NetworksService { let networkStatus = try await client.status() let finalConfiguration = try NetworkConfiguration( - id: configuration.id, + name: configuration.name, mode: configuration.mode, ipv4Subnet: configuration.ipv4Subnet, ipv6Subnet: configuration.ipv6Subnet, diff --git a/Tests/ContainerResourceTests/NetworkConfigurationTest.swift b/Tests/ContainerResourceTests/NetworkConfigurationTest.swift index dfbaf864..e3fd1faa 100644 --- a/Tests/ContainerResourceTests/NetworkConfigurationTest.swift +++ b/Tests/ContainerResourceTests/NetworkConfigurationTest.swift @@ -24,7 +24,7 @@ struct NetworkConfigurationTest { @Test func testValidationOkDefaults() throws { let id = "foo" _ = try NetworkConfiguration( - id: id, + name: id, mode: .nat, plugin: "container-network-vmnet" ) @@ -43,7 +43,7 @@ struct NetworkConfigurationTest { "baz": String(repeating: "0", count: 4096 - "baz".count - "=".count), ]) _ = try NetworkConfiguration( - id: id, + name: id, mode: .nat, ipv4Subnet: ipv4Subnet, labels: labels, @@ -67,7 +67,7 @@ struct NetworkConfigurationTest { ]) #expect { _ = try NetworkConfiguration( - id: id, + name: id, mode: .nat, ipv4Subnet: ipv4Subnet, labels: labels, @@ -76,7 +76,7 @@ struct NetworkConfigurationTest { } throws: { error in guard let err = error as? ContainerizationError else { return false } #expect(err.code == .invalidArgument) - #expect(err.message.starts(with: "invalid network ID")) + #expect(err.message.starts(with: "invalid network name")) return true } }