github.com/nais/knorten@v0.0.0-20240104110906-55926958e361/pkg/api/compute.go (about)

     1  package api
     2  
     3  import (
     4  	"net/http"
     5  	"strconv"
     6  
     7  	"github.com/gin-contrib/sessions"
     8  	"github.com/gin-gonic/gin"
     9  	"github.com/gin-gonic/gin/binding"
    10  	"github.com/go-playground/validator/v10"
    11  	"github.com/nais/knorten/pkg/database/gensql"
    12  	"github.com/nais/knorten/pkg/user"
    13  )
    14  
    15  type computeForm struct {
    16  	DiskSize string `form:"diskSize" binding:"validDiskSize"`
    17  }
    18  
    19  func (c *client) setupComputeRoutes() {
    20  	if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
    21  		err := v.RegisterValidation("validDiskSize", user.ValidateDiskSize)
    22  		if err != nil {
    23  			c.log.WithError(err).Error("can't register validator")
    24  			return
    25  		}
    26  	}
    27  
    28  	c.router.GET("/compute/new", func(ctx *gin.Context) {
    29  		c.htmlResponseWrapper(ctx, http.StatusOK, "compute/new", gin.H{})
    30  	})
    31  
    32  	c.router.POST("/compute/new", func(ctx *gin.Context) {
    33  		err := c.createComputeInstance(ctx)
    34  		if err != nil {
    35  			session := sessions.Default(ctx)
    36  			session.AddFlash(err.Error())
    37  			err := session.Save()
    38  			if err != nil {
    39  				c.log.WithError(err).Error("problem saving session")
    40  				ctx.Redirect(http.StatusSeeOther, "/compute/new")
    41  				return
    42  			}
    43  			ctx.Redirect(http.StatusSeeOther, "/compute/new")
    44  			return
    45  		}
    46  
    47  		ctx.Redirect(http.StatusSeeOther, "/oversikt")
    48  	})
    49  
    50  	c.router.GET("/compute/edit", func(ctx *gin.Context) {
    51  		user, err := getUser(ctx)
    52  		if err != nil {
    53  			session := sessions.Default(ctx)
    54  			session.AddFlash(err.Error())
    55  			err := session.Save()
    56  			if err != nil {
    57  				c.log.WithError(err).Error("problem saving session")
    58  				ctx.Redirect(http.StatusSeeOther, "/oversikt")
    59  				return
    60  			}
    61  			ctx.Redirect(http.StatusSeeOther, "/oversikt")
    62  			return
    63  		}
    64  
    65  		computeInstance, err := c.repo.ComputeInstanceGet(ctx, user.Email)
    66  		if err != nil {
    67  			session := sessions.Default(ctx)
    68  			session.AddFlash(err.Error())
    69  			err := session.Save()
    70  			if err != nil {
    71  				c.log.WithError(err).Error("problem saving session")
    72  				ctx.Redirect(http.StatusSeeOther, "/oversikt")
    73  				return
    74  			}
    75  			ctx.Redirect(http.StatusSeeOther, "/oversikt")
    76  			return
    77  		}
    78  
    79  		c.htmlResponseWrapper(ctx, http.StatusOK, "compute/edit", gin.H{
    80  			"name":     "compute-" + getNormalizedNameFromEmail(user.Email),
    81  			"diskSize": computeInstance.DiskSize,
    82  		})
    83  	})
    84  
    85  	c.router.POST("/compute/edit", func(ctx *gin.Context) {
    86  		if err := c.editCompute(ctx); err != nil {
    87  			session := sessions.Default(ctx)
    88  			session.AddFlash(err.Error())
    89  			err := session.Save()
    90  			if err != nil {
    91  				c.log.WithError(err).Error("problem saving session")
    92  				ctx.Redirect(http.StatusSeeOther, "/oversikt")
    93  				return
    94  			}
    95  			ctx.Redirect(http.StatusSeeOther, "/oversikt")
    96  			return
    97  		}
    98  		ctx.Redirect(http.StatusSeeOther, "/oversikt")
    99  	})
   100  
   101  	c.router.POST("/compute/delete", func(ctx *gin.Context) {
   102  		err := c.deleteComputeInstance(ctx)
   103  		if err != nil {
   104  			session := sessions.Default(ctx)
   105  			session.AddFlash(err.Error())
   106  			err := session.Save()
   107  			if err != nil {
   108  				c.log.WithError(err).Error("problem saving session")
   109  				ctx.Redirect(http.StatusSeeOther, "/oversikt")
   110  				return
   111  			}
   112  			ctx.Redirect(http.StatusSeeOther, "/oversikt")
   113  			return
   114  		}
   115  
   116  		ctx.Redirect(http.StatusSeeOther, "/oversikt")
   117  	})
   118  }
   119  
   120  func (c *client) editCompute(ctx *gin.Context) error {
   121  	var form computeForm
   122  	err := ctx.ShouldBindWith(&form, binding.Form)
   123  	if err != nil {
   124  		return err
   125  	}
   126  
   127  	user, err := getUser(ctx)
   128  	if err != nil {
   129  		return err
   130  	}
   131  
   132  	instance, err := c.repo.ComputeInstanceGet(ctx, user.Email)
   133  	if err != nil {
   134  		return err
   135  	}
   136  
   137  	diskSizeInt, err := strconv.ParseInt(form.DiskSize, 10, 32)
   138  	if err != nil {
   139  		return err
   140  	}
   141  	instance.DiskSize = int32(diskSizeInt)
   142  
   143  	if err := c.repo.RegisterResizeComputeDiskEvent(ctx, user.Email, instance); err != nil {
   144  		return err
   145  	}
   146  
   147  	return nil
   148  }
   149  
   150  func (c *client) deleteComputeInstance(ctx *gin.Context) error {
   151  	user, err := getUser(ctx)
   152  	if err != nil {
   153  		return err
   154  	}
   155  
   156  	return c.repo.RegisterDeleteComputeEvent(ctx, user.Email)
   157  }
   158  
   159  func (c *client) createComputeInstance(ctx *gin.Context) error {
   160  	user, err := getUser(ctx)
   161  	if err != nil {
   162  		return err
   163  	}
   164  
   165  	instance := gensql.ComputeInstance{
   166  		Owner:    user.Email,
   167  		Name:     "compute-" + getNormalizedNameFromEmail(user.Email),
   168  		DiskSize: 10,
   169  	}
   170  
   171  	return c.repo.RegisterCreateComputeEvent(ctx, instance.Owner, instance)
   172  }