Skip to content

Commit

Permalink
Provide applications summary API (#517)
Browse files Browse the repository at this point in the history
* Provide applications summary RESTful API

Signed-off-by: johnniang <johnniang@fastmail.com>

* Add test case for application summary API

Signed-off-by: johnniang <johnniang@fastmail.com>

* Rename API from /applications/-/summary to /application-summary

Signed-off-by: johnniang <johnniang@fastmail.com>
  • Loading branch information
JohnNiang authored Mar 28, 2022
1 parent 2454e14 commit 61acdb4
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 1 deletion.
34 changes: 34 additions & 0 deletions pkg/kapis/gitops/v1alpha1/argocd/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,40 @@ func (h *handler) getClusters(req *restful.Request, res *restful.Response) {
common.Response(req, res, argoClusters, err)
}

func (h *handler) applicationSummary(request *restful.Request, response *restful.Response) {
namespace := common.GetPathParameter(request, common.NamespacePathParameter)

summary, err := h.populateApplicationSummary(namespace)
common.Response(request, response, summary, err)
}

func (h *handler) populateApplicationSummary(namespace string) (*ApplicationsSummary, error) {
applicationList := &v1alpha1.ApplicationList{}
if err := h.List(context.Background(), applicationList, client.InNamespace(namespace)); err != nil {
return nil, err
}
summary := &ApplicationsSummary{
HealthStatus: map[string]int{},
SyncStatus: map[string]int{},
}
summary.Total = len(applicationList.Items)

for i := range applicationList.Items {
app := &applicationList.Items[i]
// accumulate health status
healthStatus := app.GetLabels()[v1alpha1.HealthStatusLabelKey]
if healthStatus != "" {
summary.HealthStatus[healthStatus]++
}
// accumulate sync status
syncStatus := app.GetLabels()[v1alpha1.SyncStatusLabelKey]
if syncStatus != "" {
summary.SyncStatus[syncStatus]++
}
}
return summary, nil
}

type handler struct {
client.Client
}
Expand Down
13 changes: 13 additions & 0 deletions pkg/kapis/gitops/v1alpha1/argocd/route.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ type ApplicationPageResult struct {
TotalItems int `json:"totalItems"`
}

// ApplicationsSummary is the model of application summary response.
type ApplicationsSummary struct {
Total int `json:"total"`
HealthStatus map[string]int `json:"healthStatus"`
SyncStatus map[string]int `json:"syncStatus"`
}

// RegisterRoutes is for registering Argo CD Application routes into WebService.
func RegisterRoutes(service *restful.WebService, options *common.Options) {
handler := newHandler(options)
Expand All @@ -53,6 +60,12 @@ func RegisterRoutes(service *restful.WebService, options *common.Options) {
Doc("Search applications").
Returns(http.StatusOK, api.StatusOK, ApplicationPageResult{}))

service.Route(service.GET("/namespaces/{namespace}/application-summary").
To(handler.applicationSummary).
Param(common.NamespacePathParameter).
Doc("Fetch applications summary").
Returns(http.StatusOK, api.StatusOK, ApplicationsSummary{}))

service.Route(service.POST("/namespaces/{namespace}/applications").
To(handler.createApplication).
Param(common.NamespacePathParameter).
Expand Down
17 changes: 16 additions & 1 deletion pkg/kapis/gitops/v1alpha1/argocd/route_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func TestRegisterRoutes(t *testing.T) {
options: &common.Options{GenericClient: fake.NewFakeClientWithScheme(schema)},
},
verify: func(t *testing.T, service *restful.WebService) {
assert.Equal(t, 6, len(service.Routes()))
assert.Greater(t, len(service.Routes()), 0)
},
}}
for _, tt := range tests {
Expand All @@ -76,6 +76,10 @@ func TestAPIs(t *testing.T) {
ObjectMeta: metav1.ObjectMeta{
Namespace: "ns",
Name: "app",
Labels: map[string]string{
v1alpha1.HealthStatusLabelKey: "Healthy",
v1alpha1.SyncStatusLabelKey: "Synced",
},
},
}

Expand Down Expand Up @@ -303,6 +307,17 @@ func TestAPIs(t *testing.T) {
}
]`, string(body))
},
}, {
name: "get applications summary",
request: request{
method: http.MethodGet,
uri: "/namespaces/ns/application-summary",
},
k8sclient: fake.NewFakeClientWithScheme(schema, app.DeepCopy()),
responseCode: http.StatusOK,
verify: func(t *testing.T, body []byte) {
assert.JSONEq(t, `{"total": 1, "healthStatus": { "Healthy": 1 }, "syncStatus": { "Synced": 1 }}`, string(body))
},
}}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down

0 comments on commit 61acdb4

Please sign in to comment.