mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-24 16:03:43 +08:00
Merge pull request #9690 from ioito/hotfix/qx-secgroup-optimized
fix(region): optimized secgroup rule sync
This commit is contained in:
@@ -15,8 +15,9 @@
|
||||
package compute
|
||||
|
||||
const (
|
||||
SECGROUP_STATUS_READY = "ready"
|
||||
SECGROUP_STATUS_DELETING = "deleting"
|
||||
SECGROUP_STATUS_READY = "ready"
|
||||
SECGROUP_STATUS_DELETING = "deleting" // 删除中
|
||||
SECGROUP_STATUS_SYNC_RULES = "sync_rules" // 同步规则中
|
||||
|
||||
SECGROUP_DEFAULT_ID = "default"
|
||||
)
|
||||
|
||||
@@ -32,7 +32,6 @@ import (
|
||||
"yunion.io/x/pkg/util/netutils"
|
||||
"yunion.io/x/pkg/util/osprofile"
|
||||
"yunion.io/x/pkg/util/regutils"
|
||||
"yunion.io/x/pkg/util/secrules"
|
||||
"yunion.io/x/pkg/util/timeutils"
|
||||
"yunion.io/x/pkg/utils"
|
||||
"yunion.io/x/sqlchemy"
|
||||
@@ -2317,20 +2316,9 @@ func (self *SGuest) GetSecgroups() ([]SSecurityGroup, error) {
|
||||
return secgroups, nil
|
||||
}
|
||||
|
||||
func (self *SGuest) getSecgroup() *SSecurityGroup {
|
||||
return SecurityGroupManager.FetchSecgroupById(self.SecgrpId)
|
||||
}
|
||||
|
||||
func (self *SGuest) getAdminSecgroup() *SSecurityGroup {
|
||||
return SecurityGroupManager.FetchSecgroupById(self.AdminSecgrpId)
|
||||
}
|
||||
|
||||
func (self *SGuest) GetSecgroupName() string {
|
||||
secgrp := self.getSecgroup()
|
||||
if secgrp != nil {
|
||||
return secgrp.GetName()
|
||||
}
|
||||
return ""
|
||||
secGrp, _ := SecurityGroupManager.FetchSecgroupById(self.AdminSecgrpId)
|
||||
return secGrp
|
||||
}
|
||||
|
||||
func (self *SGuest) getAdminSecgroupName() string {
|
||||
@@ -2341,31 +2329,6 @@ func (self *SGuest) getAdminSecgroupName() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SGuest) GetSecRules() []secrules.SecurityRule {
|
||||
return self.getSecRules()
|
||||
}
|
||||
|
||||
func (self *SGuest) getSecRules() []secrules.SecurityRule {
|
||||
if secgrp := self.getSecgroup(); secgrp != nil {
|
||||
return secgrp.GetSecRules("")
|
||||
}
|
||||
if rule, err := secrules.ParseSecurityRule(options.Options.DefaultSecurityRules); err == nil {
|
||||
return []secrules.SecurityRule{*rule}
|
||||
} else {
|
||||
log.Errorf("Default SecurityRules error: %v", err)
|
||||
}
|
||||
return []secrules.SecurityRule{}
|
||||
}
|
||||
|
||||
func (self *SGuest) getSecurityRules() string {
|
||||
secgrp := self.getSecgroup()
|
||||
if secgrp != nil {
|
||||
return secgrp.getSecurityRuleString("")
|
||||
} else {
|
||||
return options.Options.DefaultSecurityRules
|
||||
}
|
||||
}
|
||||
|
||||
//获取多个安全组规则,优先级降序排序
|
||||
func (self *SGuest) getSecurityGroupsRules() string {
|
||||
secgroups, _ := self.GetSecgroups()
|
||||
@@ -4089,10 +4052,12 @@ func (self *SGuest) GetJsonDescAtHypervisor(ctx context.Context, host *SHost) *j
|
||||
desc.Add(jsonutils.NewStringArray(netRoles), "network_roles")
|
||||
}
|
||||
|
||||
secGrp := self.getSecgroup()
|
||||
if secGrp != nil {
|
||||
desc.Add(jsonutils.NewString(secGrp.Name), "secgroup")
|
||||
}
|
||||
/*
|
||||
secGrp := self.getSecgroup()
|
||||
if secGrp != nil {
|
||||
desc.Add(jsonutils.NewString(secGrp.Name), "secgroup")
|
||||
}
|
||||
*/
|
||||
|
||||
secgroups, _ := self.getSecgroupJson()
|
||||
if secgroups != nil {
|
||||
|
||||
@@ -430,7 +430,8 @@ func (self *SInstanceSnapshot) ToInstanceCreateInput(
|
||||
inputSecgs := make([]string, 0)
|
||||
self.SecGroups.Unmarshal(&secGroups)
|
||||
for i := 0; i < len(secGroups); i++ {
|
||||
if secGrp := SecurityGroupManager.FetchSecgroupById(secGroups[i]); secGrp != nil {
|
||||
_, err := SecurityGroupManager.FetchSecgroupById(secGroups[i])
|
||||
if err == nil {
|
||||
inputSecgs = append(inputSecgs, secGroups[i])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/util/compare"
|
||||
"yunion.io/x/pkg/util/secrules"
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
@@ -630,3 +631,40 @@ func (self *SSecurityGroupCache) GetISecurityGroup() (cloudprovider.ICloudSecuri
|
||||
}
|
||||
return iRegion.GetISecurityGroupById(self.ExternalId)
|
||||
}
|
||||
|
||||
func (self *SSecurityGroupCache) SyncRules() error {
|
||||
region := self.GetRegion()
|
||||
if region == nil {
|
||||
return fmt.Errorf("failed to get region for secgroupcache %s(%s)", self.Name, self.Id)
|
||||
}
|
||||
iSecgroup, err := self.GetISecurityGroup()
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "GetISecurityGroup")
|
||||
}
|
||||
secgroup, err := self.GetSecgroup()
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "GetSecgroup")
|
||||
}
|
||||
|
||||
rules, err := iSecgroup.GetRules()
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "iSecgroup.GetRules")
|
||||
}
|
||||
|
||||
maxPriority := region.GetDriver().GetSecurityGroupRuleMaxPriority()
|
||||
minPriority := region.GetDriver().GetSecurityGroupRuleMinPriority()
|
||||
|
||||
defaultInRule := region.GetDriver().GetDefaultSecurityGroupInRule()
|
||||
defaultOutRule := region.GetDriver().GetDefaultSecurityGroupOutRule()
|
||||
order := region.GetDriver().GetSecurityGroupRuleOrder()
|
||||
onlyAllowRules := region.GetDriver().IsOnlySupportAllowRules()
|
||||
|
||||
localRules := secrules.SecurityRuleSet(secgroup.GetSecRules(""))
|
||||
|
||||
common, inAdds, outAdds, inDels, outDels := cloudprovider.CompareRules(minPriority, maxPriority, order, localRules, rules, defaultInRule, defaultOutRule, onlyAllowRules, false)
|
||||
|
||||
if len(inAdds) == 0 && len(inDels) == 0 && len(outAdds) == 0 && len(outDels) == 0 {
|
||||
return nil
|
||||
}
|
||||
return iSecgroup.SyncRules(common, inAdds, outAdds, inDels, outDels)
|
||||
}
|
||||
|
||||
@@ -291,6 +291,16 @@ func (self *SSecurityGroup) GetGuests() []SGuest {
|
||||
return guests
|
||||
}
|
||||
|
||||
func (self *SSecurityGroup) GetKvmGuests() ([]SGuest, error) {
|
||||
guests := []SGuest{}
|
||||
q := self.GetGuestsQuery().Equals("hypervisor", api.HYPERVISOR_KVM)
|
||||
err := db.FetchModelObjects(GuestManager, q, &guests)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "db.FetchModelObjects")
|
||||
}
|
||||
return guests, nil
|
||||
}
|
||||
|
||||
func (self *SSecurityGroup) GetSecgroupCacheQuery() *sqlchemy.SQuery {
|
||||
return SecurityGroupCacheManager.Query().Equals("secgroup_id", self.Id)
|
||||
}
|
||||
@@ -529,14 +539,12 @@ func (self *SSecurityGroup) PostCreate(ctx context.Context, userCred mcclient.To
|
||||
}
|
||||
}
|
||||
|
||||
func (manager *SSecurityGroupManager) FetchSecgroupById(secId string) *SSecurityGroup {
|
||||
if len(secId) > 0 {
|
||||
secgrp, _ := manager.FetchById(secId)
|
||||
if secgrp != nil {
|
||||
return secgrp.(*SSecurityGroup)
|
||||
}
|
||||
func (manager *SSecurityGroupManager) FetchSecgroupById(secId string) (*SSecurityGroup, error) {
|
||||
secgrp, err := manager.FetchById(secId)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "FetchById(%s)", secId)
|
||||
}
|
||||
return nil
|
||||
return secgrp.(*SSecurityGroup), nil
|
||||
}
|
||||
|
||||
func (self *SSecurityGroup) getSecurityRules(direction string) (rules []SSecurityGroupRule) {
|
||||
@@ -1027,33 +1035,49 @@ func (manager *SSecurityGroupManager) newFromCloudSecgroup(ctx context.Context,
|
||||
return &secgroup, nil
|
||||
}
|
||||
|
||||
func (manager *SSecurityGroupManager) DelaySync(ctx context.Context, userCred mcclient.TokenCredential, idStr string) {
|
||||
if secgrp := manager.FetchSecgroupById(idStr); secgrp == nil {
|
||||
log.Errorf("DelaySync secgroup failed")
|
||||
} else {
|
||||
needSync := false
|
||||
func (manager *SSecurityGroupManager) DelaySync(ctx context.Context, userCred mcclient.TokenCredential, idStr string) error {
|
||||
secgrp, err := manager.FetchSecgroupById(idStr)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "FetchSecgroupById(%s)", idStr)
|
||||
}
|
||||
needSync := false
|
||||
|
||||
func() {
|
||||
lockman.LockObject(ctx, secgrp)
|
||||
defer lockman.ReleaseObject(ctx, secgrp)
|
||||
func() {
|
||||
lockman.LockObject(ctx, secgrp)
|
||||
defer lockman.ReleaseObject(ctx, secgrp)
|
||||
|
||||
if secgrp.IsDirty {
|
||||
if _, err := db.Update(secgrp, func() error {
|
||||
secgrp.IsDirty = false
|
||||
return nil
|
||||
}); err != nil {
|
||||
log.Errorf("Update Security Group error: %s", err.Error())
|
||||
}
|
||||
needSync = true
|
||||
if secgrp.IsDirty {
|
||||
if _, err := db.Update(secgrp, func() error {
|
||||
secgrp.IsDirty = false
|
||||
return nil
|
||||
}); err != nil {
|
||||
log.Errorf("Update Security Group error: %s", err.Error())
|
||||
}
|
||||
}()
|
||||
needSync = true
|
||||
}
|
||||
}()
|
||||
|
||||
if needSync {
|
||||
for _, guest := range secgrp.GetGuests() {
|
||||
guest.StartSyncTask(ctx, userCred, true, "")
|
||||
}
|
||||
if needSync {
|
||||
guests, err := secgrp.GetKvmGuests()
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "GetKvmGuests")
|
||||
}
|
||||
for _, guest := range guests {
|
||||
guest.StartSyncTask(ctx, userCred, true, "")
|
||||
}
|
||||
}
|
||||
return secgrp.StartSecurityGroupSyncRulesTask(ctx, userCred, "")
|
||||
}
|
||||
|
||||
func (self *SSecurityGroup) StartSecurityGroupSyncRulesTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
|
||||
params := jsonutils.NewDict()
|
||||
task, err := taskman.TaskManager.NewTask(ctx, "SecurityGroupSyncRulesTask", self, userCred, params, parentTaskId, "", nil)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "NewTask")
|
||||
}
|
||||
self.SetStatus(userCred, api.SECGROUP_STATUS_SYNC_RULES, "")
|
||||
task.ScheduleRun(nil)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SSecurityGroup) DoSync(ctx context.Context, userCred mcclient.TokenCredential) {
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package tasks
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"yunion.io/x/onecloud/pkg/compute/models"
|
||||
"yunion.io/x/onecloud/pkg/util/logclient"
|
||||
)
|
||||
|
||||
type SecurityGroupSyncRulesTask struct {
|
||||
taskman.STask
|
||||
}
|
||||
|
||||
func init() {
|
||||
taskman.RegisterTask(SecurityGroupSyncRulesTask{})
|
||||
}
|
||||
|
||||
func (self *SecurityGroupSyncRulesTask) taskFailed(ctx context.Context, secgroup *models.SSecurityGroup, err error) {
|
||||
secgroup.SetStatus(self.UserCred, api.SECGROUP_STATUS_READY, "")
|
||||
logclient.AddActionLogWithContext(ctx, secgroup, logclient.ACT_SYNC_CONF, err, self.UserCred, false)
|
||||
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
|
||||
}
|
||||
|
||||
func (self *SecurityGroupSyncRulesTask) taskComplete(ctx context.Context, secgroup *models.SSecurityGroup) {
|
||||
secgroup.SetStatus(self.UserCred, api.SECGROUP_STATUS_READY, "")
|
||||
self.SetStageComplete(ctx, nil)
|
||||
}
|
||||
|
||||
func (self *SecurityGroupSyncRulesTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
|
||||
secgroup := obj.(*models.SSecurityGroup)
|
||||
caches, err := secgroup.GetSecurityGroupCaches()
|
||||
if err != nil {
|
||||
self.taskFailed(ctx, secgroup, errors.Wrapf(err, "GetSecurityGroupCaches"))
|
||||
return
|
||||
}
|
||||
|
||||
for i := range caches {
|
||||
err := caches[i].SyncRules()
|
||||
if err != nil {
|
||||
logclient.AddActionLogWithContext(ctx, secgroup, logclient.ACT_SYNC_CONF, errors.Wrapf(err, "SyncRules"), self.UserCred, false)
|
||||
}
|
||||
}
|
||||
self.taskComplete(ctx, secgroup)
|
||||
}
|
||||
Reference in New Issue
Block a user