diff --git a/backend/endpoint/workload.go b/backend/endpoint/workload.go index 47d1c2c..6df1688 100644 --- a/backend/endpoint/workload.go +++ b/backend/endpoint/workload.go @@ -6,9 +6,10 @@ import ( ) type WorkloadEndpoint struct { - podUseCase usecase.PodUseCase - deploymentUseCase usecase.DeploymentUseCase - resourceUseCase usecase.ResourceUseCase + podUseCase usecase.PodUseCase + deploymentUseCase usecase.DeploymentUseCase + resourceUseCase usecase.ResourceUseCase + troubleshootUseCase usecase.TroubleshootUseCase } func NewWorkloadEndpoint(podUseCase usecase.PodUseCase, deploymentUseCase usecase.DeploymentUseCase) *WorkloadEndpoint { @@ -51,12 +52,8 @@ func (we *WorkloadEndpoint) ResourceTuning(namespace string, clusterCtx string) we.resourceUseCase.Invoke(namespace, clusterCtx) } -func (we *WorkloadEndpoint) TroubleshootPod(name string, namespace string, clusterCtx string) { - we.podUseCase.TroubleshootPod(name, namespace, clusterCtx) -} - -func (we *WorkloadEndpoint) TroubleshootDeployment(name string, namespace string, clusterCtx string) { - we.deploymentUseCase.TroubleshootDeployment(name, namespace, clusterCtx) +func (we *WorkloadEndpoint) AutoTroubleshoot(name string, namespace string, clusterCtx string, resource string) { + we.troubleshootUseCase.Invoke(name, namespace, clusterCtx, resource) } func (we *WorkloadEndpoint) ExportManifest(name string, namespace string, clusterCtx string) ([]byte, error) { diff --git a/backend/kubeclient/deployment.go b/backend/kubeclient/deployment.go index 1c30531..b2a0461 100644 --- a/backend/kubeclient/deployment.go +++ b/backend/kubeclient/deployment.go @@ -4,6 +4,7 @@ import ( "Kubexplorer/backend/model" "context" "fmt" + v1_apps "k8s.io/api/apps/v1" v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -111,6 +112,17 @@ func (d deploymentClient) GetDeployment(name string, namespace string, clusterCt }, nil } +func (d deploymentClient) GetDeploymentV2(name string, namespace string, clusterCtx string) (*v1_apps.Deployment, error) { + client, err := d.manager.ResolveClusterContext(clusterCtx) + if err != nil { + return &v1_apps.Deployment{}, fmt.Errorf("cluster %s is not registered", clusterCtx) + } + + deployment, _ := client.AppsV1().Deployments(namespace).Get(context.TODO(), name, metav1.GetOptions{}) + + return deployment, nil +} + func (d deploymentClient) UpdateDeployment(name string, namespace string, dto model.DeploymentUpdate, clusterCtx string) error { client, err := d.manager.ResolveClusterContext(clusterCtx) if err != nil { diff --git a/backend/kubeclient/interfaces.go b/backend/kubeclient/interfaces.go index cf61d6d..2987df0 100644 --- a/backend/kubeclient/interfaces.go +++ b/backend/kubeclient/interfaces.go @@ -2,6 +2,9 @@ package kubeclient import ( "Kubexplorer/backend/model" + v1_apps "k8s.io/api/apps/v1" + v1_batch "k8s.io/api/batch/v1" + v1_core "k8s.io/api/core/v1" "k8s.io/metrics/pkg/apis/metrics/v1beta1" ) @@ -23,13 +26,20 @@ type MetricClient interface { type PodClient interface { GetPods(clusterCtx string) ([]model.PodDto, error) GetPod(name string, namespace string, clusterCtx string) (model.PodDto, error) + GetPodV2(name string, namespace string, clusterCtx string) (*v1_core.Pod, error) + UpdatePod(name string, namespace string, dto model.PodUpdate, clusterCtx string) error DeletePod(name string, namespace string, clusterCtx string) error } +type JobClient interface { + GetJob(name string, namespace string, clusterCtx string) (*v1_batch.Job, error) +} + type DeploymentClient interface { GetDeployments(clusterCtx string) ([]model.DeploymentDto, error) GetDeployment(name string, namespace string, clusterCtx string) (model.DeploymentDto, error) + GetDeploymentV2(name string, namespace string, clusterCtx string) (*v1_apps.Deployment, error) UpdateDeployment(name string, namespace string, dto model.DeploymentUpdate, clusterCtx string) error DeleteDeployment(name string, namespace string, clusterCtx string) error ExportManifest(name string, namespace string, clusterCtx string) ([]byte, error) diff --git a/backend/kubeclient/job.go b/backend/kubeclient/job.go new file mode 100644 index 0000000..0f645e7 --- /dev/null +++ b/backend/kubeclient/job.go @@ -0,0 +1,29 @@ +package kubeclient + +import ( + "context" + "fmt" + v1 "k8s.io/api/batch/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type jobClient struct { + manager ClusterResolver +} + +func NewJob(manager ClusterResolver) JobClient { + return &jobClient{ + manager: manager, + } +} + +func (j *jobClient) GetJob(name string, namespace string, clusterCtx string) (*v1.Job, error) { + client, err := j.manager.ResolveClusterContext(clusterCtx) + if err != nil { + return &v1.Job{}, fmt.Errorf("cluster %s is not registered", clusterCtx) + } + + job, _ := client.BatchV1().Jobs(namespace).Get(context.TODO(), name, metav1.GetOptions{}) + + return job, nil +} diff --git a/backend/kubeclient/pod.go b/backend/kubeclient/pod.go index f80ec3a..10ce292 100644 --- a/backend/kubeclient/pod.go +++ b/backend/kubeclient/pod.go @@ -4,6 +4,7 @@ import ( "Kubexplorer/backend/model" "context" "fmt" + v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -69,6 +70,17 @@ func (p *podClient) GetPods(clusterCtx string) ([]model.PodDto, error) { return podArray, nil } +func (p *podClient) GetPodV2(clusterCtx string, name string, namespace string) (*v1.Pod, error) { + client, err := p.manager.ResolveClusterContext(clusterCtx) + if err != nil { + return &v1.Pod{}, fmt.Errorf("cluster %s is not registered", clusterCtx) + } + + pod, _ := client.CoreV1().Pods(namespace).Get(context.TODO(), name, metav1.GetOptions{}) + + return pod, nil +} + func (p *podClient) GetPod(name string, namespace string, clusterCtx string) (model.PodDto, error) { client, err := p.manager.ResolveClusterContext(clusterCtx) if err != nil { diff --git a/backend/model/job.go b/backend/model/job.go new file mode 100644 index 0000000..54c104e --- /dev/null +++ b/backend/model/job.go @@ -0,0 +1,12 @@ +package model + +type JobDto struct { + Name string + Namespace string + Container Container + Node string + Age string + Status string + Editable []string + Labels map[string]string +} diff --git a/backend/model/troubleshoot.go b/backend/model/troubleshoot.go new file mode 100644 index 0000000..0e6872d --- /dev/null +++ b/backend/model/troubleshoot.go @@ -0,0 +1,6 @@ +package model + +type Troubleshoot struct { + Meaning string + Recommendation string +} diff --git a/backend/service/diagnostic.go b/backend/service/diagnostic.go index a528ded..bd340db 100644 --- a/backend/service/diagnostic.go +++ b/backend/service/diagnostic.go @@ -1,13 +1,13 @@ package service import ( - "context" + "Kubexplorer/backend/kubeclient" + "Kubexplorer/backend/model" "fmt" - app "k8s.io/api/apps/v1" - batch "k8s.io/api/batch/v1" - core "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/kubernetes" + + appsv1 "k8s.io/api/apps/v1" + batchv1 "k8s.io/api/batch/v1" + corev1 "k8s.io/api/core/v1" ) type SourceObject string @@ -20,10 +20,7 @@ const ( type WellKnownPodError string type WellKnownDeploymentError string - type WellKnownJobError string -type WellKnowServiceError string -type WellKnowSecretError string const ( // Pod-level @@ -36,133 +33,245 @@ const ( Unschedulable WellKnownPodError = "Unschedulable" Evicted WellKnownPodError = "Evicted" NodeLost WellKnownPodError = "NodeLost" + Completed WellKnownPodError = "Completed" + Pending WellKnownPodError = "Pending" + Terminating WellKnownPodError = "Terminating" // Deployment-level UnavailableReplicas WellKnownDeploymentError = "UnavailableReplicas" MinimumReplicasUnavailable WellKnownDeploymentError = "MinimumReplicasUnavailable" + ProgressDeadlineExceeded WellKnownDeploymentError = "ProgressDeadlineExceeded" // Job-level DeadlineExceeded WellKnownJobError = "DeadlineExceeded" BackoffLimitExceeded WellKnownJobError = "BackoffLimitExceeded" ) +var PodErrorMessages = map[WellKnownPodError]string{ + CrashLoopBackOff: "The container keeps crashing on startup. Check container logs with `kubectl logs` and verify entrypoint, configs, or dependencies.", + OOMKilled: "The container was killed due to exceeding memory limits. Increase memory limits/requests or optimize application memory usage.", + ImagePullBackOff: "Kubernetes cannot pull the container image. Verify image name, tag, registry credentials, or network access.", + ErrImagePull: "The image could not be pulled. Check that the image exists and that the registry is accessible.", + CreateContainerConfigError: "Invalid container configuration. Review environment variables, volume mounts, and container spec.", + ContainerCannotRun: "The container failed to start. Check entrypoint, permissions, or binary compatibility.", + Unschedulable: "The pod cannot be scheduled. Verify resource requests, node selectors, taints, or affinity rules.", + Evicted: "The pod was evicted due to resource pressure. Reduce requests/limits or add more cluster resources.", + NodeLost: "The node running this pod is unreachable. Check node health and networking.", + Completed: "The pod has successfully finished execution (Job/Pod complete). No action needed unless it was expected to keep running.", + Pending: "The pod is stuck in Pending. Check scheduler logs, resource availability, or PVC binding.", + Terminating: "The pod is stuck in Terminating. Check for finalizers, stuck volumes, or force delete with `kubectl delete pod --force --grace-period=0`.", +} + +var DeploymentErrorMessages = map[WellKnownDeploymentError]string{ + UnavailableReplicas: "Not enough replicas are available. Check pod errors, resource limits, or scheduling constraints.", + MinimumReplicasUnavailable: "Minimum replicas not met. Scale your cluster or adjust replica settings.", + ProgressDeadlineExceeded: "Deployment rollout is stuck. Check pod logs, events, and ensure readiness/liveness probes are correct.", +} + +var JobErrorMessages = map[WellKnownJobError]string{ + DeadlineExceeded: "The Job exceeded its active deadline. Increase `.spec.activeDeadlineSeconds` or optimize the job workload.", + BackoffLimitExceeded: "The Job retried too many times and failed. Investigate pod logs and fix underlying issues.", +} + type DiagnosticService interface { - Analyse(name string, namespace string, object SourceObject) + Analyse(name string, namespace string, clusterCtx string, resource string) model.Troubleshoot } type diagnosticService struct { - client kubernetes.Interface + pod kubeclient.PodClient + deployment kubeclient.DeploymentClient + job kubeclient.JobClient } -func NewDiagnosticService(client kubernetes.Interface) DiagnosticService { - return &diagnosticService{client: client} +func NewDiagnosticService(pod kubeclient.PodClient, deployment kubeclient.DeploymentClient, job kubeclient.JobClient) DiagnosticService { + return &diagnosticService{pod: pod, deployment: deployment, job: job} } -func (d *diagnosticService) Analyse(name string, namespace string, object SourceObject) { - - switch object { - case Pod: - pod, err := d.client.CoreV1().Pods(namespace).Get(context.TODO(), name, metav1.GetOptions{}) +func (d *diagnosticService) Analyse(name string, namespace string, clusterCtx string, resource string) model.Troubleshoot { + switch resource { + case string(Pod): + pod, err := d.pod.GetPodV2(name, namespace, clusterCtx) if err != nil { - fmt.Printf("Error retrieving Pod: %v\n", err) - return + return model.Troubleshoot{Meaning: fmt.Sprintf("Error retrieving Pod: %v", err)} } - identifyPodPotentialError(pod) - case Job: - job, err := d.client.BatchV1().Jobs(namespace).Get(context.TODO(), name, metav1.GetOptions{}) + return CheckPodErrors(*pod) + + case string(Deployment): + dep, err := d.deployment.GetDeploymentV2(name, namespace, clusterCtx) if err != nil { - fmt.Printf("Error retrieving Job: %v\n", err) - return + return model.Troubleshoot{Meaning: fmt.Sprintf("Error retrieving Deployment: %v", err)} } - identifyJobPotentialError(job) - case Deployment: - deployment, err := d.client.AppsV1().Deployments(namespace).Get(context.TODO(), name, metav1.GetOptions{}) + return CheckDeploymentErrors(*dep) + + case string(Job): + job, err := d.job.GetJob(name, namespace, clusterCtx) if err != nil { - fmt.Printf("Error retrieving Deployment: %v\n", err) - return + return model.Troubleshoot{Meaning: fmt.Sprintf("Error retrieving Job: %v", err)} } - identifyDeploymentPotentialError(deployment) + return CheckJobErrors(*job) + default: - fmt.Println("Not a valid object") + return model.Troubleshoot{Meaning: "Unsupported object type"} } - } -func identifyPodPotentialError(pod *core.Pod) { - fmt.Println("Pod:", pod.Name) - fmt.Println("Phase:", pod.Status.Phase) - fmt.Println("PodIP:", pod.Status.PodIP) - fmt.Println("Message:", pod.Status.Message) - fmt.Println("Reason:", pod.Status.Reason) - - switch pod.Status.Reason { - case string(Evicted): - fmt.Println("Evicted") - case string(NodeLost): - fmt.Println("NodeLost") +func CheckPodErrors(pod corev1.Pod) model.Troubleshoot { + // Check phase-level + switch pod.Status.Phase { + case corev1.PodPending: + if msg, ok := PodErrorMessages[Pending]; ok { + return model.Troubleshoot{ + Meaning: string(Pending), + Recommendation: msg, + } + } + case corev1.PodSucceeded: + if msg, ok := PodErrorMessages[Completed]; ok { + return model.Troubleshoot{ + Meaning: string(Completed), + Recommendation: msg, + } + } + case corev1.PodFailed: + if msg, ok := PodErrorMessages[Terminating]; ok { + return model.Troubleshoot{ + Meaning: string(Terminating), + Recommendation: msg, + } + } } - for _, container := range pod.Status.ContainerStatuses { - fmt.Println("ContainerID:", container.ContainerID) - fmt.Println("State:", container.State) - fmt.Println("Name:", container.Name) - fmt.Println("Image:", container.Image) - fmt.Println("ImageID:", container.ImageID) - - if container.State.Terminated != nil { - if container.LastTerminationState.Terminated.Reason == string(OOMKilled) { - fmt.Println("Container is crashing. Suggest increase memory usage.") + // Check conditions + for _, cond := range pod.Status.Conditions { + if cond.Type == corev1.PodScheduled && cond.Status == corev1.ConditionFalse { + if msg, ok := PodErrorMessages[Unschedulable]; ok { + return model.Troubleshoot{ + Meaning: string(Unschedulable), + Recommendation: msg, + } } } + if cond.Reason == "Evicted" { + if msg, ok := PodErrorMessages[Evicted]; ok { + return model.Troubleshoot{ + Meaning: string(Evicted), + Recommendation: msg, + } + } + } + if cond.Reason == "NodeLost" { + if msg, ok := PodErrorMessages[NodeLost]; ok { + return model.Troubleshoot{ + Meaning: string(NodeLost), + Recommendation: msg, + } + } + } + } - if container.State.Waiting != nil { - fmt.Println("Waiting.Message:", container.State.Waiting.Message) - reason := container.State.Waiting.Reason - fmt.Println("Waiting.Reason:", reason) - - switch reason { - case string(CrashLoopBackOff): - fmt.Println("Container is crashing. Suggest checking logs.") - case string(ImagePullBackOff): - fmt.Println("Container is crashing. Suggest check out the image policy.") - case string(ErrImagePull): - fmt.Println("Container is crashing. Suggest check out the image repository.") - case string(ContainerCannotRun): - fmt.Println("Container is crashing. Probably the Container Cannot Run") - case string(CreateContainerConfigError): - fmt.Println("Container is crashing. Probably the Create Container Config Error") + // Check container states + for _, cs := range pod.Status.ContainerStatuses { + if cs.State.Waiting != nil { + if msg, ok := PodErrorMessages[WellKnownPodError(cs.State.Waiting.Reason)]; ok { + return model.Troubleshoot{ + Meaning: cs.State.Waiting.Reason, + Recommendation: msg, + } + } + } + if cs.State.Terminated != nil { + if msg, ok := PodErrorMessages[WellKnownPodError(cs.State.Terminated.Reason)]; ok { + return model.Troubleshoot{ + Meaning: cs.State.Terminated.Reason, + Recommendation: msg, + } + } + } + if cs.LastTerminationState.Terminated != nil { + if msg, ok := PodErrorMessages[WellKnownPodError(cs.LastTerminationState.Terminated.Reason)]; ok { + return model.Troubleshoot{ + Meaning: cs.State.Terminated.Reason, + Recommendation: msg, + } } } } - for _, condition := range pod.Status.Conditions { - if condition.Reason == string(Unschedulable) { - fmt.Println("Container is crashing. Unschedulable state") + // Fallback: if pod.Status.Reason is set + if pod.Status.Reason != "" { + if msg, ok := PodErrorMessages[WellKnownPodError(pod.Status.Reason)]; ok { + return model.Troubleshoot{ + Meaning: pod.Status.Reason, + Recommendation: msg, + } } } + return model.Troubleshoot{Meaning: "No known pod errors detected."} } -func identifyJobPotentialError(job *batch.Job) { +func CheckDeploymentErrors(dep appsv1.Deployment) model.Troubleshoot { + desired := int32(1) + if dep.Spec.Replicas != nil { + desired = *dep.Spec.Replicas + } + available := dep.Status.AvailableReplicas + ready := dep.Status.ReadyReplicas - for _, condition := range job.Status.Conditions { - if condition.Reason == string(BackoffLimitExceeded) { - fmt.Println("Container is crashing. BackoffLimitExceeded.") + if available < desired { + if msg, ok := DeploymentErrorMessages[UnavailableReplicas]; ok { + return model.Troubleshoot{ + Meaning: string(UnavailableReplicas), + Recommendation: msg, + } } - if condition.Reason == string(DeadlineExceeded) { - fmt.Println("Container is crashing. DeadlineExceeded.") + } + if ready < desired { + if msg, ok := DeploymentErrorMessages[MinimumReplicasUnavailable]; ok { + return model.Troubleshoot{ + Meaning: string(MinimumReplicasUnavailable), + Recommendation: msg, + } } } -} -func identifyDeploymentPotentialError(deployment *app.Deployment) { - if deployment.Status.UnavailableReplicas > 0 { - fmt.Println("Deployment is unavailable") + for _, cond := range dep.Status.Conditions { + if cond.Type == appsv1.DeploymentProgressing && cond.Reason == "ProgressDeadlineExceeded" { + if msg, ok := DeploymentErrorMessages[ProgressDeadlineExceeded]; ok { + return model.Troubleshoot{ + Meaning: string(ProgressDeadlineExceeded), + Recommendation: msg, + } + } + } } - for _, condition := range deployment.Status.Conditions { - if condition.Reason == string(MinimumReplicasUnavailable) { - fmt.Println("Deployment error. MinimumReplicasUnavailable.") + return model.Troubleshoot{Meaning: "No known deployment errors detected."} +} + +func CheckJobErrors(job batchv1.Job) model.Troubleshoot { + for _, cond := range job.Status.Conditions { + if cond.Type == batchv1.JobFailed && cond.Status == corev1.ConditionTrue { + switch cond.Reason { + case "BackoffLimitExceeded": + if msg, ok := JobErrorMessages[BackoffLimitExceeded]; ok { + return model.Troubleshoot{ + Meaning: string(BackoffLimitExceeded), + Recommendation: msg, + } + } + case "DeadlineExceeded": + if msg, ok := JobErrorMessages[DeadlineExceeded]; ok { + return model.Troubleshoot{ + Meaning: string(DeadlineExceeded), + Recommendation: msg, + } + } + default: + return model.Troubleshoot{Meaning: cond.Message} + } } } + + return model.Troubleshoot{Meaning: "No known job errors detected."} } diff --git a/backend/usecase/deployment.go b/backend/usecase/deployment.go index 4601408..9970026 100644 --- a/backend/usecase/deployment.go +++ b/backend/usecase/deployment.go @@ -11,7 +11,6 @@ type DeploymentUseCase interface { GetDeployment(name string, namespace string, clusterCtx string) (model.DeploymentDto, error) UpdateDeployment(name string, namespace string, dto model.DeploymentUpdate, clusterCtx string) error DeleteDeployment(name string, namespace string, clusterCtx string) error - TroubleshootDeployment(name string, namespace string, clusterCtx string) ExportManifest(name string, namespace string, clusterCtx string) ([]byte, error) } @@ -40,10 +39,6 @@ func (d *deploymentUseCase) DeleteDeployment(name string, namespace string, clus return d.client.DeleteDeployment(name, namespace, clusterCtx) } -func (d *deploymentUseCase) TroubleshootDeployment(name string, namespace string, clusterCtx string) { - d.service.Analyse(name, namespace, service.Deployment) -} - func (d *deploymentUseCase) ExportManifest(name string, namespace string, clusterCtx string) ([]byte, error) { return d.client.ExportManifest(name, namespace, clusterCtx) } diff --git a/backend/usecase/pod.go b/backend/usecase/pod.go index 78aa26c..8016cc1 100644 --- a/backend/usecase/pod.go +++ b/backend/usecase/pod.go @@ -11,7 +11,6 @@ type PodUseCase interface { GetPod(name string, namespace string, clusterCtx string) (model.PodDto, error) UpdatePod(name string, namespace string, dto model.PodUpdate, clusterCtx string) error RestartPod(name string, namespace string, clusterCtx string) error - TroubleshootPod(name string, namespace string, clusterCtx string) } type podUseCase struct { @@ -38,7 +37,3 @@ func (p *podUseCase) UpdatePod(name string, namespace string, dto model.PodUpdat func (p *podUseCase) RestartPod(name string, namespace string, clusterCtx string) error { return p.client.DeletePod(name, namespace, clusterCtx) } - -func (p *podUseCase) TroubleshootPod(name string, namespace string, clusterCtx string) { - p.service.Analyse(name, namespace, service.Pod) -} diff --git a/backend/usecase/troubleshoot.go b/backend/usecase/troubleshoot.go new file mode 100644 index 0000000..b5bce30 --- /dev/null +++ b/backend/usecase/troubleshoot.go @@ -0,0 +1,21 @@ +package usecase + +import ( + "Kubexplorer/backend/service" +) + +type TroubleshootUseCase interface { + Invoke(name string, namespace string, clusterCtx string, resource string) +} + +type troubleshootUseCase struct { + service service.DiagnosticService +} + +func NewTroubleshootUseCase(service service.DiagnosticService) TroubleshootUseCase { + return &troubleshootUseCase{service: service} +} + +func (t *troubleshootUseCase) Invoke(name string, namespace string, clusterCtx string, resource string) { + t.service.Analyse(name, namespace, clusterCtx, resource) +} diff --git a/frontend/src/services/workload.service.ts b/frontend/src/services/workload.service.ts index 9a22016..1428ce1 100644 --- a/frontend/src/services/workload.service.ts +++ b/frontend/src/services/workload.service.ts @@ -1,4 +1,5 @@ import { + AutoTroubleshoot, DeleteDeployment, GetDeployment, GetDeployments, @@ -23,5 +24,4 @@ export const fetchUpdateDeployment = async (name: string, namespace: string, dto export const fetchDeleteDeployment = async (name: string, namespace: string, clusterCtx: string) => DeleteDeployment(name, namespace, clusterCtx) export const fetchResourceTuning = async (namespace: string) => ResourceTuning(namespace) -export const fetchTroubleshootPod = async (name: string, namespace: string, clusterCtx: string) => TroubleshootPod(name, namespace, clusterCtx) -export const fetchTroubleshootDeployment = async (name: string, namespace: string, clusterCtx: string) => TroubleshootDeployment(name, namespace, clusterCtx) +export const fetchAutoTroubleshoot = async (name: string, namespace: string, clusterCtx: string, resource: string) => AutoTroubleshoot(name, namespace, clusterCtx, resource) diff --git a/frontend/wailsjs/go/middleware/WorkloadMiddleware.d.ts b/frontend/wailsjs/go/middleware/WorkloadMiddleware.d.ts index ea949f3..a7fdedf 100755 --- a/frontend/wailsjs/go/middleware/WorkloadMiddleware.d.ts +++ b/frontend/wailsjs/go/middleware/WorkloadMiddleware.d.ts @@ -2,6 +2,8 @@ // This file is automatically generated. DO NOT EDIT import {model} from '../models'; +export function AutoTroubleshoot(arg1:string,arg2:string,arg3:string,arg4:string):Promise; + export function DeleteDeployment(arg1:string,arg2:string,arg3:string):Promise; export function ExportManifest(arg1:string,arg2:string,arg3:string):Promise>; @@ -18,10 +20,6 @@ export function ResourceTuning(arg1:string,arg2:string):Promise; export function RestartPod(arg1:string,arg2:string,arg3:string):Promise; -export function TroubleshootDeployment(arg1:string,arg2:string,arg3:string):Promise; - -export function TroubleshootPod(arg1:string,arg2:string,arg3:string):Promise; - export function UpdateDeployment(arg1:string,arg2:string,arg3:model.DeploymentUpdate,arg4:string):Promise; export function UpdatePod(arg1:string,arg2:string,arg3:model.PodUpdate,arg4:string):Promise; diff --git a/frontend/wailsjs/go/middleware/WorkloadMiddleware.js b/frontend/wailsjs/go/middleware/WorkloadMiddleware.js index 11a2799..6ad5422 100755 --- a/frontend/wailsjs/go/middleware/WorkloadMiddleware.js +++ b/frontend/wailsjs/go/middleware/WorkloadMiddleware.js @@ -2,6 +2,10 @@ // Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL // This file is automatically generated. DO NOT EDIT +export function AutoTroubleshoot(arg1, arg2, arg3, arg4) { + return window['go']['middleware']['WorkloadMiddleware']['AutoTroubleshoot'](arg1, arg2, arg3, arg4); +} + export function DeleteDeployment(arg1, arg2, arg3) { return window['go']['middleware']['WorkloadMiddleware']['DeleteDeployment'](arg1, arg2, arg3); } @@ -34,14 +38,6 @@ export function RestartPod(arg1, arg2, arg3) { return window['go']['middleware']['WorkloadMiddleware']['RestartPod'](arg1, arg2, arg3); } -export function TroubleshootDeployment(arg1, arg2, arg3) { - return window['go']['middleware']['WorkloadMiddleware']['TroubleshootDeployment'](arg1, arg2, arg3); -} - -export function TroubleshootPod(arg1, arg2, arg3) { - return window['go']['middleware']['WorkloadMiddleware']['TroubleshootPod'](arg1, arg2, arg3); -} - export function UpdateDeployment(arg1, arg2, arg3, arg4) { return window['go']['middleware']['WorkloadMiddleware']['UpdateDeployment'](arg1, arg2, arg3, arg4); } diff --git a/middleware/workload.go b/middleware/workload.go index ae1356f..9e2ab9e 100644 --- a/middleware/workload.go +++ b/middleware/workload.go @@ -57,12 +57,8 @@ func (w *WorkloadMiddleware) ResourceTuning(namespace string, clusterCtx string) w.endpoint.ResourceTuning(namespace, clusterCtx) } -func (w *WorkloadMiddleware) TroubleshootPod(name string, namespace string, clusterCtx string) { - w.endpoint.TroubleshootPod(name, namespace, clusterCtx) -} - -func (w *WorkloadMiddleware) TroubleshootDeployment(name string, namespace string, clusterCtx string) { - w.endpoint.TroubleshootDeployment(name, namespace, clusterCtx) +func (w *WorkloadMiddleware) AutoTroubleshoot(name string, namespace string, clusterCtx string, resource string) { + w.endpoint.AutoTroubleshoot(name, namespace, clusterCtx, resource) } func (w *WorkloadMiddleware) ExportManifest(name string, namespace string, clusterCtx string) ([]byte, error) { @@ -72,7 +68,9 @@ func (w *WorkloadMiddleware) ExportManifest(name string, namespace string, clust func BuildWorkload(manager kubeclient.ClusterResolver) *WorkloadMiddleware { deploymentClient := kubeclient.NewDeployment(manager) podClient := kubeclient.NewPod(manager) - diagnosticService := service.NewDiagnosticService(nil) + jobClient := kubeclient.NewJob(manager) + + diagnosticService := service.NewDiagnosticService(podClient, deploymentClient, jobClient) deploymentUseCase := usecase.NewDeploymentUseCase(deploymentClient, diagnosticService) podUseCase := usecase.NewPodUseCase(podClient, diagnosticService)