diff --git a/__debug_bin1548213419 b/__debug_bin1548213419 new file mode 100755 index 0000000..aa788a2 Binary files /dev/null and b/__debug_bin1548213419 differ diff --git a/handler/handler.go b/handler/handler.go index 3ad33e7..6e74d6b 100644 --- a/handler/handler.go +++ b/handler/handler.go @@ -10,13 +10,13 @@ import ( "log" "main/argohandler" "main/db" + "main/helpers" + "main/models" "net/http" - "sort" "strconv" "strings" "time" - "github.com/golang-jwt/jwt/v4" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" "k8s.io/kubectl/pkg/scheme" @@ -32,176 +32,9 @@ import ( "k8s.io/client-go/tools/remotecommand" ) -type User struct { - ID string `json:"id,omitempty"` - Username string `json:"username"` - Email string `json:"email"` - Password string `json:"password,omitempty"` -} - -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 int32 `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` - Available string `json:available` - Replicas int32 `json:replicas` - Message string `json:message` - Reason string `json:reason` -} - -type Daemonset struct { - Name string `json:name` - Namespace string `json:namespace` - Ready int32 `json:Ready` - Age string `json:age` - DESIRED int32 `json:desired` - CURRENT int32 `json:current` - UpdateToDate int32 `json:uptodate` - Available int32 `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 int32 `json:desired` - Current int32 `json:current` - Ready int32 `json:Ready` - Age string `json:age` - Namespace string `json:name` -} - -type ReplicationController struct { - Namespace string `json:name` - Name string `json:name` - Desired int32 `json:desired` - Current int32 `json:current` - Ready int32 `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 joinNodeSelector(m map[string]string) string { - if len(m) == 0 { - return "" - } - keys := make([]string, 0, len(m)) - for k := range m { - keys = append(keys, k) - } - sort.Strings(keys) - - parts := make([]string, 0, len(keys)) - for _, k := range keys { - parts = append(parts, k+"="+m[k]) - } - return strings.Join(parts, ",") -} - -// human prints like 3d4h5m (compact) -func human(d time.Duration) string { - if d < 0 { - d = -d - } - d = d.Round(time.Second) - - days := int(d / (24 * time.Hour)) - d -= time.Duration(days) * 24 * time.Hour - - hours := int(d / time.Hour) - d -= time.Duration(hours) * time.Hour - - mins := int(d / time.Minute) - d -= time.Duration(mins) * time.Minute - - secs := int(d / time.Second) - - if days > 0 { - if mins > 0 { - return fmt.Sprintf("%dd%dm", days, mins) - } - return fmt.Sprintf("%dd", days) - } - if hours > 0 { - if mins > 0 { - return fmt.Sprintf("%dh%dm", hours, mins) - } - return fmt.Sprintf("%dh", hours) - } - if mins > 0 { - return fmt.Sprintf("%dm", mins) - } - return fmt.Sprintf("%ds", secs) -} - -var jwtKey = []byte("mysecret123") - -func DecodeJwt(tokenString *string, user *User) { - claims := jwt.MapClaims{} - _, err := jwt.ParseWithClaims(*tokenString, claims, func(token *jwt.Token) (interface{}, error) { - return []byte(jwtKey), nil - }) - - if err != nil { - log.Println(err) - return - } - - user.Username = claims["username"].(string) -} - func CreateClusterHandler(w http.ResponseWriter, r *http.Request) { - var cluster Cluster + var cluster models.Cluster _ = json.NewDecoder(r.Body).Decode(&cluster) // vclusterCollection := db.Vclusters_details.FindOne(context.TODO(), bson.M{"name": Cluster.Name}).Decode(&existsCluster) @@ -211,7 +44,7 @@ func CreateClusterHandler(w http.ResponseWriter, r *http.Request) { return } - var existsCluster Cluster + var existsCluster models.Cluster _ = db.Vclusters_details.FindOne(context.TODO(), bson.M{"name": cluster.Name}).Decode(&existsCluster) if existsCluster.Name == cluster.Name { @@ -288,19 +121,17 @@ func getClientset(w http.ResponseWriter, clustername string) (*kubernetes.Client } func ListUserClusters(w http.ResponseWriter, r *http.Request) { - // var cluster Cluster - var header Header - var user User + var header models.Header + var user models.User header.Authorization = r.Header.Get("Authorization") - DecodeJwt(&header.Authorization, &user) + helpers.DecodeJwt(&header.Authorization, &user) - count, err := db.UserCollection.CountDocuments(context.TODO(), bson.M{"username": user.Username}) - if err != nil || count <= 0 { - http.Error(w, `{"message": "Invalid username "}`, http.StatusUnauthorized) + err := helpers.ValidateUser(user.Username) + if err != nil { + http.Error(w, "Anauthorized User", http.StatusUnauthorized) return } - _, clusterList := argohandler.ListUserClusters("userid") w.Header().Set("Content-Type", "application/json") @@ -364,9 +195,9 @@ func Cluster_services(w http.ResponseWriter, r *http.Request) { log.Fatal("Error getting list of services: ", err) } - Allservice := []Service{} + Allservice := []models.Service{} - var service Service + var service models.Service now := time.Now() for _, s := range services.Items { service.Name = s.Name @@ -375,7 +206,7 @@ func Cluster_services(w http.ResponseWriter, r *http.Request) { service.Ports = servicePortsToString(s.Spec.Ports) service.ClusterIP = s.Spec.ClusterIP age := now.Sub(s.CreationTimestamp.Time) - service.Age = human(age) + service.Age = helpers.Human(age) if len(s.Spec.ExternalIPs) > 0 { service.ExternalIP = s.Spec.ExternalIPs[0] } @@ -414,9 +245,9 @@ func Cluster_statefulset(w http.ResponseWriter, r *http.Request) { log.Fatal("Error getting list of StatefulSets: ", err) } - AllstatefulSets := []StatefulSet{} + AllstatefulSets := []models.StatefulSet{} - var StatefulSet StatefulSet + var StatefulSet models.StatefulSet now := time.Now() for _, s := range statefulSets.Items { desired := int32(1) @@ -427,7 +258,7 @@ func Cluster_statefulset(w http.ResponseWriter, r *http.Request) { StatefulSet.Name = s.Name StatefulSet.Namespace = s.Namespace age := now.Sub(s.CreationTimestamp.Time) // same as kubectl AGE - StatefulSet.Age = human(age) + StatefulSet.Age = helpers.Human(age) AllstatefulSets = append(AllstatefulSets, StatefulSet) } @@ -462,9 +293,9 @@ func Cluster_daemonsets(w http.ResponseWriter, r *http.Request) { log.Fatal("Error getting list of DaemonSets: ", err) } - AllDaemonSets := []Daemonset{} + AllDaemonSets := []models.Daemonset{} - var DaemonSets Daemonset + var DaemonSets models.Daemonset now := time.Now() for _, s := range DaemonSetss.Items { DaemonSets.Name = s.Name @@ -475,9 +306,9 @@ func Cluster_daemonsets(w http.ResponseWriter, r *http.Request) { DaemonSets.Ready = s.Status.NumberReady DaemonSets.UpdateToDate = s.Status.UpdatedNumberScheduled DaemonSets.Node = s.Spec.Template.Spec.NodeName - DaemonSets.Selector = joinNodeSelector(s.Spec.Template.Spec.NodeSelector) + DaemonSets.Selector = helpers.JoinNodeSelector(s.Spec.Template.Spec.NodeSelector) age := now.Sub(s.CreationTimestamp.Time) // same as kubectl AGE - DaemonSets.Age = human(age) + DaemonSets.Age = helpers.Human(age) AllDaemonSets = append(AllDaemonSets, DaemonSets) } @@ -513,9 +344,9 @@ func Cluster_deployments(w http.ResponseWriter, r *http.Request) { log.Fatal("Error getting list of deployments: ", err) } - Alldeployment := []Deployment{} + Alldeployment := []models.Deployment{} - var deployment Deployment + var deployment models.Deployment var avail bool var reason, msg string for _, d := range deployments.Items { @@ -573,9 +404,9 @@ func Cluster_pods(w http.ResponseWriter, r *http.Request) { log.Fatal("Error getting list of pods: ", err) } - Allpod := []Pod{} + Allpod := []models.Pod{} - var pod Pod + var pod models.Pod now := time.Now() for _, p := range pods.Items { fmt.Printf(p.Name, p.Namespace) @@ -583,7 +414,7 @@ func Cluster_pods(w http.ResponseWriter, r *http.Request) { pod.Namespace = p.Namespace pod.Status = string(p.Status.Phase) age := now.Sub(p.CreationTimestamp.Time) // same as kubectl AGE - pod.Age = human(age) + pod.Age = helpers.Human(age) var restartedCount int32 var restarts int32 @@ -605,7 +436,7 @@ func Cluster_pods(w http.ResponseWriter, r *http.Request) { } func getClusterConfig(clustername string) (string, error) { - var existsCluster Cluster + var existsCluster models.Cluster err := db.Vclusters_details.FindOne(context.TODO(), bson.M{"name": clustername}).Decode(&existsCluster) if err != nil { return "", err @@ -624,7 +455,7 @@ func Connect(w http.ResponseWriter, r *http.Request) { return } - var existsCluster Cluster + var existsCluster models.Cluster _ = db.Vclusters_details.FindOne(context.TODO(), bson.M{"name": clusterName}).Decode(&existsCluster) decoded, err := base64.StdEncoding.DecodeString(existsCluster.Cluster_config) @@ -665,9 +496,9 @@ func Cluster_jobs(w http.ResponseWriter, r *http.Request) { log.Fatal("Error getting list of Jobs: ", err) } - AllJob := []Jobs{} + AllJob := []models.Jobs{} - var job Jobs + var job models.Jobs now := time.Now() for _, d := range jobs.Items { job.Name = d.Name @@ -692,7 +523,7 @@ func Cluster_jobs(w http.ResponseWriter, r *http.Request) { job.Duration = duration age := now.Sub(d.CreationTimestamp.Time) // same as kubectl AGE - job.Age = human(age) + job.Age = helpers.Human(age) AllJob = append(AllJob, job) } @@ -727,9 +558,9 @@ func Cluster_replicasets(w http.ResponseWriter, r *http.Request) { log.Fatal("Error getting list of Replicaset: ", err) } - Allreplicaset := []Replicaset{} + Allreplicaset := []models.Replicaset{} - var replicaset Replicaset + var replicaset models.Replicaset now := time.Now() for _, d := range replicasets.Items { replicaset.Name = d.Name @@ -738,7 +569,7 @@ func Cluster_replicasets(w http.ResponseWriter, r *http.Request) { replicaset.Current = d.Status.Replicas replicaset.Ready = d.Status.ReadyReplicas age := now.Sub(d.CreationTimestamp.Time) // same as kubectl AGE - replicaset.Age = human(age) + replicaset.Age = helpers.Human(age) Allreplicaset = append(Allreplicaset, replicaset) } @@ -772,15 +603,15 @@ func Cluster_replicationcontrollers(w http.ResponseWriter, r *http.Request) { log.Fatal("Error getting list of ReplicationController: ", err) } - AllreplicationController := []ReplicationController{} + AllreplicationController := []models.ReplicationController{} - var ReplicationController ReplicationController + var ReplicationController models.ReplicationController now := time.Now() for _, d := range replicationcontrollers.Items { ReplicationController.Name = d.Name ReplicationController.Namespace = d.Namespace age := now.Sub(d.CreationTimestamp.Time) // same as kubectl AGE - ReplicationController.Age = human(age) + ReplicationController.Age = helpers.Human(age) AllreplicationController = append(AllreplicationController, ReplicationController) } @@ -814,15 +645,15 @@ func Cluster_cronjobs(w http.ResponseWriter, r *http.Request) { log.Fatal("Error getting list of ReplicationController: ", err) } - AllreplicationController := []ReplicationController{} + AllreplicationController := []models.ReplicationController{} - var ReplicationController ReplicationController + var ReplicationController models.ReplicationController now := time.Now() for _, d := range replicationcontrollers.Items { ReplicationController.Name = d.Name ReplicationController.Namespace = d.Namespace age := now.Sub(d.CreationTimestamp.Time) // same as kubectl AGE - ReplicationController.Age = human(age) + ReplicationController.Age = helpers.Human(age) ReplicationController.Desired = *d.Spec.Replicas ReplicationController.Current = d.Status.Replicas diff --git a/helpers/helpers.go b/helpers/helpers.go new file mode 100644 index 0000000..0f0e087 --- /dev/null +++ b/helpers/helpers.go @@ -0,0 +1,94 @@ +package helpers + +import ( + "context" + "fmt" + "log" + "main/db" + "main/models" + "sort" + "strings" + "time" + + "github.com/golang-jwt/jwt/v4" + "go.mongodb.org/mongo-driver/bson" +) + +func JoinNodeSelector(m map[string]string) string { + if len(m) == 0 { + return "" + } + keys := make([]string, 0, len(m)) + for k := range m { + keys = append(keys, k) + } + sort.Strings(keys) + + parts := make([]string, 0, len(keys)) + for _, k := range keys { + parts = append(parts, k+"="+m[k]) + } + return strings.Join(parts, ",") +} + +// human prints like 3d4h5m (compact) +func Human(d time.Duration) string { + if d < 0 { + d = -d + } + d = d.Round(time.Second) + + days := int(d / (24 * time.Hour)) + d -= time.Duration(days) * 24 * time.Hour + + hours := int(d / time.Hour) + d -= time.Duration(hours) * time.Hour + + mins := int(d / time.Minute) + d -= time.Duration(mins) * time.Minute + + secs := int(d / time.Second) + + if days > 0 { + if mins > 0 { + return fmt.Sprintf("%dd%dm", days, mins) + } + return fmt.Sprintf("%dd", days) + } + if hours > 0 { + if mins > 0 { + return fmt.Sprintf("%dh%dm", hours, mins) + } + return fmt.Sprintf("%dh", hours) + } + if mins > 0 { + return fmt.Sprintf("%dm", mins) + } + return fmt.Sprintf("%ds", secs) +} + +var jwtKey = []byte("mysecret123") + +func DecodeJwt(tokenString *string, user *models.User) { + claims := jwt.MapClaims{} + _, err := jwt.ParseWithClaims(*tokenString, claims, func(token *jwt.Token) (interface{}, error) { + return []byte(jwtKey), nil + }) + + if err != nil { + log.Println(err) + return + } + + user.Username = claims["username"].(string) +} + +func ValidateUser(user string) error { + count, err := db.UserCollection.CountDocuments(context.TODO(), bson.M{"username": user}) + + if err != nil || count <= 0 { + return err + } + + return nil +} diff --git a/models/workloads.go b/models/workloads.go new file mode 100644 index 0000000..19db578 --- /dev/null +++ b/models/workloads.go @@ -0,0 +1,101 @@ +package models + +import "go.mongodb.org/mongo-driver/bson/primitive" + +type User struct { + ID string `json:"id,omitempty"` + Username string `json:"username"` + Email string `json:"email"` + Password string `json:"password,omitempty"` +} + +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 int32 `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` + Available string `json:available` + Replicas int32 `json:replicas` + Message string `json:message` + Reason string `json:reason` +} + +type Daemonset struct { + Name string `json:name` + Namespace string `json:namespace` + Ready int32 `json:Ready` + Age string `json:age` + DESIRED int32 `json:desired` + CURRENT int32 `json:current` + UpdateToDate int32 `json:uptodate` + Available int32 `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 int32 `json:desired` + Current int32 `json:current` + Ready int32 `json:Ready` + Age string `json:age` + Namespace string `json:name` +} + +type ReplicationController struct { + Namespace string `json:name` + Name string `json:name` + Desired int32 `json:desired` + Current int32 `json:current` + Ready int32 `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` +}