fix: 默认不自动合并安全组

This commit is contained in:
Qu Xuan
2020-09-11 14:19:05 +08:00
parent 8bc444907b
commit 8e39b7ccb4
10 changed files with 361 additions and 313 deletions
+14 -185
View File
@@ -15,194 +15,23 @@
package compute
import (
"fmt"
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/cmd/climc/shell"
"yunion.io/x/onecloud/pkg/mcclient/modules"
"yunion.io/x/onecloud/pkg/mcclient/options"
)
func init() {
type SecGroupsListOptions struct {
Equals string `help:"Secgroup ID or Name, filter secgroups whose rules equals the specified one"`
Server string `help:"Filter secgroups bound to specified server"`
options.BaseListOptions
Ip string `help:"Filter secgroup by ip"`
Ports string `help:"Filter secgroup by ports"`
Direction string `help:"Filter secgroup by ports" choices:"all|in|out"`
}
R(&SecGroupsListOptions{}, "secgroup-list", "List all security group", func(s *mcclient.ClientSession, args *SecGroupsListOptions) error {
params, err := options.ListStructToParams(args)
if err != nil {
return err
}
result, err := modules.SecGroups.List(s, params)
if err != nil {
return err
}
printList(result, modules.SecGroups.GetColumns(s))
return nil
})
type SecGroupsCreateOptions struct {
NAME string `help:"Name of security group to create"`
RULES []string `help:"security rule to create"`
Desc string `help:"Description"`
}
R(&SecGroupsCreateOptions{}, "secgroup-create", "Create a security group", func(s *mcclient.ClientSession, args *SecGroupsCreateOptions) error {
params := jsonutils.NewDict()
params.Add(jsonutils.NewString(args.NAME), "name")
if len(args.Desc) > 0 {
params.Add(jsonutils.NewString(args.Desc), "description")
}
for i, a := range args.RULES {
params.Add(jsonutils.NewString(a), fmt.Sprintf("rule.%d", i))
}
secgroups, err := modules.SecGroups.Create(s, params)
if err != nil {
return err
}
printObject(secgroups)
return nil
})
type SecGroupsUnionOptions struct {
ID string `help:"ID or Name of security group destination"`
SECGROUPS []string `help:"source IDs or Names of secgroup"`
}
R(&SecGroupsUnionOptions{}, "secgroup-union", "Union secgroups to one secgroup", func(s *mcclient.ClientSession, args *SecGroupsUnionOptions) error {
params := jsonutils.NewDict()
secgroups := jsonutils.NewArray()
for i := 0; i < len(args.SECGROUPS); i++ {
secgroups.Add(jsonutils.NewString(args.SECGROUPS[i]))
}
params.Add(secgroups, "secgroups")
secgroup, err := modules.SecGroups.PerformAction(s, args.ID, "union", params)
if err != nil {
return err
}
printObject(secgroup)
return nil
})
type SecGroupsDetailOptions struct {
ID string `help:"ID or Name of security group"`
}
R(&SecGroupsDetailOptions{}, "secgroup-show", "Show details of a security group", func(s *mcclient.ClientSession, args *SecGroupsDetailOptions) error {
result, err := modules.SecGroups.Get(s, args.ID, nil)
if err != nil {
return err
}
printObject(result)
return nil
})
R(&SecGroupsDetailOptions{}, "secgroup-delete", "Delete a security group", func(s *mcclient.ClientSession, args *SecGroupsDetailOptions) error {
secgroups, err := modules.SecGroups.Delete(s, args.ID, nil)
if err != nil {
return err
}
printObject(secgroups)
return nil
})
R(&SecGroupsDetailOptions{}, "secgroup-public", "Make a security group publicly available", func(s *mcclient.ClientSession, args *SecGroupsDetailOptions) error {
result, err := modules.SecGroups.PerformAction(s, args.ID, "public", nil)
if err != nil {
return err
}
printObject(result)
return nil
})
R(&SecGroupsDetailOptions{}, "secgroup-private", "Make a security group private", func(s *mcclient.ClientSession, args *SecGroupsDetailOptions) error {
result, err := modules.SecGroups.PerformAction(s, args.ID, "private", nil)
if err != nil {
return err
}
printObject(result)
return nil
})
type SecGroupsUpdateOptions struct {
ID string `help:"ID of security group"`
Name string `help:"Name of security group to update"`
Desc string `help:"Description of security groups"`
}
R(&SecGroupsUpdateOptions{}, "secgroup-update", "Update details of a security group", func(s *mcclient.ClientSession, args *SecGroupsUpdateOptions) error {
params := jsonutils.NewDict()
if len(args.Name) > 0 {
params.Add(jsonutils.NewString(args.Name), "name")
}
if len(args.Desc) > 0 {
params.Add(jsonutils.NewString(args.Desc), "description")
}
secgroups, err := modules.SecGroups.Update(s, args.ID, params)
if err != nil {
return err
}
printObject(secgroups)
return nil
})
type SecGroupsAddRuleOptions struct {
ID string `help:"ID or Name of security group"`
DIRECTION string `help:"Direction of rule" choices:"in|out"`
PROTOCOL string `help:"Protocol of rule" choices:"any|tcp|udp|icmp"`
ACTION string `help:"Actin of rule" choices:"allow|deny"`
PRIORITY int `help:"Priority for rule, range 1 ~ 100"`
Cidr string `help:"IP or CIRD for rule"`
Description string `help:"Desciption for rule"`
Ports string `help:"Port for rule"`
}
R(&SecGroupsAddRuleOptions{}, "secgroup-add-rule", "Add rule for a security group", func(s *mcclient.ClientSession, args *SecGroupsAddRuleOptions) error {
params, err := options.StructToParams(args)
secgroups, err := modules.SecGroups.PerformAction(s, args.ID, "add-rule", params)
if err != nil {
return err
}
printObject(secgroups)
return nil
})
type SecurityGroupCacheSecurityGroup struct {
ID string `help:"ID or Name of security group"`
VPC string `help:"ID or Name of vpc"`
Classic *bool `help:"Is classic vpc"`
}
R(&SecurityGroupCacheSecurityGroup{}, "secgroup-cache-secgroup", "Cache security group for special vpc", func(s *mcclient.ClientSession, args *SecurityGroupCacheSecurityGroup) error {
params, err := options.StructToParams(args)
secgroups, err := modules.SecGroups.PerformAction(s, args.ID, "cache-secgroup", params)
if err != nil {
return err
}
printObject(secgroups)
return nil
})
type SecurityGroupUncacheSecurityGroup struct {
ID string `help:"ID or Name of security group"`
CACHE string `help:"ID of secgroup cache"`
}
R(&SecurityGroupUncacheSecurityGroup{}, "secgroup-uncache-secgroup", "Unache special secgroup cache", func(s *mcclient.ClientSession, args *SecurityGroupUncacheSecurityGroup) error {
params := jsonutils.NewDict()
params.Add(jsonutils.NewString(args.CACHE), "secgroupcache")
secgroups, err := modules.SecGroups.PerformAction(s, args.ID, "uncache-secgroup", params)
if err != nil {
return err
}
printObject(secgroups)
return nil
})
cmd := shell.NewResourceCmd(&modules.SecGroups)
cmd.List(&options.SecgroupListOptions{})
cmd.Create(&options.SecgroupCreateOptions{})
cmd.Show(&options.SecgroupIdOptions{})
cmd.Update(&options.BaseUpdateOptions{})
cmd.Delete(&options.SecgroupIdOptions{})
cmd.Perform("merge", &options.SecgroupMergeOptions{})
cmd.Perform("public", &options.SecgroupIdOptions{})
cmd.Perform("private", &options.SecgroupIdOptions{})
cmd.Perform("add-rule", &options.SecgroupsAddRuleOptions{})
cmd.Perform("cache-secgroup", &options.SecurityGroupCacheOptions{})
cmd.Perform("uncache-secgroup", &options.SecurityGroupUncacheSecurityGroup{})
cmd.Perform("purge", &options.SecgroupIdOptions{})
}
+3
View File
@@ -257,3 +257,6 @@ type SecgroupMergeInput struct {
// Deprecated
Secgroups []string `json:"secgroup" yunion-deprecated-by:"secgroup_ids"`
}
type SecurityGroupPurgeInput struct {
}
+57 -14
View File
@@ -355,6 +355,39 @@ func (self *SSecurityGroupCache) GetSecgroup() (*SSecurityGroup, error) {
return model.(*SSecurityGroup), nil
}
func (self *SSecurityGroupCache) syncWithCloudSecurityGroup(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, ext cloudprovider.ICloudSecurityGroup) error {
_, err := db.Update(self, func() error {
self.Status = api.SECGROUP_CACHE_STATUS_READY
self.Name = ext.GetName()
self.Description = ext.GetDescription()
self.ExternalProjectId = ext.GetProjectId()
return nil
})
if err != nil {
return errors.Wrapf(err, "db.Update")
}
secgroup, err := self.GetSecgroup()
if err != nil {
return errors.Wrapf(err, "GetSecurity")
}
cacheCount, err := secgroup.GetSecgroupCacheCount()
if err != nil {
return errors.Wrapf(err, "GetSecgroupCacheCount")
}
if cacheCount > 1 {
return nil
}
info, err := SecurityGroupManager.getRuleInfo(provider, ext)
if err != nil {
return errors.Wrapf(err, "getRuleInfo")
}
err = secgroup.SyncSecurityGroupRules(ctx, userCred, info)
if err != nil {
return errors.Wrapf(err, "SyncSecurityGroupRules")
}
return nil
}
func (manager *SSecurityGroupCacheManager) SyncSecurityGroupCaches(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, secgroups []cloudprovider.ICloudSecurityGroup, vpc *SVpc) ([]SSecurityGroup, []cloudprovider.ICloudSecurityGroup, compare.SyncResult) {
lockman.LockClass(ctx, manager, db.GetLockClassKey(manager, userCred))
defer lockman.ReleaseClass(ctx, manager, db.GetLockClassKey(manager, userCred))
@@ -415,25 +448,18 @@ func (manager *SSecurityGroupCacheManager) SyncSecurityGroupCaches(ctx context.C
}
for i := 0; i < len(commondb); i++ {
_, err = db.Update(&commondb[i], func() error {
commondb[i].Status = api.SECGROUP_CACHE_STATUS_READY
commondb[i].Name = commonext[i].GetName()
commondb[i].Description = commonext[i].GetDescription()
commondb[i].ExternalProjectId = commonext[i].GetProjectId()
return nil
})
err = commondb[i].syncWithCloudSecurityGroup(ctx, userCred, provider, commonext[i])
if err != nil {
syncResult.UpdateError(err)
} else {
syncResult.Update()
syncResult.UpdateError(errors.Wrapf(err, "syncWithCloudSecurityGroup"))
continue
}
syncResult.Update()
}
//相同的不能同步, 原因: 多个平台的安全组可能共用一个本地安全组,下面仅仅是新加的安全组
for i := 0; i < len(added); i++ {
secgroup, err := SecurityGroupManager.newFromCloudSecgroup(ctx, userCred, provider, added[i])
if err != nil {
syncResult.AddError(err)
syncResult.AddError(errors.Wrapf(err, "newFromCloudSecgroup"))
continue
}
if secgroup.ProjectId != provider.ProjectId {
@@ -450,7 +476,7 @@ func (manager *SSecurityGroupCacheManager) SyncSecurityGroupCaches(ctx context.C
}
cache, err := manager.NewCache(ctx, userCred, secgroup.Id, vpcId, vpc.CloudregionId, provider.Id, added[i].GetProjectId())
if err != nil {
syncResult.AddError(fmt.Errorf("failed to create secgroup cache for secgroup %s(%s) provider: %s: %s", secgroup.Name, secgroup.Name, provider.Name, err))
syncResult.AddError(errors.Wrapf(err, "NewCache for secgroup %s provider %s", secgroup.Name, provider.Name))
continue
}
_, err = db.Update(cache, func() error {
@@ -461,7 +487,7 @@ func (manager *SSecurityGroupCacheManager) SyncSecurityGroupCaches(ctx context.C
return nil
})
if err != nil {
syncResult.AddError(err)
syncResult.AddError(errors.Wrapf(err, "db.Update"))
continue
}
localSecgroups = append(localSecgroups, *secgroup)
@@ -560,3 +586,20 @@ func (manager *SSecurityGroupCacheManager) ListItemExportKeys(ctx context.Contex
return q, nil
}
func (self *SSecurityGroupCache) GetISecurityGroup() (cloudprovider.ICloudSecurityGroup, error) {
if len(self.ExternalId) == 0 {
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "empty externalId")
}
manager := self.GetCloudprovider()
if manager == nil {
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "failed to found manager")
}
iRegion, err := self.GetIRegion()
if err != nil {
return nil, errors.Wrapf(err, "GetIRegion")
}
return iRegion.GetISecurityGroupById(self.ExternalId)
}
+10 -14
View File
@@ -22,7 +22,6 @@ import (
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/compare"
"yunion.io/x/pkg/util/regutils"
"yunion.io/x/pkg/util/secrules"
"yunion.io/x/pkg/util/stringutils"
@@ -463,8 +462,7 @@ func (manager *SSecurityGroupRuleManager) getRulesBySecurityGroup(secgroup *SSec
return rules, nil
}
func (manager *SSecurityGroupRuleManager) SyncRules(ctx context.Context, userCred mcclient.TokenCredential, secgroup *SSecurityGroup, rules cloudprovider.SecurityRuleSet) compare.SyncResult {
syncResult := compare.SyncResult{}
func (self *SSecurityGroup) SyncRules(ctx context.Context, userCred mcclient.TokenCredential, rules cloudprovider.SecurityRuleSet) error {
priority, prePriority := 10, 0
for i := 0; i < len(rules); i++ {
// 这里避免了Rule规则优先级在 1-100之外的问题,ext.GetRules()不需要进行优先级转换
@@ -473,19 +471,17 @@ func (manager *SSecurityGroupRuleManager) SyncRules(ctx context.Context, userCre
}
prePriority = rules[i].Priority
rules[i].Priority = priority
_, err := manager.newFromCloudSecurityGroup(ctx, userCred, rules[i], secgroup)
_, err := self.newFromCloudSecurityGroupRule(ctx, userCred, rules[i])
if err != nil {
syncResult.AddError(err)
continue
return errors.Wrapf(err, "newFromCloudSecurityGroupRule")
}
syncResult.Add()
}
return syncResult
return nil
}
func (manager *SSecurityGroupRuleManager) newFromCloudSecurityGroup(ctx context.Context, userCred mcclient.TokenCredential, rule cloudprovider.SecurityRule, secgroup *SSecurityGroup) (*SSecurityGroupRule, error) {
lockman.LockClass(ctx, manager, db.GetLockClassKey(manager, userCred))
defer lockman.ReleaseClass(ctx, manager, db.GetLockClassKey(manager, userCred))
func (self *SSecurityGroup) newFromCloudSecurityGroupRule(ctx context.Context, userCred mcclient.TokenCredential, rule cloudprovider.SecurityRule) (*SSecurityGroupRule, error) {
lockman.LockObject(ctx, self)
defer lockman.ReleaseObject(ctx, self)
protocol := rule.Protocol
if len(protocol) == 0 {
@@ -506,11 +502,11 @@ func (manager *SSecurityGroupRuleManager) newFromCloudSecurityGroup(ctx context.
Action: string(rule.Action),
Description: rule.Description,
}
secrule.SecgroupId = secgroup.Id
secrule.SecgroupId = self.Id
err := manager.TableSpec().Insert(ctx, secrule)
err := SecurityGroupRuleManager.TableSpec().Insert(ctx, secrule)
if err != nil {
return nil, err
return nil, errors.Wrapf(err, "SecurityGroupRuleManager.Insert")
}
return secrule, nil
}
+106 -38
View File
@@ -37,6 +37,7 @@ import (
"yunion.io/x/onecloud/pkg/cloudcommon/policy"
"yunion.io/x/onecloud/pkg/cloudcommon/validators"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/compute/options"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/auth"
@@ -539,6 +540,14 @@ func totalSecurityGroupCount(scope rbacutils.TRbacScope, ownerId mcclient.IIdent
return q.CountWithError()
}
func (self *SSecurityGroup) AllowPerformPurge(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return self.IsOwner(userCred) || db.IsAdminAllowPerform(userCred, self, "purge")
}
func (self *SSecurityGroup) PerformPurge(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
return nil, self.StartDeleteSecurityGroupTask(ctx, userCred, true, "")
}
func (self *SSecurityGroup) AllowPerformUncacheSecgroup(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return self.IsOwner(userCred) || db.IsAdminAllowPerform(userCred, self, "uncache-secgroup")
}
@@ -814,7 +823,57 @@ func (manager *SSecurityGroupManager) getSecurityGroups() ([]SSecurityGroup, err
}
}
func (manager *SSecurityGroupManager) newFromCloudSecgroup(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, extSec cloudprovider.ICloudSecurityGroup) (*SSecurityGroup, error) {
func (self *SSecurityGroup) cleanRules(ctx context.Context, userCred mcclient.TokenCredential) error {
rules := []SSecurityGroupRule{}
q := SecurityGroupRuleManager.Query().Equals("secgroup_id", self.Id)
err := db.FetchModelObjects(SecurityGroupRuleManager, q, &rules)
if err != nil {
return errors.Wrapf(err, "db.FetchModelObjects")
}
for i := range rules {
err = rules[i].Delete(ctx, userCred)
if err != nil {
return errors.Wrapf(err, "DeleteRule(%s)", rules[i].Id)
}
}
return nil
}
func (self *SSecurityGroup) SyncSecurityGroupRules(ctx context.Context, userCred mcclient.TokenCredential, info *sRuleInfo) error {
inRules := cloudprovider.AddDefaultRule(info.inRules, info.defaultInRule, "in:deny any", info.order, info.minPriority, info.maxPriority, info.onlyAllowRules)
cloudprovider.SortSecurityRule(inRules, info.order, info.onlyAllowRules)
outRules := cloudprovider.AddDefaultRule(info.outRules, info.defaultOutRule, "out:allow any", info.order, info.minPriority, info.maxPriority, info.onlyAllowRules)
cloudprovider.SortSecurityRule(outRules, info.order, info.onlyAllowRules)
err := self.cleanRules(ctx, userCred)
if err != nil {
return errors.Wrapf(err, "cleanRules")
}
err = self.SyncRules(ctx, userCred, inRules)
if err != nil {
return errors.Wrapf(err, "SyncInRules")
}
err = self.SyncRules(ctx, userCred, outRules)
if err != nil {
return errors.Wrapf(err, "SyncOutRules")
}
return nil
}
type sRuleInfo struct {
rules []cloudprovider.SecurityRule
inRules []cloudprovider.SecurityRule
outRules []cloudprovider.SecurityRule
defaultInRule cloudprovider.SecurityRule
defaultOutRule cloudprovider.SecurityRule
order cloudprovider.TPriorityOrder
onlyAllowRules bool
maxPriority int
minPriority int
}
func (manager *SSecurityGroupManager) getRuleInfo(provider *SCloudprovider, extSec cloudprovider.ICloudSecurityGroup) (*sRuleInfo, error) {
regionDriver, err := provider.GetRegionDriver()
if err != nil {
return nil, errors.Wrap(err, "provider.GetRegionDriver")
@@ -825,36 +884,48 @@ func (manager *SSecurityGroupManager) newFromCloudSecgroup(ctx context.Context,
return nil, errors.Wrap(err, "extSec.GetRules")
}
inRules := []cloudprovider.SecurityRule{}
outRules := []cloudprovider.SecurityRule{}
info := &sRuleInfo{
rules: rules,
inRules: []cloudprovider.SecurityRule{},
outRules: []cloudprovider.SecurityRule{},
defaultInRule: regionDriver.GetDefaultSecurityGroupInRule(),
defaultOutRule: regionDriver.GetDefaultSecurityGroupOutRule(),
order: regionDriver.GetSecurityGroupRuleOrder(),
onlyAllowRules: regionDriver.IsOnlySupportAllowRules(),
maxPriority: regionDriver.GetSecurityGroupRuleMaxPriority(),
minPriority: regionDriver.GetSecurityGroupRuleMinPriority(),
}
for i := range rules {
if rules[i].Direction == secrules.DIR_IN {
inRules = append(inRules, rules[i])
info.inRules = append(info.inRules, rules[i])
} else {
outRules = append(outRules, rules[i])
info.outRules = append(info.outRules, rules[i])
}
}
return info, nil
}
maxPriority := regionDriver.GetSecurityGroupRuleMaxPriority()
minPriority := regionDriver.GetSecurityGroupRuleMinPriority()
defaultInRule := regionDriver.GetDefaultSecurityGroupInRule()
defaultOutRule := regionDriver.GetDefaultSecurityGroupOutRule()
order := regionDriver.GetSecurityGroupRuleOrder()
onlyAllowRules := regionDriver.IsOnlySupportAllowRules()
// 查询与provider在同域的安全组,比对寻找一个与云上安全组规则相同的安全组
secgroups := []SSecurityGroup{}
q := manager.Query().Equals("domain_id", provider.DomainId)
err = db.FetchModelObjects(manager, q, &secgroups)
func (manager *SSecurityGroupManager) newFromCloudSecgroup(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, extSec cloudprovider.ICloudSecurityGroup) (*SSecurityGroup, error) {
info, err := manager.getRuleInfo(provider, extSec)
if err != nil {
return nil, errors.Wrap(err, "db.FetchModelObjects")
return nil, errors.Wrapf(err, "getRuleInfo")
}
for i := range secgroups {
localRules := secrules.SecurityRuleSet(secgroups[i].GetSecRules(""))
_, inAdds, outAdds, inDels, outDels := cloudprovider.CompareRules(minPriority, maxPriority, order, localRules, rules, defaultInRule, defaultOutRule, onlyAllowRules, false)
if len(inAdds) == 0 && len(outAdds) == 0 && len(inDels) == 0 && len(outDels) == 0 {
return &secgroups[i], nil
if options.Options.EnableAutoMergeSecurityGroup {
// 查询与provider在同域的安全组,比对寻找一个与云上安全组规则相同的安全组
secgroups := []SSecurityGroup{}
q := manager.Query().Equals("domain_id", provider.DomainId)
err = db.FetchModelObjects(manager, q, &secgroups)
if err != nil {
return nil, errors.Wrap(err, "db.FetchModelObjects")
}
for i := range secgroups {
localRules := secrules.SecurityRuleSet(secgroups[i].GetSecRules(""))
_, inAdds, outAdds, inDels, outDels := cloudprovider.CompareRules(info.minPriority, info.maxPriority, info.order, localRules, info.rules, info.defaultInRule, info.defaultOutRule, info.onlyAllowRules, false)
if len(inAdds) == 0 && len(outAdds) == 0 && len(inDels) == 0 && len(outDels) == 0 {
return &secgroups[i], nil
}
}
}
@@ -863,31 +934,26 @@ func (manager *SSecurityGroupManager) newFromCloudSecgroup(ctx context.Context,
secgroup := SSecurityGroup{}
secgroup.SetModelManager(manager, &secgroup)
newName, err := db.GenerateName(manager, userCred, extSec.GetName())
secgroup.Name, err = db.GenerateName(manager, userCred, extSec.GetName())
if err != nil {
return nil, err
}
secgroup.Name = newName
secgroup.Description = extSec.GetDescription()
secgroup.ProjectId = provider.ProjectId
secgroup.DomainId = provider.DomainId
if err := manager.TableSpec().Insert(ctx, &secgroup); err != nil {
return nil, err
err = manager.TableSpec().Insert(ctx, &secgroup)
if err != nil {
return nil, errors.Wrapf(err, "Insert")
}
//这里必须先同步下规则,不然下次对比此安全组规则为空
inRules = cloudprovider.AddDefaultRule(inRules, defaultInRule, "in:deny any", order, minPriority, maxPriority, onlyAllowRules)
cloudprovider.SortSecurityRule(inRules, order, onlyAllowRules)
outRules = cloudprovider.AddDefaultRule(outRules, defaultOutRule, "out:allow any", order, minPriority, maxPriority, onlyAllowRules)
cloudprovider.SortSecurityRule(outRules, order, onlyAllowRules)
SecurityGroupRuleManager.SyncRules(ctx, userCred, &secgroup, inRules)
SecurityGroupRuleManager.SyncRules(ctx, userCred, &secgroup, outRules)
err = secgroup.SyncSecurityGroupRules(ctx, userCred, info)
if err != nil {
return nil, errors.Wrapf(err, "SyncSecurityGroupRules")
}
db.OpsLog.LogEvent(&secgroup, db.ACT_CREATE, secgroup.GetShortDesc(ctx), userCred)
return &secgroup, nil
}
@@ -1029,10 +1095,12 @@ func (self *SSecurityGroup) GetSecurityGroupCaches() ([]SSecurityGroupCache, err
}
func (self *SSecurityGroup) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
return self.StartDeleteSecurityGroupTask(ctx, userCred, jsonutils.NewDict(), "")
return self.StartDeleteSecurityGroupTask(ctx, userCred, false, "")
}
func (self *SSecurityGroup) StartDeleteSecurityGroupTask(ctx context.Context, userCred mcclient.TokenCredential, params *jsonutils.JSONDict, parentTaskId string) error {
func (self *SSecurityGroup) StartDeleteSecurityGroupTask(ctx context.Context, userCred mcclient.TokenCredential, isPurge bool, parentTaskId string) error {
params := jsonutils.NewDict()
params.Add(jsonutils.NewBool(isPurge), "purge")
self.SetStatus(userCred, api.SECGROUP_STATUS_DELETING, "")
task, err := taskman.TaskManager.NewTask(ctx, "SecurityGroupDeleteTask", self, userCred, params, parentTaskId, "", nil)
if err != nil {
+2
View File
@@ -145,6 +145,8 @@ type ComputeOptions struct {
SASControllerOptions
common_options.CommonOptions
common_options.DBOptions
EnableAutoMergeSecurityGroup bool `help:"Enable auto merge secgroup when sync security group from cloud, default False" default:"false"`
}
type SCapabilityOptions struct {
@@ -16,7 +16,6 @@ package tasks
import (
"context"
"database/sql"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
@@ -26,7 +25,6 @@ import (
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type SecurityGroupCacheDeleteTask struct {
@@ -37,13 +35,9 @@ func init() {
taskman.RegisterTask(SecurityGroupCacheDeleteTask{})
}
func (self *SecurityGroupCacheDeleteTask) taskFailed(ctx context.Context, cache *models.SSecurityGroupCache, err jsonutils.JSONObject) {
cache.SetStatus(self.UserCred, api.SECGROUP_CACHE_STATUS_DELETE_FAILED, err.String())
secgroup, _ := cache.GetSecgroup()
if secgroup != nil {
logclient.AddActionLogWithStartable(self, secgroup, logclient.ACT_DELETE, err, self.UserCred, false)
}
self.SetStageFailed(ctx, err)
func (self *SecurityGroupCacheDeleteTask) taskFailed(ctx context.Context, cache *models.SSecurityGroupCache, err error) {
cache.SetStatus(self.UserCred, api.SECGROUP_CACHE_STATUS_DELETE_FAILED, err.Error())
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *SecurityGroupCacheDeleteTask) taskComplete(ctx context.Context, cache *models.SSecurityGroupCache) {
@@ -54,38 +48,18 @@ func (self *SecurityGroupCacheDeleteTask) taskComplete(ctx context.Context, cach
func (self *SecurityGroupCacheDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
cache := obj.(*models.SSecurityGroupCache)
if len(cache.ExternalId) == 0 {
self.taskComplete(ctx, cache)
return
}
_, err := models.CloudproviderManager.FetchById(cache.ManagerId)
if err == sql.ErrNoRows {
self.taskComplete(ctx, cache)
return
}
iRegion, err := cache.GetIRegion()
iSecgroup, err := cache.GetISecurityGroup()
if err != nil {
if errors.Cause(err) == cloudprovider.ErrNotFound {
self.taskComplete(ctx, cache)
return
}
self.taskFailed(ctx, cache, jsonutils.NewString(errors.Wrap(err, "cache.GetIRegion").Error()))
return
}
iSecgroup, err := iRegion.GetISecurityGroupById(cache.ExternalId)
if err != nil {
if err == cloudprovider.ErrNotFound {
self.taskComplete(ctx, cache)
return
}
self.taskFailed(ctx, cache, jsonutils.NewString(errors.Wrap(err, "iRegion.GetIStoragecacheById").Error()))
self.taskFailed(ctx, cache, errors.Wrapf(err, "GetISecurityGroup"))
return
}
err = iSecgroup.Delete()
if err != nil {
self.taskFailed(ctx, cache, jsonutils.NewString(err.Error()))
self.taskFailed(ctx, cache, errors.Wrapf(err, "iSecgroup.Delete"))
return
}
self.taskComplete(ctx, cache)
+33 -30
View File
@@ -18,11 +18,14 @@ 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/cloudprovider"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type SecurityGroupDeleteTask struct {
@@ -33,42 +36,42 @@ func init() {
taskman.RegisterTask(SecurityGroupDeleteTask{})
}
func (self *SecurityGroupDeleteTask) getErrorCount() int64 {
count, _ := self.GetParams().Int("faild_count")
return count
}
func (self *SecurityGroupDeleteTask) addErrorCount() {
count := self.getErrorCount()
count += 1
self.GetParams().Set("failed_count", jsonutils.NewInt(count))
func (self *SecurityGroupDeleteTask) taskFailed(ctx context.Context, secgroup *models.SSecurityGroup, err error) {
secgroup.SetStatus(self.UserCred, api.SECGROUP_STATUS_READY, "")
logclient.AddActionLogWithContext(ctx, secgroup, logclient.ACT_DELOCATE, err, self.UserCred, false)
self.SetStageFailed(ctx, jsonutils.Marshal(err))
}
func (self *SecurityGroupDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
self.SetStage("OnSecurityGroupUncacheComplete", nil)
self.OnSecurityGroupUncacheComplete(ctx, obj, data)
}
func (self *SecurityGroupDeleteTask) OnSecurityGroupUncacheComplete(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
secgroup := obj.(*models.SSecurityGroup)
secgroupCaches, err := secgroup.GetSecurityGroupCaches()
caches, err := secgroup.GetSecurityGroupCaches()
if err != nil {
secgroup.SetStatus(self.UserCred, api.SECGROUP_STATUS_READY, "")
self.SetStageFailed(ctx, jsonutils.Marshal(err))
self.taskFailed(ctx, secgroup, errors.Wrapf(err, "GetSecurityGroupCaches"))
return
}
errCount := self.getErrorCount()
if len(secgroupCaches) == int(errCount) {
if errCount == 0 {
secgroup.RealDelete(ctx, self.UserCred)
}
secgroup.SetStatus(self.UserCred, api.SECGROUP_STATUS_READY, "")
self.SetStageComplete(ctx, nil)
return
}
secgroupCaches[errCount].StartSecurityGroupCacheDeleteTask(ctx, self.UserCred, self.GetTaskId())
}
func (self *SecurityGroupDeleteTask) OnSecurityGroupUncacheCompleteFailed(ctx context.Context, obj db.IStandaloneModel, err jsonutils.JSONObject) {
self.addErrorCount()
isPurge := jsonutils.QueryBoolean(self.Params, "purge", false)
for i := range caches {
if !isPurge {
iSecgroup, err := caches[i].GetISecurityGroup()
if err != nil {
if errors.Cause(err) == cloudprovider.ErrNotFound {
caches[i].RealDelete(ctx, self.GetUserCred())
continue
}
self.taskFailed(ctx, secgroup, errors.Wrapf(err, "GetISecurityGroup for cache %s(%s)", caches[i].Name, caches[i].Id))
return
}
err = iSecgroup.Delete()
if err != nil {
self.taskFailed(ctx, secgroup, errors.Wrapf(err, "iSecgroup.Delete"))
return
}
}
caches[i].RealDelete(ctx, self.GetUserCred())
}
secgroup.RealDelete(ctx, self.GetUserCred())
self.SetStageComplete(ctx, nil)
}
+11
View File
@@ -337,6 +337,17 @@ func (opts *BaseUpdateOptions) GetId() string {
return opts.ID
}
func (opts *BaseUpdateOptions) Params() (jsonutils.JSONObject, error) {
params := jsonutils.NewDict()
if len(opts.Name) > 0 {
params.Add(jsonutils.NewString(opts.Name), "name")
}
if len(opts.Desc) > 0 {
params.Add(jsonutils.NewString(opts.Desc), "description")
}
return params, nil
}
type BasePublicOptions struct {
ID string `help:"ID or name of resource" json:"-"`
Scope string `help:"sharing scope" choices:"system|domain"`
+119
View File
@@ -0,0 +1,119 @@
// 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 options
import (
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/secrules"
)
type SecgroupListOptions struct {
BaseListOptions
Equals string `help:"Secgroup ID or Name, filter secgroups whose rules equals the specified one"`
Server string `help:"Filter secgroups bound to specified server"`
Ip string `help:"Filter secgroup by ip"`
Ports string `help:"Filter secgroup by ports"`
Direction string `help:"Filter secgroup by ports" choices:"all|in|out"`
}
func (opts *SecgroupListOptions) Params() (jsonutils.JSONObject, error) {
return ListStructToParams(opts)
}
type SecgroupCreateOptions struct {
BaseCreateOptions
Rules []string `help:"security rule to create"`
}
func (opts *SecgroupCreateOptions) Params() (jsonutils.JSONObject, error) {
params := jsonutils.Marshal(opts).(*jsonutils.JSONDict)
params.Remove("rules")
rules := []secrules.SecurityRule{}
for i, ruleStr := range opts.Rules {
rule, err := secrules.ParseSecurityRule(ruleStr)
if err != nil {
return nil, errors.Wrapf(err, "ParseSecurityRule(%s)", ruleStr)
}
rule.Priority = i + 1
rules = append(rules, *rule)
}
if len(rules) > 0 {
params.Add(jsonutils.Marshal(rules), "rules")
}
return params, nil
}
type SecgroupIdOptions struct {
ID string `help:"ID or Name of security group destination"`
}
func (opts *SecgroupIdOptions) GetId() string {
return opts.ID
}
func (opts *SecgroupIdOptions) Params() (jsonutils.JSONObject, error) {
return nil, nil
}
type SecgroupMergeOptions struct {
SecgroupIdOptions
SECGROUPS []string `help:"source IDs or Names of secgroup"`
}
func (opts *SecgroupMergeOptions) Params() (jsonutils.JSONObject, error) {
return jsonutils.Marshal(map[string][]string{"secgruops": opts.SECGROUPS}), nil
}
type SecgroupsAddRuleOptions struct {
SecgroupIdOptions
DIRECTION string `help:"Direction of rule" choices:"in|out"`
PROTOCOL string `help:"Protocol of rule" choices:"any|tcp|udp|icmp"`
ACTION string `help:"Actin of rule" choices:"allow|deny"`
PRIORITY int `help:"Priority for rule, range 1 ~ 100"`
Cidr string `help:"IP or CIRD for rule"`
Description string `help:"Desciption for rule"`
Ports string `help:"Port for rule"`
}
func (opts *SecgroupsAddRuleOptions) Params() (jsonutils.JSONObject, error) {
params := jsonutils.Marshal(opts).(*jsonutils.JSONDict)
params.Remove("id")
return params, nil
}
type SecurityGroupCacheOptions struct {
SecgroupIdOptions
VPC string `help:"ID or Name of vpc"`
Classic *bool `help:"Is classic vpc"`
}
func (opts *SecurityGroupCacheOptions) Params() (jsonutils.JSONObject, error) {
params := jsonutils.Marshal(opts).(*jsonutils.JSONDict)
params.Remove("id")
return params, nil
}
type SecurityGroupUncacheSecurityGroup struct {
SecgroupIdOptions
CACHE string `help:"ID of secgroup cache"`
}
func (opts *SecurityGroupUncacheSecurityGroup) Params() (jsonutils.JSONObject, error) {
params := jsonutils.Marshal(opts).(*jsonutils.JSONDict)
params.Remove("id")
return params, nil
}