Added endpoint for portal stats (#2891)
* added endpoint for portal stats Signed-off-by: Soumya Ghosh Dastidar <gdsoumya@gmail.com>
This commit is contained in:
parent
98129e963a
commit
2913b0fcbd
|
@ -2,8 +2,9 @@ package authorization
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type contextKey string
|
||||
|
@ -30,8 +31,8 @@ func Middleware(handler http.Handler) http.Handler {
|
|||
})
|
||||
}
|
||||
|
||||
// RestMiddleware ...
|
||||
func RestMiddleware(handler http.Handler) http.Handler {
|
||||
// RestMiddlewareWithRole verifies jwt and checks if user has enough privilege to access route
|
||||
func RestMiddlewareWithRole(handler http.Handler, roles []string) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
jwt := ""
|
||||
auth, err := r.Cookie(CookieName)
|
||||
|
@ -40,14 +41,24 @@ func RestMiddleware(handler http.Handler) http.Handler {
|
|||
} else if r.Header.Get("Authorization") != "" {
|
||||
jwt = r.Header.Get("Authorization")
|
||||
}
|
||||
_, err = UserValidateJWT(jwt)
|
||||
user, err := UserValidateJWT(jwt)
|
||||
if err != nil {
|
||||
fmt.Println("Error in Cookie: ", err)
|
||||
logrus.WithError(err).Error("Invalid Auth Cookie")
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
w.Write([]byte("Error verifying JWT token: " + err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if len(roles) == 0 {
|
||||
handler.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
for _, role := range roles {
|
||||
if role == user["role"] {
|
||||
handler.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
}
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
return
|
||||
})
|
||||
}
|
||||
|
|
|
@ -82,3 +82,17 @@ func GetClusterWithProjectID(projectID string, clusterType *string) ([]*Cluster,
|
|||
|
||||
return clusters, nil
|
||||
}
|
||||
|
||||
// GetClusters returns all the clusters matching the query
|
||||
func GetClusters(ctx context.Context, query bson.D) ([]*Cluster, error) {
|
||||
var clusters []*Cluster
|
||||
results, err := mongodb.Operator.List(ctx, mongodb.ClusterCollection, query)
|
||||
if err != nil {
|
||||
return []*Cluster{}, err
|
||||
}
|
||||
err = results.All(ctx, &clusters)
|
||||
if err != nil {
|
||||
return []*Cluster{}, err
|
||||
}
|
||||
return clusters, nil
|
||||
}
|
||||
|
|
|
@ -41,6 +41,22 @@ func GetProject(ctx context.Context, query bson.D) (*Project, error) {
|
|||
return project, err
|
||||
}
|
||||
|
||||
// GetProjects takes a query parameter to retrieve the projects that match query
|
||||
func GetProjects(ctx context.Context, query bson.D) ([]Project, error) {
|
||||
results, err := mongodb.Operator.List(ctx, mongodb.ProjectCollection, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var projects []Project
|
||||
err = results.All(ctx, &projects)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return projects, nil
|
||||
}
|
||||
|
||||
// GetProjectsByUserID returns a project based on the userID
|
||||
func GetProjectsByUserID(ctx context.Context, userID string) ([]Project, error) {
|
||||
var projects []Project
|
||||
|
|
|
@ -59,8 +59,7 @@ func GetUserByUserID(ctx context.Context, userID string) (*User, error) {
|
|||
}
|
||||
|
||||
// GetUsers returns the list of users present in the project
|
||||
func GetUsers(ctx context.Context) ([]User, error) {
|
||||
query := bson.D{{}}
|
||||
func GetUsers(ctx context.Context, query bson.D) ([]User, error) {
|
||||
result, err := mongodb.Operator.List(ctx, mongodb.UserCollection, query)
|
||||
if err != nil {
|
||||
log.Print("Error getting users : ", err)
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
package stat
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/litmuschaos/litmus/litmus-portal/graphql-server/pkg/database/mongodb/cluster"
|
||||
"github.com/litmuschaos/litmus/litmus-portal/graphql-server/pkg/database/mongodb/project"
|
||||
"github.com/litmuschaos/litmus/litmus-portal/graphql-server/pkg/database/mongodb/usermanagement"
|
||||
"github.com/litmuschaos/litmus/litmus-portal/graphql-server/pkg/database/mongodb/workflow"
|
||||
"github.com/litmuschaos/litmus/litmus-portal/graphql-server/utils"
|
||||
"github.com/sirupsen/logrus"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
)
|
||||
|
||||
type AgentCount struct {
|
||||
Namespaced int `json:"ns_scope"`
|
||||
Cluster int `json:"cluster_scope"`
|
||||
Total int `json:"total_count"`
|
||||
}
|
||||
type OverviewStat struct {
|
||||
UserCount int `json:"user_count"`
|
||||
ProjectCount int `json:"project_count"`
|
||||
AgentCount AgentCount `json:"agent_count"`
|
||||
WorkflowScheduleCount int `json:"schedule_count"`
|
||||
WorkflowRunCount int `json:"run_count"`
|
||||
}
|
||||
|
||||
//GetStats returns the portals overview
|
||||
func GetStats(w http.ResponseWriter, r *http.Request) {
|
||||
users, err := usermanagement.GetUsers(r.Context(), bson.D{})
|
||||
if err != nil {
|
||||
logrus.WithError(err).Errorf("failed to get users for stat")
|
||||
utils.WriteHeaders(&w, http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
agentNS, err := cluster.GetClusters(r.Context(), bson.D{{"agent_scope", "namespace"}, {"is_removed", false}})
|
||||
if err != nil {
|
||||
logrus.WithError(err).Errorf("failed to get agents(ns) for stat")
|
||||
utils.WriteHeaders(&w, http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
agents, err := cluster.GetClusters(r.Context(), bson.D{{"is_removed", false}})
|
||||
if err != nil {
|
||||
logrus.WithError(err).Errorf("failed to get agents for stat")
|
||||
utils.WriteHeaders(&w, http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
projects, err := project.GetProjects(r.Context(), bson.D{})
|
||||
if err != nil {
|
||||
logrus.WithError(err).Errorf("failed to get projects for stat")
|
||||
utils.WriteHeaders(&w, http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
workflows, err := workflow.GetWorkflows(bson.D{})
|
||||
if err != nil {
|
||||
logrus.WithError(err).Errorf("failed to get workflows for stat")
|
||||
utils.WriteHeaders(&w, http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
runCount := 0
|
||||
for _, workFlowInput := range workflows {
|
||||
runCount += len(workFlowInput.WorkflowRuns)
|
||||
}
|
||||
|
||||
overview := OverviewStat{
|
||||
UserCount: len(users),
|
||||
ProjectCount: len(projects),
|
||||
WorkflowRunCount: runCount,
|
||||
WorkflowScheduleCount: len(workflows),
|
||||
AgentCount: AgentCount{
|
||||
Namespaced: len(agentNS),
|
||||
Total: len(agents),
|
||||
Cluster: len(agents) - len(agentNS),
|
||||
},
|
||||
}
|
||||
data, err := json.Marshal(overview)
|
||||
if err != nil {
|
||||
logrus.WithError(err).Errorf("failed to marshal stat")
|
||||
utils.WriteHeaders(&w, http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
utils.WriteHeaders(&w, http.StatusOK)
|
||||
w.Write(data)
|
||||
}
|
|
@ -6,12 +6,12 @@ import (
|
|||
"log"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
|
||||
"github.com/litmuschaos/litmus/litmus-portal/graphql-server/graph/model"
|
||||
dbOperationsUserManagement "github.com/litmuschaos/litmus/litmus-portal/graphql-server/pkg/database/mongodb/usermanagement"
|
||||
dbSchemaUserManagement "github.com/litmuschaos/litmus/litmus-portal/graphql-server/pkg/database/mongodb/usermanagement"
|
||||
"github.com/litmuschaos/litmus/litmus-portal/graphql-server/pkg/project"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -73,7 +73,7 @@ func GetUser(ctx context.Context, username string) (*model.User, error) {
|
|||
// GetUsers queries the list of all the users from the DB and returns it in the appropriate format
|
||||
func GetUsers(ctx context.Context) ([]*model.User, error) {
|
||||
|
||||
users, err := dbOperationsUserManagement.GetUsers(ctx)
|
||||
users, err := dbOperationsUserManagement.GetUsers(ctx, bson.D{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -7,22 +7,21 @@ import (
|
|||
"runtime"
|
||||
"time"
|
||||
|
||||
"github.com/litmuschaos/litmus/litmus-portal/graphql-server/pkg/database/mongodb"
|
||||
|
||||
"github.com/99designs/gqlgen/graphql/handler"
|
||||
"github.com/99designs/gqlgen/graphql/handler/extension"
|
||||
"github.com/99designs/gqlgen/graphql/handler/transport"
|
||||
"github.com/99designs/gqlgen/graphql/playground"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/rs/cors"
|
||||
|
||||
"github.com/litmuschaos/litmus/litmus-portal/graphql-server/graph"
|
||||
"github.com/litmuschaos/litmus/litmus-portal/graphql-server/graph/generated"
|
||||
"github.com/litmuschaos/litmus/litmus-portal/graphql-server/pkg/authorization"
|
||||
"github.com/litmuschaos/litmus/litmus-portal/graphql-server/pkg/database/mongodb"
|
||||
"github.com/litmuschaos/litmus/litmus-portal/graphql-server/pkg/file_handlers"
|
||||
gitOpsHandler "github.com/litmuschaos/litmus/litmus-portal/graphql-server/pkg/gitops/handler"
|
||||
"github.com/litmuschaos/litmus/litmus-portal/graphql-server/pkg/myhub"
|
||||
"github.com/litmuschaos/litmus/litmus-portal/graphql-server/pkg/stat"
|
||||
"github.com/rs/cors"
|
||||
)
|
||||
|
||||
const defaultPort = "8080"
|
||||
|
@ -75,7 +74,8 @@ func main() {
|
|||
router.Handle("/", playground.Handler("GraphQL playground", "/query"))
|
||||
router.Handle("/query", authorization.Middleware(srv))
|
||||
router.HandleFunc("/file/{key}{path:.yaml}", file_handlers.FileHandler)
|
||||
router.Handle("/icon/{ProjectID}/{HubName}/{ChartName}/{IconName}", authorization.RestMiddleware(myhub.GetIconHandler)).Methods("GET")
|
||||
router.Handle("/icon/{ProjectID}/{HubName}/{ChartName}/{IconName}", authorization.RestMiddlewareWithRole(myhub.GetIconHandler, nil)).Methods("GET")
|
||||
router.Handle("/stats", authorization.RestMiddlewareWithRole(http.HandlerFunc(stat.GetStats), []string{"admin"})).Methods("GET")
|
||||
log.Printf("connect to http://localhost:%s/ for GraphQL playground", port)
|
||||
log.Fatal(http.ListenAndServe(":"+port, router))
|
||||
|
||||
|
|
Loading…
Reference in New Issue