mirror of
https://github.com/hhftechnology/middleware-manager.git
synced 2026-04-28 03:29:42 +00:00
bugfixes-clearing-router-and-merge
This commit is contained in:
parent
54c741b56a
commit
e578ec6a81
4 changed files with 92 additions and 29 deletions
|
|
@ -24,13 +24,24 @@ func NewServiceHandler(db *sql.DB) *ServiceHandler {
|
|||
|
||||
// GetServices returns all service configurations
|
||||
// Supports pagination via ?page=N&page_size=M query parameters
|
||||
// By default only returns active services; use ?status=all to include disabled
|
||||
func (h *ServiceHandler) GetServices(c *gin.Context) {
|
||||
usePagination := IsPaginationRequested(c)
|
||||
params := GetPaginationParams(c)
|
||||
|
||||
// Filter by status - default to active only
|
||||
statusFilter := c.DefaultQuery("status", "active")
|
||||
statusCondition := "WHERE status = 'active'"
|
||||
if statusFilter == "all" {
|
||||
statusCondition = ""
|
||||
} else if statusFilter == "disabled" {
|
||||
statusCondition = "WHERE status = 'disabled'"
|
||||
}
|
||||
|
||||
var total int
|
||||
if usePagination {
|
||||
err := h.DB.QueryRow("SELECT COUNT(*) FROM services").Scan(&total)
|
||||
countQuery := "SELECT COUNT(*) FROM services " + statusCondition
|
||||
err := h.DB.QueryRow(countQuery).Scan(&total)
|
||||
if err != nil {
|
||||
log.Printf("Error counting services: %v", err)
|
||||
ResponseWithError(c, http.StatusInternalServerError, "Failed to count services")
|
||||
|
|
@ -38,7 +49,7 @@ func (h *ServiceHandler) GetServices(c *gin.Context) {
|
|||
}
|
||||
}
|
||||
|
||||
query := "SELECT id, name, type, config FROM services ORDER BY name"
|
||||
query := "SELECT id, name, type, config, COALESCE(status, 'active') as status, COALESCE(source_type, '') as source_type FROM services " + statusCondition + " ORDER BY name"
|
||||
var rows *sql.Rows
|
||||
var err error
|
||||
|
||||
|
|
@ -58,8 +69,8 @@ func (h *ServiceHandler) GetServices(c *gin.Context) {
|
|||
|
||||
services := []map[string]interface{}{}
|
||||
for rows.Next() {
|
||||
var id, name, typ, configStr string
|
||||
if err := rows.Scan(&id, &name, &typ, &configStr); err != nil {
|
||||
var id, name, typ, configStr, status, sourceType string
|
||||
if err := rows.Scan(&id, &name, &typ, &configStr, &status, &sourceType); err != nil {
|
||||
log.Printf("Error scanning service row: %v", err)
|
||||
continue
|
||||
}
|
||||
|
|
@ -71,10 +82,12 @@ func (h *ServiceHandler) GetServices(c *gin.Context) {
|
|||
}
|
||||
|
||||
services = append(services, map[string]interface{}{
|
||||
"id": id,
|
||||
"name": name,
|
||||
"type": typ,
|
||||
"config": config,
|
||||
"id": id,
|
||||
"name": name,
|
||||
"type": typ,
|
||||
"config": config,
|
||||
"status": status,
|
||||
"source_type": sourceType,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -150,7 +163,7 @@ func (h *ServiceHandler) CreateService(c *gin.Context) {
|
|||
id, service.Name, service.Type)
|
||||
|
||||
result, txErr := tx.Exec(
|
||||
"INSERT INTO services (id, name, type, config) VALUES (?, ?, ?, ?)",
|
||||
"INSERT INTO services (id, name, type, config, status, source_type) VALUES (?, ?, ?, ?, 'active', 'manual')",
|
||||
id, service.Name, service.Type, string(configJSON),
|
||||
)
|
||||
|
||||
|
|
@ -192,8 +205,11 @@ func (h *ServiceHandler) GetService(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
var name, typ, configStr string
|
||||
err := h.DB.QueryRow("SELECT name, type, config FROM services WHERE id = ?", id).Scan(&name, &typ, &configStr)
|
||||
var name, typ, configStr, status, sourceType string
|
||||
err := h.DB.QueryRow(
|
||||
"SELECT name, type, config, COALESCE(status, 'active'), COALESCE(source_type, '') FROM services WHERE id = ?",
|
||||
id,
|
||||
).Scan(&name, &typ, &configStr, &status, &sourceType)
|
||||
if err == sql.ErrNoRows {
|
||||
ResponseWithError(c, http.StatusNotFound, "Service not found")
|
||||
return
|
||||
|
|
@ -210,10 +226,12 @@ func (h *ServiceHandler) GetService(c *gin.Context) {
|
|||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"id": id,
|
||||
"name": name,
|
||||
"type": typ,
|
||||
"config": config,
|
||||
"id": id,
|
||||
"name": name,
|
||||
"type": typ,
|
||||
"config": config,
|
||||
"status": status,
|
||||
"source_type": sourceType,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -578,6 +578,45 @@ func runPostMigrationUpdates(db *sql.DB) error {
|
|||
// Create index on host for faster lookups when matching by host
|
||||
_, _ = db.Exec("CREATE INDEX IF NOT EXISTS idx_resources_host ON resources(host)")
|
||||
|
||||
// Check for status column in services table (for tracking sync state)
|
||||
var hasServicesStatusColumn bool
|
||||
err = db.QueryRow(`
|
||||
SELECT COUNT(*) > 0
|
||||
FROM pragma_table_info('services')
|
||||
WHERE name = 'status'
|
||||
`).Scan(&hasServicesStatusColumn)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to check if services.status column exists: %w", err)
|
||||
}
|
||||
if !hasServicesStatusColumn {
|
||||
log.Println("Adding status column to services table")
|
||||
if _, err := db.Exec("ALTER TABLE services ADD COLUMN status TEXT NOT NULL DEFAULT 'active'"); err != nil {
|
||||
return fmt.Errorf("failed to add status column to services: %w", err)
|
||||
}
|
||||
log.Println("Successfully added status column to services table")
|
||||
}
|
||||
|
||||
// Check for source_type column in services table (for tracking sync origin)
|
||||
var hasServicesSourceTypeColumn bool
|
||||
err = db.QueryRow(`
|
||||
SELECT COUNT(*) > 0
|
||||
FROM pragma_table_info('services')
|
||||
WHERE name = 'source_type'
|
||||
`).Scan(&hasServicesSourceTypeColumn)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to check if services.source_type column exists: %w", err)
|
||||
}
|
||||
if !hasServicesSourceTypeColumn {
|
||||
log.Println("Adding source_type column to services table")
|
||||
if _, err := db.Exec("ALTER TABLE services ADD COLUMN source_type TEXT DEFAULT ''"); err != nil {
|
||||
return fmt.Errorf("failed to add source_type column to services: %w", err)
|
||||
}
|
||||
log.Println("Successfully added source_type column to services table")
|
||||
}
|
||||
|
||||
// Create index on services status for faster filtering
|
||||
_, _ = db.Exec("CREATE INDEX IF NOT EXISTS idx_services_status ON services(status)")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -73,6 +73,8 @@ CREATE TABLE IF NOT EXISTS services (
|
|||
name TEXT NOT NULL,
|
||||
type TEXT NOT NULL,
|
||||
config TEXT NOT NULL,
|
||||
status TEXT NOT NULL DEFAULT 'active',
|
||||
source_type TEXT DEFAULT '', -- 'pangolin', 'traefik', 'manual', etc.
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
|
|
|||
|
|
@ -122,9 +122,10 @@ func (sw *ServiceWatcher) checkServices() error {
|
|||
return fmt.Errorf("failed to fetch services: %w", err)
|
||||
}
|
||||
|
||||
// Get all existing services from the database
|
||||
// Get all existing active Pangolin-synced services from the database
|
||||
// We only track Pangolin-synced services for cleanup (source_type = 'pangolin')
|
||||
var existingServices []string
|
||||
rows, err := sw.db.Query("SELECT id FROM services")
|
||||
rows, err := sw.db.Query("SELECT id FROM services WHERE status = 'active' AND source_type = 'pangolin'")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to query existing services: %w", err)
|
||||
}
|
||||
|
|
@ -167,19 +168,22 @@ func (sw *ServiceWatcher) checkServices() error {
|
|||
foundServices[normalizedID] = true
|
||||
}
|
||||
|
||||
// Optionally, mark services as "inactive" if they no longer exist in the data source
|
||||
// This is commented out by default to avoid deleting user-created services
|
||||
/*
|
||||
// Mark Pangolin-synced services as disabled if they no longer exist in the data source
|
||||
// Only affects services with source_type = 'pangolin' (already filtered in the query above)
|
||||
for _, serviceID := range existingServices {
|
||||
normalizedID := util.NormalizeID(serviceID)
|
||||
if !foundServices[normalizedID] {
|
||||
log.Printf("Service %s no longer exists in data source, consider marking as inactive", serviceID)
|
||||
// Optional: You could update a status field if you add one to the services table
|
||||
// _, err := sw.db.Exec("UPDATE services SET status = 'inactive' WHERE id = ?", serviceID)
|
||||
log.Printf("Service %s no longer exists in Pangolin, marking as disabled", serviceID)
|
||||
_, err := sw.db.Exec(
|
||||
"UPDATE services SET status = 'disabled', updated_at = ? WHERE id = ?",
|
||||
time.Now(), serviceID,
|
||||
)
|
||||
if err != nil {
|
||||
log.Printf("Error marking service as disabled: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -449,9 +453,9 @@ func (sw *ServiceWatcher) createService(service models.Service) error {
|
|||
return fmt.Errorf("error checking service existence in transaction: %w", err)
|
||||
}
|
||||
|
||||
// Insert the service
|
||||
// Insert the service with source_type for tracking origin
|
||||
_, err = tx.Exec(
|
||||
"INSERT INTO services (id, name, type, config, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?)",
|
||||
"INSERT INTO services (id, name, type, config, status, source_type, created_at, updated_at) VALUES (?, ?, ?, ?, 'active', 'pangolin', ?, ?)",
|
||||
service.ID, service.Name, service.Type, string(configJSON), time.Now(), time.Now(),
|
||||
)
|
||||
|
||||
|
|
@ -504,9 +508,9 @@ func (sw *ServiceWatcher) updateService(service models.Service, existingID strin
|
|||
|
||||
// Update the service using a transaction
|
||||
return sw.db.WithTransaction(func(tx *sql.Tx) error {
|
||||
// Update the service using the existing ID
|
||||
// Update the service using the existing ID, ensure status is active and source_type is pangolin
|
||||
result, err := tx.Exec(
|
||||
"UPDATE services SET name = ?, type = ?, config = ?, updated_at = ? WHERE id = ?",
|
||||
"UPDATE services SET name = ?, type = ?, config = ?, status = 'active', source_type = 'pangolin', updated_at = ? WHERE id = ?",
|
||||
service.Name, service.Type, string(configJSON), time.Now(), existingID,
|
||||
)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue