Merge pull request #6986 from swordqiu/hotfix/qj-validate-ip-for-syncfixnics

fix: validate candiate ip for sync-fix-nics
This commit is contained in:
yunion-ci-robot
2020-07-03 16:34:29 +08:00
committed by GitHub
3 changed files with 37 additions and 6 deletions
+5
View File
@@ -340,3 +340,8 @@ type GuestSaveToTemplateInput struct {
// The generate name of guest template
GenerateName string `json:"generate_name"`
}
type GuestSyncFixNicsInput struct {
// 需要修正的IP地址列表
Ip []string `json:"ip"`
}
+25 -6
View File
@@ -4044,14 +4044,14 @@ func (self *SGuest) createConvertedServer(
func (self *SGuest) AllowPerformSyncFixNics(ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
data jsonutils.JSONObject) bool {
input api.GuestSyncFixNicsInput) bool {
return db.IsAdminAllowPerform(userCred, self, "sync-fix-nics")
}
func (self *SGuest) PerformSyncFixNics(ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
input api.GuestSyncFixNicsInput) (jsonutils.JSONObject, error) {
iVM, err := self.GetIVM()
if err != nil {
return nil, httperrors.NewGeneralError(err)
@@ -4064,11 +4064,30 @@ func (self *SGuest) PerformSyncFixNics(ctx context.Context,
if host == nil {
return nil, httperrors.NewInternalServerError("host not found???")
}
iplistArray, err := data.Get("ip")
if err != nil {
return nil, httperrors.NewInputParameterError("missing field ip, list of ip")
iplist := input.Ip
// validate iplist
if len(iplist) == 0 {
return nil, httperrors.NewInputParameterError("empty ip list")
}
for _, ip := range iplist {
// ip is reachable on host
net, err := host.getNetworkOfIPOnHost(ip)
if err != nil {
return nil, httperrors.NewInputParameterError("Unreachable IP %s: %s", ip, err)
}
// check ip is reserved or free
rip := ReservedipManager.GetReservedIP(net, ip)
if rip == nil {
// check ip is free
nip, err := net.GetFreeIPWithLock(ctx, userCred, nil, nil, ip, "", false)
if err != nil {
return nil, httperrors.NewInputParameterError("Unavailable IP %s: occupied", ip)
}
if nip != ip {
return nil, httperrors.NewInputParameterError("Unavailable IP %s: occupied", ip)
}
}
}
iplist := iplistArray.(*jsonutils.JSONArray).GetStringArray()
errs := make([]error, 0)
for i := range vnics {
ip := vnics[i].GetIP()
+7
View File
@@ -440,6 +440,13 @@ func (self *SNetwork) getFreeIP(addrTable map[string]bool, recentUsedAddrTable m
return "", httperrors.NewInsufficientResourceError("Out of IP address")
}
func (self *SNetwork) GetFreeIPWithLock(ctx context.Context, userCred mcclient.TokenCredential, addrTable map[string]bool, recentUsedAddrTable map[string]bool, candidate string, allocDir api.IPAllocationDirection, reserved bool) (string, error) {
lockman.LockObject(ctx, self)
defer lockman.ReleaseObject(ctx, self)
return self.GetFreeIP(ctx, userCred, addrTable, recentUsedAddrTable, candidate, allocDir, reserved)
}
func (self *SNetwork) GetFreeIP(ctx context.Context, userCred mcclient.TokenCredential, addrTable map[string]bool, recentUsedAddrTable map[string]bool, candidate string, allocDir api.IPAllocationDirection, reserved bool) (string, error) {
// if reserved true, first try find IP in reserved IP pool
if reserved {