Skip to content

Commit db2b84c

Browse files
committed
feat: allow to save cluster + token to kubeconf (#23649)
Signed-off-by: Andre Dietisheim <[email protected]> Assisted by: gemini-cli Assisted by: cursor Assisted by: qwen-code
1 parent 8d10739 commit db2b84c

24 files changed

+3220
-1107
lines changed
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright (c) 2025 Red Hat, Inc.
3+
* This program and the accompanying materials are made
4+
* available under the terms of the Eclipse Public License 2.0
5+
* which is available at https://www.eclipse.org/legal/epl-2.0/
6+
*
7+
* SPDX-License-Identifier: EPL-2.0
8+
*
9+
* Contributors:
10+
* Red Hat, Inc. - initial API and implementation
11+
*/
12+
package com.redhat.devtools.gateway.kubeconfig
13+
14+
import com.fasterxml.jackson.databind.ObjectMapper
15+
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory
16+
import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator
17+
import io.kubernetes.client.persister.ConfigPersister
18+
import java.io.File
19+
20+
class BlockStyleFilePersister(private val file: File) : ConfigPersister {
21+
22+
@Throws(java.io.IOException::class)
23+
override fun save(
24+
contexts: ArrayList<Any?>,
25+
clusters: ArrayList<Any?>,
26+
users: ArrayList<Any?>,
27+
preferences: Any?,
28+
currentContext: String?
29+
) {
30+
val config = mapOf(
31+
"apiVersion" to "v1",
32+
"kind" to "Config",
33+
"current-context" to currentContext,
34+
"preferences" to preferences,
35+
36+
"clusters" to clusters,
37+
"contexts" to contexts,
38+
"users" to users,
39+
)
40+
41+
synchronized(file) {
42+
val yamlFactory = YAMLFactory().apply {
43+
configure(YAMLGenerator.Feature.MINIMIZE_QUOTES, true)
44+
configure(YAMLGenerator.Feature.INDENT_ARRAYS_WITH_INDICATOR, true)
45+
}
46+
val mapper = ObjectMapper(yamlFactory)
47+
mapper.writeValue(file, config)
48+
}
49+
}
50+
}

src/main/kotlin/com/redhat/devtools/gateway/kubeconfig/FileWatcher.kt

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import kotlin.io.path.exists
1818
import kotlin.io.path.isRegularFile
1919

2020
class FileWatcher(
21-
private val scope: CoroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Default),
21+
private val scope: CoroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.IO),
2222
private val dispatcher: CoroutineDispatcher = Dispatchers.IO,
2323
private val watchService: WatchService = FileSystems.getDefault().newWatchService()
2424
) {
@@ -29,23 +29,31 @@ class FileWatcher(
2929

3030
fun start() {
3131
this.watchJob = scope.launch(dispatcher) {
32-
while (isActive) {
33-
val key = watchService.poll(100, java.util.concurrent.TimeUnit.MILLISECONDS)
34-
if (key == null) {
35-
delay(100)
36-
continue
32+
try {
33+
while (isActive) {
34+
val key = watchService.poll(100, java.util.concurrent.TimeUnit.MILLISECONDS)
35+
if (key == null) {
36+
delay(100)
37+
continue
38+
}
39+
val dir = registeredKeys[key] ?: continue
40+
pollEvents(key, dir)
41+
key.reset()
3742
}
38-
val dir = registeredKeys[key] ?: continue
39-
pollEvents(key, dir)
40-
key.reset()
43+
} catch (e: ClosedWatchServiceException) {
44+
// Watch service was closed, exit gracefully
4145
}
4246
}
4347
}
4448

4549
fun stop() {
4650
watchJob?.cancel()
4751
watchJob = null
48-
watchService.close()
52+
try {
53+
watchService.close()
54+
} catch (e: Exception) {
55+
// Ignore exceptions when closing
56+
}
4957
}
5058

5159
fun addFile(path: Path): FileWatcher {

0 commit comments

Comments
 (0)