[ADD] add api for updating http rule

This commit is contained in:
GLYASAI 2018-11-21 17:15:40 +08:00
parent 086aa7b058
commit 61b01f2b95
6 changed files with 146 additions and 24 deletions

View File

@ -43,16 +43,14 @@ func (g *GatewayStruct) HttpRule(w http.ResponseWriter, r *http.Request) {
g.addHttpRule(w, r)
case "PUT":
g.updateHttpRule(w, r)
logrus.Debug("Update application rule.")
case "Delete":
g.deleteHttpRule(w, r)
logrus.Debugf("Delete application rule.")
}
}
func (g *GatewayStruct) addHttpRule(w http.ResponseWriter, r *http.Request) {
logrus.Debugf("add application rule.")
var req api_model.AppRuleStruct
logrus.Debugf("add http rule.")
var req api_model.HttpRuleStruct
ok := httputil.ValidatorRequestStructAndErrorResponse(r, w, &req, nil)
if !ok {
return
@ -62,6 +60,7 @@ func (g *GatewayStruct) addHttpRule(w http.ResponseWriter, r *http.Request) {
serviceID := r.Context().Value(middleware.ContextKey("service_id")).(string)
// TODO: shouldn't write the business logic here
httpRule := &model.HttpRule{
UUID: util.NewUUID(),
ServiceID: serviceID,
@ -84,13 +83,7 @@ func (g *GatewayStruct) addHttpRule(w http.ResponseWriter, r *http.Request) {
}
if req.CertificateID != "" {
cert := &model.Certificate{
UUID: req.CertificateID,
CertificateName: req.CertificateName,
Certificate: req.Certificate,
PrivateKey: req.PrivateKey,
}
if err := h.AddCertificate(cert, tx); err != nil {
if err := h.AddCertificate(&req, tx); err != nil {
httputil.ReturnError(r, w, 500, fmt.Sprintf("Unexpected error occorred while adding certificate: %v", err))
return
}
@ -113,7 +106,50 @@ func (g *GatewayStruct) addHttpRule(w http.ResponseWriter, r *http.Request) {
}
func (g *GatewayStruct) updateHttpRule(w http.ResponseWriter, r *http.Request) {
logrus.Debugf("update http rule.")
var req api_model.HttpRuleStruct
ok := httputil.ValidatorRequestStructAndErrorResponse(r, w, &req, nil)
if !ok {
return
}
reqJson, _ := json.Marshal(req)
logrus.Debugf("Request is : %s", string(reqJson))
serviceID := r.Context().Value(middleware.ContextKey("service_id")).(string)
// TODO: shouldn't write the business logic here
// begin transaction
tx := db.GetManager().Begin()
h := handler.GetGatewayHandler()
httpRule, err := h.UpdateHttpRule(&req, serviceID, tx)
if err != nil {
tx.Rollback()
httputil.ReturnError(r, w, 500, fmt.Sprintf("Unexpected error occorred while " +
"updating http rule: %v", err))
return
}
if err := h.AddCertificate(&req, tx); err != nil {
tx.Rollback()
httputil.ReturnError(r, w, 500, fmt.Sprintf("Unexpected error occorred while " +
"updating certificate: %v", err))
return
}
if err := h.AddRuleExtensions(httpRule.UUID, req.RuleExtensions, tx); err != nil {
tx.Rollback()
httputil.ReturnError(r, w, 500, fmt.Sprintf("Unexpected error occorred while adding rule extensions: %v", err))
return
}
// end transaction
if err := tx.Commit().Error; err != nil {
tx.Rollback()
httputil.ReturnError(r, w, 500, fmt.Sprintf("Unexpected error occorred while commit transaction: %v", err))
return
}
httputil.ReturnSuccess(r, w, "success")
}
func (g *GatewayStruct) deleteHttpRule(w http.ResponseWriter, r *http.Request) {

View File

@ -19,6 +19,7 @@
package handler
import (
"fmt"
apimodel "github.com/goodrain/rainbond/api/model"
"github.com/goodrain/rainbond/db"
"github.com/goodrain/rainbond/db/model"
@ -37,15 +38,67 @@ func CreateGatewayManager(dbmanager db.Manager) *GatewayAction {
}
}
// AddHttpRule adds http rule to db if it doesn't exists.
func (g *GatewayAction) AddHttpRule(httpRule *model.HttpRule, tx *gorm.DB) error {
return g.dbmanager.HttpRuleDaoTransactions(tx).AddModel(httpRule)
}
// AddCertificate adds certificate to db if is doesn't exists
func (g *GatewayAction) AddCertificate(certificate *model.Certificate, tx *gorm.DB) error {
return g.dbmanager.CertificateDaoTransactions(tx).AddModel(certificate)
func (g *GatewayAction) UpdateHttpRule(req *apimodel.HttpRuleStruct, serviceID string, tx *gorm.DB) (httpRule *model.HttpRule, err error) {
rule, err := g.dbmanager.HttpRuleDaoTransactions(tx).GetHttpRuleByServiceIDAndContainerPort(serviceID, req.ContainerPort)
if err != nil {
return nil, err
}
if rule == nil {
return nil, fmt.Errorf("HttpRule dosen't exist based on ServiceID(%s) and ContainerPort(%v)", serviceID, req.ContainerPort)
}
// delete old Certificate
if err := g.dbmanager.CertificateDaoTransactions(tx).DeleteCertificateByID(rule.CertificateID); err != nil {
return nil, err
}
// delete old RuleExtensions
if err := g.dbmanager.RuleExtensionDaoTransactions(tx).DeleteRuleExtensionByRuleID(rule.UUID); err != nil {
return nil, err
}
rule.Path = req.Path
rule.Domain = req.Domain
rule.Header = req.Header
rule.Cookie = req.Cookie
rule.LoadBalancerType = req.LoadBalancerType
rule.CertificateID = req.CertificateID
return rule, g.dbmanager.HttpRuleDaoTransactions(tx).UpdateModel(rule)
}
// AddCertificate adds certificate to db if it doesn't exists
func (g *GatewayAction) AddCertificate(req *apimodel.HttpRuleStruct, tx *gorm.DB) error {
cert := &model.Certificate{
UUID: req.CertificateID,
CertificateName: req.CertificateName,
Certificate: req.Certificate,
PrivateKey: req.PrivateKey,
}
return g.dbmanager.CertificateDaoTransactions(tx).AddModel(cert)
}
func (g *GatewayAction) UpdateCertificate(req apimodel.HttpRuleStruct, httpRule *model.HttpRule, tx *gorm.DB) error {
// delete old certificate
cert, err := g.dbmanager.CertificateDaoTransactions(tx).GetCertificateByID(req.CertificateID)
if err != nil {
return err
}
if cert == nil {
return fmt.Errorf("Certificate doesn't exist based on certificateID(%s)", req.CertificateID)
}
cert.CertificateName = req.CertificateName
cert.Certificate = req.Certificate
cert.PrivateKey = req.PrivateKey
return g.dbmanager.CertificateDaoTransactions(tx).UpdateModel(cert)
}
// AddRuleExtensions adds rule extensions to db if any of they doesn't exists
func (g *GatewayAction) AddRuleExtensions(ruleID string, ruleExtensions []*apimodel.RuleExtensionStruct, tx *gorm.DB) error {
for _, ruleExtension := range ruleExtensions {
re := &model.RuleExtension{

View File

@ -26,6 +26,8 @@ import (
type GatewayHandler interface {
AddHttpRule(httpRule *dbmodel.HttpRule, tx *gorm.DB) error
AddCertificate(certificate *dbmodel.Certificate, tx *gorm.DB) error
UpdateHttpRule(req *apimodel.HttpRuleStruct, serviceID string, tx *gorm.DB) (*dbmodel.HttpRule, error)
AddCertificate(req *apimodel.HttpRuleStruct, tx *gorm.DB) error
UpdateCertificate(req apimodel.HttpRuleStruct, httpRule *dbmodel.HttpRule, tx *gorm.DB) error
AddRuleExtensions(ruleID string, ruleExtensions []*apimodel.RuleExtensionStruct, tx *gorm.DB) error
}

View File

@ -18,8 +18,8 @@
package model
//AppRuleStruct -
type AppRuleStruct struct {
//HttpRuleStruct -
type HttpRuleStruct struct {
ContainerPort int `json:"container_port" validate:"container_port|required"`
Domain string `json:"domain"`
Path string `json:"path"`

View File

@ -409,12 +409,14 @@ type ServiceSourceDao interface {
type CertificateDao interface {
Dao
GetCertificateByID(certificateID string) (*model.Certificate, error)
DeleteCertificateByID(certificateID string) error
}
// RuleExtensionDao -
type RuleExtensionDao interface {
Dao
GetRuleExtensionByServiceID(serviceID string) ([]*model.RuleExtension, error)
GetRuleExtensionByRuleID(ruleID string) ([]*model.RuleExtension, error)
DeleteRuleExtensionByRuleID(ruleID string) error
}
// HttpRuleDao -

View File

@ -47,8 +47,15 @@ func (c *CertificateDaoImpl) AddModel(mo model.Interface) error {
return nil
}
func (c *CertificateDaoImpl) UpdateModel(model.Interface) error {
return nil
func (c *CertificateDaoImpl) UpdateModel(mo model.Interface) error {
cert, ok := mo.(*model.Certificate)
if !ok {
return fmt.Errorf("Failed to convert %s to *model.Certificate", reflect.TypeOf(mo).String())
}
return c.DB.Table(cert.TableName()).
Where("uuid = ?", cert.UUID).
Update(cert).Error
}
// GetCertificateByID gets a certificate by matching id
@ -63,6 +70,13 @@ func (c *CertificateDaoImpl) GetCertificateByID(certificateID string) (*model.Ce
return certificate, nil
}
func (c *CertificateDaoImpl) DeleteCertificateByID(certificateID string) error {
cert := &model.Certificate{
UUID: certificateID,
}
return c.DB.Where("uuid=?", certificateID).Delete(cert).Error
}
type RuleExtensionDaoImpl struct {
DB *gorm.DB
}
@ -86,9 +100,9 @@ func (c *RuleExtensionDaoImpl) UpdateModel(model.Interface) error {
return nil
}
func (c *RuleExtensionDaoImpl) GetRuleExtensionByServiceID(serviceID string) ([]*model.RuleExtension, error) {
func (c *RuleExtensionDaoImpl) GetRuleExtensionByRuleID(ruleID string) ([]*model.RuleExtension, error) {
var ruleExtension []*model.RuleExtension
if err := c.DB.Where("service_id = ?", serviceID).Find(&ruleExtension).Error; err != nil {
if err := c.DB.Where("rule_id = ?", ruleID).Find(&ruleExtension).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return ruleExtension, nil
}
@ -97,6 +111,14 @@ func (c *RuleExtensionDaoImpl) GetRuleExtensionByServiceID(serviceID string) ([]
return ruleExtension, nil
}
// DeleteRuleExtensionByRuleID delete rule extensions by ruleID
func (c *RuleExtensionDaoImpl) DeleteRuleExtensionByRuleID(ruleID string) error {
re := &model.RuleExtension{
RuleID: ruleID,
}
return c.DB.Where("rule_id=?", ruleID).Delete(re).Error
}
type HttpRuleDaoImpl struct {
DB *gorm.DB
}
@ -116,8 +138,15 @@ func (h *HttpRuleDaoImpl) AddModel(mo model.Interface) error {
return nil
}
func (h *HttpRuleDaoImpl) UpdateModel(model.Interface) error {
return nil
func (h *HttpRuleDaoImpl) UpdateModel(mo model.Interface) error {
hr, ok := mo.(*model.HttpRule)
if !ok {
return fmt.Errorf("Failed to convert %s to *model.HttpRule", reflect.TypeOf(mo).String())
}
return h.DB.Table(hr.TableName()).
Where("uuid = ?", hr.UUID).
Update(hr).Error
}
// GetHttpRuleByServiceIDAndContainerPort gets a HttpRule based on serviceID and containerPort