mirror of
https://gitee.com/rainbond/Rainbond.git
synced 2024-12-02 03:37:46 +08:00
[FIX] failed to add endpoint with port
This commit is contained in:
parent
6d7690a51b
commit
103ad550ee
@ -20,13 +20,15 @@ package controller
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/Sirupsen/logrus"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/goodrain/rainbond/api/controller/validation"
|
||||
"github.com/goodrain/rainbond/api/handler"
|
||||
"github.com/goodrain/rainbond/api/middleware"
|
||||
"github.com/goodrain/rainbond/api/model"
|
||||
"github.com/goodrain/rainbond/db/errors"
|
||||
httputil "github.com/goodrain/rainbond/util/http"
|
||||
)
|
||||
|
||||
@ -52,16 +54,20 @@ func (t *ThirdPartyServiceController) addEndpoints(w http.ResponseWriter, r *htt
|
||||
if !httputil.ValidatorRequestStructAndErrorResponse(r, w, &data, nil) {
|
||||
return
|
||||
}
|
||||
values := make(map[string][]string)
|
||||
if strings.Contains(data.IP, "127.0.0.1") {
|
||||
values["ip"] = []string{"The ip field is can't contains '127.0.0.1'"}
|
||||
}
|
||||
if len(values) != 0 {
|
||||
ipAddress := strings.Split(data.Address, ":")[0]
|
||||
if err := validation.ValidateEndpointIP(ipAddress); len(err) > 0 {
|
||||
values := make(map[string][]string, 1)
|
||||
values["ip"] = err
|
||||
httputil.ReturnValidationError(r, w, values)
|
||||
return
|
||||
}
|
||||
|
||||
sid := r.Context().Value(middleware.ContextKey("service_id")).(string)
|
||||
if err := handler.Get3rdPartySvcHandler().AddEndpoints(sid, &data); err != nil {
|
||||
if err == errors.ErrRecordAlreadyExist {
|
||||
httputil.ReturnError(r, w, 400, err.Error())
|
||||
return
|
||||
}
|
||||
httputil.ReturnError(r, w, 500, err.Error())
|
||||
return
|
||||
}
|
||||
@ -73,14 +79,16 @@ func (t *ThirdPartyServiceController) updEndpoints(w http.ResponseWriter, r *htt
|
||||
if !httputil.ValidatorRequestStructAndErrorResponse(r, w, &data, nil) {
|
||||
return
|
||||
}
|
||||
values := make(map[string][]string)
|
||||
if strings.Contains(data.IP, "127.0.0.1") {
|
||||
values["ip"] = []string{"The ip field is can't contains '127.0.0.1'"}
|
||||
}
|
||||
if len(values) != 0 {
|
||||
httputil.ReturnValidationError(r, w, values)
|
||||
return
|
||||
if data.Address != "" {
|
||||
ipAddress := strings.Split(data.Address, ":")[0]
|
||||
if err := validation.ValidateEndpointIP(ipAddress); len(err) > 0 {
|
||||
values := make(map[string][]string, 1)
|
||||
values["address"] = err
|
||||
httputil.ReturnValidationError(r, w, values)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if err := handler.Get3rdPartySvcHandler().UpdEndpoints(&data); err != nil {
|
||||
httputil.ReturnError(r, w, 500, err.Error())
|
||||
return
|
||||
|
59
api/controller/validation/validation.go
Normal file
59
api/controller/validation/validation.go
Normal file
@ -0,0 +1,59 @@
|
||||
package validation
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
|
||||
k8svalidation "k8s.io/apimachinery/pkg/util/validation"
|
||||
)
|
||||
|
||||
// ValidateDomain tests that the argument is a valid domain.
|
||||
func ValidateDomain(domain string) []string {
|
||||
if strings.TrimSpace(domain) == "" {
|
||||
return nil
|
||||
}
|
||||
var errs []string
|
||||
if strings.Contains(domain, "*") {
|
||||
errs = k8svalidation.IsWildcardDNS1123Subdomain(domain)
|
||||
} else {
|
||||
errs = k8svalidation.IsDNS1123Subdomain(domain)
|
||||
}
|
||||
return errs
|
||||
}
|
||||
|
||||
// ValidateEndpointAddress tests that the argument is a valid endpoint address.
|
||||
func ValidateEndpointAddress(address string) []string {
|
||||
ip := net.ParseIP(address)
|
||||
if ip == nil {
|
||||
return ValidateDomain(address)
|
||||
}
|
||||
return ValidateEndpointIP(address)
|
||||
}
|
||||
|
||||
// ValidateEndpointIP tests that the argument is a valid IP address.
|
||||
func ValidateEndpointIP(ipAddress string) []string {
|
||||
// We disallow some IPs as endpoints or external-ips. Specifically,
|
||||
// unspecified and loopback addresses are nonsensical and link-local
|
||||
// addresses tend to be used for node-centric purposes (e.g. metadata
|
||||
// service).
|
||||
err := []string{}
|
||||
ip := net.ParseIP(ipAddress)
|
||||
if ip == nil {
|
||||
err = append(err, fmt.Sprintf("%s must be a valid IP address", ipAddress))
|
||||
return err
|
||||
}
|
||||
if ip.IsUnspecified() {
|
||||
err = append(err, fmt.Sprintf("%s may not be unspecified (0.0.0.0)", ipAddress))
|
||||
}
|
||||
if ip.IsLoopback() {
|
||||
err = append(err, fmt.Sprintf("%s may not be in the loopback range (127.0.0.0/8)", ipAddress))
|
||||
}
|
||||
if ip.IsLinkLocalUnicast() {
|
||||
err = append(err, fmt.Sprintf("%s may not be in the link-local range (169.254.0.0/16)", ipAddress))
|
||||
}
|
||||
if ip.IsLinkLocalMulticast() {
|
||||
err = append(err, fmt.Sprintf("%s may not be in the link-local multicast range (224.0.0.0/24)", ipAddress))
|
||||
}
|
||||
return err
|
||||
}
|
@ -20,6 +20,9 @@ package handler
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/goodrain/rainbond/api/model"
|
||||
"github.com/goodrain/rainbond/db"
|
||||
@ -44,11 +47,12 @@ func Create3rdPartySvcHandler(dbmanager db.Manager, statusCli *client.AppRuntime
|
||||
|
||||
// AddEndpoints adds endpoints for third-party service.
|
||||
func (t *ThirdPartyServiceHanlder) AddEndpoints(sid string, d *model.AddEndpiontsReq) error {
|
||||
address, port := convertAddressPort(d.Address)
|
||||
ep := &dbmodel.Endpoint{
|
||||
UUID: util.NewUUID(),
|
||||
ServiceID: sid,
|
||||
IP: d.IP,
|
||||
Port: 0,
|
||||
IP: address,
|
||||
Port: port,
|
||||
IsOnline: &d.IsOnline,
|
||||
}
|
||||
if err := t.dbmanager.EndpointsDao().AddModel(ep); err != nil {
|
||||
@ -66,8 +70,10 @@ func (t *ThirdPartyServiceHanlder) UpdEndpoints(d *model.UpdEndpiontsReq) error
|
||||
logrus.Warningf("EpID: %s; error getting endpoints: %v", d.EpID, err)
|
||||
return err
|
||||
}
|
||||
if d.IP != "" {
|
||||
ep.IP = d.IP
|
||||
if d.Address != "" {
|
||||
address, port := convertAddressPort(d.Address)
|
||||
ep.IP = address
|
||||
ep.Port = port
|
||||
}
|
||||
ep.IsOnline = &d.IsOnline
|
||||
if err := t.dbmanager.EndpointsDao().UpdateModel(ep); err != nil {
|
||||
@ -79,6 +85,22 @@ func (t *ThirdPartyServiceHanlder) UpdEndpoints(d *model.UpdEndpiontsReq) error
|
||||
return nil
|
||||
}
|
||||
|
||||
func convertAddressPort(s string) (address string, port int) {
|
||||
addressport := strings.Split(s, ":")
|
||||
// compatible with ipv6
|
||||
addressSli := addressport[:func() int {
|
||||
if len(addressport) == 2 {
|
||||
return len(addressport) - 1
|
||||
}
|
||||
return len(addressport)
|
||||
}()]
|
||||
address = strings.Join(addressSli, ":")
|
||||
if len(addressport) == 2 {
|
||||
port, _ = strconv.Atoi(addressport[1])
|
||||
}
|
||||
return address, port
|
||||
}
|
||||
|
||||
// DelEndpoints deletes endpoints for third-party service.
|
||||
func (t *ThirdPartyServiceHanlder) DelEndpoints(epid, sid string) error {
|
||||
if err := t.dbmanager.EndpointsDao().DelByUUID(epid); err != nil {
|
||||
@ -100,7 +122,7 @@ func (t *ThirdPartyServiceHanlder) ListEndpoints(sid string) ([]*model.EndpointR
|
||||
for _, item := range endpoints {
|
||||
m[item.UUID] = &model.EndpointResp{
|
||||
EpID: item.UUID,
|
||||
IP: func(ip string, p int) string {
|
||||
Address: func(ip string, p int) string {
|
||||
if p != 0 {
|
||||
return fmt.Sprintf("%s:%d", ip, p)
|
||||
}
|
||||
@ -127,7 +149,7 @@ func (t *ThirdPartyServiceHanlder) ListEndpoints(sid string) ([]*model.EndpointR
|
||||
}
|
||||
m[item.Uuid] = &model.EndpointResp{
|
||||
EpID: item.Uuid,
|
||||
IP: item.Ip,
|
||||
Address: item.Ip,
|
||||
Status: item.Status,
|
||||
IsOnline: true,
|
||||
IsStatic: false,
|
||||
|
@ -20,14 +20,14 @@ package model
|
||||
|
||||
// AddEndpiontsReq is one of the Endpoints in the request to add the endpints.
|
||||
type AddEndpiontsReq struct {
|
||||
IP string `json:"ip" validate:"required|ip_v4"`
|
||||
Address string `json:"address" validate:"address|required"`
|
||||
IsOnline bool `json:"is_online" validate:"required"`
|
||||
}
|
||||
|
||||
// UpdEndpiontsReq is one of the Endpoints in the request to update the endpints.
|
||||
type UpdEndpiontsReq struct {
|
||||
EpID string `json:"ep_id" validate:"required|len:32"`
|
||||
IP string `json:"ip" validate:"ip_v4"`
|
||||
Address string `json:"address"`
|
||||
IsOnline bool `json:"is_online" validate:"required"`
|
||||
}
|
||||
|
||||
@ -40,7 +40,7 @@ type DelEndpiontsReq struct {
|
||||
// update or delete the endpints.
|
||||
type EndpointResp struct {
|
||||
EpID string `json:"ep_id"`
|
||||
IP string `json:"ip"`
|
||||
Address string `json:"address"`
|
||||
Status string `json:"status"`
|
||||
IsOnline bool `json:"is_online"`
|
||||
IsStatic bool `json:"is_static"`
|
||||
|
@ -24,6 +24,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/goodrain/rainbond/db/model"
|
||||
"github.com/goodrain/rainbond/db/errors"
|
||||
"github.com/jinzhu/gorm"
|
||||
)
|
||||
|
||||
@ -44,7 +45,7 @@ func (e *EndpointDaoImpl) AddModel(mo model.Interface) error {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return fmt.Errorf("Endpoint exists based on servicd_id(%s) and ip(%s)", ep.ServiceID, ep.IP)
|
||||
return errors.ErrRecordAlreadyExist
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user