Skip to content

Commit

Permalink
backend: refactor listing valid contexts and error
Browse files Browse the repository at this point in the history
This removes the dependacy of manually parsing of k8s resources. It was
a problem as we had to be in sync with k8s API changes, which is not a
good way. This change removes that and it splits kubeconfig into
seperate contexts and validates them.

Fixes: #2347
Co-Authored-By: Santhosh Nagaraj <sannagaraj@microsoft.com>
Signed-off-by: Kautilya Tripathi <ktripathi@microsoft.com>
  • Loading branch information
knrt10 and yolossn committed Sep 23, 2024
1 parent b3bcc27 commit a07ce59
Show file tree
Hide file tree
Showing 5 changed files with 708 additions and 608 deletions.
1 change: 1 addition & 0 deletions backend/cmd/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ type Cluster struct {
Server string `json:"server,omitempty"`
AuthType string `json:"auth_type"`
Metadata map[string]interface{} `json:"meta_data"`
Error string `json:"error,omitempty"`
}

type ClusterReq struct {
Expand Down
92 changes: 46 additions & 46 deletions backend/cmd/headlamp.go
Original file line number Diff line number Diff line change
Expand Up @@ -1013,6 +1013,14 @@ func handleClusterAPI(c *HeadlampConfig, router *mux.Router) {
return
}

if kContext.Error != "" {
logger.Log(logger.LevelError, map[string]string{"key": contextKey},
errors.New(kContext.Error), "context has error")
http.Error(w, kContext.Error, http.StatusBadRequest)

return
}

clusterURL, err := url.Parse(kContext.Cluster.Server)
if err != nil {
logger.Log(logger.LevelError, map[string]string{"ClusterURL": kContext.Cluster.Server},
Expand Down Expand Up @@ -1062,6 +1070,15 @@ func (c *HeadlampConfig) getClusters() []Cluster {
for _, context := range contexts {
context := context

if context.Error != "" {
clusters = append(clusters, Cluster{
Name: context.Name,
Error: context.Error,
})

continue
}

// Dynamic clusters should not be visible to other users.
if context.Internal {
continue
Expand Down Expand Up @@ -1143,27 +1160,7 @@ func parseClusterFromKubeConfig(kubeConfigs []string) ([]Cluster, []error) {
var setupErrors []error

for _, kubeConfig := range kubeConfigs {
var contexts []kubeconfig.Context

kubeConfigByte, err := base64.StdEncoding.DecodeString(kubeConfig)
if err != nil {
logger.Log(logger.LevelError, nil, err, "decoding kubeconfig")

setupErrors = append(setupErrors, err)

continue
}

config, err := clientcmd.Load(kubeConfigByte)
if err != nil {
logger.Log(logger.LevelError, nil, err, "loading kubeconfig")

setupErrors = append(setupErrors, err)

continue
}

contexts, errs := kubeconfig.LoadContextsFromAPIConfig(config, true)
contexts, errs := kubeconfig.LoadContextsFromBase64String(kubeConfig, kubeconfig.DynamicCluster)
if len(errs) > 0 {
setupErrors = append(setupErrors, errs...)
continue
Expand Down Expand Up @@ -1221,39 +1218,42 @@ func (c *HeadlampConfig) addCluster(w http.ResponseWriter, r *http.Request) {
var setupErrors []error

if clusterReq.KubeConfig != nil {
kubeConfigByte, err := base64.StdEncoding.DecodeString(*clusterReq.KubeConfig)
if err != nil {
logger.Log(logger.LevelError, nil, err, "decoding kubeconfig")
http.Error(w, "decoding kubeconfig", http.StatusBadRequest)
// get contexts from kubeconfig earlier to skip proxy setup and parse errors.
contexts, setupErrors = kubeconfig.LoadContextsFromBase64String(*clusterReq.KubeConfig, kubeconfig.DynamicCluster)

return
}
if len(setupErrors) == 0 {
kubeConfigByte, err := base64.StdEncoding.DecodeString(*clusterReq.KubeConfig)
if err != nil {
logger.Log(logger.LevelError, nil, err, "decoding kubeconfig")
http.Error(w, "decoding kubeconfig", http.StatusBadRequest)

config, err := clientcmd.Load(kubeConfigByte)
if err != nil {
logger.Log(logger.LevelError, nil, err, "loading kubeconfig")
http.Error(w, "loading kubeconfig", http.StatusBadRequest)
return
}

return
}
config, err := clientcmd.Load(kubeConfigByte)
if err != nil {
logger.Log(logger.LevelError, nil, err, "loading kubeconfig")
http.Error(w, "loading kubeconfig", http.StatusBadRequest)

kubeConfigPersistenceDir, err := defaultKubeConfigPersistenceDir()
if err != nil {
logger.Log(logger.LevelError, nil, err, "getting default kubeconfig persistence dir")
http.Error(w, "getting default kubeconfig persistence dir", http.StatusInternalServerError)
return
}

return
}
kubeConfigPersistenceDir, err := defaultKubeConfigPersistenceDir()
if err != nil {
logger.Log(logger.LevelError, nil, err, "getting default kubeconfig persistence dir")
http.Error(w, "getting default kubeconfig persistence dir", http.StatusInternalServerError)

err = kubeconfig.WriteToFile(*config, kubeConfigPersistenceDir)
if err != nil {
logger.Log(logger.LevelError, nil, err, "writing kubeconfig")
http.Error(w, "writing kubeconfig", http.StatusBadRequest)
return
}

return
}
err = kubeconfig.WriteToFile(*config, kubeConfigPersistenceDir)
if err != nil {
logger.Log(logger.LevelError, nil, err, "writing kubeconfig")
http.Error(w, "writing kubeconfig", http.StatusBadRequest)

contexts, setupErrors = kubeconfig.LoadContextsFromAPIConfig(config, false)
return
}
}
} else {
conf := &api.Config{
Clusters: map[string]*api.Cluster{
Expand Down
Loading

0 comments on commit a07ce59

Please sign in to comment.