Files
vclusterapi/handler/handler.go
Ybehrooz 1bf0f9835e fix
2025-07-26 12:51:20 +03:30

637 lines
16 KiB
Go

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)
}