mirror of
https://github.com/community-scripts/ProxmoxVE.git
synced 2025-03-08 13:19:05 +00:00
[API]Add more enpoints to API (#2390)
* Add pagination to API * Add pagination to API
This commit is contained in:
parent
afe4af2ff6
commit
1711e44a4d
283
api/main.go
283
api/main.go
@ -11,6 +11,7 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
@ -31,6 +32,7 @@ func loadEnv() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DataModel represents a single document in MongoDB
|
||||||
type DataModel struct {
|
type DataModel struct {
|
||||||
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"`
|
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"`
|
||||||
CT_TYPE uint `json:"ct_type" bson:"ct_type"`
|
CT_TYPE uint `json:"ct_type" bson:"ct_type"`
|
||||||
@ -56,6 +58,13 @@ type StatusModel struct {
|
|||||||
STATUS string `json:"status" bson:"status"`
|
STATUS string `json:"status" bson:"status"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type CountResponse struct {
|
||||||
|
TotalEntries int64 `json:"total_entries"`
|
||||||
|
StatusCount map[string]int64 `json:"status_count"`
|
||||||
|
NSAPPCount map[string]int64 `json:"nsapp_count"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConnectDatabase initializes the MongoDB connection
|
||||||
func ConnectDatabase() {
|
func ConnectDatabase() {
|
||||||
loadEnv()
|
loadEnv()
|
||||||
|
|
||||||
@ -78,6 +87,7 @@ func ConnectDatabase() {
|
|||||||
fmt.Println("Connected to MongoDB on 10.10.10.18")
|
fmt.Println("Connected to MongoDB on 10.10.10.18")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UploadJSON handles API requests and stores data as a document in MongoDB
|
||||||
func UploadJSON(w http.ResponseWriter, r *http.Request) {
|
func UploadJSON(w http.ResponseWriter, r *http.Request) {
|
||||||
var input DataModel
|
var input DataModel
|
||||||
|
|
||||||
@ -98,6 +108,7 @@ func UploadJSON(w http.ResponseWriter, r *http.Request) {
|
|||||||
json.NewEncoder(w).Encode(map[string]string{"message": "Data saved successfully"})
|
json.NewEncoder(w).Encode(map[string]string{"message": "Data saved successfully"})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateStatus updates the status of a record based on RANDOM_ID
|
||||||
func UpdateStatus(w http.ResponseWriter, r *http.Request) {
|
func UpdateStatus(w http.ResponseWriter, r *http.Request) {
|
||||||
var input StatusModel
|
var input StatusModel
|
||||||
|
|
||||||
@ -120,6 +131,7 @@ func UpdateStatus(w http.ResponseWriter, r *http.Request) {
|
|||||||
json.NewEncoder(w).Encode(map[string]string{"message": "Record updated successfully"})
|
json.NewEncoder(w).Encode(map[string]string{"message": "Record updated successfully"})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetDataJSON fetches all data from MongoDB
|
||||||
func GetDataJSON(w http.ResponseWriter, r *http.Request) {
|
func GetDataJSON(w http.ResponseWriter, r *http.Request) {
|
||||||
var records []DataModel
|
var records []DataModel
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||||
@ -144,6 +156,270 @@ func GetDataJSON(w http.ResponseWriter, r *http.Request) {
|
|||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
json.NewEncoder(w).Encode(records)
|
json.NewEncoder(w).Encode(records)
|
||||||
}
|
}
|
||||||
|
func GetPaginatedData(w http.ResponseWriter, r *http.Request) {
|
||||||
|
page, _ := strconv.Atoi(r.URL.Query().Get("page"))
|
||||||
|
limit, _ := strconv.Atoi(r.URL.Query().Get("limit"))
|
||||||
|
if page < 1 {
|
||||||
|
page = 1
|
||||||
|
}
|
||||||
|
if limit < 1 {
|
||||||
|
limit = 10
|
||||||
|
}
|
||||||
|
skip := (page - 1) * limit
|
||||||
|
var records []DataModel
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
options := options.Find().SetSkip(int64(skip)).SetLimit(int64(limit))
|
||||||
|
cursor, err := collection.Find(ctx, bson.M{}, options)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer cursor.Close(ctx)
|
||||||
|
|
||||||
|
for cursor.Next(ctx) {
|
||||||
|
var record DataModel
|
||||||
|
if err := cursor.Decode(&record); err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
records = append(records, record)
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
json.NewEncoder(w).Encode(records)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetSummary(w http.ResponseWriter, r *http.Request) {
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
totalCount, err := collection.CountDocuments(ctx, bson.M{})
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
statusCount := make(map[string]int64)
|
||||||
|
nsappCount := make(map[string]int64)
|
||||||
|
|
||||||
|
pipeline := []bson.M{
|
||||||
|
{"$group": bson.M{"_id": "$status", "count": bson.M{"$sum": 1}}},
|
||||||
|
}
|
||||||
|
cursor, err := collection.Aggregate(ctx, pipeline)
|
||||||
|
if err == nil {
|
||||||
|
for cursor.Next(ctx) {
|
||||||
|
var result struct {
|
||||||
|
ID string `bson:"_id"`
|
||||||
|
Count int64 `bson:"count"`
|
||||||
|
}
|
||||||
|
if err := cursor.Decode(&result); err == nil {
|
||||||
|
statusCount[result.ID] = result.Count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pipeline = []bson.M{
|
||||||
|
{"$group": bson.M{"_id": "$nsapp", "count": bson.M{"$sum": 1}}},
|
||||||
|
}
|
||||||
|
cursor, err = collection.Aggregate(ctx, pipeline)
|
||||||
|
if err == nil {
|
||||||
|
for cursor.Next(ctx) {
|
||||||
|
var result struct {
|
||||||
|
ID string `bson:"_id"`
|
||||||
|
Count int64 `bson:"count"`
|
||||||
|
}
|
||||||
|
if err := cursor.Decode(&result); err == nil {
|
||||||
|
nsappCount[result.ID] = result.Count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
response := CountResponse{
|
||||||
|
TotalEntries: totalCount,
|
||||||
|
StatusCount: statusCount,
|
||||||
|
NSAPPCount: nsappCount,
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
json.NewEncoder(w).Encode(response)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetByNsapp(w http.ResponseWriter, r *http.Request) {
|
||||||
|
nsapp := r.URL.Query().Get("nsapp")
|
||||||
|
var records []DataModel
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
cursor, err := collection.Find(ctx, bson.M{"nsapp": nsapp})
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer cursor.Close(ctx)
|
||||||
|
|
||||||
|
for cursor.Next(ctx) {
|
||||||
|
var record DataModel
|
||||||
|
if err := cursor.Decode(&record); err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
records = append(records, record)
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
json.NewEncoder(w).Encode(records)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetByDateRange(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
|
startDate := r.URL.Query().Get("start_date")
|
||||||
|
endDate := r.URL.Query().Get("end_date")
|
||||||
|
|
||||||
|
if startDate == "" || endDate == "" {
|
||||||
|
http.Error(w, "Both start_date and end_date are required", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
start, err := time.Parse("2006-01-02T15:04:05.999999+00:00", startDate+"T00:00:00+00:00")
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, "Invalid start_date format", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
end, err := time.Parse("2006-01-02T15:04:05.999999+00:00", endDate+"T23:59:59+00:00")
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, "Invalid end_date format", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var records []DataModel
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
cursor, err := collection.Find(ctx, bson.M{
|
||||||
|
"created_at": bson.M{
|
||||||
|
"$gte": start,
|
||||||
|
"$lte": end,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer cursor.Close(ctx)
|
||||||
|
|
||||||
|
for cursor.Next(ctx) {
|
||||||
|
var record DataModel
|
||||||
|
if err := cursor.Decode(&record); err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
records = append(records, record)
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
json.NewEncoder(w).Encode(records)
|
||||||
|
}
|
||||||
|
func GetByStatus(w http.ResponseWriter, r *http.Request) {
|
||||||
|
status := r.URL.Query().Get("status")
|
||||||
|
var records []DataModel
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
cursor, err := collection.Find(ctx, bson.M{"status": status})
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer cursor.Close(ctx)
|
||||||
|
|
||||||
|
for cursor.Next(ctx) {
|
||||||
|
var record DataModel
|
||||||
|
if err := cursor.Decode(&record); err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
records = append(records, record)
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
json.NewEncoder(w).Encode(records)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetByOS(w http.ResponseWriter, r *http.Request) {
|
||||||
|
osType := r.URL.Query().Get("os_type")
|
||||||
|
osVersion := r.URL.Query().Get("os_version")
|
||||||
|
var records []DataModel
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
cursor, err := collection.Find(ctx, bson.M{"os_type": osType, "os_version": osVersion})
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer cursor.Close(ctx)
|
||||||
|
|
||||||
|
for cursor.Next(ctx) {
|
||||||
|
var record DataModel
|
||||||
|
if err := cursor.Decode(&record); err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
records = append(records, record)
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
json.NewEncoder(w).Encode(records)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetErrors(w http.ResponseWriter, r *http.Request) {
|
||||||
|
errorCount := make(map[string]int)
|
||||||
|
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
cursor, err := collection.Find(ctx, bson.M{"error": bson.M{"$ne": ""}})
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer cursor.Close(ctx)
|
||||||
|
|
||||||
|
for cursor.Next(ctx) {
|
||||||
|
var record DataModel
|
||||||
|
if err := cursor.Decode(&record); err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if record.ERROR != "" {
|
||||||
|
errorCount[record.ERROR]++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type ErrorCountResponse struct {
|
||||||
|
Error string `json:"error"`
|
||||||
|
Count int `json:"count"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var errorCounts []ErrorCountResponse
|
||||||
|
for err, count := range errorCount {
|
||||||
|
errorCounts = append(errorCounts, ErrorCountResponse{
|
||||||
|
Error: err,
|
||||||
|
Count: count,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
json.NewEncoder(w).Encode(struct {
|
||||||
|
ErrorCounts []ErrorCountResponse `json:"error_counts"`
|
||||||
|
}{
|
||||||
|
ErrorCounts: errorCounts,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
ConnectDatabase()
|
ConnectDatabase()
|
||||||
@ -152,6 +428,13 @@ func main() {
|
|||||||
router.HandleFunc("/upload", UploadJSON).Methods("POST")
|
router.HandleFunc("/upload", UploadJSON).Methods("POST")
|
||||||
router.HandleFunc("/upload/updatestatus", UpdateStatus).Methods("POST")
|
router.HandleFunc("/upload/updatestatus", UpdateStatus).Methods("POST")
|
||||||
router.HandleFunc("/data/json", GetDataJSON).Methods("GET")
|
router.HandleFunc("/data/json", GetDataJSON).Methods("GET")
|
||||||
|
router.HandleFunc("/data/paginated", GetPaginatedData).Methods("GET")
|
||||||
|
router.HandleFunc("/data/summary", GetSummary).Methods("GET")
|
||||||
|
router.HandleFunc("/data/nsapp", GetByNsapp).Methods("GET")
|
||||||
|
router.HandleFunc("/data/date", GetByDateRange).Methods("GET")
|
||||||
|
router.HandleFunc("/data/status", GetByStatus).Methods("GET")
|
||||||
|
router.HandleFunc("/data/os", GetByOS).Methods("GET")
|
||||||
|
router.HandleFunc("/data/errors", GetErrors).Methods("GET")
|
||||||
|
|
||||||
c := cors.New(cors.Options{
|
c := cors.New(cors.Options{
|
||||||
AllowedOrigins: []string{"*"},
|
AllowedOrigins: []string{"*"},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user