877 lines
22 KiB
Go
877 lines
22 KiB
Go
package handler
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/base64"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"log"
|
|
"main/argohandler"
|
|
"main/db"
|
|
"net/http"
|
|
"sort"
|
|
"strings"
|
|
"time"
|
|
|
|
appsv1 "k8s.io/api/apps/v1"
|
|
corev1 "k8s.io/api/core/v1"
|
|
"k8s.io/kubectl/pkg/scheme"
|
|
|
|
// "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/rest"
|
|
"k8s.io/client-go/tools/clientcmd"
|
|
"k8s.io/client-go/tools/remotecommand"
|
|
)
|
|
|
|
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)
|
|
}
|
|
|
|
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, *rest.Config, error) {
|
|
|
|
kubeconfig, err := getClusterConfig(clustername)
|
|
if err != nil {
|
|
http.Error(w, "File to get kubeconfig", http.StatusInternalServerError)
|
|
return nil, nil, err
|
|
}
|
|
|
|
kubeconfigbyte := []byte(kubeconfig)
|
|
config, err := clientcmd.RESTConfigFromKubeConfig(kubeconfigbyte)
|
|
if err != nil {
|
|
log.Println("Error creating rest config:", err)
|
|
return nil, nil, err
|
|
}
|
|
|
|
clientset, err := kubernetes.NewForConfig(config)
|
|
if err != nil {
|
|
log.Println("Error creating clientSet:", err)
|
|
return nil, nil, err
|
|
}
|
|
|
|
return clientset, config, 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
|
|
now := time.Now()
|
|
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
|
|
age := now.Sub(s.CreationTimestamp.Time)
|
|
service.Age = human(age)
|
|
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
|
|
now := time.Now()
|
|
for _, s := range statefulSets.Items {
|
|
desired := int32(1)
|
|
if s.Spec.Replicas != nil {
|
|
desired = *s.Spec.Replicas
|
|
}
|
|
StatefulSet.Ready = fmt.Sprintf("%d/%d", s.Status.ReadyReplicas, desired)
|
|
StatefulSet.Name = s.Name
|
|
StatefulSet.Namespace = s.Namespace
|
|
age := now.Sub(s.CreationTimestamp.Time) // same as kubectl AGE
|
|
StatefulSet.Age = human(age)
|
|
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
|
|
now := time.Now()
|
|
for _, s := range DaemonSetss.Items {
|
|
DaemonSets.Name = s.Name
|
|
DaemonSets.Namespace = s.Namespace
|
|
DaemonSets.DESIRED = s.Status.DesiredNumberScheduled
|
|
DaemonSets.CURRENT = s.Status.CurrentNumberScheduled
|
|
DaemonSets.Available = s.Status.NumberAvailable
|
|
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)
|
|
age := now.Sub(s.CreationTimestamp.Time) // same as kubectl AGE
|
|
DaemonSets.Age = human(age)
|
|
|
|
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
|
|
var avail bool
|
|
var reason, msg string
|
|
for _, d := range deployments.Items {
|
|
deployment.Name = d.Name
|
|
deployment.Namespace = d.Namespace
|
|
deployment.Replicas = *d.Spec.Replicas
|
|
for _, c := range d.Status.Conditions {
|
|
if c.Type == appsv1.DeploymentAvailable {
|
|
avail = (c.Status == corev1.ConditionTrue)
|
|
reason, msg = c.Reason, c.Message
|
|
deployment.Available = fmt.Sprintf("%t", avail)
|
|
deployment.Message = msg
|
|
deployment.Reason = reason
|
|
}
|
|
}
|
|
|
|
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
|
|
now := time.Now()
|
|
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)
|
|
age := now.Sub(p.CreationTimestamp.Time) // same as kubectl AGE
|
|
pod.Age = human(age)
|
|
|
|
var restartedCount int32
|
|
var restarts int32
|
|
for _, st := range p.Status.ContainerStatuses {
|
|
restarts += st.RestartCount
|
|
}
|
|
pod.Restart = restartedCount
|
|
|
|
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
|
|
now := time.Now()
|
|
for _, d := range jobs.Items {
|
|
job.Name = d.Name
|
|
job.Namespace = d.Namespace
|
|
|
|
status := "Active"
|
|
if d.Status.Succeeded > 0 {
|
|
status = "Complete"
|
|
} else if d.Status.Failed > 0 {
|
|
status = "Failed"
|
|
}
|
|
job.Status = status
|
|
|
|
completions := fmt.Sprintf("%d/%d", d.Status.Succeeded, *d.Spec.Completions)
|
|
job.Completion = completions
|
|
|
|
duration := "-"
|
|
if d.Status.StartTime != nil && d.Status.CompletionTime != nil {
|
|
d := d.Status.CompletionTime.Time.Sub(d.Status.StartTime.Time)
|
|
duration = d.String()
|
|
}
|
|
job.Duration = duration
|
|
|
|
age := now.Sub(d.CreationTimestamp.Time) // same as kubectl AGE
|
|
job.Age = human(age)
|
|
|
|
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
|
|
now := time.Now()
|
|
for _, d := range replicasets.Items {
|
|
replicaset.Name = d.Name
|
|
replicaset.Namespace = d.Namespace
|
|
replicaset.Desired = *d.Spec.Replicas
|
|
replicaset.Current = d.Status.Replicas
|
|
replicaset.Ready = d.Status.ReadyReplicas
|
|
age := now.Sub(d.CreationTimestamp.Time) // same as kubectl AGE
|
|
replicaset.Age = human(age)
|
|
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
|
|
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)
|
|
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
|
|
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.Desired = *d.Spec.Replicas
|
|
ReplicationController.Current = d.Status.Replicas
|
|
ReplicationController.Ready = d.Status.ReadyReplicas
|
|
|
|
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 Pod_logs(w http.ResponseWriter, r *http.Request) {
|
|
clustername := r.URL.Query().Get("Name")
|
|
namespace := r.URL.Query().Get("Namespace")
|
|
podName := r.URL.Query().Get("Pod")
|
|
// containerName := podName
|
|
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)
|
|
}
|
|
|
|
podLogOpts := corev1.PodLogOptions{}
|
|
req := clientset.CoreV1().Pods(namespace).GetLogs(podName, &podLogOpts)
|
|
podLogs, err := req.Stream(context.TODO())
|
|
if err != nil {
|
|
http.Error(w, "an error happend in getting logs", http.StatusBadRequest)
|
|
return
|
|
}
|
|
defer podLogs.Close()
|
|
|
|
buf := new([]byte)
|
|
*buf, err = io.ReadAll(podLogs)
|
|
if err != nil {
|
|
http.Error(w, "an error happend in getting logs", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(string(*buf))
|
|
}
|
|
|
|
func Pod_exec(w http.ResponseWriter, r *http.Request) {
|
|
clustername := r.URL.Query().Get("Name")
|
|
namespace := r.URL.Query().Get("Namespace")
|
|
podName := r.URL.Query().Get("Pod")
|
|
command := r.URL.Query().Get("Command")
|
|
|
|
if clustername == "" || namespace == "" || podName == "" {
|
|
http.Error(w, "Missing required parameters (Name, Namespace, Pod)", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
clientset, config, err := getClientset(w, clustername)
|
|
if err != nil {
|
|
http.Error(w, "Error getting Kubernetes clientset", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
cmd := []string{command}
|
|
|
|
req := clientset.CoreV1().RESTClient().
|
|
Post().
|
|
Resource("pods").
|
|
Name(podName).
|
|
Namespace(namespace).
|
|
SubResource("exec").
|
|
VersionedParams(&corev1.PodExecOptions{
|
|
Command: cmd,
|
|
Stdout: true,
|
|
Stderr: true,
|
|
Stdin: false,
|
|
TTY: false,
|
|
}, scheme.ParameterCodec)
|
|
|
|
exec, err := remotecommand.NewSPDYExecutor(config, "POST", req.URL())
|
|
if err != nil {
|
|
http.Error(w, "Error creating executor: "+err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
var stdout, stderr bytes.Buffer
|
|
|
|
err = exec.StreamWithContext(r.Context(), remotecommand.StreamOptions{
|
|
Stdout: &stdout,
|
|
Stderr: &stderr,
|
|
Tty: false,
|
|
})
|
|
|
|
if err != nil {
|
|
http.Error(w, "Error streaming command output: "+err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
output := map[string]interface{}{
|
|
"stdout": strings.Split(strings.TrimSpace(stdout.String()), "\n"),
|
|
"stderr": strings.TrimSpace(stderr.String()),
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(output)
|
|
}
|