summaryrefslogtreecommitdiffstats
path: root/web/handler/instance.go
diff options
context:
space:
mode:
Diffstat (limited to 'web/handler/instance.go')
-rw-r--r--web/handler/instance.go95
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",
+ })
+ }
+}