package handler import ( "context" "encoding/base64" "encoding/json" "fmt" "log" "main/argohandler" "main/db" "net/http" "strings" corev1 "k8s.io/api/core/v1" // "github.com/gorilla/mux" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/clientcmd" ) type Cluster struct { ID primitive.ObjectID `bson:"_id,omitempty"` Name string `json:"name"` Namespace string `json:"namespace"` ControlPlane string `json:"controlPlane"` PlatformVersion string `json:"platformversion` Cpu string `json:"cpu"` Memory string `json:"memory"` CreatedAt string `json:"createdAt"` UserID primitive.ObjectID `json:"userId"` Cluster_config string `json:"clusterconfig"` } type Header struct { Authorization string `bson:"token"` } type Pod struct { Name string `json:name` Namespace string `json:name` Status string `json:status` Restart string `json:restart` Age string `json:age` } type Service struct { Name string `json:name` Namespace string `json:name` Type string `json:type` ClusterIP string `json:clusterIp` ExternalIP string `json:externalIp` Ports string `json:ports` Age string `json:age` } type Deployment struct { Name string `json:name` Namespace string `json:namespace` Ready string `json:Ready` UpdateToDate string `json:uptodate` Available string `json:available` } type Daemonset struct { Name string `json:name` Namespace string `json:namespace` Ready string `json:Ready` Age string `json:age` DESIRED string `json:desired` CURRENT string `json:current` UpdateToDate string `json:uptodate` Available string `json:available` Node string `json:node` Selector string `json:selector` } type Jobs struct { Namespace string `json:name` Name string `json:name` Status string `json:status` Completion string `json:completion` Duration string `json:duration` Age string `json:age` } type Replicaset struct { Name string `json:name` Desired string `json:desired` Current string `json:current` Ready string `json:Ready` Age string `json:age` Namespace string `json:name` } type ReplicationController struct { Namespace string `json:name` Name string `json:name` Desired string `json:desired` Current string `json:current` Ready string `json:Ready` Age string `json:age` } type StatefulSet struct { Namespace string `json:name` Name string `json:name` Ready string `json:Ready` Age string `json:age` } func CreateClusterHandler(w http.ResponseWriter, r *http.Request) { var cluster Cluster _ = json.NewDecoder(r.Body).Decode(&cluster) var header Header header.Authorization = r.Header.Get("Authorization") // vclusterCollection := db.Vclusters_details.FindOne(context.TODO(), bson.M{"name": Cluster.Name}).Decode(&existsCluster) if cluster.Name == "" || cluster.ControlPlane == "" || cluster.PlatformVersion == "" || cluster.Cpu == "" || cluster.Memory == "" { http.Error(w, "Invalid input", http.StatusBadRequest) return } var existsCluster Cluster _ = db.Vclusters_details.FindOne(context.TODO(), bson.M{"name": cluster.Name}).Decode(&existsCluster) if existsCluster.Name == cluster.Name { http.Error(w, "Cluster name is duplicated", http.StatusBadRequest) return } res, err := db.Vclusters_details.InsertOne(context.TODO(), cluster) if err != nil { http.Error(w, `{"message": "Could not create cluster"}`, http.StatusInternalServerError) } objectID := res.InsertedID.(primitive.ObjectID) idStr := objectID.Hex() argohandler.CreateApp(idStr, cluster.Name, cluster.ControlPlane, cluster.PlatformVersion, cluster.Cpu, cluster.Memory, "userid") response := map[string]string{"message": "Cluster created"} w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(response) } func getClientset(w http.ResponseWriter, clustername string) (*kubernetes.Clientset, error) { kubeconfig, err := getClusterConfig(clustername) if err != nil { http.Error(w, "File to get kubeconfig", http.StatusInternalServerError) return nil, err } kubeconfigbyte := []byte(kubeconfig) config, err := clientcmd.RESTConfigFromKubeConfig(kubeconfigbyte) if err != nil { log.Fatal("Error creating clientSet:", err) } clientset, err := kubernetes.NewForConfig(config) if err != nil { log.Fatal("Error creating clientSet:", err) } return clientset, nil } func ListUserClusters(w http.ResponseWriter, r *http.Request) { // var cluster Cluster _, clusterList := argohandler.ListUserClusters("userid") w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(clusterList) } func Cluster_namespaces(w http.ResponseWriter, r *http.Request) { clustername := r.URL.Query().Get("Name") if clustername == "" { http.Error(w, "Missing 'Name' parameter", http.StatusBadRequest) return } clientset, err := getClientset(w, clustername) if err != nil { log.Fatal("Error getting clientset: ", err) } listOfnamespaces, err := clientset.CoreV1().Namespaces().List(context.TODO(), metav1.ListOptions{}) if err != nil { log.Fatal("Error getting list of pods: ", err) } var nslist []string for _, ns := range listOfnamespaces.Items { nslist = append(nslist, ns.Name) } if err != nil { http.Error(w, "Internal Error", http.StatusInternalServerError) } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(nslist) } func Cluster_services(w http.ResponseWriter, r *http.Request) { clustername := r.URL.Query().Get("Name") namespace := r.URL.Query().Get("Namespace") if clustername == "" { http.Error(w, "Missing 'Name' parameter", http.StatusBadRequest) return } clientset, err := getClientset(w, clustername) if err != nil { log.Fatal("Error getting clientset: ", err) } services, err := clientset.CoreV1().Services(namespace).List(context.TODO(), metav1.ListOptions{}) if err != nil { log.Fatal("Error getting list of services: ", err) } Allservice := []Service{} var service Service for _, s := range services.Items { service.Name = s.Name service.Namespace = s.Namespace service.Type = string(s.Spec.Type) service.Ports = servicePortsToString(s.Spec.Ports) service.ClusterIP = s.Spec.ClusterIP if len(s.Spec.ExternalIPs) > 0 { service.ExternalIP = s.Spec.ExternalIPs[0] } Allservice = append(Allservice, service) } //pod_list, err := json.Marshal(Allservice) if err != nil { http.Error(w, "Internal Error", http.StatusInternalServerError) } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(Allservice) } func Cluster_statefulset(w http.ResponseWriter, r *http.Request) { clustername := r.URL.Query().Get("Name") namespace := r.URL.Query().Get("Namespace") if clustername == "" { http.Error(w, "Missing 'Name' parameter", http.StatusBadRequest) return } clientset, err := getClientset(w, clustername) if err != nil { log.Fatal("Error getting clientset: ", err) } statefulSets, err := clientset.AppsV1().StatefulSets(namespace).List(context.TODO(), metav1.ListOptions{}) if err != nil { log.Fatal("Error getting list of StatefulSets: ", err) } AllstatefulSets := []StatefulSet{} var StatefulSet StatefulSet for _, s := range statefulSets.Items { StatefulSet.Name = s.Name StatefulSet.Namespace = s.Namespace StatefulSet.Ready = string(s.Status.ReadyReplicas) AllstatefulSets = append(AllstatefulSets, StatefulSet) } //pod_list, err := json.Marshal(Allservice) if err != nil { http.Error(w, "Internal Error", http.StatusInternalServerError) } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(AllstatefulSets) } func Cluster_daemonsets(w http.ResponseWriter, r *http.Request) { clustername := r.URL.Query().Get("Name") namespace := r.URL.Query().Get("Namespace") if clustername == "" { http.Error(w, "Missing 'Name' parameter", http.StatusBadRequest) return } clientset, err := getClientset(w, clustername) if err != nil { log.Fatal("Error getting clientset: ", err) } DaemonSetss, err := clientset.AppsV1().DaemonSets(namespace).List(context.TODO(), metav1.ListOptions{}) if err != nil { log.Fatal("Error getting list of DaemonSets: ", err) } AllDaemonSets := []Daemonset{} var DaemonSets Daemonset for _, s := range DaemonSetss.Items { DaemonSets.Name = s.Name DaemonSets.Namespace = s.Namespace DaemonSets.DESIRED = string(s.Status.DesiredNumberScheduled) DaemonSets.CURRENT = string(s.Status.NumberReady) DaemonSets.Available = string(s.Status.NumberAvailable) AllDaemonSets = append(AllDaemonSets, DaemonSets) } //pod_list, err := json.Marshal(Allservice) if err != nil { http.Error(w, "Internal Error", http.StatusInternalServerError) } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(AllDaemonSets) } func Cluster_deployments(w http.ResponseWriter, r *http.Request) { clustername := r.URL.Query().Get("Name") namespace := r.URL.Query().Get("Namespace") if clustername == "" { http.Error(w, "Missing 'Name' parameter", http.StatusBadRequest) return } clientset, err := getClientset(w, clustername) if err != nil { log.Fatal("Error getting clientset: ", err) } deployments, err := clientset.AppsV1().Deployments(namespace).List(context.TODO(), metav1.ListOptions{}) if err != nil { log.Fatal("Error getting list of deployments: ", err) } Alldeployment := []Deployment{} var deployment Deployment for _, d := range deployments.Items { deployment.Name = d.Name deployment.Namespace = d.Namespace Alldeployment = append(Alldeployment, deployment) } if err != nil { http.Error(w, "Internal Error", http.StatusInternalServerError) } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(Alldeployment) } func servicePortsToString(ports []corev1.ServicePort) string { var parts []string for _, p := range ports { // Example format: "80/TCP" parts = append(parts, fmt.Sprintf("%d/%s", p.Port, p.Protocol)) } return strings.Join(parts, ", ") } func Cluster_pods(w http.ResponseWriter, r *http.Request) { clustername := r.URL.Query().Get("Name") namespace := r.URL.Query().Get("Namespace") if clustername == "" { http.Error(w, "Missing 'Name' parameter", http.StatusBadRequest) return } clientset, err := getClientset(w, clustername) if err != nil { log.Fatal("Error getting clientset: ", err) } pods, err := clientset.CoreV1().Pods(namespace).List(context.TODO(), metav1.ListOptions{}) if err != nil { log.Fatal("Error getting list of pods: ", err) } Allpod := []Pod{} var pod Pod for _, p := range pods.Items { fmt.Printf(p.Name, p.Namespace) pod.Name = p.Name pod.Namespace = p.Namespace pod.Status = string(p.Status.Phase) Allpod = append(Allpod, pod) } //pod_list, err := json.Marshal(Allpod) if err != nil { http.Error(w, "Internal Error", http.StatusInternalServerError) } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(Allpod) } func getClusterConfig(clustername string) (string, error) { var existsCluster Cluster err := db.Vclusters_details.FindOne(context.TODO(), bson.M{"name": clustername}).Decode(&existsCluster) if err != nil { return "", err } decoded, err := base64.StdEncoding.DecodeString(existsCluster.Cluster_config) return string(decoded), nil } func Connect(w http.ResponseWriter, r *http.Request) { clusterName := r.URL.Query().Get("Name") if clusterName == "" { http.Error(w, "Missing 'Name' parameter", http.StatusBadRequest) return } var existsCluster Cluster _ = db.Vclusters_details.FindOne(context.TODO(), bson.M{"name": clusterName}).Decode(&existsCluster) decoded, err := base64.StdEncoding.DecodeString(existsCluster.Cluster_config) if err != nil { http.Error(w, "Failed to decode cluster config", http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/x-yaml") w.Header().Set("Content-Disposition", `attachment; filename="`+clusterName+`.yaml"`) w.Write(decoded) } // func Cluster_details(w http.ResponseWriter, r *http.Request) { // } func Cluster_jobs(w http.ResponseWriter, r *http.Request) { clustername := r.URL.Query().Get("Name") namespace := r.URL.Query().Get("Namespace") if clustername == "" { http.Error(w, "Missing 'Name' parameter", http.StatusBadRequest) return } clientset, err := getClientset(w, clustername) if err != nil { log.Fatal("Error getting Jobs: ", err) } jobs, err := clientset.BatchV1().Jobs(namespace).List(context.TODO(), metav1.ListOptions{}) if err != nil { log.Fatal("Error getting list of Jobs: ", err) } AllJob := []Jobs{} var job Jobs for _, d := range jobs.Items { job.Name = d.Name job.Namespace = d.Namespace AllJob = append(AllJob, job) } if err != nil { http.Error(w, "Internal Error", http.StatusInternalServerError) } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(AllJob) } func Cluster_replicasets(w http.ResponseWriter, r *http.Request) { clustername := r.URL.Query().Get("Name") namespace := r.URL.Query().Get("Namespace") if clustername == "" { http.Error(w, "Missing 'Name' parameter", http.StatusBadRequest) return } clientset, err := getClientset(w, clustername) if err != nil { log.Fatal("Error getting replicasets: ", err) } replicasets, err := clientset.AppsV1().ReplicaSets(namespace).List(context.TODO(), metav1.ListOptions{}) if err != nil { log.Fatal("Error getting list of Replicaset: ", err) } Allreplicaset := []Replicaset{} var replicaset Replicaset for _, d := range replicasets.Items { replicaset.Name = d.Name replicaset.Namespace = d.Namespace Allreplicaset = append(Allreplicaset, replicaset) } if err != nil { http.Error(w, "Internal Error", http.StatusInternalServerError) } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(Allreplicaset) } func Cluster_replicationcontrollers(w http.ResponseWriter, r *http.Request) { clustername := r.URL.Query().Get("Name") namespace := r.URL.Query().Get("Namespace") if clustername == "" { http.Error(w, "Missing 'Name' parameter", http.StatusBadRequest) return } clientset, err := getClientset(w, clustername) if err != nil { log.Fatal("Error getting Replicationcontrollers: ", err) } replicationcontrollers, err := clientset.CoreV1().ReplicationControllers(namespace).List(context.TODO(), metav1.ListOptions{}) if err != nil { log.Fatal("Error getting list of ReplicationController: ", err) } AllreplicationController := []ReplicationController{} var ReplicationController ReplicationController for _, d := range replicationcontrollers.Items { ReplicationController.Name = d.Name ReplicationController.Namespace = d.Namespace AllreplicationController = append(AllreplicationController, ReplicationController) } if err != nil { http.Error(w, "Internal Error", http.StatusInternalServerError) } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(AllreplicationController) } func Cluster_cronjobs(w http.ResponseWriter, r *http.Request) { clustername := r.URL.Query().Get("Name") namespace := r.URL.Query().Get("Namespace") if clustername == "" { http.Error(w, "Missing 'Name' parameter", http.StatusBadRequest) return } clientset, err := getClientset(w, clustername) if err != nil { log.Fatal("Error getting Replicationcontrollers: ", err) } replicationcontrollers, err := clientset.CoreV1().ReplicationControllers(namespace).List(context.TODO(), metav1.ListOptions{}) if err != nil { log.Fatal("Error getting list of ReplicationController: ", err) } AllreplicationController := []ReplicationController{} var ReplicationController ReplicationController for _, d := range replicationcontrollers.Items { ReplicationController.Name = d.Name ReplicationController.Namespace = d.Namespace AllreplicationController = append(AllreplicationController, ReplicationController) } if err != nil { http.Error(w, "Internal Error", http.StatusInternalServerError) } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(AllreplicationController) }