diff --git a/src/handlers/actions/actions.go b/src/handlers/actions/actions.go index 150483c..1dcdc63 100644 --- a/src/handlers/actions/actions.go +++ b/src/handlers/actions/actions.go @@ -1,10 +1,54 @@ package actions -import "net/http" +import ( + "context" + "fmt" + "io" + "net/http" + + "git.dcntrlized.org/Dcntrlized/Maestro/lib/docker" +) func RunAction(w http.ResponseWriter, r *http.Request) { - // Stub, to implement, receives an action via frontend code and redirects it to the correct container, which will execute it and return the result to the frontend - // Request comes in format {"container_id": string, "action": { "method": "GET" | "POST" | "PUT" | "DELETE", "action_name": string }, "payload": object} + // Runs an action on the container specified by the actionName and containerId path parameters. + actionName := r.PathValue("actionName") + containerId := r.PathValue("containerId") - http.Error(w, "Action not implemented", http.StatusNotImplemented) + // Get IP address of the container using containerId + dockerClient, err := docker.NewDockerClient() + if err != nil { + http.Error(w, "Failed to create Docker client", http.StatusInternalServerError) + return + } + + inspectData, err := dockerClient.ContainerInspect(context.Background(), containerId) + if err != nil { + http.Error(w, "Failed to inspect container", http.StatusInternalServerError) + return + } + + network, _, err := docker.ExtractNetworkInfo(context.Background(), dockerClient, inspectData) + if err != nil { + http.Error(w, "Failed to extract network info", http.StatusInternalServerError) + return + } + + // Construct the URL for the action endpoint + actionURL := fmt.Sprintf("http://%s:%d/%s", network.IPAddress, network.Ports[0].Host, actionName) // Assuming network.Ports[0] is the main port. Might change in the future + + // Forward the request to the container's action endpoint + resp, err := http.Get(actionURL) + if err != nil { + http.Error(w, "Failed to forward request to container", http.StatusInternalServerError) + return + } + defer resp.Body.Close() + + // Copy the response from the container back to the original response writer + w.WriteHeader(resp.StatusCode) + _, err = io.Copy(w, resp.Body) + if err != nil { + http.Error(w, "Failed to read response from container", http.StatusInternalServerError) + return + } } diff --git a/src/main.go b/src/main.go index 4992565..38d1deb 100644 --- a/src/main.go +++ b/src/main.go @@ -43,7 +43,7 @@ func main() { mux.HandleFunc("/api/containers", containers.NewListContainersHandler(cache)) mux.HandleFunc("/api/ws", wsHub.HandleWS) mux.HandleFunc("/api/containers/install", containers.InstallContainer) - mux.HandleFunc("/api/actions", actions.RunAction) + mux.HandleFunc("/api/actions/{actionName}/{containerId}", actions.RunAction) mux.HandleFunc("/api/registry", handlers.GetRegistry) if os.Getenv("DEV_MODE") != "true" {