diff --git a/controllers/domain.go b/controllers/domain.go index a9adc1f..124a85e 100644 --- a/controllers/domain.go +++ b/controllers/domain.go @@ -1,6 +1,7 @@ package controllers import ( + "fmt" "reCoreD-UI/models" "strconv" @@ -10,6 +11,11 @@ import ( ) func (c *Controller) CreateDomain(d *models.Domain) error { + nss, err := c.GetDNS() + if err != nil { + return err + } + return c.DB.Transaction(func(tx *gorm.DB) error { if err := tx.Create(d).Error; err != nil { return err @@ -30,6 +36,18 @@ func (c *Controller) CreateDomain(d *models.Domain) error { return err } + for i, ns := range nss { + record := &models.RecordWithType[dns.NSRecord]{} + record.Zone = d.DomainName + record.RecordType = models.RecordTypeNS + record.Content.Host = ns + record.Name = fmt.Sprintf("ns%d", i+1) + + if err := tx.Create(record.ToRecord()).Error; err != nil { + return err + } + } + return nil }) } diff --git a/controllers/record.go b/controllers/record.go index acea319..d4b7acd 100644 --- a/controllers/record.go +++ b/controllers/record.go @@ -4,34 +4,9 @@ import ( "fmt" "reCoreD-UI/models" - dns "github.com/cloud66-oss/coredns_mysql" - "gorm.io/gorm" ) -func (c *Controller) SetupNSRecord(domain *models.Domain) error { - nss, err := c.GetDNS() - if err != nil { - return err - } - - return c.DB.Transaction(func(tx *gorm.DB) error { - for i, ns := range nss { - record := &models.RecordWithType[dns.NSRecord]{} - record.Zone = domain.DomainName - record.RecordType = models.RecordTypeNS - record.Content.Host = ns - record.Name = fmt.Sprintf("ns%d", i+1) - - if err := tx.Create(record.ToRecord()).Error; err != nil { - return err - } - } - - return nil - }) -} - func (c *Controller) CreateRecord(r *models.Record) error { if r.RecordType != models.RecordTypeSOA { domains, err := c.GetDomains(r.Zone) @@ -60,7 +35,7 @@ func (c *Controller) CreateRecords(rs []*models.Record) error { }) } -func (c *Controller) GetRecords(cond map[string]any) ([]models.Record, error) { +func (c *Controller) GetRecords(cond map[string]string) ([]models.Record, error) { var records []models.Record if err := c.DB.Where(cond).Find(&records).Error; err != nil { @@ -76,8 +51,11 @@ func (c *Controller) UpdateRecord(r *models.Record) error { }) } -func (c *Controller) DeleteRecord(id string) error { +func (c *Controller) DeleteRecord(domain, id string) error { return c.DB.Transaction(func(tx *gorm.DB) error { - return tx.Where("record_type != ?", models.RecordTypeSOA).Where("id = ?", id).Delete(&models.Record{}).Error + return tx.Where("record_type != ?", models.RecordTypeSOA). + Where("id = ?", id). + Where("zone = ?", domain). + Delete(&models.Record{}).Error }) } diff --git a/server/handlers_domains.go b/server/handlers_domains.go index 6f8dfad..402e50a 100644 --- a/server/handlers_domains.go +++ b/server/handlers_domains.go @@ -8,20 +8,6 @@ import ( "github.com/sirupsen/logrus" ) -type Response struct { - Succeed bool `json:"succeed"` - Message string `json:"message"` - Data interface{} `json:"data"` -} - -func errorHandler(c *gin.Context, err error) { - c.JSON(http.StatusInternalServerError, Response{ - Succeed: false, - Message: err.Error(), - Data: nil, - }) -} - func (s *Server) getDomains(c *gin.Context) { domains, err := s.controller.GetDomains("") if err != nil { diff --git a/server/handlers_records.go b/server/handlers_records.go index a86bc12..8ba795e 100644 --- a/server/handlers_records.go +++ b/server/handlers_records.go @@ -1,2 +1,124 @@ package server +import ( + "net/http" + "reCoreD-UI/models" + + "github.com/gin-gonic/gin" +) + +func (s *Server) getRecords(c *gin.Context) { + query := make(map[string]string) + if err := c.BindQuery(&query); err != nil { + c.JSON(http.StatusBadRequest, Response{ + Succeed: false, + Message: err.Error(), + }) + return + } + domain := c.Param("domain") + query["zone"] = domain + + records, err := s.controller.GetRecords(query) + if err != nil { + errorHandler(c, err) + return + } + + c.JSON(http.StatusOK, Response{ + Succeed: true, + Data: records, + }) +} + +func (s *Server) createRecord(c *gin.Context) { + record := &models.Record{} + if err := c.BindJSON(record); err != nil { + c.JSON(http.StatusBadRequest, Response{ + Succeed: false, + Message: err.Error(), + }) + return + } + + domain := c.Param("domain") + if domain != record.Zone { + c.JSON(http.StatusBadRequest, Response{ + Succeed: false, + Message: "request body doesn't match URI", + }) + return + } + + if err := s.controller.CreateRecord(record); err != nil { + errorHandler(c, err) + return + } + + c.JSON(http.StatusCreated, Response{ + Succeed: true, + }) +} + +func (s *Server) createRecords(c *gin.Context) { + var records []*models.Record + if err := c.BindJSON(&records); err != nil { + c.JSON(http.StatusBadRequest, Response{ + Succeed: false, + Message: err.Error(), + }) + return + } + + if err := s.controller.CreateRecords(records); err != nil { + errorHandler(c, err) + return + } + + c.JSON(http.StatusCreated, Response{ + Succeed: true, + }) +} + +func (s *Server) updateRecord(c *gin.Context) { + record := &models.Record{} + if err := c.BindJSON(record); err != nil { + c.JSON(http.StatusBadRequest, Response{ + Succeed: false, + Message: err.Error(), + }) + return + } + + domain := c.Param("domain") + if domain != record.Zone { + c.JSON(http.StatusBadRequest, Response{ + Succeed: false, + Message: "request body doesn't match URI", + }) + return + } + + if err := s.controller.UpdateRecord(record); err != nil { + errorHandler(c, err) + return + } + + c.JSON(http.StatusOK, Response{ + Succeed: true, + }) +} + +func (s *Server) deleteRecord(c *gin.Context) { + domain := c.Param("domain") + id := c.Param("id") + + if err := s.controller.DeleteRecord(domain, id); err != nil { + errorHandler(c, err) + return + } + + c.JSON(http.StatusNoContent, Response{ + Succeed: true, + }) +} diff --git a/server/response.go b/server/response.go new file mode 100644 index 0000000..cd4dc92 --- /dev/null +++ b/server/response.go @@ -0,0 +1,21 @@ +package server + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +type Response struct { + Succeed bool `json:"succeed"` + Message string `json:"message"` + Data interface{} `json:"data"` +} + +func errorHandler(c *gin.Context, err error) { + c.JSON(http.StatusInternalServerError, Response{ + Succeed: false, + Message: err.Error(), + Data: nil, + }) +} diff --git a/server/route.go b/server/route.go index a1b6298..df9c8ed 100644 --- a/server/route.go +++ b/server/route.go @@ -30,7 +30,11 @@ func (s *Server) setupRoute() { records := groupV1.Group("/records") records. - GET("/") + GET("/:domain", s.getRecords). + POST("/:domain", s.createRecord). + POST("/:domain/bulk", s.createRecords). + PUT("/:domain", s.updateRecord). + DELETE("/:domain/:id", s.deleteRecord) server.Use(func(ctx *gin.Context) { uri := ctx.Request.RequestURI