Skip to content

Commit bc040fc

Browse files
committed
complete refactoring k8s client NewService
1 parent 3a2de84 commit bc040fc

File tree

4 files changed

+74
-101
lines changed

4 files changed

+74
-101
lines changed

cmd/cmd.go

+16-4
Original file line numberDiff line numberDiff line change
@@ -289,8 +289,14 @@ func getKubeConfigPath(cmd *cobra.Command) string {
289289
return filepath.Join(homeDir(), ".kube", "config")
290290
}
291291

292-
func getKubeContexts(cmd *cobra.Command) string {
293-
return cmd.Flags().Lookup("context").Value.String()
292+
func getKubeContexts(cmd *cobra.Command) []string {
293+
contextsString := cmd.Flags().Lookup("context").Value.String()
294+
trimmed := strings.Trim(strings.TrimSpace(contextsString), ",")
295+
var contexts []string
296+
if len(trimmed) > 0 {
297+
contexts = strings.Split(trimmed, ",")
298+
}
299+
return contexts
294300
}
295301

296302
func getDescending(cmd *cobra.Command) bool {
@@ -353,8 +359,14 @@ func getLogFilter(cmd *cobra.Command) model.LogFilter {
353359
return model.LogFilter{}
354360
}
355361

356-
func getNamespaces(cmd *cobra.Command) string {
357-
return cmd.Flags().Lookup("namespace").Value.String()
362+
func getNamespaces(cmd *cobra.Command) []string {
363+
namespacesString := cmd.Flags().Lookup("namespace").Value.String()
364+
trimmed := strings.Trim(strings.TrimSpace(namespacesString), ",")
365+
var namespaces []string
366+
if len(trimmed) > 0 {
367+
namespaces = strings.Split(trimmed, ",")
368+
}
369+
return namespaces
358370
}
359371

360372
func getSelector(cmd *cobra.Command) labels.Selector {

internal/config.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@ import (
88
type Config struct {
99
AllNamespaces bool
1010
ContainerLimit int
11-
Contexts string
11+
Contexts []string
1212
Descending bool
1313
IgnoreOwnerTypes []string
1414
KubeConfigPath string
1515
LogsView bool
1616
LogFilter model.LogFilter
1717
Matchers model.Matchers
18-
Namespaces string
18+
Namespaces []string
1919
Selector labels.Selector
2020
SinceTime model.SinceTime
2121
Version string

internal/k8s/client/client.go

-45
Original file line numberDiff line numberDiff line change
@@ -47,51 +47,6 @@ type clientImpl struct {
4747
allClusterNamespaces []model.ClusterNamespaces
4848
}
4949

50-
// TODO LEO: make these not just strings
51-
func NewClient(
52-
ctx context.Context,
53-
kubeConfigPath string,
54-
contextString string,
55-
namespaceString string,
56-
useAllNamespaces bool,
57-
) (Client, error) {
58-
rawKubeConfig, loadingRules, err := getKubeConfig(kubeConfigPath)
59-
if err != nil {
60-
return clientImpl{}, err
61-
}
62-
63-
contexts, err := getContexts(contextString, rawKubeConfig)
64-
if err != nil {
65-
return clientImpl{}, err
66-
}
67-
dev.Debug(fmt.Sprintf("using contexts %v", contexts))
68-
69-
clusters := getClustersFromContexts(contexts, rawKubeConfig)
70-
71-
clusterToContext, err := validateUniqueClusters(contexts, clusters, rawKubeConfig)
72-
if err != nil {
73-
return clientImpl{}, err
74-
}
75-
76-
allClusterNamespaces := buildClusterNamespaces(namespaceString, useAllNamespaces, clusters, clusterToContext, rawKubeConfig)
77-
for _, cn := range allClusterNamespaces {
78-
for _, namespace := range cn.Namespaces {
79-
dev.Debug(fmt.Sprintf("using cluster '%s' namespace '%s'", cn.Cluster, namespace))
80-
}
81-
}
82-
83-
clusterToClientSet, err := createClientSets(clusters, clusterToContext, loadingRules)
84-
if err != nil {
85-
return clientImpl{}, err
86-
}
87-
88-
return clientImpl{
89-
ctx: ctx,
90-
clusterToClientset: clusterToClientSet,
91-
allClusterNamespaces: allClusterNamespaces,
92-
}, nil
93-
}
94-
9550
func (c clientImpl) AllClusterNamespaces() []model.ClusterNamespaces {
9651
return c.allClusterNamespaces
9752
}

internal/k8s/client/client_init.go

+56-50
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,50 @@
11
package client
22

33
import (
4+
"context"
45
"fmt"
5-
"github.com/robinovitch61/kl/internal/dev"
66
"github.com/robinovitch61/kl/internal/model"
7+
"os"
8+
"strings"
9+
10+
"github.com/robinovitch61/kl/internal/dev"
711
"k8s.io/client-go/kubernetes"
812
"k8s.io/client-go/tools/clientcmd"
913
"k8s.io/client-go/tools/clientcmd/api"
10-
"os"
11-
"strings"
1214
)
1315

14-
// getKubeConfig gets kubeconfig, accounting for multiple file paths
15-
func getKubeConfig(kubeConfigPath string) (api.Config, *clientcmd.ClientConfigLoadingRules, error) {
16-
loadingRules := clientcmd.NewDefaultClientConfigLoadingRules()
17-
kubeconfigPaths := strings.Split(kubeConfigPath, string(os.PathListSeparator))
18-
dev.Debug(fmt.Sprintf("kubeconfig paths: %v", kubeconfigPaths))
19-
20-
loadingRules.Precedence = kubeconfigPaths
21-
clientConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, nil)
22-
rawKubeConfig, err := clientConfig.RawConfig()
16+
func NewClient(
17+
ctx context.Context,
18+
kubeConfigPath string,
19+
contexts []string,
20+
namespaces []string,
21+
useAllNamespaces bool,
22+
) (Client, error) {
23+
rawKubeConfig, loadingRules, err := getKubeConfig(kubeConfigPath)
2324
if err != nil {
24-
return api.Config{}, loadingRules, fmt.Errorf("failed to load kubeconfig: %w", err)
25-
}
26-
return rawKubeConfig, loadingRules, nil
27-
}
28-
29-
func getContexts(contextString string, config api.Config) ([]string, error) {
30-
contextsString := strings.Trim(strings.TrimSpace(contextString), ",")
31-
var contexts []string
32-
if len(contextsString) > 0 {
33-
contexts = strings.Split(contextsString, ",")
34-
}
35-
36-
if len(contexts) == 0 && config.CurrentContext != "" {
37-
contexts = []string{config.CurrentContext}
25+
return clientImpl{}, err
3826
}
3927

4028
if len(contexts) == 0 {
41-
return nil, fmt.Errorf("no contexts specified and no current context found in kubeconfig")
29+
if rawKubeConfig.CurrentContext != "" {
30+
dev.Debug(fmt.Sprintf("no contexts specified, using current context %s", rawKubeConfig.CurrentContext))
31+
contexts = []string{rawKubeConfig.CurrentContext}
32+
} else {
33+
return nil, fmt.Errorf("no contexts specified and no current context found in kubeconfig")
34+
}
4235
}
43-
4436
for _, c := range contexts {
45-
if _, exists := config.Contexts[c]; !exists {
37+
if _, exists := rawKubeConfig.Contexts[c]; !exists {
4638
return nil, fmt.Errorf("context %s not found in kubeconfig", c)
4739
}
4840
}
41+
dev.Debug(fmt.Sprintf("using contexts %v", contexts))
4942

50-
return contexts, nil
51-
}
52-
53-
func getClustersFromContexts(contexts []string, rawKubeConfig api.Config) []string {
54-
var clusters []string
55-
for _, contextName := range contexts {
56-
clusterName := rawKubeConfig.Contexts[contextName].Cluster
57-
clusters = append(clusters, clusterName)
43+
clusters := make([]string, len(contexts))
44+
for i := range contexts {
45+
clusters[i] = rawKubeConfig.Contexts[contexts[i]].Cluster
5846
}
59-
return clusters
60-
}
6147

62-
func validateUniqueClusters(contexts []string, clusters []string, rawKubeConfig api.Config) (map[string]string, error) {
6348
clusterToContext := make(map[string]string)
6449
for _, contextName := range contexts {
6550
clusterName := rawKubeConfig.Contexts[contextName].Cluster
@@ -68,15 +53,6 @@ func validateUniqueClusters(contexts []string, clusters []string, rawKubeConfig
6853
}
6954
clusterToContext[clusterName] = contextName
7055
}
71-
return clusterToContext, nil
72-
}
73-
74-
func buildClusterNamespaces(allNamespaces string, useAllNamespaces bool, clusters []string, clusterToContext map[string]string, rawKubeConfig api.Config) []model.ClusterNamespaces {
75-
namespacesString := strings.Trim(strings.TrimSpace(allNamespaces), ",")
76-
var namespaces []string
77-
if len(namespacesString) > 0 {
78-
namespaces = strings.Split(namespacesString, ",")
79-
}
8056

8157
var allClusterNamespaces []model.ClusterNamespaces
8258
for _, cluster := range clusters {
@@ -96,7 +72,37 @@ func buildClusterNamespaces(allNamespaces string, useAllNamespaces bool, cluster
9672
allClusterNamespaces = append(allClusterNamespaces, cn)
9773
}
9874
}
99-
return allClusterNamespaces
75+
for _, cn := range allClusterNamespaces {
76+
for _, namespace := range cn.Namespaces {
77+
dev.Debug(fmt.Sprintf("using cluster '%s' namespace '%s'", cn.Cluster, namespace))
78+
}
79+
}
80+
81+
clusterToClientSet, err := createClientSets(clusters, clusterToContext, loadingRules)
82+
if err != nil {
83+
return clientImpl{}, err
84+
}
85+
86+
return clientImpl{
87+
ctx: ctx,
88+
clusterToClientset: clusterToClientSet,
89+
allClusterNamespaces: allClusterNamespaces,
90+
}, nil
91+
}
92+
93+
// getKubeConfig gets kubeconfig, accounting for multiple file paths
94+
func getKubeConfig(kubeConfigPath string) (api.Config, *clientcmd.ClientConfigLoadingRules, error) {
95+
loadingRules := clientcmd.NewDefaultClientConfigLoadingRules()
96+
kubeconfigPaths := strings.Split(kubeConfigPath, string(os.PathListSeparator))
97+
dev.Debug(fmt.Sprintf("kubeconfig paths: %v", kubeconfigPaths))
98+
99+
loadingRules.Precedence = kubeconfigPaths
100+
clientConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, nil)
101+
rawKubeConfig, err := clientConfig.RawConfig()
102+
if err != nil {
103+
return api.Config{}, loadingRules, fmt.Errorf("failed to load kubeconfig: %w", err)
104+
}
105+
return rawKubeConfig, loadingRules, nil
100106
}
101107

102108
func createClientSets(clusters []string, clusterToContext map[string]string, loadingRules *clientcmd.ClientConfigLoadingRules) (map[string]*kubernetes.Clientset, error) {

0 commit comments

Comments
 (0)