Initial commit.
This commit is contained in:
206
internal/api/v1/handlers_apps.go
Normal file
206
internal/api/v1/handlers_apps.go
Normal file
@@ -0,0 +1,206 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
|
||||
"github.com/wild-cloud/wild-central/daemon/internal/apps"
|
||||
"github.com/wild-cloud/wild-central/daemon/internal/operations"
|
||||
)
|
||||
|
||||
// AppsListAvailable lists all available apps
|
||||
func (api *API) AppsListAvailable(w http.ResponseWriter, r *http.Request) {
|
||||
// List available apps from apps directory
|
||||
appsMgr := apps.NewManager(api.dataDir, api.appsDir)
|
||||
appList, err := appsMgr.ListAvailable()
|
||||
if err != nil {
|
||||
respondError(w, http.StatusInternalServerError, fmt.Sprintf("Failed to list apps: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
respondJSON(w, http.StatusOK, map[string]interface{}{
|
||||
"apps": appList,
|
||||
})
|
||||
}
|
||||
|
||||
// AppsGetAvailable returns details for an available app
|
||||
func (api *API) AppsGetAvailable(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
appName := vars["app"]
|
||||
|
||||
// Get app details
|
||||
appsMgr := apps.NewManager(api.dataDir, api.appsDir)
|
||||
app, err := appsMgr.Get(appName)
|
||||
if err != nil {
|
||||
respondError(w, http.StatusNotFound, fmt.Sprintf("App not found: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
respondJSON(w, http.StatusOK, app)
|
||||
}
|
||||
|
||||
// AppsListDeployed lists deployed apps for an instance
|
||||
func (api *API) AppsListDeployed(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
instanceName := vars["name"]
|
||||
|
||||
// Validate instance exists
|
||||
if err := api.instance.ValidateInstance(instanceName); err != nil {
|
||||
respondError(w, http.StatusNotFound, fmt.Sprintf("Instance not found: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
// List deployed apps
|
||||
appsMgr := apps.NewManager(api.dataDir, api.appsDir)
|
||||
deployedApps, err := appsMgr.ListDeployed(instanceName)
|
||||
if err != nil {
|
||||
respondError(w, http.StatusInternalServerError, fmt.Sprintf("Failed to list apps: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
respondJSON(w, http.StatusOK, map[string]interface{}{
|
||||
"apps": deployedApps,
|
||||
})
|
||||
}
|
||||
|
||||
// AppsAdd adds an app to instance configuration
|
||||
func (api *API) AppsAdd(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
instanceName := vars["name"]
|
||||
|
||||
// Validate instance exists
|
||||
if err := api.instance.ValidateInstance(instanceName); err != nil {
|
||||
respondError(w, http.StatusNotFound, fmt.Sprintf("Instance not found: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
// Parse request
|
||||
var req struct {
|
||||
Name string `json:"name"`
|
||||
Config map[string]string `json:"config"`
|
||||
}
|
||||
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
respondError(w, http.StatusBadRequest, "Invalid request body")
|
||||
return
|
||||
}
|
||||
|
||||
if req.Name == "" {
|
||||
respondError(w, http.StatusBadRequest, "app name is required")
|
||||
return
|
||||
}
|
||||
|
||||
// Add app
|
||||
appsMgr := apps.NewManager(api.dataDir, api.appsDir)
|
||||
if err := appsMgr.Add(instanceName, req.Name, req.Config); err != nil {
|
||||
respondError(w, http.StatusInternalServerError, fmt.Sprintf("Failed to add app: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
respondJSON(w, http.StatusCreated, map[string]string{
|
||||
"message": "App added to configuration",
|
||||
"app": req.Name,
|
||||
})
|
||||
}
|
||||
|
||||
// AppsDeploy deploys an app to the cluster
|
||||
func (api *API) AppsDeploy(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
instanceName := vars["name"]
|
||||
appName := vars["app"]
|
||||
|
||||
// Validate instance exists
|
||||
if err := api.instance.ValidateInstance(instanceName); err != nil {
|
||||
respondError(w, http.StatusNotFound, fmt.Sprintf("Instance not found: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
// Start deploy operation
|
||||
opsMgr := operations.NewManager(api.dataDir)
|
||||
opID, err := opsMgr.Start(instanceName, "deploy_app", appName)
|
||||
if err != nil {
|
||||
respondError(w, http.StatusInternalServerError, fmt.Sprintf("Failed to start operation: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
// Deploy in background
|
||||
go func() {
|
||||
appsMgr := apps.NewManager(api.dataDir, api.appsDir)
|
||||
opsMgr.UpdateStatus(instanceName, opID, "running")
|
||||
|
||||
if err := appsMgr.Deploy(instanceName, appName); err != nil {
|
||||
opsMgr.Update(instanceName, opID, "failed", err.Error(), 0)
|
||||
} else {
|
||||
opsMgr.Update(instanceName, opID, "completed", "App deployed", 100)
|
||||
}
|
||||
}()
|
||||
|
||||
respondJSON(w, http.StatusAccepted, map[string]string{
|
||||
"operation_id": opID,
|
||||
"message": "App deployment initiated",
|
||||
})
|
||||
}
|
||||
|
||||
// AppsDelete deletes an app
|
||||
func (api *API) AppsDelete(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
instanceName := vars["name"]
|
||||
appName := vars["app"]
|
||||
|
||||
// Validate instance exists
|
||||
if err := api.instance.ValidateInstance(instanceName); err != nil {
|
||||
respondError(w, http.StatusNotFound, fmt.Sprintf("Instance not found: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
// Start delete operation
|
||||
opsMgr := operations.NewManager(api.dataDir)
|
||||
opID, err := opsMgr.Start(instanceName, "delete_app", appName)
|
||||
if err != nil {
|
||||
respondError(w, http.StatusInternalServerError, fmt.Sprintf("Failed to start operation: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
// Delete in background
|
||||
go func() {
|
||||
appsMgr := apps.NewManager(api.dataDir, api.appsDir)
|
||||
opsMgr.UpdateStatus(instanceName, opID, "running")
|
||||
|
||||
if err := appsMgr.Delete(instanceName, appName); err != nil {
|
||||
opsMgr.Update(instanceName, opID, "failed", err.Error(), 0)
|
||||
} else {
|
||||
opsMgr.Update(instanceName, opID, "completed", "App deleted", 100)
|
||||
}
|
||||
}()
|
||||
|
||||
respondJSON(w, http.StatusAccepted, map[string]string{
|
||||
"operation_id": opID,
|
||||
"message": "App deletion initiated",
|
||||
})
|
||||
}
|
||||
|
||||
// AppsGetStatus returns app status
|
||||
func (api *API) AppsGetStatus(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
instanceName := vars["name"]
|
||||
appName := vars["app"]
|
||||
|
||||
// Validate instance exists
|
||||
if err := api.instance.ValidateInstance(instanceName); err != nil {
|
||||
respondError(w, http.StatusNotFound, fmt.Sprintf("Instance not found: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
// Get status
|
||||
appsMgr := apps.NewManager(api.dataDir, api.appsDir)
|
||||
status, err := appsMgr.GetStatus(instanceName, appName)
|
||||
if err != nil {
|
||||
respondError(w, http.StatusInternalServerError, fmt.Sprintf("Failed to get status: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
respondJSON(w, http.StatusOK, status)
|
||||
}
|
||||
Reference in New Issue
Block a user