Skip to content

Commit d6abdf7

Browse files
nefilimnefilim
andauthored
Refactor configuration builers and add support for overriding the current k8s context (#47)
* Refactor configuration builers and add support for overriding the current k8s context * reformatted with tab indents * reformatted swift-format * Refactor KubeConfigLoader as KubeConfig extensions * Clean up comments * Add back a few convenience functions * swiftformat --------- Co-authored-by: nefilim <nefilim@nefilim.org>
1 parent 5a40aaa commit d6abdf7

File tree

3 files changed

+309
-276
lines changed

3 files changed

+309
-276
lines changed

Sources/SwiftkubeClient/Client/KubernetesClient.swift

Lines changed: 19 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -104,56 +104,6 @@ public actor KubernetesClient {
104104
}()
105105
#endif
106106

107-
/// Create a new instance of the Kubernetes client.
108-
///
109-
/// The client tries to resolve a `kube config` automatically from different sources in the following order:
110-
///
111-
/// - A Kube config file at path of environment variable `KUBECONFIG` (if set)
112-
/// - A Kube config file in the user's `$HOME/.kube/config` directory
113-
/// - `ServiceAccount` token located at `/var/run/secrets/kubernetes.io/serviceaccount/token` and a mounted CA certificate, if it's running in Kubernetes.
114-
///
115-
/// Returns `nil` if a configuration can't be found.
116-
///
117-
/// - Parameters:
118-
/// - provider: A ``EventLoopGroupProvider`` to specify how ``EventLoopGroup`` will be created.
119-
/// - logger: The logger to use for this client.
120-
public init?(
121-
provider: HTTPClient.EventLoopGroupProvider = .shared(MultiThreadedEventLoopGroup(numberOfThreads: 1)),
122-
logger: Logger? = nil
123-
) {
124-
let logger = logger ?? SwiftkubeClient.loggingDisabled
125-
126-
guard
127-
let config = KubernetesClientConfig.initialize(logger: logger)
128-
else {
129-
return nil
130-
}
131-
132-
self.init(config: config, provider: provider, logger: logger)
133-
}
134-
135-
/// Create a new instance of the Kubernetes client.
136-
///
137-
/// - Parameters:
138-
/// - url: The url to load the configuration from for this client instance. It can be a local file or remote URL.
139-
/// - provider: A ``EventLoopGroupProvider`` to specify how ``EventLoopGroup`` will be created.
140-
/// - logger: The logger to use for this client.
141-
public init?(
142-
fromURL url: URL,
143-
provider: HTTPClient.EventLoopGroupProvider = .shared(MultiThreadedEventLoopGroup(numberOfThreads: 1)),
144-
logger: Logger? = nil
145-
) {
146-
let logger = logger ?? SwiftkubeClient.loggingDisabled
147-
148-
guard
149-
let config = KubernetesClientConfig.create(fromUrl: url, logger: logger)
150-
else {
151-
return nil
152-
}
153-
154-
self.init(config: config, provider: provider, logger: logger)
155-
}
156-
157107
/// Create a new instance of the Kubernetes client.
158108
///
159109
/// - Parameters:
@@ -216,6 +166,25 @@ public actor KubernetesClient {
216166
)
217167
}
218168

169+
public static func forContext(
170+
context: String,
171+
provider: HTTPClient.EventLoopGroupProvider = .shared(MultiThreadedEventLoopGroup(numberOfThreads: 1)),
172+
logger: Logger? = nil
173+
) throws -> KubernetesClient? {
174+
try KubeConfig.fromLocalEnvironment()
175+
.flatMap { try KubernetesClientConfig.from(kubeConfig: $0, context: context, logger: logger) }
176+
.map { KubernetesClient(config: $0) }
177+
}
178+
179+
public static func forCurrentContext(
180+
provider: HTTPClient.EventLoopGroupProvider = .shared(MultiThreadedEventLoopGroup(numberOfThreads: 1)),
181+
logger: Logger? = nil
182+
) throws -> KubernetesClient? {
183+
try KubeConfig.fromLocalEnvironment()
184+
.flatMap { try KubernetesClientConfig.from(kubeConfig: $0, logger: logger) }
185+
.map { KubernetesClient(config: $0) }
186+
}
187+
219188
/// Shuts down the client gracefully.
220189
///
221190
/// This function uses a completion instead of an EventLoopFuture, because the underlying event loop will be closed

Sources/SwiftkubeClient/Config/KubeConfig.swift

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
//
1616

1717
import Foundation
18+
import Logging
19+
import NIOSSL
20+
import Yams
1821

1922
// MARK: - KubeConfig
2023

@@ -49,6 +52,35 @@ public struct KubeConfig: Codable, Sendable {
4952
public var currentContext: String?
5053
}
5154

55+
public extension KubeConfig {
56+
57+
static func from(config: String) throws -> KubeConfig {
58+
let decoder = YAMLDecoder()
59+
60+
return try decoder.decode(KubeConfig.self, from: config)
61+
}
62+
63+
static func from(url: URL) throws -> KubeConfig {
64+
let contents = try String(contentsOf: url, encoding: .utf8)
65+
66+
return try from(config: contents)
67+
}
68+
69+
static func fromLocalEnvironment(envVar: String = "KUBECONFIG", logger: Logger? = nil) throws -> KubeConfig? {
70+
let kubeConfigURL: URL? = ProcessInfo.processInfo.environment[envVar].map { URL(fileURLWithPath: $0) } ?? ProcessInfo.processInfo.environment["HOME"].map { URL(fileURLWithPath: $0 + "/.kube/config") }
71+
72+
guard let kubeConfigURL else {
73+
logger?.warning(
74+
"Skipping local kubeconfig loading, neither environment variable KUBECONFIG nor HOME are set."
75+
)
76+
return nil
77+
}
78+
logger?.info("Loading configuration from \(kubeConfigURL)")
79+
80+
return try from(url: kubeConfigURL)
81+
}
82+
}
83+
5284
// MARK: - Cluster
5385

5486
/// Cluster contains information about how to communicate with a kubernetes cluster.

0 commit comments

Comments
 (0)