diff options
Diffstat (limited to 'web/handler/instance.go')
| -rw-r--r-- | web/handler/instance.go | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/web/handler/instance.go b/web/handler/instance.go new file mode 100644 index 0000000..0222a42 --- /dev/null +++ b/web/handler/instance.go @@ -0,0 +1,95 @@ +package handler + +import ( + "fmt" + "html/template" + "log/slog" + "net/http" + "time" + + "git.leonardobishop.net/instancer/pkg/deployer" + "git.leonardobishop.net/instancer/pkg/session" +) + +func GetInstances(tmpl *template.Template, dockerDeployer *deployer.DockerDeployer) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + session := r.Context().Value("session").(*session.UserSession) + + instances, err := dockerDeployer.GetTeamInstances(r.Context(), session.Team) + if err != nil { + slog.Error("could not get team instances", "team", session.Team, "error", err) + http.Error(w, "Internal server error", http.StatusInternalServerError) + return + } + + type instanceView struct { + ChallengeName string + DeployKey string + Address template.HTML + ExpiresIn string + } + var instanceViews []instanceView + for _, instance := range instances { + var expiresIn string + timeLeft := time.Until(instance.ExpiresAt) + if timeLeft <= 0 { + expiresIn = "now" + } else { + expiresIn = fmt.Sprintf("%dm %ds", int(timeLeft.Minutes()), int(timeLeft.Seconds())%60) + } + + var address string + + if instance.AddressFormat == "http" || instance.AddressFormat == "https" { + address = `<a target="_blank" href="` + instance.AddressFormat + "://" + instance.Address + `">` + instance.Address + `</a>` + } else { + address = `<code>` + instance.Address + `</code>` + } + + instanceViews = append(instanceViews, instanceView{ + ChallengeName: instance.ChallengeName, + DeployKey: instance.DeployKey, + Address: template.HTML(address), + ExpiresIn: expiresIn, + }) + } + + if err := tmpl.ExecuteTemplate(w, "f_instance.html", struct { + Instances []instanceView + }{ + Instances: instanceViews, + }); err != nil { + http.Error(w, "Internal server error", http.StatusInternalServerError) + return + } + } +} + +func PostStopInstance(tmpl *template.Template, dockerDeployer *deployer.DockerDeployer) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + session := r.Context().Value("session").(*session.UserSession) + deployKey := r.PathValue("deployKey") + + err := dockerDeployer.StopInstance(r.Context(), deployKey, session.Team) + if err != nil { + tmpl.ExecuteTemplate(w, "f_instance_result.html", struct { + State string + Message string + }{ + State: "danger", + Message: "Could not stop instance" + err.Error(), + }) + return + } + + w.Header().Set("HX-Trigger", "poll-instances-now") + + tmpl.ExecuteTemplate(w, "f_deploy_result.html", struct { + State string + Message string + }{ + State: "success", + Message: "Instance " + deployKey + " stopped", + }) + } +} |
