Skip to content

Commit

Permalink
feat: Add Kubernetes Jobs support to the application
Browse files Browse the repository at this point in the history
This commit introduces comprehensive support for Kubernetes Jobs, including:
- Backend methods to fetch Jobs in KubeHelper
- Controller methods for listing and retrieving Job details
- UI components to display and interact with Jobs
- API endpoints for Jobs
- Caching mechanism for Job-related data

The implementation follows the existing patterns used for other Kubernetes resources like Deployments and PostgreSQL.
  • Loading branch information
Tycale committed Dec 31, 2024
1 parent ba6618b commit 485ac0a
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 0 deletions.
16 changes: 16 additions & 0 deletions internal/k8s/kube.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,3 +201,19 @@ func (k *KubeHelper) GetPostgresql(namespace, name string) (map[string]interface
}
return unstr.Object, nil
}

func (k *KubeHelper) GetJobs(namespace string) ([]batchv1.Job, error) {
jobs, err := k.client.BatchV1().Jobs(namespace).List(context.Background(), metav1.ListOptions{})
if err != nil {
return nil, err
}
return jobs.Items, nil
}

func (k *KubeHelper) GetJob(namespace string, name string) (*batchv1.Job, error) {
job, err := k.client.BatchV1().Jobs(namespace).Get(context.Background(), name, metav1.GetOptions{})
if err != nil {
return nil, err
}
return job, nil
}
42 changes: 42 additions & 0 deletions internal/server/controller/badges.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type BadgesController struct {
podCache *cache.Cache[string, BadgeMessage]
kustomizationCache *cache.Cache[string, BadgeMessage]
postgresqlCache *cache.Cache[string, BadgeMessage]
jobCache *cache.Cache[string, BadgeMessage]
}

func NewBadgesController(base *BaseController) *BadgesController {
Expand Down Expand Up @@ -216,6 +217,47 @@ func (s *BadgesController) Pod(c *gin.Context) {
s.Success(c, badgeMessage)
}

func (s *BadgesController) Job(c *gin.Context) {
namespace := c.Param("namespace")
jobName := c.Param("job")

key := fmt.Sprintf("/kube/job/%s/%s", namespace, jobName)
badgeMessage, ok := s.jobCache.Get(key)
if !ok {
job, err := s.KubeHelper.GetJob(namespace, jobName)
if err != nil {
s.NotFound(c)
return
}

label := jobName
message := "Unknown"
messageColor := badges.Blue

if job.Status.Succeeded > 0 {
message = "Succeeded"
messageColor = badges.Green
} else if job.Status.Failed > 0 {
message = "Failed"
messageColor = badges.Red
} else if job.Status.Active > 0 {
message = "Active"
messageColor = badges.Yellow
}

badgeMessage = BadgeMessage{
Key: key,
Label: label,
Message: message,
MessageColor: messageColor,
}

s.jobCache.Set(key, badgeMessage, s.getCacheDuration())
}

s.Success(c, badgeMessage)
}

func (s *BadgesController) Postgresql(c *gin.Context) {
namespace := c.Param("namespace")
postgresqlName := c.Param("postgresql")
Expand Down
29 changes: 29 additions & 0 deletions internal/server/controller/kube.go
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,35 @@ func (s *KubeController) mapToConfig(configMap map[string]string) *model.KubeBad
return &config
}

func (s *KubeController) ListJobs(c *gin.Context) {
namespace := c.Param("namespace")
key := fmt.Sprintf("jobs_%s", namespace)

result, ok := s.cache.Get(key)
if !ok || c.Query("force") == "true" {
jobs, err := s.KubeHelper.GetJobs(namespace)
if err != nil {
c.JSON(500, gin.H{
"error": err.Error(),
})
return
}
var out []model.KubeBadges
for _, job := range jobs {
out = append(out, model.KubeBadges{
Kind: "job",
Name: job.Name,
Key: fmt.Sprintf("/kube/job/%s/%s", namespace, job.Name),
Badge: fmt.Sprintf("/badges/kube/job/%s/%s", namespace, job.Name),
})
}
result = out
s.cache.Set(key, result, time.Minute*2)
}

c.JSON(http.StatusOK, s.populateKubeBadges(result))
}

func (s *KubeController) ListPostgresqls(c *gin.Context) {
namespace := c.Param("namespace")
key := fmt.Sprintf("postgresql_%s", namespace)
Expand Down
2 changes: 2 additions & 0 deletions internal/server/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ func (s *Server) initRouter() {
// List Kustomizations (optional)
api.GET("/kustomizations/:namespace", kubeController.ListKustomizations)
api.GET("/postgresqls/:namespace", kubeController.ListPostgresqls)
api.GET("/jobs/:namespace", kubeController.ListJobs)
}

badges := s.internalEngine.Group("/badges")
Expand All @@ -110,6 +111,7 @@ func (s *Server) initRouter() {

badges.GET("/kube/kustomization/:namespace/:kustomization", badgesController.Kustomization)
badges.GET("/kube/postgresql/:namespace/:postgresql", badgesController.Postgresql)
badges.GET("/kube/job/:namespace/:job", badgesController.Job)
}

// for external api
Expand Down
6 changes: 6 additions & 0 deletions ui/lib/app/api/api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,10 @@ class Api extends GetConnect {
return (data as List).map((item) => KubeBadge.fromJson(item)).toList();
});
}

Future<Response<List<KubeBadge>>> listJobs(String namespace, bool force) {
return get('/api/jobs/$namespace?force=$force', decoder: (data) {
return (data as List).map((item) => KubeBadge.fromJson(item)).toList();
});
}
}

0 comments on commit 485ac0a

Please sign in to comment.