Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 35 additions & 1 deletion cluster/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,14 @@ func (cm *Manager) LoadInClusterConfig(name string) error {
return fmt.Errorf("failed to connect to cluster: %w", err)
}

// Detect the namespace from the service account namespace file
namespace := detectInClusterNamespace("")

contextInfo := &kai.ContextInfo{
Name: name,
Cluster: "in-cluster",
User: "service-account",
Namespace: "default",
Namespace: namespace,
ServerURL: config.Host,
ConfigPath: "",
IsActive: true,
Expand All @@ -97,6 +100,7 @@ func (cm *Manager) LoadInClusterConfig(name string) error {
slog.Info("in-cluster config loaded",
slog.String("context", name),
slog.String("server", config.Host),
slog.String("namespace", namespace),
)

return nil
Expand Down Expand Up @@ -511,6 +515,36 @@ func validateFile(path string) error {
return nil
}

// detectInClusterNamespace reads the namespace from the service account namespace file
// when running inside a Kubernetes pod. Falls back to "default" if the file cannot be read.
// If customPath is provided and not empty, it will be used instead of the default Kubernetes path.
func detectInClusterNamespace(customPath string) string {
namespaceFile := "/var/run/secrets/kubernetes.io/serviceaccount/namespace"
if customPath != "" {
namespaceFile = customPath
}

// #nosec G304 - This is a well-known Kubernetes service account file path
data, err := os.ReadFile(namespaceFile)
if err != nil {
slog.Debug("failed to read namespace from service account file, using default",
slog.String("file", namespaceFile),
slog.String("error", err.Error()),
)
return "default"
}

namespace := strings.TrimSpace(string(data))
if namespace == "" {
slog.Debug("namespace file is empty, using default",
slog.String("file", namespaceFile),
)
return "default"
}

return namespace
}

func ptr[T any](v T) *T {
return &v
}
Expand Down
58 changes: 58 additions & 0 deletions cluster/manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,64 @@ func TestExtendedClusterManager(t *testing.T) {

func TestInClusterConfig(t *testing.T) {
t.Run("LoadInClusterConfig", testLoadInClusterConfig)
t.Run("DetectInClusterNamespace", testDetectInClusterNamespace)
}

func testDetectInClusterNamespace(t *testing.T) {
t.Run("NamespaceFileDoesNotExist", func(t *testing.T) {
// When the namespace file doesn't exist, should return "default"
namespace := detectInClusterNamespace("/nonexistent/path/namespace")
assert.Equal(t, "default", namespace)
})

t.Run("NamespaceFileExists", func(t *testing.T) {
// Create a temporary directory and file to simulate the service account namespace file
tmpDir := t.TempDir()
namespaceFile := filepath.Join(tmpDir, "namespace")

// Write a test namespace to the file
testNs := "my-custom-namespace"
err := os.WriteFile(namespaceFile, []byte(testNs), 0600)
require.NoError(t, err)

// Test the actual function
namespace := detectInClusterNamespace(namespaceFile)
assert.Equal(t, testNs, namespace)
})

t.Run("NamespaceFileIsEmpty", func(t *testing.T) {
// Create a temporary empty file
tmpDir := t.TempDir()
namespaceFile := filepath.Join(tmpDir, "namespace")

err := os.WriteFile(namespaceFile, []byte(""), 0600)
require.NoError(t, err)

// Test that empty file returns "default"
namespace := detectInClusterNamespace(namespaceFile)
assert.Equal(t, "default", namespace)
})

t.Run("NamespaceFileWithWhitespace", func(t *testing.T) {
// Create a temporary file with whitespace
tmpDir := t.TempDir()
namespaceFile := filepath.Join(tmpDir, "namespace")

testNs := "my-namespace"
err := os.WriteFile(namespaceFile, []byte(" "+testNs+" \n"), 0600)
require.NoError(t, err)

// Test that whitespace is trimmed
namespace := detectInClusterNamespace(namespaceFile)
assert.Equal(t, testNs, namespace)
})

t.Run("DefaultPath", func(t *testing.T) {
// When no custom path is provided, should use default path
// Since the default path won't exist in test environment, it should return "default"
namespace := detectInClusterNamespace("")
assert.Equal(t, "default", namespace)
})
}

func testLoadInClusterConfig(t *testing.T) {
Expand Down
Loading