Skip to content

Commit

Permalink
add vcluster health checks
Browse files Browse the repository at this point in the history
  • Loading branch information
isaaguilar committed Aug 11, 2023
1 parent d5c0c56 commit 8cb8e68
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 0 deletions.
2 changes: 2 additions & 0 deletions pkg/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ func (h APIHandler) RegisterRoutes() {

cluster := routes.Group("/cluster")
cluster.POST("/", h.AddCluster) // Resource from Add/Update/Delete event
cluster.GET("/:cluster_name/health", h.VClusterHealth)
cluster.GET("/:cluster_name/tfohealth", h.VClusterTFOHealth)
cluster.PUT("/:cluster_name/sync-dependencies", h.SyncEvent)
cluster.POST("/:cluster_name/event", h.ResourceEvent) // routes.GET("/cluster-name/:cluster_name", h.GetCluster) // to be removed
cluster.PUT("/:cluster_name/event", h.ResourceEvent)
Expand Down
62 changes: 62 additions & 0 deletions pkg/api/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,68 @@ func (h APIHandler) getClusterID(clusterName string) uint {
return clusters[0].ID
}

func (h APIHandler) VClusterHealth(c *gin.Context) {
clusterName := c.Param("cluster_name")
clusterID := h.getClusterID(clusterName)
if clusterID == 0 {
c.JSON(http.StatusUnprocessableEntity, response(http.StatusUnprocessableEntity, fmt.Sprintf("cluster_name '%s' not found", clusterName), nil))
return
}
config, err := getVclusterConfig(h.clientset, "internal", clusterName)
if err != nil {
c.JSON(http.StatusUnprocessableEntity, response(http.StatusUnprocessableEntity, err.Error(), nil))
return
}
clientset := kubernetes.NewForConfigOrDie(config)
n, err := clientset.CoreV1().Namespaces().List(c, metav1.ListOptions{})
if err != nil {
c.JSON(http.StatusUnprocessableEntity, response(http.StatusUnprocessableEntity, err.Error(), nil))
return
}
if len(n.Items) == 0 {
c.JSON(http.StatusUnprocessableEntity, response(http.StatusUnprocessableEntity, "No namespaces available", nil))
return
}
c.JSON(http.StatusNoContent, nil)
}

func (h APIHandler) VClusterTFOHealth(c *gin.Context) {
clusterName := c.Param("cluster_name")
clusterID := h.getClusterID(clusterName)
if clusterID == 0 {
c.JSON(http.StatusUnprocessableEntity, response(http.StatusUnprocessableEntity, fmt.Sprintf("cluster_name '%s' not found", clusterName), nil))
return
}
config, err := getVclusterConfig(h.clientset, "internal", clusterName)
if err != nil {
c.JSON(http.StatusUnprocessableEntity, response(http.StatusUnprocessableEntity, err.Error(), nil))
return
}
tfoclientset := tfo.NewForConfigOrDie(config)
if _, err = tfoclientset.TfV1beta1().Terraforms("").List(c, metav1.ListOptions{}); err != nil {
// tfo client cannot query crds and therefore tfo health is not ready
c.JSON(http.StatusUnprocessableEntity, response(http.StatusUnprocessableEntity, err.Error(), nil))
return
}

// Following checks if tfo is running. TFO must be installed similar to the bundled packages in the
// terraform-operator github repo.
clientset := kubernetes.NewForConfigOrDie(config)
n, err := clientset.CoreV1().Pods("tf-system").List(c, metav1.ListOptions{
LabelSelector: "app=terraform-operator,component=controller",
FieldSelector: "status.phase=Running",
})
if err != nil {
c.JSON(http.StatusUnprocessableEntity, response(http.StatusUnprocessableEntity, err.Error(), nil))
return
}
if len(n.Items) == 0 {
c.JSON(http.StatusUnprocessableEntity, response(http.StatusUnprocessableEntity, "Terraform operator controller is not running", nil))
return
}
c.JSON(http.StatusNoContent, nil)
}

// ResourcePoll is a short poll that checks and returns resources created from the tf resource's workflow
// that have the correct label and annotation value.
func (h APIHandler) ResourcePoll(c *gin.Context) {
Expand Down

0 comments on commit 8cb8e68

Please sign in to comment.