fix(region): secgroup sync

This commit is contained in:
ioito
2023-04-28 13:28:58 +08:00
parent 22fa5923dc
commit f9178f77c5
82 changed files with 1061 additions and 3770 deletions
-1
View File
@@ -36,5 +36,4 @@ func init() {
cmd.Perform("purge", &options.SecgroupIdOptions{})
cmd.Perform("change-owner", &options.SecgroupChangeOwnerOptions{})
cmd.Perform("import-rules", &options.SecgroupImportRulesOptions{})
cmd.Get("references", &options.SecgroupIdOptions{})
}
+2 -4
View File
@@ -84,12 +84,12 @@ require (
k8s.io/client-go v0.19.3
k8s.io/cluster-bootstrap v0.19.3
moul.io/http2curl/v2 v2.3.0
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20230420032540-1c19d25fb1fa
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20230428051550-621cd3dd1771
yunion.io/x/executor v0.0.0-20211018100936-39a2cd966656
yunion.io/x/jsonutils v1.0.1-0.20230417123225-5dcde3e4598b
yunion.io/x/log v1.0.1-0.20230411060016-feb3f46ab361
yunion.io/x/ovsdb v0.0.0-20230306173834-f164f413a900
yunion.io/x/pkg v1.0.1-0.20230420104238-bbd084afbdfe
yunion.io/x/pkg v1.0.1-0.20230427104242-202edd119017
yunion.io/x/s3cli v0.0.0-20190917004522-13ac36d8687e
yunion.io/x/sqlchemy v1.1.2-0.20230422192549-7a9668176f46
yunion.io/x/structarg v0.0.0-20220312084958-9c6c79c7d1c6
@@ -267,5 +267,3 @@ require (
sigs.k8s.io/structured-merge-diff/v4 v4.0.1 // indirect
sigs.k8s.io/yaml v1.2.0 // indirect
)
replace github.com/jaypipes/ghw => github.com/wanyaoqi/ghw v0.10.1
+6 -6
View File
@@ -428,6 +428,8 @@ github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJ
github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28=
github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/ipandtcp/godingtalk v0.0.0-20180410032244-ca3d6ac197fb/go.mod h1:3umLciE1jBnh2LgrL15R2zbEe+HVPRZXnlSjjb/dYiw=
github.com/jaypipes/ghw v0.10.1-0.20230329185050-227643e14380 h1:jyt0G4jRwqNEbe+oeUy21l/0+QopoMXnnz1Xb3W3cUA=
github.com/jaypipes/ghw v0.10.1-0.20230329185050-227643e14380/go.mod h1:jeJGbkRB2lL3/gxYzNYzEDETV1ZJ56OKr+CSeSEym+g=
github.com/jdcloud-api/jdcloud-sdk-go v1.55.0 h1:mzVj8r6fluEwjn8ogqtGfYW2qSIVUaEq0JAsvjCav3A=
github.com/jdcloud-api/jdcloud-sdk-go v1.55.0/go.mod h1:UrKjuULIWLjHFlG6aSPunArE5QX57LftMmStAZJBEX8=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
@@ -718,8 +720,6 @@ github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaU
github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
github.com/vmware/govmomi v0.20.1 h1:7b/SeTUB3tER8ZLGLLLH3xcnB2xeuLULXmfPFqPSRZA=
github.com/vmware/govmomi v0.20.1/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU=
github.com/wanyaoqi/ghw v0.10.1 h1:HAknfzkXb7bukOtXzKkoxrbGwCtgYnnlTev2ZMXsxXY=
github.com/wanyaoqi/ghw v0.10.1/go.mod h1:jeJGbkRB2lL3/gxYzNYzEDETV1ZJ56OKr+CSeSEym+g=
github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
github.com/willf/bitset v1.1.9 h1:GBtFynGY9ZWZmEC9sWuu41/7VBXPFCOAbCbqTflOg9c=
github.com/willf/bitset v1.1.9/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
@@ -1185,8 +1185,8 @@ sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20230420032540-1c19d25fb1fa h1:adb5M4Gjq6eJuCfPd6nmX0jYo9c1k7tMFTD8++RCTqw=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20230420032540-1c19d25fb1fa/go.mod h1:VBAtfyGMDW11x5JmF0vUEmn/PmNpZ8CKBAQCiyz+cDY=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20230428051550-621cd3dd1771 h1:79YnZ8Ce693/8oaRUFASdGeC/ZeJznDhz7bZRr1Sa7A=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20230428051550-621cd3dd1771/go.mod h1:crMeQeaNaZefTXfXbQkoj5SStggqkSNVABHtYBFjM3Y=
yunion.io/x/executor v0.0.0-20211018100936-39a2cd966656 h1:0zlZD5uhZoIHgLVAWCz2aHaYk2ZrNsACCYD7R6EIBII=
yunion.io/x/executor v0.0.0-20211018100936-39a2cd966656/go.mod h1:Uxuou9WQIeJXNpy7t2fPLL0BYLvLiMvGQwY7Qc6aSws=
yunion.io/x/jsonutils v0.0.0-20190625054549-a964e1e8a051/go.mod h1:4N0/RVzsYL3kH3WE/H1BjUQdFiWu50JGCFQuuy+Z634=
@@ -1204,8 +1204,8 @@ yunion.io/x/pkg v0.0.0-20190620104149-945c25821dbf/go.mod h1:t6rEGG2sQ4J7DhFxSZV
yunion.io/x/pkg v0.0.0-20190628082551-f4033ba2ea30/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E=
yunion.io/x/pkg v0.0.0-20200814072949-4f1b541857d6/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E=
yunion.io/x/pkg v1.0.1-0.20220819080140-55b265a8658e/go.mod h1:nYOMflWG1wQC6301rGVglQva9bYbJxHThEJUxRAgMFc=
yunion.io/x/pkg v1.0.1-0.20230420104238-bbd084afbdfe h1:pwjs6kOP3cenRN+Oc2zyJerAhBAn4owaLbzZyLx5/rA=
yunion.io/x/pkg v1.0.1-0.20230420104238-bbd084afbdfe/go.mod h1:ksCJVQ+DwKrJ5QBEoU8pzrDFfDaZVAFH/iJ6yQCYxJk=
yunion.io/x/pkg v1.0.1-0.20230427104242-202edd119017 h1:UbdLKvnWMSWnRt24LKoaBr2vGI2QfgDG9GbugCKjpAQ=
yunion.io/x/pkg v1.0.1-0.20230427104242-202edd119017/go.mod h1:ksCJVQ+DwKrJ5QBEoU8pzrDFfDaZVAFH/iJ6yQCYxJk=
yunion.io/x/s3cli v0.0.0-20190917004522-13ac36d8687e h1:v+EzIadodSwkdZ/7bremd7J8J50Cise/HCylsOJngmo=
yunion.io/x/s3cli v0.0.0-20190917004522-13ac36d8687e/go.mod h1:0iFKpOs1y4lbCxeOmq3Xx/0AcQoewVPwj62eRluioEo=
yunion.io/x/sqlchemy v1.0.1/go.mod h1:FTdwPdGhMgh4E+UFXc9klI1Ok34fMuybTT+jLhOaIjI=
+7 -7
View File
@@ -17,7 +17,6 @@ package compute
import (
"fmt"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/regutils"
"yunion.io/x/pkg/util/secrules"
@@ -82,10 +81,6 @@ type SSecgroupRuleResource struct {
// requried: false
// example: test to create rule
Description string `json:"description"`
// 对端安全组Id, 此参数和cidr参数互斥,并且优先级高于cidr, 同时peer_secgroup_id不能和它所在的安全组ID相同
// required: false
PeerSecgroupId string `json:"peer_secgroup_id"`
}
type SSecgroupRuleCreateInput struct {
@@ -246,6 +241,9 @@ type SecgroupDetails struct {
// admin_secgrp_id为此安全组的云主机数量, , 不包含回收站云主机
AdminGuestCnt int `json:"admin_guest_cnt,allowempty"`
// 所有关联的资源数量
TotalCnt int `json:"total_cnt,allowempty"`
// 安全组缓存数量
CacheCnt int `json:"cache_cnt,allowempty"`
// 规则信息
@@ -254,8 +252,6 @@ type SecgroupDetails struct {
InRules []SecgroupRuleDetails `json:"in_rules"`
// 出方向规则信息
OutRules []SecgroupRuleDetails `json:"out_rules"`
CloudCaches []jsonutils.JSONObject `json:"cloud_caches"`
}
type SecurityGroupResourceInfo struct {
@@ -333,3 +329,7 @@ type SSecurityGroupRef struct {
func (self *SSecurityGroupRef) Sum() {
self.TotalCnt = self.GuestCnt + self.AdminGuestCnt + self.RdsCnt + self.RedisCnt
}
type SecurityGroupCacheInput struct {
VpcId string `json:"vpc_id"`
}
+1
View File
@@ -19,5 +19,6 @@ const (
SECGROUP_CACHE_STATUS_UNKNOWN = "unknown"
SECGROUP_CACHE_STATUS_DELETING = "deleting"
SECGROUP_CACHE_STATUS_CACHING = "caching"
SECGROUP_CACHE_STATUS_CACHE_FAILED = "cache_failed"
SECGROUP_CACHE_STATUS_DELETE_FAILED = "delete_failed"
)
+1 -2
View File
@@ -22,6 +22,5 @@ type SecgroupRuleDetails struct {
SSecurityGroupRule
SecurityGroupResourceInfo
ProjectId string `json:"tenant_id"`
PeerSecgroup string `json:"peer_secgroup"`
ProjectId string `json:"tenant_id"`
}
+9 -10
View File
@@ -2483,16 +2483,15 @@ type SSecurityGroupResourceBase struct {
type SSecurityGroupRule struct {
apis.SResourceBase
SSecurityGroupResourceBase
Id string `json:"id"`
Priority int64 `json:"priority"`
Protocol string `json:"protocol"`
Ports string `json:"ports"`
Direction string `json:"direction"`
CIDR string `json:"cidr"`
Action string `json:"action"`
Description string `json:"description"`
PeerSecgroupId string `json:"peer_secgroup_id"`
IsDirty bool `json:"is_dirty"`
Id string `json:"id"`
Priority int64 `json:"priority"`
Protocol string `json:"protocol"`
Ports string `json:"ports"`
Direction string `json:"direction"`
CIDR string `json:"cidr"`
Action string `json:"action"`
Description string `json:"description"`
IsDirty bool `json:"is_dirty"`
}
// SServerSku is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SServerSku.
+4 -4
View File
@@ -395,7 +395,7 @@ func (self *SManagedVirtualizedGuestDriver) RequestDeployGuestOnHost(ctx context
return errors.Wrap(err, "vpc.GetRegion")
}
vpcId, err := region.GetDriver().GetSecurityGroupVpcId(ctx, task.GetUserCred(), region, host, vpc, false)
vpcId, err := region.GetDriver().GetSecurityGroupVpcId(ctx, task.GetUserCred(), region, host, vpc)
if err != nil {
return errors.Wrap(err, "GetSecurityGroupVpcId")
}
@@ -405,7 +405,7 @@ func (self *SManagedVirtualizedGuestDriver) RequestDeployGuestOnHost(ctx context
return errors.Wrap(err, "GetSecgroups")
}
for i, secgroup := range secgroups {
externalId, err := region.GetDriver().RequestSyncSecurityGroup(ctx, task.GetUserCred(), vpcId, vpc, &secgroup, desc.ProjectId, "", true)
externalId, err := region.GetDriver().RequestSyncSecurityGroup(ctx, task.GetUserCred(), vpcId, vpc, &secgroup, desc.ProjectId, "")
if err != nil {
return errors.Wrap(err, "RequestSyncSecurityGroup")
}
@@ -1094,7 +1094,7 @@ func (self *SManagedVirtualizedGuestDriver) RequestSyncSecgroupsOnHost(ctx conte
region, _ := host.GetRegion()
vpcId, err := region.GetDriver().GetSecurityGroupVpcId(ctx, task.GetUserCred(), region, host, vpc, false)
vpcId, err := region.GetDriver().GetSecurityGroupVpcId(ctx, task.GetUserCred(), region, host, vpc)
if err != nil {
return errors.Wrap(err, "GetSecurityGroupVpcId")
}
@@ -1114,7 +1114,7 @@ func (self *SManagedVirtualizedGuestDriver) RequestSyncSecgroupsOnHost(ctx conte
}
externalIds := []string{}
for _, secgroup := range secgroups {
externalId, err := region.GetDriver().RequestSyncSecurityGroup(ctx, task.GetUserCred(), vpcId, vpc, &secgroup, remoteProjectId, "", true)
externalId, err := region.GetDriver().RequestSyncSecurityGroup(ctx, task.GetUserCred(), vpcId, vpc, &secgroup, remoteProjectId, "")
if err != nil {
return errors.Wrap(err, "RequestSyncSecurityGroup")
}
+1 -2
View File
@@ -290,8 +290,7 @@ func syncRegionVPCs(
syncVpcWires(ctx, userCred, syncResults, provider, &localVpcs[j], remoteVpcs[j], syncRange)
if localRegion.GetDriver().IsSecurityGroupBelongVpc() ||
(localRegion.GetDriver().IsSecurityGroupBelongGlobalVpc() && !utils.IsInStringArray(localVpcs[j].GlobalvpcId, globalVpcIds)) ||
localRegion.GetDriver().IsSupportClassicSecurityGroup() || j == 0 { //有vpc属性的每次都同步,支持classic的vpc也同步,否则仅同步一次
(localRegion.GetDriver().IsSecurityGroupBelongGlobalVpc() && !utils.IsInStringArray(localVpcs[j].GlobalvpcId, globalVpcIds)) || j == 0 { //有vpc属性的每次都同步,支持classic的vpc也同步,否则仅同步一次
if len(localVpcs[j].GlobalvpcId) > 0 {
globalVpcIds = append(globalVpcIds, localVpcs[j].GlobalvpcId)
}
+1 -42
View File
@@ -67,12 +67,6 @@ func (self *SGuest) PerformAddSecgroup(
secgroupIds = append(secgroupIds, secgroup.Id)
}
reg, err := self.getRegion()
if err != nil {
return nil, errors.Wrap(err, "getRegion")
}
supportPeerSecgrp := reg.GetDriver().IsSupportPeerSecgroup()
secgroupNames := []string{}
for _, secgroupId := range input.SecgroupIds {
secgrp, err := SecurityGroupManager.FetchByIdOrName(userCred, secgroupId)
@@ -92,14 +86,6 @@ func (self *SGuest) PerformAddSecgroup(
return nil, httperrors.NewInputParameterError("security group %s has already been assigned to guest %s", secgrp.GetName(), self.Name)
}
hasPeerSecgrp, err := secgrp.(*SSecurityGroup).HasPeerSecgroup()
if err != nil {
return nil, errors.Wrap(err, "secgrp.HasPeerSecgroup")
}
if hasPeerSecgrp && !supportPeerSecgrp {
return nil, errors.Wrap(httperrors.ErrNotSupported, "guest not support peer security group")
}
secgroupIds = append(secgroupIds, secgrp.GetId())
secgroupNames = append(secgroupNames, secgrp.GetName())
}
@@ -271,19 +257,6 @@ func (self *SGuest) performAssignSecgroup(
return nil, httperrors.NewInputParameterError("The secgroup name %s does not meet the requirements, please change the name", secObj.GetName())
}
reg, err := self.getRegion()
if err != nil {
return nil, errors.Wrap(err, "getRegion")
}
supportPeerSecgrp := reg.GetDriver().IsSupportPeerSecgroup()
hasPeerSecgrp, err := secObj.(*SSecurityGroup).HasPeerSecgroup()
if err != nil {
return nil, errors.Wrap(err, "secgrp.HasPeerSecgroup")
}
if hasPeerSecgrp && !supportPeerSecgrp {
return nil, errors.Wrap(httperrors.ErrNotSupported, "guest not support peer security group")
}
err = self.saveDefaultSecgroupId(userCred, input.SecgroupId, isAdmin)
if err != nil {
return nil, err
@@ -317,12 +290,6 @@ func (self *SGuest) PerformSetSecgroup(
return nil, httperrors.NewUnsupportOperationError("guest %s band to up to %d security groups", self.Name, maxCount)
}
reg, err := self.getRegion()
if err != nil {
return nil, errors.Wrap(err, "getRegion")
}
supportPeerSecgrp := reg.GetDriver().IsSupportPeerSecgroup()
secgroupIds := []string{}
secgroupNames := []string{}
for _, secgroupId := range input.SecgroupIds {
@@ -340,20 +307,12 @@ func (self *SGuest) PerformSetSecgroup(
}
if !utils.IsInStringArray(secgrp.GetId(), secgroupIds) {
hasPeerSecgrp, err := secgrp.(*SSecurityGroup).HasPeerSecgroup()
if err != nil {
return nil, errors.Wrap(err, "secgrp.HasPeerSecgroup")
}
if hasPeerSecgrp && !supportPeerSecgrp {
return nil, errors.Wrap(httperrors.ErrNotSupported, "guest not support peer security group")
}
secgroupIds = append(secgroupIds, secgrp.GetId())
secgroupNames = append(secgroupNames, secgrp.GetName())
}
}
err = self.saveSecgroups(ctx, userCred, secgroupIds)
err := self.saveSecgroups(ctx, userCred, secgroupIds)
if err != nil {
return nil, httperrors.NewGeneralError(errors.Wrapf(err, "saveSecgroups"))
}
+3 -11
View File
@@ -125,23 +125,15 @@ type IRegionDriver interface {
RequestPackInstanceBackup(ctx context.Context, ib *SInstanceBackup, task taskman.ITask, packageName string) error
RequestUnpackInstanceBackup(ctx context.Context, ib *SInstanceBackup, task taskman.ITask, packageName string, metadataOnly bool) error
RequestCacheSecurityGroup(ctx context.Context, userCred mcclient.TokenCredential, region *SCloudregion, vpc *SVpc, secgroup *SSecurityGroup, classic bool, removeProjectId string, task taskman.ITask) error
RequestSyncSecurityGroup(ctx context.Context, userCred mcclient.TokenCredential, vpcId string, vpc *SVpc, secgroup *SSecurityGroup, removeProjectId, service string, skipSyncRule bool) (string, error)
GetDefaultSecurityGroupInRule() cloudprovider.SecurityRule
RequestCacheSecurityGroup(ctx context.Context, userCred mcclient.TokenCredential, region *SCloudregion, vpc *SVpc, secgroup *SSecurityGroup, removeProjectId string, task taskman.ITask) error
RequestSyncSecurityGroup(ctx context.Context, userCred mcclient.TokenCredential, vpcId string, vpc *SVpc, secgroup *SSecurityGroup, removeProjectId, service string) (string, error)
GenerateSecurityGroupName(name string) string
IsAllowSecurityGroupNameRepeat() bool
GetDefaultSecurityGroupOutRule() cloudprovider.SecurityRule
GetSecurityGroupRuleMaxPriority() int
GetSecurityGroupRuleMinPriority() int
IsOnlySupportAllowRules() bool
IsPeerSecgroupWithSameProject() bool
IsSupportPeerSecgroup() bool
IsSupportClassicSecurityGroup() bool
IsSecurityGroupBelongVpc() bool
IsVpcBelongGlobalVpc() bool
IsSecurityGroupBelongGlobalVpc() bool //安全组子账号范围内可用
GetDefaultSecurityGroupVpcId() string
GetSecurityGroupVpcId(ctx context.Context, userCred mcclient.TokenCredential, region *SCloudregion, host *SHost, vpc *SVpc, classic bool) (string, error)
GetSecurityGroupVpcId(ctx context.Context, userCred mcclient.TokenCredential, region *SCloudregion, host *SHost, vpc *SVpc) (string, error)
GetSecurityGroupPublicScope(service string) rbacscope.TRbacScope
IsSupportedBillingCycle(bc billing.SBillingCycle, resource string) bool
+52 -183
View File
@@ -18,6 +18,7 @@ import (
"context"
"database/sql"
"fmt"
"sort"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/jsonutils"
@@ -184,11 +185,6 @@ func (self *SSecurityGroupCache) GetIRegion(ctx context.Context) (cloudprovider.
return provider.GetIRegionById(region.ExternalId)
}
func (sgc *SSecurityGroupCache) IsSupportPeerSecgroup() bool {
driver := GetRegionDriver(sgc.GetProviderName())
return driver.IsSupportPeerSecgroup()
}
func (manager *SSecurityGroupCacheManager) FilterByOwner(q *sqlchemy.SQuery, userCred mcclient.IIdentityProvider, scope rbacscope.TRbacScope) *sqlchemy.SQuery {
if userCred != nil {
sq := SecurityGroupManager.Query("id")
@@ -393,29 +389,16 @@ func (self *SSecurityGroupCache) SyncBaseInfo(ctx context.Context, userCred mccl
return nil
}
func (self *SSecurityGroupCache) syncWithCloudSecurityGroup(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, ext cloudprovider.ICloudSecurityGroup) ([]SSecurityGroupRule, error) {
func (self *SSecurityGroupCache) syncWithCloudSecurityGroup(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, ext cloudprovider.ICloudSecurityGroup) error {
err := self.SyncBaseInfo(ctx, userCred, ext)
if err != nil {
return nil, errors.Wrapf(err, "db.Update")
return errors.Wrapf(err, "db.Update")
}
secgroup, err := self.GetSecgroup()
if err != nil {
return nil, errors.Wrapf(err, "GetSecurity")
return errors.Wrapf(err, "GetSecurity")
}
cacheCount, err := secgroup.GetSecgroupCacheCount()
if err != nil {
return nil, errors.Wrapf(err, "GetSecgroupCacheCount")
}
if cacheCount > 1 {
return nil, nil
}
dest := cloudprovider.NewSecRuleInfo(GetRegionDriver(provider.Provider))
dest.Rules, err = ext.GetRules()
if err != nil {
return nil, errors.Wrapf(err, "GetRules")
}
rules, _ := secgroup.SyncSecurityGroupRules(ctx, userCred, dest)
return rules, nil
return secgroup.SyncSecurityGroupRules(ctx, userCred, self, provider, ext)
}
func (manager *SSecurityGroupCacheManager) SyncSecurityGroupCaches(
@@ -441,7 +424,7 @@ func (manager *SSecurityGroupCacheManager) SyncSecurityGroupCaches(
vpcId := ""
if region.GetDriver().IsSecurityGroupBelongGlobalVpc() {
vpcId, err = region.GetDriver().GetSecurityGroupVpcId(ctx, userCred, region, nil, vpc, false)
vpcId, err = region.GetDriver().GetSecurityGroupVpcId(ctx, userCred, region, nil, vpc)
if err != nil {
syncResult.Error(errors.Wrap(err, "GetSecurityGroupVpcId"))
return localSecgroups, remoteSecgroups, syncResult
@@ -449,12 +432,6 @@ func (manager *SSecurityGroupCacheManager) SyncSecurityGroupCaches(
region = nil
} else if region.GetDriver().IsSecurityGroupBelongVpc() {
vpcId = vpc.ExternalId
} else if region.GetDriver().IsSupportClassicSecurityGroup() && len(secgroups) > 0 {
vpcId, err = region.GetDriver().GetSecurityGroupVpcId(ctx, userCred, region, nil, vpc, secgroups[0].GetVpcId() == "classic")
if err != nil {
syncResult.Error(errors.Wrap(err, "GetSecurityGroupVpcId"))
return localSecgroups, remoteSecgroups, syncResult
}
} else {
vpcId = region.GetDriver().GetDefaultSecurityGroupVpcId()
}
@@ -488,27 +465,23 @@ func (manager *SSecurityGroupCacheManager) SyncSecurityGroupCaches(
}
}
rules := []SSecurityGroupRule{}
if !xor {
for i := 0; i < len(commondb); i++ {
_rules, err := commondb[i].syncWithCloudSecurityGroup(ctx, userCred, provider, commonext[i])
err := commondb[i].syncWithCloudSecurityGroup(ctx, userCred, provider, commonext[i])
if err != nil {
syncResult.UpdateError(errors.Wrapf(err, "syncWithCloudSecurityGroup"))
continue
}
rules = append(rules, _rules...)
syncResult.Update()
}
}
for i := 0; i < len(added); i++ {
secgroup, _rules, err := SecurityGroupManager.newFromCloudSecgroup(ctx, userCred, provider, added[i])
secgroup, err := SecurityGroupManager.newFromCloudSecgroup(ctx, userCred, provider, added[i])
if err != nil {
syncResult.AddError(errors.Wrapf(err, "newFromCloudSecgroup"))
continue
}
rules = append(rules, _rules...)
if secgroup.ProjectId != provider.ProjectId {
_, err = secgroup.PerformPublic(ctx, userCred, nil,
apis.PerformPublicProjectInput{
@@ -548,17 +521,6 @@ func (manager *SSecurityGroupCacheManager) SyncSecurityGroupCaches(
remoteSecgroups = append(remoteSecgroups, added[i])
syncResult.Add()
}
for i := range rules {
if len(rules[i].PeerSecgroupId) > 0 {
cache, _ := db.FetchByExternalId(SecurityGroupCacheManager, rules[i].PeerSecgroupId)
if cache != nil {
db.Update(&rules[i], func() error {
rules[i].PeerSecgroupId = cache.(*SSecurityGroupCache).SecgroupId
return nil
})
}
}
}
return localSecgroups, remoteSecgroups, syncResult
}
@@ -627,8 +589,7 @@ func (self *SSecurityGroupCache) StartSecurityGroupCacheDeleteTask(ctx context.C
if err != nil {
return err
}
task.ScheduleRun(nil)
return nil
return task.ScheduleRun(nil)
}
func (manager *SSecurityGroupCacheManager) InitializeData() error {
@@ -715,19 +676,19 @@ func (self *SSecurityGroupCache) GetISecurityGroup(ctx context.Context) (cloudpr
return iRegion.GetISecurityGroupById(self.ExternalId)
}
func (self *SSecurityGroupCache) GetOrCreateISecurityGroup(ctx context.Context) (cloudprovider.ICloudSecurityGroup, bool, error) {
func (self *SSecurityGroupCache) GetOrCreateISecurityGroup(ctx context.Context) (cloudprovider.ICloudSecurityGroup, error) {
secgroup, err := self.GetISecurityGroup(ctx)
if err != nil {
if errors.Cause(err) == cloudprovider.ErrNotFound {
secgroup, err = self.CreateISecurityGroup(ctx)
if err != nil {
return nil, false, errors.Wrapf(err, "CreateISecurityGroup")
return nil, errors.Wrapf(err, "CreateISecurityGroup")
}
return secgroup, true, nil
return secgroup, nil
}
return nil, false, errors.Wrapf(err, "GetIISecurityGroup")
return nil, errors.Wrapf(err, "GetIISecurityGroup")
}
return secgroup, false, nil
return secgroup, nil
}
func (self *SSecurityGroupCache) CreateISecurityGroup(ctx context.Context) (cloudprovider.ICloudSecurityGroup, error) {
@@ -768,14 +729,50 @@ func (self *SSecurityGroupCache) CreateISecurityGroup(ctx context.Context) (clou
self.Name = opts.Name
}
conf := &cloudprovider.SecurityGroupCreateInput{
secgroup, err := self.GetSecgroup()
if err != nil {
return nil, errors.Wrapf(err, "GetSecgroup")
}
_, in, out, err := secgroup.GetSecuritRuleSet()
if err != nil {
return nil, errors.Wrapf(err, "GetSecuritRuleSet")
}
opts := &cloudprovider.SecurityGroupCreateInput{
Name: self.Name,
Desc: self.Description,
VpcId: self.VpcId,
ProjectId: self.ExternalProjectId,
InRules: []cloudprovider.SecurityRule{},
OutRules: []cloudprovider.SecurityRule{},
}
iSecgroup, err := iRegion.CreateISecurityGroup(conf)
for i := range in {
opts.InRules = append(opts.InRules, cloudprovider.SecurityRule{SecurityRule: in[i]})
}
for i := range out {
opts.OutRules = append(opts.OutRules, cloudprovider.SecurityRule{SecurityRule: out[i]})
}
sort.Sort(sort.Reverse(cloudprovider.SecurityRuleSet(opts.InRules)))
sort.Sort(sort.Reverse(cloudprovider.SecurityRuleSet(opts.OutRules)))
opts.OnCreated = func(id string) {
_, err := db.Update(self, func() error {
self.ExternalId = id
return nil
})
if err != nil {
log.Errorf("failed to set secgroup cache %s(%s) externalId %s", self.Name, self.Id, id)
}
}
iSecgroup, err := iRegion.CreateISecurityGroup(opts)
if err != nil {
db.Update(self, func() error {
self.Status = api.SECGROUP_CACHE_STATUS_CACHE_FAILED
return nil
})
return nil, errors.Wrapf(err, "iRegion.CreateISecurityGroup")
}
_, err = db.Update(self, func() error {
@@ -786,131 +783,3 @@ func (self *SSecurityGroupCache) CreateISecurityGroup(ctx context.Context) (clou
})
return iSecgroup, nil
}
func (self *SSecurityGroupCache) getSecurityRuleSet(ctx context.Context) (cloudprovider.SecurityRuleSet, []SSecurityGroupCache, error) {
secgroup, err := self.GetSecgroup()
if err != nil {
return nil, nil, errors.Wrapf(err, "GetSecgroup")
}
rules, err := secgroup.getSecurityRules()
if err != nil {
return nil, nil, errors.Wrapf(err, "getSecurityRules")
}
return self.convertRules(ctx, rules)
}
func (self *SSecurityGroupCache) GetOldSecuritRuleSet(ctx context.Context) (cloudprovider.SecurityRuleSet, []SSecurityGroupCache, error) {
secgroup, err := self.GetSecgroup()
if err != nil {
return nil, nil, errors.Wrapf(err, "GetSecgroup")
}
rules, err := secgroup.GetOldRules()
if err != nil {
return nil, nil, errors.Wrapf(err, "GetOldRules")
}
return self.convertRules(ctx, rules)
}
func (self *SSecurityGroupCache) convertRules(ctx context.Context, rules []SSecurityGroupRule) (cloudprovider.SecurityRuleSet, []SSecurityGroupCache, error) {
ruleSet := cloudprovider.SecurityRuleSet{}
caches := []SSecurityGroupCache{}
driver := GetRegionDriver(self.GetProviderName())
for i := range rules {
if !driver.IsSupportPeerSecgroup() && len(rules[i].PeerSecgroupId) > 0 {
continue
}
//这里没必要拆分为单个单个的端口,到公有云那边适配
rule, err := rules[i].toRule()
if err != nil {
return nil, nil, errors.Wrapf(err, "toRule")
}
peerExtId := ""
if len(rules[i].PeerSecgroupId) > 0 {
_peerSecgroup, err := SecurityGroupManager.FetchById(rules[i].PeerSecgroupId)
if err != nil {
return nil, nil, errors.Wrapf(err, "SecurityGroupManager.FetchById(%s)", rules[i].PeerSecgroupId)
}
peerSecgroup := _peerSecgroup.(*SSecurityGroup)
peerCaches, err := peerSecgroup.GetSecurityGroupCaches()
if err != nil {
return nil, nil, errors.Wrapf(err, "peerSecgroup.GetSecurityGroupCaches")
}
for _, cache := range peerCaches {
if cache.ManagerId == self.ManagerId && cache.VpcId == self.VpcId && len(cache.ExternalId) > 0 && (!driver.IsPeerSecgroupWithSameProject() || cache.ExternalProjectId == self.ExternalProjectId) {
peerExtId = cache.ExternalId
break
}
}
if len(peerExtId) == 0 {
cache, err := SecurityGroupCacheManager.newCache(ctx, peerSecgroup.Id, peerSecgroup.Name, self.VpcId, self.CloudregionId, self.ManagerId, self.ExternalProjectId)
if err != nil {
return nil, nil, errors.Wrapf(err, "SecurityGroupCacheManager.newCache")
}
iSecgroup, err := cache.CreateISecurityGroup(ctx)
if err != nil {
return nil, nil, errors.Wrapf(err, "cache.CreateISecurityGroup")
}
peerExtId = iSecgroup.GetGlobalId()
caches = append(caches, *cache)
}
}
ruleSet = append(ruleSet, cloudprovider.SecurityRule{
SecurityRule: *rule,
ExternalId: rules[i].Id,
PeerSecgroupId: peerExtId,
})
}
return ruleSet, caches, nil
}
func (self *SSecurityGroupCache) SyncRules(ctx context.Context, skipSyncRule bool) error {
region, err := self.GetRegion()
if err != nil {
return err
}
iSecgroup, err := self.GetISecurityGroup(ctx)
if err != nil {
return errors.Wrapf(err, "GetISecurityGroup")
}
if skipSyncRule {
return nil
}
rules, err := iSecgroup.GetRules()
if err != nil {
return errors.Wrapf(err, "iSecgroup.GetRules")
}
localRules, caches, err := self.getSecurityRuleSet(ctx)
if err != nil {
return errors.Wrapf(err, "getSecurityRuleSet")
}
src := cloudprovider.NewSecRuleInfo(GetRegionDriver(api.CLOUD_PROVIDER_ONECLOUD))
src.Rules = localRules
dest := cloudprovider.NewSecRuleInfo(GetRegionDriver(region.Provider))
dest.Rules = rules
common, inAdds, outAdds, inDels, outDels := cloudprovider.CompareRules(src, dest, false)
if len(inAdds) == 0 && len(inDels) == 0 && len(outAdds) == 0 && len(outDels) == 0 {
return nil
}
if len(inDels)+len(outDels) > 10 {
return fmt.Errorf("too many rules operations with %s inDel:%d outDel:%d inAdd:%d outAdd: %d", self.Name, len(inDels), len(outDels), len(inAdds), len(outAdds))
}
err = iSecgroup.SyncRules(common, inAdds, outAdds, inDels, outDels)
if err != nil {
return errors.Wrapf(err, "iSecgroup.SyncRules")
}
for i := range caches {
err = caches[i].SyncRules(ctx, skipSyncRule)
if err != nil {
return errors.Wrapf(err, "SyncRules for caches %s(%s)", caches[i].Name, caches[i].Id)
}
}
return nil
}
+8 -139
View File
@@ -16,10 +16,8 @@ package models
import (
"context"
"fmt"
"net"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
@@ -31,7 +29,6 @@ import (
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudcommon/validators"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
@@ -62,17 +59,14 @@ type SSecurityGroupRule struct {
db.SResourceBase
SSecurityGroupResourceBase `create:"required"`
Id string `width:"128" charset:"ascii" primary:"true" list:"user"`
Priority int64 `default:"1" list:"user" update:"user" list:"user"`
Protocol string `width:"5" charset:"ascii" nullable:"false" list:"user" update:"user" create:"required"`
Ports string `width:"256" charset:"ascii" list:"user" update:"user" create:"optional"`
Direction string `width:"3" charset:"ascii" list:"user" create:"required"`
CIDR string `width:"256" charset:"ascii" list:"user" update:"user" create:"optional"`
Action string `width:"5" charset:"ascii" nullable:"false" list:"user" update:"user" create:"required"`
Description string `width:"256" charset:"utf8" list:"user" update:"user" create:"optional"`
PeerSecgroupId string `width:"128" charset:"ascii" create:"optional" list:"user" update:"user"`
IsDirty bool `nullable:"false" default:"false"`
Id string `width:"128" charset:"ascii" primary:"true" list:"user"`
Priority int64 `default:"1" list:"user" update:"user" list:"user"`
Protocol string `width:"5" charset:"ascii" nullable:"false" list:"user" update:"user" create:"required"`
Ports string `width:"256" charset:"ascii" list:"user" update:"user" create:"optional"`
Direction string `width:"3" charset:"ascii" list:"user" create:"required"`
CIDR string `width:"256" charset:"ascii" list:"user" update:"user" create:"optional"`
Action string `width:"5" charset:"ascii" nullable:"false" list:"user" update:"user" create:"required"`
Description string `width:"256" charset:"utf8" list:"user" update:"user" create:"optional"`
}
func (self *SSecurityGroupRule) GetId() string {
@@ -174,7 +168,6 @@ func (manager *SSecurityGroupRuleManager) FetchCustomizeColumns(
bRows := manager.SResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
secRows := manager.SSecurityGroupResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
secIds := make([]string, len(objs))
peerIds := make([]string, len(objs))
for i := range rows {
rows[i] = api.SecgroupRuleDetails{
ResourceBaseDetails: bRows[i],
@@ -182,7 +175,6 @@ func (manager *SSecurityGroupRuleManager) FetchCustomizeColumns(
}
rule := objs[i].(*SSecurityGroupRule)
secIds[i] = rule.SecgroupId
peerIds[i] = rule.PeerSecgroupId
}
secgroups := make(map[string]SSecurityGroup)
@@ -192,12 +184,6 @@ func (manager *SSecurityGroupRuleManager) FetchCustomizeColumns(
return rows
}
peerMaps, err := db.FetchIdNameMap2(SecurityGroupManager, peerIds)
if err != nil {
log.Errorf("db.FetchIdNameMap2 fail: %v", err)
return rows
}
virObjs := make([]interface{}, len(objs))
for i := range rows {
if secgroup, ok := secgroups[secIds[i]]; ok {
@@ -209,7 +195,6 @@ func (manager *SSecurityGroupRuleManager) FetchCustomizeColumns(
projRows := SecurityGroupManager.SProjectizedResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, virObjs, fields, isList)
for i := range rows {
rows[i].ProjectizedResourceInfo = projRows[i]
rows[i].PeerSecgroup, _ = peerMaps[peerIds[i]]
}
return rows
@@ -279,16 +264,6 @@ func (manager *SSecurityGroupRuleManager) ValidateCreateData(ctx context.Context
return input, httperrors.NewForbiddenError("not enough privilege")
}
if len(input.PeerSecgroupId) > 0 {
_, err = validators.ValidateModel(userCred, SecurityGroupManager, &input.PeerSecgroupId)
if err != nil {
return input, err
}
if input.PeerSecgroupId == input.SecgroupId {
return input, httperrors.NewInputParameterError("peer_secgroup_id can not point to secgroup self")
}
}
err = input.Check()
if err != nil {
return input, err
@@ -327,27 +302,6 @@ func (self *SSecurityGroupRule) ValidateUpdateData(ctx context.Context, userCred
input.CIDR = self.CIDR
}
if len(input.PeerSecgroupId) > 0 {
_, err := validators.ValidateModel(userCred, SecurityGroupManager, &input.PeerSecgroupId)
if err != nil {
return input, err
}
if input.PeerSecgroupId == self.Id {
return input, httperrors.NewInputParameterError("peer_secgroup_id can not point to secgroup self")
}
// verify whether cache support peer secgroup
sg := self.GetSecGroup()
caches, err := sg.GetSecurityGroupCaches()
if err != nil {
return input, errors.Wrap(err, "sg.GetSecurityGroupCaches")
}
for _, c := range caches {
if !c.IsSupportPeerSecgroup() {
return input, errors.Wrapf(httperrors.ErrConflict, "the security group has been assigned to a provider not support peer security group")
}
}
}
err := input.Check()
if err != nil {
return input, err
@@ -402,14 +356,6 @@ func (self *SSecurityGroupRule) toRule() (*secrules.SecurityRule, error) {
func (self *SSecurityGroupRule) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) {
self.SResourceBase.PostCreate(ctx, userCred, ownerId, query, data)
db.Update(self, func() error {
if len(self.PeerSecgroupId) > 0 {
self.CIDR = ""
}
self.IsDirty = true
return nil
})
log.Debugf("POST Create %s", data)
if secgroup := self.GetSecGroup(); secgroup != nil {
logclient.AddSimpleActionLog(secgroup, logclient.ACT_ALLOCATE, data, userCred, true)
@@ -420,42 +366,15 @@ func (self *SSecurityGroupRule) PostCreate(ctx context.Context, userCred mcclien
func (self *SSecurityGroupRule) PreDelete(ctx context.Context, userCred mcclient.TokenCredential) {
self.SResourceBase.PreDelete(ctx, userCred)
db.Update(self, func() error {
self.IsDirty = true
return nil
})
if secgroup := self.GetSecGroup(); secgroup != nil {
logclient.AddSimpleActionLog(secgroup, logclient.ACT_DELETE, jsonutils.Marshal(self), userCred, true)
secgroup.DoSync(ctx, userCred)
}
}
func (self *SSecurityGroupRule) PreUpdate(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) {
old := &SSecurityGroupRule{}
old.SetModelManager(SecurityGroupRuleManager, old)
jsonutils.Update(old, self)
old.IsDirty = true
old.Deleted = true
old.Id = fmt.Sprintf("%s-back", self.Id)
err := SecurityGroupRuleManager.TableSpec().InsertOrUpdate(ctx, old)
if err != nil {
log.Errorf("insert old rule error: %v", err)
}
}
func (self *SSecurityGroupRule) PostUpdate(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) {
self.SResourceBase.PostUpdate(ctx, userCred, query, data)
db.Update(self, func() error {
if data.Contains("peer_secgroup_id") {
self.CIDR = ""
} else if data.Contains("cidr") {
self.PeerSecgroupId = ""
}
return nil
})
log.Debugf("POST Update %s", data)
if secgroup := self.GetSecGroup(); secgroup != nil {
logclient.AddSimpleActionLog(secgroup, logclient.ACT_UPDATE, data, userCred, true)
@@ -472,56 +391,6 @@ func (manager *SSecurityGroupRuleManager) getRulesBySecurityGroup(secgroup *SSec
return rules, nil
}
func (self *SSecurityGroup) newFromCloudSecurityGroupRule(ctx context.Context, userCred mcclient.TokenCredential, rule cloudprovider.SecurityRule) (*SSecurityGroupRule, bool, error) {
lockman.LockObject(ctx, self)
defer lockman.ReleaseObject(ctx, self)
isNeedFix := false
protocol := rule.Protocol
if len(protocol) == 0 {
protocol = secrules.PROTO_ANY
}
cidr := "0.0.0.0/0"
if rule.IPNet != nil && rule.IPNet.String() != "<nil>" {
cidr = rule.IPNet.String()
}
if len(rule.PeerSecgroupId) > 0 {
cidr = ""
cache, _ := db.FetchByExternalId(SecurityGroupCacheManager, rule.PeerSecgroupId)
if cache != nil {
rule.PeerSecgroupId = cache.(*SSecurityGroupCache).SecgroupId
}
isNeedFix = true
}
err := rule.ValidateRule()
if err != nil {
return nil, isNeedFix, errors.Wrapf(err, "ValidateRule %s ", jsonutils.Marshal(rule).String())
}
secrule := &SSecurityGroupRule{
Priority: int64(rule.Priority),
Protocol: protocol,
Ports: rule.GetPortsString(),
Direction: string(rule.Direction),
CIDR: cidr,
Action: string(rule.Action),
Description: rule.Description,
PeerSecgroupId: rule.PeerSecgroupId,
}
secrule.SetModelManager(SecurityGroupRuleManager, secrule)
secrule.SecgroupId = self.Id
err = SecurityGroupRuleManager.TableSpec().Insert(ctx, secrule)
if err != nil {
return nil, isNeedFix, errors.Wrapf(err, "SecurityGroupRuleManager.Insert")
}
return secrule, isNeedFix, nil
}
func (self *SSecurityGroupRule) GetOwnerId() mcclient.IIdentityProvider {
secgrp := self.GetSecGroup()
if secgrp != nil {
+189 -215
View File
@@ -25,7 +25,7 @@ import (
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/compare"
"yunion.io/x/pkg/gotypes"
"yunion.io/x/pkg/util/rbacscope"
"yunion.io/x/pkg/util/regutils"
"yunion.io/x/pkg/util/secrules"
@@ -504,18 +504,10 @@ func (manager *SSecurityGroupManager) FetchCustomizeColumns(
return rows
}
peerSecgroupIds := []string{}
for _, rule := range rules {
if len(rule.PeerSecgroupId) > 0 {
peerSecgroupIds = append(peerSecgroupIds, rule.PeerSecgroupId)
}
}
peerMaps, err := db.FetchIdNameMap2(SecurityGroupManager, peerSecgroupIds)
totalCnt, err := manager.TotalCnt(secgroupIds)
if err != nil {
return rows
}
ruleMaps := map[string][]SSecurityGroupRule{}
for i := range rules {
if _, ok := ruleMaps[rules[i].SecgroupId]; !ok {
@@ -534,9 +526,6 @@ func (manager *SSecurityGroupManager) FetchCustomizeColumns(
for j := range rules {
rule := api.SecgroupRuleDetails{}
jsonutils.Update(&rule, rules[j])
if len(rules[j].PeerSecgroupId) > 0 {
rule.PeerSecgroup, _ = peerMaps[rules[j].PeerSecgroupId]
}
_rules = append(_rules, rule)
switch rule.Direction {
case secrules.DIR_IN:
@@ -552,19 +541,8 @@ func (manager *SSecurityGroupManager) FetchCustomizeColumns(
rows[i].GuestCnt, _ = normalGuestMaps[secgroupIds[i]]
rows[i].AdminGuestCnt, _ = adminGuestMaps[secgroupIds[i]]
rows[i].SystemGuestCnt, _ = systemGuestMaps[secgroupIds[i]]
}
withCache, _ := query.Bool("with_cache")
if withCache {
secgroupIds := make([]string, len(secgroups))
for i := range secgroups {
secgroupIds[i] = secgroups[i].Id
}
cacheDetails, err := manager.GetCacheDetails(ctx, userCred, secgroupIds)
if err != nil {
log.Errorf("unable to Get cacheDetails: %v", err)
}
for i := range rows {
rows[i].CloudCaches = cacheDetails[secgroupIds[i]]
if cnt, ok := totalCnt[secgroupIds[i]]; ok {
rows[i].TotalCnt = cnt.TotalCnt
}
}
return rows
@@ -678,44 +656,42 @@ func (self *SSecurityGroup) getSecurityRules() ([]SSecurityGroupRule, error) {
return rules, nil
}
func (self *SSecurityGroup) GetSecuritRuleSet() (cloudprovider.SecurityRuleSet, error) {
ruleSet := cloudprovider.SecurityRuleSet{}
func (self *SSecurityGroup) GetSecuritRuleSet() ([]SSecurityGroupRule, secrules.SecurityRuleSet, secrules.SecurityRuleSet, error) {
rules, err := self.getSecurityRules()
if err != nil {
return ruleSet, errors.Wrapf(err, "getSecurityRules")
return nil, nil, nil, errors.Wrapf(err, "getSecurityRules")
}
in, out := secrules.SecurityRuleSet{}, secrules.SecurityRuleSet{}
for i := range rules {
//这里没必要拆分为单个单个的端口,到公有云那边适配
rule, err := rules[i].toRule()
if err != nil {
return nil, errors.Wrapf(err, "toRule")
return nil, nil, nil, errors.Wrapf(err, "toRule")
}
ruleSet = append(ruleSet, cloudprovider.SecurityRule{
SecurityRule: *rule,
ExternalId: rules[i].Id,
})
}
return ruleSet, nil
}
/*
func (self *SSecurityGroup) GetSecRules() ([]secrules.SecurityRule, error) {
rules := make([]secrules.SecurityRule, 0)
_rules, err := self.getSecurityRules()
if err != nil {
return nil, errors.Wrapf(err, "getSecurityRules()")
}
for _, _rule := range _rules {
//这里没必要拆分为单个单个的端口,到公有云那边适配
rule, err := _rule.toRule()
if err != nil {
return nil, errors.Wrapf(err, "toRule")
if rule.Protocol != secrules.PROTO_ICMP && len(rule.Ports) > 0 {
ports := rule.Ports
rule.Ports = []int{}
for _, port := range ports {
rule.PortStart, rule.PortEnd = port, port
switch rule.Direction {
case secrules.DIR_IN:
in = append(in, *rule)
case secrules.DIR_OUT:
out = append(out, *rule)
}
}
} else {
switch rule.Direction {
case secrules.DIR_IN:
in = append(in, *rule)
case secrules.DIR_OUT:
out = append(out, *rule)
}
}
rules = append(rules, *rule)
}
return rules, nil
outAllowAny := secrules.MustParseSecurityRule("out:allow any")
out = append(out, *outAllowAny)
return rules, in, out, nil
}
*/
func (self *SSecurityGroup) getSecurityRuleString() (string, error) {
secgrouprules, err := self.getSecurityRules()
@@ -762,60 +738,36 @@ func (self *SSecurityGroup) PerformUncacheSecgroup(ctx context.Context, userCred
return nil, cache.StartSecurityGroupCacheDeleteTask(ctx, userCred, "")
}
func (self *SSecurityGroup) PerformCacheSecgroup(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
vpcV := validators.NewModelIdOrNameValidator("vpc", "vpc", nil)
err := vpcV.Validate(data.(*jsonutils.JSONDict))
func (self *SSecurityGroup) PerformCacheSecgroup(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input *api.SecurityGroupCacheInput) (jsonutils.JSONObject, error) {
vpcObj, err := validators.ValidateModel(userCred, VpcManager, &input.VpcId)
if err != nil {
return nil, err
}
vpc := vpcV.Model.(*SVpc)
vpc := vpcObj.(*SVpc)
if len(vpc.ExternalId) == 0 {
return nil, httperrors.NewInputParameterError("vpc %s(%s) is not a managed resouce", vpc.Name, vpc.Id)
}
region, err := vpc.GetRegion()
if err != nil {
return nil, err
}
classic, _ := data.Bool("classic")
if classic && !region.GetDriver().IsSupportClassicSecurityGroup() {
return nil, httperrors.NewInputParameterError("Not support cache classic security group")
manager := vpc.GetCloudprovider()
if manager == nil {
return nil, httperrors.NewInputParameterError("vpc %s(%s) is not a managed resouce", vpc.Name, vpc.Id)
}
hasPeerSg, err := self.HasPeerSecgroup()
if err != nil {
return nil, errors.Wrap(err, "HasPeerSecgroup")
}
if hasPeerSg && !region.GetDriver().IsSupportPeerSecgroup() {
return nil, httperrors.NewConflictError("target region not support peer secgroup")
if !manager.IsAvailable() {
return nil, httperrors.NewInputParameterError("cloudprovider %s(%s) is not available", manager.Name, manager.Id)
}
return nil, self.StartSecurityGroupCacheTask(ctx, userCred, vpc.Id, classic, "")
return nil, self.StartSecurityGroupCacheTask(ctx, userCred, vpc.Id, "")
}
func (sg *SSecurityGroup) HasPeerSecgroup() (bool, error) {
rules, err := sg.getSecurityRules()
if err != nil {
return false, errors.Wrap(err, "GetSecRules")
}
for _, r := range rules {
if len(r.PeerSecgroupId) > 0 {
return true, nil
}
}
return false, nil
}
func (self *SSecurityGroup) StartSecurityGroupCacheTask(ctx context.Context, userCred mcclient.TokenCredential, vpcId string, classic bool, parentTaskId string) error {
func (self *SSecurityGroup) StartSecurityGroupCacheTask(ctx context.Context, userCred mcclient.TokenCredential, vpcId string, parentTaskId string) error {
params := jsonutils.NewDict()
params.Add(jsonutils.NewString(vpcId), "vpc_id")
params.Add(jsonutils.NewBool(classic), "classic")
task, err := taskman.TaskManager.NewTask(ctx, "SecurityGroupCacheTask", self, userCred, params, parentTaskId, "", nil)
if err != nil {
return err
return errors.Wrapf(err, "NewTask")
}
task.ScheduleRun(nil)
return nil
return task.ScheduleRun(nil)
}
func (self *SSecurityGroup) PerformAddRule(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
@@ -979,8 +931,8 @@ func (self *SSecurityGroup) PerformMerge(ctx context.Context, userCred mcclient.
}
func (self *SSecurityGroup) GetAllowList() (secrules.SecurityRuleSet, secrules.SecurityRuleSet, error) {
in := secrules.SecurityRuleSet{*secrules.MustParseSecurityRule("in:deny any")}
out := secrules.SecurityRuleSet{*secrules.MustParseSecurityRule("out:allow any")}
in := secrules.SecurityRuleSet{}
out := secrules.SecurityRuleSet{}
rules, err := self.getSecurityRules()
if err != nil {
return in, out, errors.Wrapf(err, "GetSecRules")
@@ -993,6 +945,8 @@ func (self *SSecurityGroup) GetAllowList() (secrules.SecurityRuleSet, secrules.S
out = append(out, *r)
}
}
in = append(in, *secrules.MustParseSecurityRule("in:deny any"))
out = append(out, *secrules.MustParseSecurityRule("out:allow any"))
return in.AllowList(), out.AllowList(), nil
}
@@ -1052,81 +1006,140 @@ func (manager *SSecurityGroupManager) getSecurityGroups() ([]SSecurityGroup, err
}
}
func (self *SSecurityGroup) removeRules(ruleIds []string, result *compare.SyncResult) {
if len(ruleIds) == 0 {
return
}
rules := []SSecurityGroupRule{}
q := SecurityGroupRuleManager.Query().In("id", ruleIds)
err := db.FetchModelObjects(SecurityGroupRuleManager, q, &rules)
if err != nil {
result.DeleteError(errors.Wrapf(err, "db.FetchModelObjects"))
return
}
for i := range rules {
err = rules[i].Delete(context.TODO(), nil)
if err != nil {
result.DeleteError(errors.Wrapf(err, "delte rule %s", rules[i].Id))
continue
}
result.Delete()
}
func (self *SSecurityGroup) clearRules() error {
_, err := sqlchemy.GetDB().Exec(
fmt.Sprintf(
"delete from %s where secgroup_id = ?",
SecurityGroupRuleManager.TableSpec().Name(),
), self.Id,
)
return err
}
func (self *SSecurityGroup) SyncSecurityGroupRules(ctx context.Context, userCred mcclient.TokenCredential, src cloudprovider.SecRuleInfo) ([]SSecurityGroupRule, compare.SyncResult) {
result := compare.SyncResult{}
localRules, err := self.GetSecuritRuleSet()
func (self *SSecurityGroup) SyncSecurityGroupRules(ctx context.Context, userCred mcclient.TokenCredential, cache *SSecurityGroupCache, provider *SCloudprovider, ext cloudprovider.ICloudSecurityGroup) error {
cacheCount, err := self.GetSecgroupCacheCount()
if err != nil {
result.Error(errors.Wrapf(err, "GetSecuritRuleSet"))
return nil, result
return errors.Wrapf(err, "GetSecgroupCacheCount")
}
dest := cloudprovider.NewSecRuleInfo(GetRegionDriver(api.CLOUD_PROVIDER_ONECLOUD))
dest.Rules = localRules
_, inAdds, outAdds, inDels, outDels := cloudprovider.CompareRules(src, dest, false)
if len(inAdds)+len(inDels)+len(outAdds)+len(outDels) == 0 {
return nil, result
kvmGuests, err := self.GetKvmGuests()
if err != nil {
return errors.Wrapf(err, "GetKvmGuests")
}
ruleIds := []string{}
for _, dels := range [][]cloudprovider.SecurityRule{inDels, outDels} {
for i := range dels {
if len(dels[i].ExternalId) > 0 {
ruleIds = append(ruleIds, dels[i].ExternalId)
}
}
if (cacheCount > 1 || len(kvmGuests) > 0) && !options.Options.EnableAutoSplitSecurityGroup {
return nil
}
self.removeRules(ruleIds, &result)
extRules, extInRules, extOutRules, err := cloudprovider.GetSecurityGroupRules(ext)
if err != nil {
return errors.Wrapf(err, "GetSecurityGroupRules")
}
rules := []SSecurityGroupRule{}
for _, adds := range [][]cloudprovider.SecurityRule{inAdds, outAdds} {
for i := range adds {
rule, isNeedFix, err := self.newFromCloudSecurityGroupRule(ctx, userCred, adds[i])
extInAllow := extInRules.AllowList()
extOutAllow := extOutRules.AllowList()
dbRules, in, out, err := self.GetSecuritRuleSet()
if err != nil {
return errors.Wrapf(err, "GetSecuritRuleSet")
}
inAllow := in.AllowList()
outAllow := out.AllowList()
if extInAllow.Equals(inAllow) && extOutAllow.Equals(outAllow) {
return nil
}
if cacheCount > 1 || len(kvmGuests) > 0 {
if options.Options.EnableAutoSplitSecurityGroup {
secgroup, err := SecurityGroupManager.newFromCloudSecgroup(ctx, userCred, provider, ext)
if err != nil {
result.AddError(errors.Wrapf(err, "newFromCloudSecurityGroupRule"))
continue
return errors.Wrapf(err, "newFromCloudSecgroup")
}
if isNeedFix && rule != nil {
rules = append(rules, *rule)
notes := map[string]interface{}{
"old secgroup_id": cache.SecgroupId,
"old in allow rules": inAllow.String(),
"new in allow rules": extInAllow.String(),
"ext in rules": extInRules,
"old out allow rules": outAllow.String(),
"new out allow rules": extOutAllow.String(),
"ext out rules:": extOutRules,
}
result.Add()
logclient.AddSimpleActionLog(secgroup, logclient.ACT_SYNC_CONF, notes, userCred, true)
_, err = db.Update(cache, func() error {
cache.SecgroupId = secgroup.Id
return nil
})
return err
}
return nil
}
log.Infof("Sync Rules for Secgroup %s(%s) result: %s", self.Name, self.Id, result.Result())
return rules, result
err = self.clearRules()
if err != nil {
return errors.Wrapf(err, "clearRules")
}
self.syncRules(ctx, extInRules)
self.syncRules(ctx, extOutRules)
notes := map[string]interface{}{
"old in allow rules": inAllow.String(),
"new in allow rules": extInAllow.String(),
"old out allow rules": outAllow.String(),
"new out allow rules": extOutAllow.String(),
"old rules": dbRules,
"new rules": extRules,
}
logclient.AddSimpleActionLog(self, logclient.ACT_SYNC_CONF, notes, userCred, true)
return nil
}
func (manager *SSecurityGroupManager) newFromCloudSecgroup(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, extSec cloudprovider.ICloudSecurityGroup) (*SSecurityGroup, []SSecurityGroupRule, error) {
dest := cloudprovider.NewSecRuleInfo(GetRegionDriver(provider.Provider))
var err error
dest.Rules, err = extSec.GetRules()
if err != nil {
return nil, nil, errors.Wrapf(err, "extSec.GetRules")
func (self *SSecurityGroup) syncRules(ctx context.Context, rules secrules.SecurityRuleSet) error {
errs := []error{}
priority := 100
var action secrules.TSecurityRuleAction
for i := 0; i < len(rules); i++ {
if len(action) == 0 {
action = rules[i].Action
}
if action != rules[i].Action && priority > 1 {
action = rules[i].Action
priority--
}
lockman.LockObject(ctx, self)
defer lockman.ReleaseObject(ctx, self)
dbRule := &SSecurityGroupRule{}
dbRule.SetModelManager(SecurityGroupRuleManager, dbRule)
dbRule.Direction = string(rules[i].Direction)
dbRule.Protocol = rules[i].Protocol
dbRule.Priority = int64(priority)
dbRule.Ports = rules[i].GetPortsString()
dbRule.CIDR = "0.0.0.0/0"
if rules[i].IPNet != nil && rules[i].IPNet.String() != "<nil>" {
dbRule.CIDR = rules[i].IPNet.String()
}
dbRule.Action = string(rules[i].Action)
dbRule.SecgroupId = self.Id
dbRule.Description = rules[i].Description
err := SecurityGroupRuleManager.TableSpec().Insert(ctx, dbRule)
if err != nil {
errs = append(errs, errors.Wrapf(err, "insert"))
}
}
src := cloudprovider.NewSecRuleInfo(GetRegionDriver(api.CLOUD_PROVIDER_ONECLOUD))
return errors.NewAggregate(errs)
}
func (manager *SSecurityGroupManager) newFromCloudSecgroup(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, extSec cloudprovider.ICloudSecurityGroup) (*SSecurityGroup, error) {
_, extInRules, extOutRules, err := cloudprovider.GetSecurityGroupRules(extSec)
if err != nil {
return nil, errors.Wrapf(err, "GetSecurityGroupRules")
}
extInAllow := extInRules.AllowList()
extOutAllow := extOutRules.AllowList()
if options.Options.EnableAutoMergeSecurityGroup {
// 查询与provider在同域的安全组,比对寻找一个与云上安全组规则相同的安全组
@@ -1134,17 +1147,18 @@ func (manager *SSecurityGroupManager) newFromCloudSecgroup(ctx context.Context,
q := manager.Query().Equals("domain_id", provider.DomainId)
err = db.FetchModelObjects(manager, q, &secgroups)
if err != nil {
return nil, nil, errors.Wrap(err, "db.FetchModelObjects")
return nil, errors.Wrap(err, "db.FetchModelObjects")
}
for i := range secgroups {
src.Rules, err = secgroups[i].GetSecuritRuleSet()
_, in, out, err := secgroups[i].GetSecuritRuleSet()
if err != nil {
log.Warningf("GetSecuritRuleSet %s(%s) error: %v", secgroups[i].Name, secgroups[i].Id, err)
continue
}
_, inAdds, outAdds, inDels, outDels := cloudprovider.CompareRules(src, dest, false)
if len(inAdds) == 0 && len(outAdds) == 0 && len(inDels) == 0 && len(outDels) == 0 {
return &secgroups[i], nil, nil
inAllow := in.AllowList()
outAllow := out.AllowList()
if extInAllow.Equals(inAllow) && extOutAllow.Equals(outAllow) {
return &secgroups[i], nil
}
}
}
@@ -1173,17 +1187,18 @@ func (manager *SSecurityGroupManager) newFromCloudSecgroup(ctx context.Context,
return manager.TableSpec().Insert(ctx, &secgroup)
}()
if err != nil {
return nil, nil, errors.Wrapf(err, "Insert")
return nil, errors.Wrapf(err, "Insert")
}
rules, _ := secgroup.SyncSecurityGroupRules(ctx, userCred, dest)
secgroup.syncRules(ctx, extInRules)
secgroup.syncRules(ctx, extOutRules)
db.OpsLog.LogEvent(&secgroup, db.ACT_CREATE, secgroup.GetShortDesc(ctx), userCred)
notifyclient.EventNotify(ctx, userCred, notifyclient.SEventNotifyParam{
Obj: &secgroup,
Action: notifyclient.ActionSyncCreate,
})
return &secgroup, rules, nil
return &secgroup, nil
}
func (manager *SSecurityGroupManager) DelaySync(ctx context.Context, userCred mcclient.TokenCredential, idStr string) error {
@@ -1217,17 +1232,6 @@ func (manager *SSecurityGroupManager) DelaySync(ctx context.Context, userCred mc
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
}
@@ -1244,7 +1248,7 @@ func (self *SSecurityGroup) DoSync(ctx context.Context, userCred mcclient.TokenC
}
func (manager *SSecurityGroupManager) InitializeData() error {
_, err := manager.FetchById("default")
_, err := manager.FetchById(api.SECGROUP_DEFAULT_ID)
if err != nil && err != sql.ErrNoRows {
return errors.Wrapf(err, `manager.FetchById("default")`)
}
@@ -1280,9 +1284,7 @@ func (manager *SSecurityGroupManager) InitializeData() error {
}
}
guests := make([]SGuest, 0)
q := GuestManager.Query()
q = q.Filter(sqlchemy.OR(sqlchemy.IsEmpty(q.Field("secgrp_id")), sqlchemy.IsNull(q.Field("secgrp_id"))))
q := GuestManager.Query().Equals("hypervisor", api.HYPERVISOR_KVM).IsNullOrEmpty("secgrp_id")
err = db.FetchModelObjects(GuestManager, q, &guests)
if err != nil {
log.Errorf("fetch guests without secgroup fail %s", err)
@@ -1290,7 +1292,7 @@ func (manager *SSecurityGroupManager) InitializeData() error {
}
for i := 0; i < len(guests); i += 1 {
db.Update(&guests[i], func() error {
guests[i].SecgrpId = "default"
guests[i].SecgrpId = api.SECGROUP_DEFAULT_ID
return nil
})
}
@@ -1312,17 +1314,6 @@ func (manager *SSecurityGroupManager) InitializeData() error {
return nil
}
func (self *SSecurityGroup) GetSecurityGroupReferences() ([]SSecurityGroup, error) {
sq := SecurityGroupRuleManager.Query("secgroup_id").Equals("peer_secgroup_id", self.Id).Distinct().SubQuery()
q := SecurityGroupManager.Query().In("id", sq)
groups := []SSecurityGroup{}
err := db.FetchModelObjects(SecurityGroupManager, q, &groups)
if err != nil {
return nil, errors.Wrapf(err, "db.FetchModelObjects")
}
return groups, nil
}
func (sm *SSecurityGroupManager) query(manager db.IModelManager, field, label string, secIds []string) *sqlchemy.SSubQuery {
sq := manager.Query().SubQuery()
@@ -1386,19 +1377,19 @@ func (self *SSecurityGroup) ValidateDeleteCondition(ctx context.Context, info js
if self.Id == options.Options.DefaultAdminSecurityGroupId {
return httperrors.NewProtectedResourceError("not allow to delete default admin security group")
}
cnts, err := SecurityGroupManager.TotalCnt([]string{self.Id})
if err != nil {
return errors.Wrapf(err, "SecurityGroupManager.TotalCnt")
}
if cnt, ok := cnts[self.Id]; ok && cnt.TotalCnt > 0 {
return httperrors.NewNotEmptyError("the security group %s is in use cnt: %s", self.Id, jsonutils.Marshal(cnt).String())
}
references, err := self.GetSecurityGroupReferences()
if err != nil {
return httperrors.NewGeneralError(err)
}
if len(references) > 0 {
return httperrors.NewNotEmptyError("the other security group is in use")
if !gotypes.IsNil(info) {
cnt, _ := info.Int("total_cnt")
if cnt > 0 {
return httperrors.NewNotEmptyError("the security group %s is in use cnt: %d", self.Id, cnt)
}
} else {
cnts, err := SecurityGroupManager.TotalCnt([]string{self.Id})
if err != nil {
return errors.Wrapf(err, "SecurityGroupManager.TotalCnt")
}
if cnt, ok := cnts[self.Id]; ok && cnt.TotalCnt > 0 {
return httperrors.NewNotEmptyError("the security group %s is in use cnt: %s", self.Id, jsonutils.Marshal(cnt).String())
}
}
return self.SSharableVirtualResourceBase.ValidateDeleteCondition(ctx, nil)
}
@@ -1424,10 +1415,9 @@ func (self *SSecurityGroup) StartDeleteSecurityGroupTask(ctx context.Context, us
self.SetStatus(userCred, api.SECGROUP_STATUS_DELETING, "")
task, err := taskman.TaskManager.NewTask(ctx, "SecurityGroupDeleteTask", self, userCred, params, parentTaskId, "", nil)
if err != nil {
return err
return errors.Wrapf(err, "SecurityGroupDeleteTask")
}
task.ScheduleRun(nil)
return nil
return task.ScheduleRun(nil)
}
func (self *SSecurityGroup) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
@@ -1469,22 +1459,6 @@ func (sg *SSecurityGroup) GetUsages() []db.IUsage {
}
}
// 获取引用信息
func (self *SSecurityGroup) GetDetailsReferences(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) ([]cloudprovider.SecurityGroupReference, error) {
groups, err := self.GetSecurityGroupReferences()
if err != nil {
return nil, errors.Wrapf(err, "GetSecurityGroupReferences")
}
ret := []cloudprovider.SecurityGroupReference{}
for i := range groups {
ret = append(ret, cloudprovider.SecurityGroupReference{
Id: groups[i].Id,
Name: groups[i].Name,
})
}
return ret, nil
}
func (self *SSecurityGroup) PerformImportRules(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.SecgroupImportRulesInput) (jsonutils.JSONObject, error) {
for i := range input.Rules {
if input.Rules[i].Priority == nil {
+1
View File
@@ -170,6 +170,7 @@ type ComputeOptions struct {
common_options.DBOptions
EnableAutoMergeSecurityGroup bool `help:"Enable auto merge secgroup when sync security group from cloud, default False" default:"false"`
EnableAutoSplitSecurityGroup bool `help:"Enable auto split secgroup when sync security group with diffrent rules from cloud, default False" default:"true"`
DeleteSnapshotExpiredRelease bool `help:"Should the virtual machine be automatically deleted when the virtual machine expires?" default:"false"`
DeleteEipExpiredRelease bool `help:"Should the EIP be automatically deleted when the virtual machine expires?" default:"false"`
DeleteDisksExpiredRelease bool `help:"Should the Disks be automatically deleted when the virtual machine expires?" default:"false"`
-21
View File
@@ -26,7 +26,6 @@ import (
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/billing"
"yunion.io/x/pkg/util/regutils"
"yunion.io/x/pkg/util/secrules"
"yunion.io/x/pkg/utils"
billing_api "yunion.io/x/onecloud/pkg/apis/billing"
@@ -58,26 +57,6 @@ func (self *SAliyunRegionDriver) GenerateSecurityGroupName(name string) string {
return name
}
func (self *SAliyunRegionDriver) GetDefaultSecurityGroupInRule() cloudprovider.SecurityRule {
return cloudprovider.SecurityRule{SecurityRule: *secrules.MustParseSecurityRule("in:deny any")}
}
func (self *SAliyunRegionDriver) GetDefaultSecurityGroupOutRule() cloudprovider.SecurityRule {
return cloudprovider.SecurityRule{SecurityRule: *secrules.MustParseSecurityRule("out:allow any")}
}
func (self *SAliyunRegionDriver) GetSecurityGroupRuleMaxPriority() int {
return 1
}
func (self *SAliyunRegionDriver) GetSecurityGroupRuleMinPriority() int {
return 100
}
func (self *SAliyunRegionDriver) IsSupportPeerSecgroup() bool {
return true
}
func (self *SAliyunRegionDriver) GetProvider() string {
return api.CLOUD_PROVIDER_ALIYUN
}
-21
View File
@@ -25,7 +25,6 @@ import (
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/pinyinutils"
"yunion.io/x/pkg/util/secrules"
"yunion.io/x/pkg/utils"
api "yunion.io/x/onecloud/pkg/apis/compute"
@@ -55,26 +54,6 @@ func (self *SAwsRegionDriver) GenerateSecurityGroupName(name string) string {
return pinyinutils.Text2Pinyin(name)
}
func (self *SAwsRegionDriver) GetDefaultSecurityGroupInRule() cloudprovider.SecurityRule {
return cloudprovider.SecurityRule{SecurityRule: *secrules.MustParseSecurityRule("in:deny any")}
}
func (self *SAwsRegionDriver) GetDefaultSecurityGroupOutRule() cloudprovider.SecurityRule {
return cloudprovider.SecurityRule{SecurityRule: *secrules.MustParseSecurityRule("out:deny any")}
}
func (self *SAwsRegionDriver) GetSecurityGroupRuleMaxPriority() int {
return 0
}
func (self *SAwsRegionDriver) GetSecurityGroupRuleMinPriority() int {
return 0
}
func (self *SAwsRegionDriver) IsOnlySupportAllowRules() bool {
return true
}
func (self *SAwsRegionDriver) GetProvider() string {
return api.CLOUD_PROVIDER_AWS
}
-21
View File
@@ -20,7 +20,6 @@ import (
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/util/pinyinutils"
"yunion.io/x/pkg/util/secrules"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/validators"
@@ -50,26 +49,6 @@ func (self *SAzureRegionDriver) GenerateSecurityGroupName(name string) string {
return pinyinutils.Text2Pinyin(name)
}
func (self *SAzureRegionDriver) IsSupportClassicSecurityGroup() bool {
return true
}
func (self *SAzureRegionDriver) GetDefaultSecurityGroupInRule() cloudprovider.SecurityRule {
return cloudprovider.SecurityRule{SecurityRule: *secrules.MustParseSecurityRule("in:deny any")}
}
func (self *SAzureRegionDriver) GetDefaultSecurityGroupOutRule() cloudprovider.SecurityRule {
return cloudprovider.SecurityRule{SecurityRule: *secrules.MustParseSecurityRule("out:deny any")}
}
func (self *SAzureRegionDriver) GetSecurityGroupRuleMaxPriority() int {
return 100
}
func (self *SAzureRegionDriver) GetSecurityGroupRuleMinPriority() int {
return 4096
}
func (self *SAzureRegionDriver) ValidateCreateVpcData(ctx context.Context, userCred mcclient.TokenCredential, input api.VpcCreateInput) (api.VpcCreateInput, error) {
cidrV := validators.NewIPv4PrefixValidator("cidr_block")
if err := cidrV.Validate(jsonutils.Marshal(input).(*jsonutils.JSONDict)); err != nil {
+6 -39
View File
@@ -25,7 +25,6 @@ import (
"yunion.io/x/pkg/util/billing"
"yunion.io/x/pkg/util/pinyinutils"
"yunion.io/x/pkg/util/rbacscope"
"yunion.io/x/pkg/util/secrules"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
@@ -237,12 +236,8 @@ func (self *SBaseRegionDriver) GenerateSecurityGroupName(name string) string {
return pinyinutils.Text2Pinyin(name)
}
func (self *SBaseRegionDriver) RequestCacheSecurityGroup(ctx context.Context, userCred mcclient.TokenCredential, region *models.SCloudregion, vpc *models.SVpc, secgroup *models.SSecurityGroup, classic bool, remoteProjectId string, task taskman.ITask) error {
return fmt.Errorf("Not Implemented RequestCacheSecurityGroup")
}
func (self *SBaseRegionDriver) IsSupportClassicSecurityGroup() bool {
return false
func (self *SBaseRegionDriver) RequestCacheSecurityGroup(ctx context.Context, userCred mcclient.TokenCredential, region *models.SCloudregion, vpc *models.SVpc, secgroup *models.SSecurityGroup, remoteProjectId string, task taskman.ITask) error {
return errors.Wrapf(cloudprovider.ErrNotImplemented, "RequestCacheSecurityGroup")
}
func (self *SBaseRegionDriver) IsSecurityGroupBelongVpc() bool {
@@ -265,40 +260,12 @@ func (self *SBaseRegionDriver) GetSecurityGroupPublicScope(service string) rbacs
return rbacscope.ScopeSystem
}
func (self *SBaseRegionDriver) GetSecurityGroupVpcId(ctx context.Context, userCred mcclient.TokenCredential, region *models.SCloudregion, host *models.SHost, vpc *models.SVpc, classic bool) (string, error) {
return "", cloudprovider.ErrNotImplemented
func (self *SBaseRegionDriver) GetSecurityGroupVpcId(ctx context.Context, userCred mcclient.TokenCredential, region *models.SCloudregion, host *models.SHost, vpc *models.SVpc) (string, error) {
return "", errors.Wrapf(cloudprovider.ErrNotImplemented, "GetSecurityGroupVpcId")
}
func (self *SBaseRegionDriver) RequestSyncSecurityGroup(ctx context.Context, userCred mcclient.TokenCredential, vpcId string, vpc *models.SVpc, secgroup *models.SSecurityGroup, removeProjectId, service string, skipSyncRule bool) (string, error) {
return "", fmt.Errorf("Not Implemented RequestSyncSecurityGroup")
}
func (self *SBaseRegionDriver) IsOnlySupportAllowRules() bool {
return false
}
func (self *SBaseRegionDriver) IsSupportPeerSecgroup() bool {
return false
}
func (self *SBaseRegionDriver) IsPeerSecgroupWithSameProject() bool {
return false
}
func (self *SBaseRegionDriver) GetDefaultSecurityGroupInRule() cloudprovider.SecurityRule {
return cloudprovider.SecurityRule{SecurityRule: *secrules.MustParseSecurityRule("in:deny any")}
}
func (self *SBaseRegionDriver) GetDefaultSecurityGroupOutRule() cloudprovider.SecurityRule {
return cloudprovider.SecurityRule{SecurityRule: *secrules.MustParseSecurityRule("out:allow any")}
}
func (self *SBaseRegionDriver) GetSecurityGroupRuleMaxPriority() int {
return 100
}
func (self *SBaseRegionDriver) GetSecurityGroupRuleMinPriority() int {
return 1
func (self *SBaseRegionDriver) RequestSyncSecurityGroup(ctx context.Context, userCred mcclient.TokenCredential, vpcId string, vpc *models.SVpc, secgroup *models.SSecurityGroup, removeProjectId, service string) (string, error) {
return "", errors.Wrapf(cloudprovider.ErrNotImplemented, "RequestSyncSecurityGroup")
}
func (self *SBaseRegionDriver) ValidateCreateDBInstanceData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, input api.DBInstanceCreateInput, skus []models.SDBInstanceSku, network *models.SNetwork) (api.DBInstanceCreateInput, error) {
-11
View File
@@ -18,9 +18,6 @@ import (
"context"
"strings"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/pkg/util/secrules"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/mcclient"
@@ -54,14 +51,6 @@ func (self *SBingoCloudRegionDriver) IsSecurityGroupBelongVpc() bool {
return false
}
func (self *SBingoCloudRegionDriver) GetDefaultSecurityGroupInRule() cloudprovider.SecurityRule {
return cloudprovider.SecurityRule{SecurityRule: *secrules.MustParseSecurityRule("in:allow any")}
}
func (self *SBingoCloudRegionDriver) GetDefaultSecurityGroupOutRule() cloudprovider.SecurityRule {
return cloudprovider.SecurityRule{SecurityRule: *secrules.MustParseSecurityRule("out:allow any")}
}
func (self *SBingoCloudRegionDriver) ValidateCreateSnapshotData(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, storage *models.SStorage, input *api.SnapshotCreateInput) error {
return nil
}
-4
View File
@@ -46,10 +46,6 @@ func (self *SCloudpodsRegionDriver) GenerateSecurityGroupName(name string) strin
return name
}
func (self *SCloudpodsRegionDriver) IsSupportPeerSecgroup() bool {
return false
}
func (self *SCloudpodsRegionDriver) ValidateCreateVpcData(ctx context.Context, userCred mcclient.TokenCredential, input api.VpcCreateInput) (api.VpcCreateInput, error) {
if !utils.IsInStringArray(input.CidrBlock, []string{"192.168.0.0/16", "10.0.0.0/8", "172.16.0.0/12"}) {
return input, httperrors.NewInputParameterError("Invalid cidr_block, want 192.168.0.0/16|10.0.0.0/8|172.16.0.0/12, got %s", input.CidrBlock)
-22
View File
@@ -18,9 +18,7 @@ import (
"context"
"strings"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/util/secrules"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/validators"
@@ -49,26 +47,6 @@ func (self *SCtyunRegionDriver) GenerateSecurityGroupName(name string) string {
return name
}
func (self *SCtyunRegionDriver) GetDefaultSecurityGroupInRule() cloudprovider.SecurityRule {
return cloudprovider.SecurityRule{SecurityRule: *secrules.MustParseSecurityRule("in:deny any")}
}
func (self *SCtyunRegionDriver) GetDefaultSecurityGroupOutRule() cloudprovider.SecurityRule {
return cloudprovider.SecurityRule{SecurityRule: *secrules.MustParseSecurityRule("out:deny any")}
}
func (self *SCtyunRegionDriver) GetSecurityGroupRuleMaxPriority() int {
return 0
}
func (self *SCtyunRegionDriver) GetSecurityGroupRuleMinPriority() int {
return 0
}
func (self *SCtyunRegionDriver) IsOnlySupportAllowRules() bool {
return true
}
func (self *SCtyunRegionDriver) GetProvider() string {
return api.CLOUD_PROVIDER_CTYUN
}
-21
View File
@@ -23,7 +23,6 @@ import (
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/billing"
"yunion.io/x/pkg/util/secrules"
"yunion.io/x/pkg/utils"
api "yunion.io/x/onecloud/pkg/apis/compute"
@@ -55,26 +54,6 @@ func (self *SHuaWeiRegionDriver) GenerateSecurityGroupName(name string) string {
return name
}
func (self *SHuaWeiRegionDriver) GetDefaultSecurityGroupInRule() cloudprovider.SecurityRule {
return cloudprovider.SecurityRule{SecurityRule: *secrules.MustParseSecurityRule("in:deny any")}
}
func (self *SHuaWeiRegionDriver) GetDefaultSecurityGroupOutRule() cloudprovider.SecurityRule {
return cloudprovider.SecurityRule{SecurityRule: *secrules.MustParseSecurityRule("out:allow any")}
}
func (self *SHuaWeiRegionDriver) GetSecurityGroupRuleMaxPriority() int {
return 0
}
func (self *SHuaWeiRegionDriver) GetSecurityGroupRuleMinPriority() int {
return 0
}
func (self *SHuaWeiRegionDriver) IsOnlySupportAllowRules() bool {
return true
}
func (self *SHuaWeiRegionDriver) GetProvider() string {
return api.CLOUD_PROVIDER_HUAWEI
}
-16
View File
@@ -15,9 +15,6 @@
package regiondrivers
import (
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/pkg/util/secrules"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/compute/models"
)
@@ -40,19 +37,6 @@ func (self *SJDcloudRegionDriver) IsCertificateBelongToRegion() bool {
return false
}
// https://docs.jdcloud.com/cn/virtual-private-cloud/api/modifynetworksecuritygrouprules
func (self *SJDcloudRegionDriver) IsOnlySupportAllowRules() bool {
return true
}
func (self *SJDcloudRegionDriver) IsSecurityGroupBelongVpc() bool {
return true
}
func (self *SJDcloudRegionDriver) GetDefaultSecurityGroupInRule() cloudprovider.SecurityRule {
return cloudprovider.SecurityRule{SecurityRule: *secrules.MustParseSecurityRule("in:deny any")}
}
func (self *SJDcloudRegionDriver) GetDefaultSecurityGroupOutRule() cloudprovider.SecurityRule {
return cloudprovider.SecurityRule{SecurityRule: *secrules.MustParseSecurityRule("out:allow any")}
}
-4
View File
@@ -69,10 +69,6 @@ func (self *SKVMRegionDriver) GetProvider() string {
return api.CLOUD_PROVIDER_ONECLOUD
}
func (self *SKVMRegionDriver) IsSupportPeerSecgroup() bool {
return true
}
func (self *SKVMRegionDriver) IsAllowSecurityGroupNameRepeat() bool {
return false
}
+16 -22
View File
@@ -1260,24 +1260,22 @@ func (self *SManagedVirtualizationRegionDriver) RequestPreSnapshotPolicyApply(ct
return nil
}
func (self *SManagedVirtualizationRegionDriver) GetSecurityGroupVpcId(ctx context.Context, userCred mcclient.TokenCredential, region *models.SCloudregion, host *models.SHost, vpc *models.SVpc, classic bool) (string, error) {
func (self *SManagedVirtualizationRegionDriver) GetSecurityGroupVpcId(ctx context.Context, userCred mcclient.TokenCredential, region *models.SCloudregion, host *models.SHost, vpc *models.SVpc) (string, error) {
if region.GetDriver().IsSecurityGroupBelongGlobalVpc() {
gvpc, err := vpc.GetGlobalVpc()
if err != nil {
return "", err
}
return gvpc.ExternalId, nil
} else if region.GetDriver().IsSupportClassicSecurityGroup() && (classic || (host != nil && strings.HasSuffix(host.Name, "-classic"))) {
return "classic", nil
} else if region.GetDriver().IsSecurityGroupBelongVpc() {
return vpc.ExternalId, nil
}
return region.GetDriver().GetDefaultSecurityGroupVpcId(), nil
}
func (self *SManagedVirtualizationRegionDriver) RequestSyncSecurityGroup(ctx context.Context, userCred mcclient.TokenCredential, vpcId string, vpc *models.SVpc, secgroup *models.SSecurityGroup, remoteProjectId, service string, skipSyncRule bool) (string, error) {
lockman.LockRawObject(ctx, "secgroupcache", fmt.Sprintf("%s-%s-%s", secgroup.Id, vpcId, vpc.ManagerId))
defer lockman.ReleaseRawObject(ctx, "secgroupcache", fmt.Sprintf("%s-%s-%s", secgroup.Id, vpcId, vpc.ManagerId))
func (self *SManagedVirtualizationRegionDriver) RequestSyncSecurityGroup(ctx context.Context, userCred mcclient.TokenCredential, vpcId string, vpc *models.SVpc, secgroup *models.SSecurityGroup, remoteProjectId, service string) (string, error) {
lockman.LockRawObject(ctx, models.SecurityGroupCacheManager.Keyword(), fmt.Sprintf("%s-%s-%s", secgroup.Id, vpcId, vpc.ManagerId))
defer lockman.ReleaseRawObject(ctx, models.SecurityGroupCacheManager.Keyword(), fmt.Sprintf("%s-%s-%s", secgroup.Id, vpcId, vpc.ManagerId))
region, err := vpc.GetRegion()
if err != nil {
@@ -1293,25 +1291,21 @@ func (self *SManagedVirtualizationRegionDriver) RequestSyncSecurityGroup(ctx con
return "", errors.Wrap(err, "SSecurityGroupCache.Register")
}
_, isNew, err := cache.GetOrCreateISecurityGroup(ctx)
_, err = cache.GetOrCreateISecurityGroup(ctx)
if err != nil {
return "", errors.Wrapf(err, "GetOrCreateISecurityGroup")
}
if isNew {
skipSyncRule = false
}
return cache.ExternalId, cache.SyncRules(ctx, skipSyncRule)
return cache.ExternalId, nil
}
func (self *SManagedVirtualizationRegionDriver) RequestCacheSecurityGroup(ctx context.Context, userCred mcclient.TokenCredential, region *models.SCloudregion, vpc *models.SVpc, secgroup *models.SSecurityGroup, classic bool, removeProjectId string, task taskman.ITask) error {
vpcId, err := region.GetDriver().GetSecurityGroupVpcId(ctx, userCred, region, nil, vpc, classic)
func (self *SManagedVirtualizationRegionDriver) RequestCacheSecurityGroup(ctx context.Context, userCred mcclient.TokenCredential, region *models.SCloudregion, vpc *models.SVpc, secgroup *models.SSecurityGroup, removeProjectId string, task taskman.ITask) error {
vpcId, err := region.GetDriver().GetSecurityGroupVpcId(ctx, userCred, region, nil, vpc)
if err != nil {
return errors.Wrap(err, "GetSecurityGroupVpcId")
}
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
_, err := self.RequestSyncSecurityGroup(ctx, userCred, vpcId, vpc, secgroup, removeProjectId, "", false)
_, err := self.RequestSyncSecurityGroup(ctx, userCred, vpcId, vpc, secgroup, removeProjectId, "")
return nil, err
})
return nil
@@ -1385,11 +1379,11 @@ func (self *SManagedVirtualizationRegionDriver) RequestCreateDBInstance(ctx cont
return nil, errors.Wrapf(err, "GetSecgroups")
}
for i := range secgroups {
vpcId, err := region.GetDriver().GetSecurityGroupVpcId(ctx, userCred, region, nil, vpc, false)
vpcId, err := region.GetDriver().GetSecurityGroupVpcId(ctx, userCred, region, nil, vpc)
if err != nil {
return nil, errors.Wrap(err, "GetSecurityGroupVpcId")
}
secId, err := region.GetDriver().RequestSyncSecurityGroup(ctx, userCred, vpcId, vpc, &secgroups[i], desc.ProjectId, "", true)
secId, err := region.GetDriver().RequestSyncSecurityGroup(ctx, userCred, vpcId, vpc, &secgroups[i], desc.ProjectId, "")
if err != nil {
return nil, errors.Wrap(err, "SyncSecurityGroup")
}
@@ -1547,11 +1541,11 @@ func (self *SManagedVirtualizationRegionDriver) RequestCreateDBInstanceFromBacku
return nil, errors.Wrapf(err, "GetSecgroups")
}
for i := range secgroups {
vpcId, err := region.GetDriver().GetSecurityGroupVpcId(ctx, userCred, region, nil, vpc, false)
vpcId, err := region.GetDriver().GetSecurityGroupVpcId(ctx, userCred, region, nil, vpc)
if err != nil {
return nil, errors.Wrap(err, "GetSecurityGroupVpcId")
}
secId, err := region.GetDriver().RequestSyncSecurityGroup(ctx, userCred, vpcId, vpc, &secgroups[i], desc.ProjectId, "", true)
secId, err := region.GetDriver().RequestSyncSecurityGroup(ctx, userCred, vpcId, vpc, &secgroups[i], desc.ProjectId, "")
if err != nil {
return nil, errors.Wrap(err, "SyncSecurityGroup")
}
@@ -2895,13 +2889,13 @@ func (self *SManagedVirtualizationRegionDriver) RequestSyncSecgroupsForElasticca
if err != nil {
return nil, errors.Wrapf(err, "GetRegion")
}
vpcId, err := self.GetSecurityGroupVpcId(ctx, userCred, region, nil, vpc, false)
vpcId, err := self.GetSecurityGroupVpcId(ctx, userCred, region, nil, vpc)
if err != nil {
return nil, errors.Wrap(err, "GetSecurityGroupVpcId")
}
for i := range ess {
externalId, err := self.RequestSyncSecurityGroup(ctx, task.GetUserCred(), vpcId, vpc, ess[i].GetSecGroup(), "", "redis", true)
externalId, err := self.RequestSyncSecurityGroup(ctx, task.GetUserCred(), vpcId, vpc, ess[i].GetSecGroup(), "", "redis")
if err != nil {
return nil, errors.Wrap(err, "RequestSyncSecurityGroup")
}
@@ -3013,7 +3007,7 @@ func (self *SManagedVirtualizationRegionDriver) RequestSyncRdsSecurityGroups(ctx
}
secgroupIds := []string{}
for i := range secgroups {
secgroupId, err := self.RequestSyncSecurityGroup(ctx, userCred, vpc.ExternalId, vpc, &secgroups[i], iRds.GetProjectId(), "rds", true)
secgroupId, err := self.RequestSyncSecurityGroup(ctx, userCred, vpc.ExternalId, vpc, &secgroups[i], iRds.GetProjectId(), "rds")
if err != nil {
return nil, errors.Wrapf(err, "RequestSyncSecurityGroup")
}
-21
View File
@@ -22,7 +22,6 @@ import (
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/util/rbacscope"
"yunion.io/x/pkg/util/secrules"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
@@ -51,26 +50,6 @@ func (self *SOpenStackRegionDriver) GenerateSecurityGroupName(name string) strin
return name
}
func (self *SOpenStackRegionDriver) GetDefaultSecurityGroupInRule() cloudprovider.SecurityRule {
return cloudprovider.SecurityRule{SecurityRule: *secrules.MustParseSecurityRule("in:deny any")}
}
func (self *SOpenStackRegionDriver) GetDefaultSecurityGroupOutRule() cloudprovider.SecurityRule {
return cloudprovider.SecurityRule{SecurityRule: *secrules.MustParseSecurityRule("out:deny any")}
}
func (self *SOpenStackRegionDriver) GetSecurityGroupRuleMaxPriority() int {
return 0
}
func (self *SOpenStackRegionDriver) GetSecurityGroupRuleMinPriority() int {
return 0
}
func (self *SOpenStackRegionDriver) IsOnlySupportAllowRules() bool {
return true
}
func (self *SOpenStackRegionDriver) GetSecurityGroupPublicScope(service string) rbacscope.TRbacScope {
return rbacscope.ScopeProject
}
-25
View File
@@ -24,7 +24,6 @@ import (
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/billing"
"yunion.io/x/pkg/util/rbacscope"
"yunion.io/x/pkg/util/secrules"
"yunion.io/x/pkg/utils"
api "yunion.io/x/onecloud/pkg/apis/compute"
@@ -55,30 +54,6 @@ func (self *SQcloudRegionDriver) GenerateSecurityGroupName(name string) string {
return name
}
func (self *SQcloudRegionDriver) GetDefaultSecurityGroupInRule() cloudprovider.SecurityRule {
return cloudprovider.SecurityRule{SecurityRule: *secrules.MustParseSecurityRule("in:deny any")}
}
func (self *SQcloudRegionDriver) GetDefaultSecurityGroupOutRule() cloudprovider.SecurityRule {
return cloudprovider.SecurityRule{SecurityRule: *secrules.MustParseSecurityRule("out:deny any")}
}
func (self *SQcloudRegionDriver) GetSecurityGroupRuleMaxPriority() int {
return 0
}
func (self *SQcloudRegionDriver) GetSecurityGroupRuleMinPriority() int {
return 100
}
func (self *SQcloudRegionDriver) IsSupportPeerSecgroup() bool {
return true
}
func (self *SQcloudRegionDriver) IsPeerSecgroupWithSameProject() bool {
return true
}
func (self *SQcloudRegionDriver) GetProvider() string {
return api.CLOUD_PROVIDER_QCLOUD
}
@@ -1,72 +0,0 @@
// 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 regiondrivers
import (
"testing"
"yunion.io/x/cloudmux/pkg/cloudprovider"
)
func TestAliyunRuleSync(t *testing.T) {
data := []TestData{
{
Name: "Test out rules",
SrcRules: cloudprovider.SecurityRuleSet{
ruleWithPriority("in:allow tcp 1212", 52),
ruleWithPriority("in:allow tcp 22", 51),
ruleWithPriority("in:allow tcp 3389", 50),
ruleWithPriority("in:allow udp 1231", 49),
ruleWithPriority("in:deny tcp 443", 48),
},
DestRules: []cloudprovider.SecurityRule{
ruleWithName("", "in:deny tcp 443", 1),
ruleWithName("", "in:allow udp 1231", 1),
ruleWithName("", "in:allow tcp 3389", 100),
ruleWithName("", "in:allow tcp 22", 100),
ruleWithName("", "in:allow tcp 1212", 100),
},
Common: []cloudprovider.SecurityRule{
ruleWithName("", "in:deny tcp 443", 1),
ruleWithName("", "in:allow udp 1231", 1),
ruleWithName("", "in:allow tcp 3389", 100),
ruleWithName("", "in:allow tcp 22", 100),
ruleWithName("", "in:allow tcp 1212", 100),
},
InAdds: []cloudprovider.SecurityRule{},
OutAdds: []cloudprovider.SecurityRule{},
InDels: []cloudprovider.SecurityRule{},
OutDels: []cloudprovider.SecurityRule{},
},
{
Name: "Test tcp rules",
SrcRules: cloudprovider.SecurityRuleSet{
ruleWithPriority("out:deny tcp 443", 48),
},
DestRules: []cloudprovider.SecurityRule{},
Common: []cloudprovider.SecurityRule{},
InAdds: []cloudprovider.SecurityRule{},
OutAdds: []cloudprovider.SecurityRule{
ruleWithName("", "out:deny tcp 443", 99),
},
InDels: []cloudprovider.SecurityRule{},
OutDels: []cloudprovider.SecurityRule{},
},
}
for _, d := range data {
d.Test(t, &SKVMRegionDriver{}, &SAliyunRegionDriver{})
}
}
@@ -1,70 +0,0 @@
// 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 regiondrivers
import (
"testing"
"yunion.io/x/cloudmux/pkg/cloudprovider"
)
func TestAwsRuleSync(t *testing.T) {
data := []TestData{
{
Name: "Test remove out allow rules",
SrcRules: cloudprovider.SecurityRuleSet{
ruleWithPriority("out:deny any", 1),
},
DestRules: []cloudprovider.SecurityRule{
ruleWithName("test-allow any", "out:allow any", 1),
},
Common: []cloudprovider.SecurityRule{},
InAdds: []cloudprovider.SecurityRule{},
OutAdds: []cloudprovider.SecurityRule{},
InDels: []cloudprovider.SecurityRule{},
OutDels: []cloudprovider.SecurityRule{
ruleWithName("test-allow any", "out:allow any", 1),
},
},
{
Name: "Test out deny rules",
SrcRules: cloudprovider.SecurityRuleSet{
ruleWithPriority("out:deny any", 1),
},
DestRules: []cloudprovider.SecurityRule{},
Common: []cloudprovider.SecurityRule{},
InAdds: []cloudprovider.SecurityRule{},
OutAdds: []cloudprovider.SecurityRule{},
InDels: []cloudprovider.SecurityRule{},
OutDels: []cloudprovider.SecurityRule{},
},
{
Name: "Test out allow rules",
SrcRules: cloudprovider.SecurityRuleSet{},
DestRules: []cloudprovider.SecurityRule{},
Common: []cloudprovider.SecurityRule{},
InAdds: []cloudprovider.SecurityRule{},
OutAdds: []cloudprovider.SecurityRule{
ruleWithName("", "out:allow any", 0),
},
InDels: []cloudprovider.SecurityRule{},
OutDels: []cloudprovider.SecurityRule{},
},
}
for _, d := range data {
d.Test(t, &SKVMRegionDriver{}, &SAwsRegionDriver{})
}
}
@@ -1,236 +0,0 @@
// 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 regiondrivers
import (
"testing"
"yunion.io/x/cloudmux/pkg/cloudprovider"
)
func TestAzureRuleSync(t *testing.T) {
data := []TestData{
{
Name: "Test empty rules",
SrcRules: cloudprovider.SecurityRuleSet{},
DestRules: []cloudprovider.SecurityRule{},
Common: []cloudprovider.SecurityRule{},
InAdds: []cloudprovider.SecurityRule{},
OutAdds: []cloudprovider.SecurityRule{
ruleWithName("", "out:allow any", 4096),
},
InDels: []cloudprovider.SecurityRule{},
OutDels: []cloudprovider.SecurityRule{},
},
{
Name: "Test diff rules",
SrcRules: cloudprovider.SecurityRuleSet{
ruleWithPriority("out:allow tcp 100-200", 99),
ruleWithPriority("out:allow udp 200-300", 98),
},
DestRules: []cloudprovider.SecurityRule{
ruleWithName("test-tcp", "out:allow tcp 100-200", 1000),
ruleWithName("test-udp", "out:allow udp 200-300", 1002),
},
Common: []cloudprovider.SecurityRule{},
InAdds: []cloudprovider.SecurityRule{},
OutAdds: []cloudprovider.SecurityRule{
ruleWithName("", "out:allow tcp 100-200", 4094),
ruleWithName("", "out:allow udp 200-300", 4095),
ruleWithName("", "out:allow any", 4096),
},
InDels: []cloudprovider.SecurityRule{},
OutDels: []cloudprovider.SecurityRule{
ruleWithName("test-tcp", "out:allow tcp 100-200", 1000),
ruleWithName("test-udp", "out:allow udp 200-300", 1002),
},
},
{
Name: "Test add rules",
SrcRules: cloudprovider.SecurityRuleSet{
ruleWithPriority("in:allow tcp", 100),
ruleWithPriority("in:allow udp", 99),
ruleWithPriority("out:deny any", 1),
},
DestRules: []cloudprovider.SecurityRule{
ruleWithName("allow-ssh", "in:allow tcp 22", 300),
},
Common: []cloudprovider.SecurityRule{},
InAdds: []cloudprovider.SecurityRule{
ruleWithName("", "in:allow tcp", 4094),
ruleWithName("", "in:allow udp", 4095),
},
OutAdds: []cloudprovider.SecurityRule{},
InDels: []cloudprovider.SecurityRule{
ruleWithName("allow-ssh", "in:allow tcp 22", 300),
},
OutDels: []cloudprovider.SecurityRule{},
},
{
Name: "Test insert rules",
SrcRules: cloudprovider.SecurityRuleSet{
ruleWithPriority("in:allow tcp", 100),
ruleWithPriority("in:allow udp", 99),
ruleWithPriority("in:allow icmp", 98),
ruleWithPriority("out:deny any", 1),
},
DestRules: []cloudprovider.SecurityRule{
ruleWithName("allow-tcp", "in:allow tcp", 300),
ruleWithName("allow-icmp", "in:allow icmp", 400),
},
Common: []cloudprovider.SecurityRule{
ruleWithName("allow-icmp", "in:allow icmp", 400),
},
InAdds: []cloudprovider.SecurityRule{
ruleWithName("", "in:allow tcp", 398),
ruleWithName("", "in:allow udp", 399),
},
OutAdds: []cloudprovider.SecurityRule{},
InDels: []cloudprovider.SecurityRule{
ruleWithName("allow-tcp", "in:allow tcp", 300),
},
OutDels: []cloudprovider.SecurityRule{},
},
{
Name: "Test icmp rules",
SrcRules: cloudprovider.SecurityRuleSet{
ruleWithPriority("in:allow tcp 33", 10),
ruleWithPriority("in:allow tcp 22", 1),
ruleWithPriority("out:deny any", 1),
},
DestRules: []cloudprovider.SecurityRule{
ruleWithName("allow-tcp-22", "in:allow tcp 22", 300),
},
Common: []cloudprovider.SecurityRule{
ruleWithName("allow-tcp-22", "in:allow tcp 22", 300),
},
InAdds: []cloudprovider.SecurityRule{
ruleWithName("", "in:allow tcp 33", 299),
},
OutAdds: []cloudprovider.SecurityRule{},
InDels: []cloudprovider.SecurityRule{},
OutDels: []cloudprovider.SecurityRule{},
},
{
Name: "Test a rules",
SrcRules: cloudprovider.SecurityRuleSet{
ruleWithPriority("in:allow tcp 1050", 5),
ruleWithPriority("in:allow tcp 1011", 4),
ruleWithPriority("in:allow tcp 1002", 3),
ruleWithPriority("in:allow tcp 22", 2),
ruleWithPriority("in:allow udp 55", 1),
ruleWithPriority("out:deny any", 1),
},
DestRules: []cloudprovider.SecurityRule{
ruleWithName("in_allow_udp_55_4014", "in:allow udp 55", 4014),
ruleWithName("in_allow_tcp_22_4013", "in:allow tcp 22", 4013),
ruleWithName("in_allow_tcp_1002_4012", "in:allow tcp 1002", 4012),
ruleWithName("in_allow_tcp_1010_4011", "in:allow tcp 1010", 4011),
ruleWithName("in_allow_tcp_1050_4010", "in:allow tcp 1050", 4010),
},
Common: []cloudprovider.SecurityRule{
ruleWithName("in_allow_tcp_22_4013", "in:allow tcp 22", 4013),
ruleWithName("in_allow_udp_55_4014", "in:allow udp 55", 4014),
ruleWithName("in_allow_tcp_1002_4012", "in:allow tcp 1002", 4012),
ruleWithName("in_allow_tcp_1050_4010", "in:allow tcp 1050", 4010),
},
InAdds: []cloudprovider.SecurityRule{
ruleWithName("", "in:allow tcp 1011", 4011),
},
OutAdds: []cloudprovider.SecurityRule{},
InDels: []cloudprovider.SecurityRule{
ruleWithName("in_allow_tcp_1010_4011", "in:allow tcp 1010", 4011),
},
OutDels: []cloudprovider.SecurityRule{},
},
{
Name: "Test b rules",
SrcRules: cloudprovider.SecurityRuleSet{
ruleWithPriority("in:allow udp 1055", 20),
ruleWithPriority("in:allow icmp", 15),
ruleWithPriority("in:allow tcp 1050", 5),
ruleWithPriority("in:allow tcp 1012", 4),
ruleWithPriority("in:allow tcp 1002", 3),
ruleWithPriority("in:allow tcp 22", 2),
ruleWithPriority("in:allow udp 55", 1),
ruleWithPriority("out:deny any", 1),
},
DestRules: []cloudprovider.SecurityRule{
ruleWithName("in_allow_udp_55_4014", "in:allow udp 55", 4014),
ruleWithName("in_allow_tcp_22_4013", "in:allow tcp 22", 4013),
ruleWithName("in_allow_tcp_1002_4012", "in:allow tcp 1002", 4012),
ruleWithName("in_allow_tcp_1012_4011", "in:allow tcp 1012", 4011),
ruleWithName("in_allow_tcp_1050_4010", "in:allow tcp 1050", 4010),
ruleWithName("in_allow_tcp_1055_4009", "in:allow tcp 1055", 4009),
},
Common: []cloudprovider.SecurityRule{
ruleWithName("in_allow_tcp_22_4013", "in:allow tcp 22", 4013),
ruleWithName("in_allow_udp_55_4014", "in:allow udp 55", 4014),
ruleWithName("in_allow_tcp_1002_4012", "in:allow tcp 1002", 4012),
ruleWithName("in_allow_tcp_1012_4011", "in:allow tcp 1012", 4011),
ruleWithName("in_allow_tcp_1050_4010", "in:allow tcp 1050", 4010),
},
InAdds: []cloudprovider.SecurityRule{
ruleWithName("", "in:allow icmp", 4009),
ruleWithName("", "in:allow udp 1055", 4008),
},
OutAdds: []cloudprovider.SecurityRule{},
InDels: []cloudprovider.SecurityRule{
ruleWithName("in_allow_tcp_1055_4009", "in:allow tcp 1055", 4009),
},
OutDels: []cloudprovider.SecurityRule{},
},
}
for _, d := range data {
d.Test(t, &SKVMRegionDriver{}, &SAzureRegionDriver{})
}
}
func TestAzureUniqPriorityRuleSync(t *testing.T) {
cases := []struct {
in cloudprovider.SecurityRuleSet
out cloudprovider.SecurityRuleSet
}{
{
in: cloudprovider.SecurityRuleSet{
ruleWithName("", "out:allow icmp", 99),
ruleWithName("", "out:allow tcp 100-200", 99),
ruleWithName("", "out:allow udp 200-300", 99),
},
out: cloudprovider.SecurityRuleSet{
ruleWithName("", "out:allow icmp", 99),
ruleWithName("", "out:allow tcp 100-200", 98),
ruleWithName("", "out:allow udp 200-300", 97),
},
},
}
for _, c := range cases {
rules := cloudprovider.SortUniqPriority(c.in)
if len(c.out) != len(rules) {
t.Fatalf("invalid output")
}
for i := range rules {
if rules[i].String() != c.out[i].String() {
t.Fatalf("rule shoud be %s not %s", c.out[i].String(), rules[i].String())
}
if rules[i].Priority != c.out[i].Priority {
t.Fatalf("rule %s priority should be %d not %d", rules[i].String(), c.out[i].Priority, rules[i].Priority)
}
}
}
}
@@ -1,48 +0,0 @@
// 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 regiondrivers
import (
"testing"
"yunion.io/x/cloudmux/pkg/cloudprovider"
)
func TestCtyunRuleSync(t *testing.T) {
data := []TestData{
{
Name: "Test out deny rules",
SrcRules: cloudprovider.SecurityRuleSet{
ruleWithPriority("out:deny tcp 200", 1),
},
DestRules: []cloudprovider.SecurityRule{},
Common: []cloudprovider.SecurityRule{},
InAdds: []cloudprovider.SecurityRule{},
OutAdds: []cloudprovider.SecurityRule{
ruleWithName("", "out:allow icmp", 0),
ruleWithName("", "out:allow tcp 1-199", 0),
ruleWithName("", "out:allow tcp 201-65535", 0),
ruleWithName("", "out:allow udp", 0),
},
InDels: []cloudprovider.SecurityRule{},
OutDels: []cloudprovider.SecurityRule{},
},
}
for _, d := range data {
d.Test(t, &SKVMRegionDriver{}, &SCtyunRegionDriver{})
}
}
@@ -1,106 +0,0 @@
// 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 regiondrivers
import (
"testing"
"yunion.io/x/cloudmux/pkg/cloudprovider"
)
func TestKvmRuleSync(t *testing.T) {
data := []TestData{
{
Name: "Test kvm deny rules",
SrcRules: cloudprovider.SecurityRuleSet{},
DestRules: []cloudprovider.SecurityRule{},
Common: []cloudprovider.SecurityRule{},
InAdds: []cloudprovider.SecurityRule{},
OutAdds: []cloudprovider.SecurityRule{
ruleWithName("", "out:deny any", 1),
},
InDels: []cloudprovider.SecurityRule{},
OutDels: []cloudprovider.SecurityRule{},
},
}
for _, d := range data {
d.Test(t, &SAzureRegionDriver{}, &SKVMRegionDriver{})
}
aliyun := []TestData{
{
Name: "Test aliyun rules",
SrcRules: cloudprovider.SecurityRuleSet{
ruleWithName("allow tcp 443", "in:allow tcp 443", 1),
ruleWithName("allow tcp 6379", "in:allow tcp 6379", 1),
ruleWithName("allow tcp 3389", "in:allow tcp 3389", 1),
ruleWithName("allow tcp 1521", "in:allow tcp 1521", 1),
ruleWithName("allow tcp 80", "in:allow tcp 80", 1),
ruleWithName("deny tcp 1521", "in:deny tcp 1521", 12),
},
DestRules: []cloudprovider.SecurityRule{
ruleWithName("allow tcp", "in:allow tcp", 51),
ruleWithName("allow tcp 1521", "in:allow tcp 1521", 50),
ruleWithName("allow tcp 3389", "in:allow tcp 3389", 50),
ruleWithName("allow tcp 443", "in:allow tcp 443", 50),
ruleWithName("allow tcp 6379", "in:allow tcp 6379", 50),
ruleWithName("allow tcp 80", "in:allow tcp 80", 50),
ruleWithName("allow tcp", "in:allow tcp", 1),
},
Common: []cloudprovider.SecurityRule{},
InAdds: []cloudprovider.SecurityRule{
ruleWithName("", "in:allow tcp 1521", 1),
ruleWithName("", "in:allow tcp 3389", 1),
ruleWithName("", "in:allow tcp 443", 1),
ruleWithName("", "in:allow tcp 6379", 1),
ruleWithName("", "in:allow tcp 80", 1),
},
OutAdds: []cloudprovider.SecurityRule{},
InDels: []cloudprovider.SecurityRule{
ruleWithName("allow tcp", "in:allow tcp", 51),
ruleWithName("allow tcp", "in:allow tcp", 1),
ruleWithName("allow tcp 1521", "in:allow tcp 1521", 50),
ruleWithName("allow tcp 3389", "in:allow tcp 3389", 50),
ruleWithName("allow tcp 443", "in:allow tcp 443", 50),
ruleWithName("allow tcp 6379", "in:allow tcp 6379", 50),
ruleWithName("allow tcp 80", "in:allow tcp 80", 50),
},
OutDels: []cloudprovider.SecurityRule{},
},
{
Name: "Test aliyun peer rules",
SrcRules: cloudprovider.SecurityRuleSet{
ruleWithPeerSecgroup("allow tcp 443", "in:allow tcp 443", 1, "peer1"),
ruleWithName("deny tcp 1521", "in:deny tcp 1521", 12),
},
DestRules: []cloudprovider.SecurityRule{},
Common: []cloudprovider.SecurityRule{},
InAdds: []cloudprovider.SecurityRule{
ruleWithPeerSecgroup("allow tcp 443", "in:allow tcp 443", 3, "peer1"),
ruleWithName("deny tcp 1521", "in:deny tcp 1521", 2),
},
OutAdds: []cloudprovider.SecurityRule{},
InDels: []cloudprovider.SecurityRule{},
OutDels: []cloudprovider.SecurityRule{},
},
}
for _, d := range aliyun {
d.Test(t, &SAliyunRegionDriver{}, &SKVMRegionDriver{})
}
}
@@ -1,71 +0,0 @@
// 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 regiondrivers
import (
"testing"
"yunion.io/x/cloudmux/pkg/cloudprovider"
)
func TestOpenStackRuleSync(t *testing.T) {
data := []TestData{
{
Name: "Test deny rules",
SrcRules: cloudprovider.SecurityRuleSet{
ruleWithPriority("in:deny any", 100),
ruleWithPriority("in:allow any", 99),
ruleWithPriority("out:allow any", 100),
},
DestRules: []cloudprovider.SecurityRule{
ruleWithName("", "in:allow any", 1),
},
Common: []cloudprovider.SecurityRule{},
InAdds: []cloudprovider.SecurityRule{},
OutAdds: []cloudprovider.SecurityRule{
ruleWithName("", "out:allow any", 0),
},
InDels: []cloudprovider.SecurityRule{
ruleWithName("", "in:allow any", 1),
},
OutDels: []cloudprovider.SecurityRule{},
},
{
Name: "Test deny rules 2",
SrcRules: cloudprovider.SecurityRuleSet{
ruleWithPriority("in:deny any", 100),
ruleWithPriority("in:allow any", 99),
ruleWithPriority("out:allow any", 100),
},
DestRules: []cloudprovider.SecurityRule{
ruleWithName("", "in:allow any", 0),
ruleWithName("", "out:allow any", 0),
},
Common: []cloudprovider.SecurityRule{
ruleWithName("", "out:allow any", 0),
},
InAdds: []cloudprovider.SecurityRule{},
OutAdds: []cloudprovider.SecurityRule{},
InDels: []cloudprovider.SecurityRule{
ruleWithName("", "in:allow any", 0),
},
OutDels: []cloudprovider.SecurityRule{},
},
}
for _, d := range data {
d.Test(t, &SKVMRegionDriver{}, &SOpenStackRegionDriver{})
}
}
@@ -1,152 +0,0 @@
// 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 regiondrivers
import (
"testing"
"yunion.io/x/cloudmux/pkg/cloudprovider"
)
func TestQcloudRuleSync(t *testing.T) {
data := []TestData{
{
Name: "Test out rules",
SrcRules: cloudprovider.SecurityRuleSet{
ruleWithPriority("out:deny any", 1),
ruleWithPriority("out:allow 10.160.240.0/20 any", 10),
},
DestRules: []cloudprovider.SecurityRule{},
Common: []cloudprovider.SecurityRule{},
InAdds: []cloudprovider.SecurityRule{},
OutAdds: []cloudprovider.SecurityRule{
ruleWithPriority("out:allow 10.160.240.0/20 any", 100),
},
InDels: []cloudprovider.SecurityRule{},
OutDels: []cloudprovider.SecurityRule{},
},
{
Name: "Test out rules",
SrcRules: cloudprovider.SecurityRuleSet{
ruleWithPriority("out:deny any", 1),
ruleWithPriority("out:allow 10.160.240.0/20 any", 10),
},
DestRules: []cloudprovider.SecurityRule{
ruleWithPriority("out:allow any", 2),
},
Common: []cloudprovider.SecurityRule{},
InAdds: []cloudprovider.SecurityRule{},
OutAdds: []cloudprovider.SecurityRule{
ruleWithPriority("out:allow 10.160.240.0/20 any", 2),
},
InDels: []cloudprovider.SecurityRule{},
OutDels: []cloudprovider.SecurityRule{
ruleWithPriority("out:allow any", 2),
},
},
{
Name: "Test peer out rules",
SrcRules: cloudprovider.SecurityRuleSet{
ruleWithPeerSecgroup("", "out:allow tcp", 1, "sec2"),
ruleWithPriority("out:deny any", 1),
},
DestRules: []cloudprovider.SecurityRule{
ruleWithPeerSecgroup("", "out:allow tcp", 2, "sec2"),
ruleWithPriority("out:deny any", 1),
},
Common: []cloudprovider.SecurityRule{
ruleWithPeerSecgroup("", "out:allow tcp", 2, "sec2"),
ruleWithPriority("out:deny any", 1),
},
InAdds: []cloudprovider.SecurityRule{},
OutAdds: []cloudprovider.SecurityRule{},
InDels: []cloudprovider.SecurityRule{},
OutDels: []cloudprovider.SecurityRule{},
},
{
Name: "Test peer out rules priority",
SrcRules: cloudprovider.SecurityRuleSet{
ruleWithPeerSecgroup("", "out:allow tcp", 2, "sec2"),
ruleWithPriority("out:deny any", 1),
},
DestRules: []cloudprovider.SecurityRule{
ruleWithPeerSecgroup("", "out:allow tcp", 2, "sec2"),
ruleWithPriority("out:deny any", 1),
},
Common: []cloudprovider.SecurityRule{
ruleWithPriority("out:deny any", 1),
},
InAdds: []cloudprovider.SecurityRule{},
OutAdds: []cloudprovider.SecurityRule{
ruleWithPeerSecgroup("", "out:allow tcp", 0, "sec2"),
},
InDels: []cloudprovider.SecurityRule{},
OutDels: []cloudprovider.SecurityRule{
ruleWithPeerSecgroup("", "out:allow tcp", 2, "sec2"),
},
},
{
Name: "Test peer out rules priority 2",
SrcRules: cloudprovider.SecurityRuleSet{
ruleWithPeerSecgroup("", "out:deny tcp", 4, "sec2"),
ruleWithPriority("out:allow any", 5),
},
DestRules: []cloudprovider.SecurityRule{
ruleWithPeerSecgroup("", "out:deny tcp", 0, "sec2"),
ruleWithPriority("out:allow any", 3),
},
Common: []cloudprovider.SecurityRule{
ruleWithPeerSecgroup("", "out:deny tcp", 1, "sec2"),
},
InAdds: []cloudprovider.SecurityRule{},
OutAdds: []cloudprovider.SecurityRule{
ruleWithPriority("out:allow any", 0),
},
InDels: []cloudprovider.SecurityRule{},
OutDels: []cloudprovider.SecurityRule{
ruleWithPriority("out:allow any", 3),
},
},
{
Name: "Test peer out rules 1",
SrcRules: cloudprovider.SecurityRuleSet{
ruleWithPeerSecgroup("", "out:deny tcp 22", 60, "Sys-Default"),
ruleWithPriority("out:allow 10.0.0.0/8 udp", 10),
},
DestRules: []cloudprovider.SecurityRule{
ruleWithPriority("out:allow any", 1),
ruleWithPeerSecgroup("", "out:deny tcp 22", 2, "Sys-Default"),
ruleWithPriority("out:allow 10.0.0.0/8 udp", 3),
ruleWithPriority("out:allow any", 4),
},
Common: []cloudprovider.SecurityRule{
ruleWithPeerSecgroup("", "out:deny tcp 22", 2, "Sys-Default"),
ruleWithPriority("out:allow 10.0.0.0/8 udp", 3),
ruleWithPriority("out:allow any", 4),
},
InAdds: []cloudprovider.SecurityRule{},
OutAdds: []cloudprovider.SecurityRule{},
InDels: []cloudprovider.SecurityRule{},
OutDels: []cloudprovider.SecurityRule{
ruleWithPriority("out:allow any", 1),
},
},
}
for _, d := range data {
d.Test(t, &SKVMRegionDriver{}, &SQcloudRegionDriver{})
}
}
-156
View File
@@ -1,156 +0,0 @@
// 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 regiondrivers
import (
"fmt"
"sort"
"testing"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/pkg/util/secrules"
"yunion.io/x/pkg/util/stringutils"
)
type TestData struct {
Name string
SrcRules cloudprovider.SecurityRuleSet
DestRules cloudprovider.SecurityRuleSet
Common cloudprovider.SecurityRuleSet
InAdds cloudprovider.SecurityRuleSet
OutAdds cloudprovider.SecurityRuleSet
InDels cloudprovider.SecurityRuleSet
OutDels cloudprovider.SecurityRuleSet
}
func (d TestData) Clone() TestData {
return TestData{
Name: d.Name,
SrcRules: d.SrcRules,
DestRules: d.DestRules,
Common: cloudprovider.SecurityRuleSet{},
InAdds: cloudprovider.SecurityRuleSet{},
OutAdds: cloudprovider.SecurityRuleSet{},
InDels: cloudprovider.SecurityRuleSet{},
OutDels: cloudprovider.SecurityRuleSet{},
}
}
func (d TestData) Test(t *testing.T, srcD, destD cloudprovider.SecDriver) {
t.Logf("check %s", d.Name)
src, dest := cloudprovider.NewSecRuleInfo(srcD), cloudprovider.NewSecRuleInfo(destD)
src.Rules, dest.Rules = d.SrcRules, d.DestRules
common, inAdds, outAdds, inDels, outDels := cloudprovider.CompareRules(src, dest, true)
check(t, "common", common, d.Common, 0, 0)
check(t, "inAdds", inAdds, d.InAdds, dest.MinPriority, dest.MaxPriority)
check(t, "outAdds", outAdds, d.OutAdds, dest.MinPriority, dest.MaxPriority)
check(t, "inDels", inDels, d.InDels, 0, 0)
check(t, "outDels", outDels, d.OutDels, 0, 0)
t.Logf("check %s reverse", d.Name)
rd := d.Clone()
dest.Rules = append(dest.Rules, inAdds...)
dest.Rules = append(dest.Rules, outAdds...)
externalIds := []string{}
for i := range inDels {
if len(inDels[i].ExternalId) > 0 {
externalIds = append(externalIds, inDels[i].ExternalId)
} else {
externalIds = append(externalIds, fmt.Sprintf("%s-%d", inDels[i].String(), inDels[i].Priority))
}
}
for i := range outDels {
if len(outDels[i].ExternalId) > 0 {
externalIds = append(externalIds, outDels[i].ExternalId)
} else {
externalIds = append(externalIds, fmt.Sprintf("%s-%d", outDels[i].String(), outDels[i].Priority))
}
}
dest.Rules = append(append(common, inAdds...), outAdds...)
_, inAdds, outAdds, inDels, outDels = cloudprovider.CompareRules(dest, src, true)
//check(t, "common", common, rd.Common)
check(t, "inAdds", inAdds, rd.InAdds, dest.MinPriority, dest.MaxPriority)
check(t, "outAdds", outAdds, rd.OutAdds, dest.MinPriority, dest.MaxPriority)
check(t, "inDels", inDels, rd.InDels, 0, 0)
check(t, "outDels", outDels, rd.OutDels, 0, 0)
}
var ruleWithPriority = func(ruleStr string, priority int) cloudprovider.SecurityRule {
rule := secrules.MustParseSecurityRule(ruleStr)
if rule == nil {
panic(fmt.Sprintf("invalid rule str %s", ruleStr))
}
rule.Priority = priority
return cloudprovider.SecurityRule{SecurityRule: *rule, Id: stringutils.UUID4()}
}
var ruleWithName = func(name, ruleStr string, priority int) cloudprovider.SecurityRule {
return cloudprovider.SecurityRule{
Name: name,
ExternalId: name,
SecurityRule: ruleWithPriority(ruleStr, priority).SecurityRule,
}
}
var ruleWithPeerSecgroup = func(name, ruleStr string, priority int, peerSecgroup string) cloudprovider.SecurityRule {
return cloudprovider.SecurityRule{
Name: name,
ExternalId: name,
PeerSecgroupId: peerSecgroup,
SecurityRule: ruleWithPriority(ruleStr, priority).SecurityRule,
}
}
var check = func(t *testing.T, name string, ret, expect []cloudprovider.SecurityRule, min, max int) {
var show = func(info string, rules []cloudprovider.SecurityRule) {
t.Logf("%s: %d\n", info, len(rules))
for _, r := range rules {
t.Logf("Name: %s id: %s external id: %s priority: %d %s\n", r.Name, r.Id, r.ExternalId, r.Priority, r.String())
}
}
if len(ret) != len(expect) {
show(fmt.Sprintf("%s rule", name), ret)
show(fmt.Sprintf("%s expect", name), expect)
t.Fatalf("invalid rules for %s current is %d expect %d", name, len(ret), len(expect))
}
sort.Sort(cloudprovider.SecurityRuleSet(ret))
sort.Sort(cloudprovider.SecurityRuleSet(expect))
if max < min {
max, min = min, max
}
for i := range ret {
if ret[i].Name != expect[i].Name {
show(fmt.Sprintf("%s rule", name), ret)
show(fmt.Sprintf("%s expect", name), expect)
t.Fatalf("invalid index(%d) %s rule name %s expect %s", i, name, ret[i].Name, expect[i].Name)
}
if ret[i].Priority != expect[i].Priority {
show(fmt.Sprintf("%s rule", name), ret)
show(fmt.Sprintf("%s expect", name), expect)
t.Fatalf("invalid index(%d) %s rule priority %d expect %d", i, name, ret[i].Priority, expect[i].Priority)
}
if max != min && (ret[i].Priority < min || ret[i].Priority > max) {
t.Fatalf("invalid index(%d) %s rules %s priority should be in [%d, %d] current is %d", i, name, ret[i].String(), min, max, ret[i].Priority)
}
if ret[i].String() != expect[i].String() {
show(fmt.Sprintf("%s rule", name), ret)
show(fmt.Sprintf("%s expect", name), expect)
t.Fatalf("invalid index(%d) %s rules %s expect %s", i, name, ret[i].String(), expect[i].String())
}
}
}
-18
View File
@@ -17,9 +17,7 @@ package regiondrivers
import (
"context"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/util/secrules"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/validators"
@@ -45,22 +43,6 @@ func (self *SUcloudRegionDriver) GenerateSecurityGroupName(name string) string {
return name
}
func (self *SUcloudRegionDriver) GetDefaultSecurityGroupInRule() cloudprovider.SecurityRule {
return cloudprovider.SecurityRule{SecurityRule: *secrules.MustParseSecurityRule("in:deny any")}
}
func (self *SUcloudRegionDriver) GetDefaultSecurityGroupOutRule() cloudprovider.SecurityRule {
return cloudprovider.SecurityRule{SecurityRule: *secrules.MustParseSecurityRule("out:allow any")}
}
func (self *SUcloudRegionDriver) GetSecurityGroupRuleMaxPriority() int {
return 3
}
func (self *SUcloudRegionDriver) GetSecurityGroupRuleMinPriority() int {
return 1
}
func (self *SUcloudRegionDriver) GetProvider() string {
return api.CLOUD_PROVIDER_UCLOUD
}
-23
View File
@@ -18,9 +18,6 @@ import (
"context"
"database/sql"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/pkg/util/secrules"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/httperrors"
@@ -44,26 +41,6 @@ func (self *SZStackRegionDriver) GenerateSecurityGroupName(name string) string {
return name
}
func (self *SZStackRegionDriver) GetDefaultSecurityGroupInRule() cloudprovider.SecurityRule {
return cloudprovider.SecurityRule{SecurityRule: *secrules.MustParseSecurityRule("in:deny any")}
}
func (self *SZStackRegionDriver) GetDefaultSecurityGroupOutRule() cloudprovider.SecurityRule {
return cloudprovider.SecurityRule{SecurityRule: *secrules.MustParseSecurityRule("out:allow any")}
}
func (self *SZStackRegionDriver) GetSecurityGroupRuleMaxPriority() int {
return 1
}
func (self *SZStackRegionDriver) GetSecurityGroupRuleMinPriority() int {
return 1
}
func (self *SZStackRegionDriver) IsOnlySupportAllowRules() bool {
return true
}
func (self *SZStackRegionDriver) GetProvider() string {
return api.CLOUD_PROVIDER_ZSTACK
}
@@ -34,8 +34,8 @@ func init() {
taskman.RegisterTask(SecurityGroupCacheTask{})
}
func (self *SecurityGroupCacheTask) taskFailed(ctx context.Context, secgroup *models.SSecurityGroup, reason jsonutils.JSONObject) {
self.SetStageFailed(ctx, reason)
func (self *SecurityGroupCacheTask) taskFailed(ctx context.Context, secgroup *models.SSecurityGroup, err error) {
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *SecurityGroupCacheTask) getVpc() (*models.SVpc, error) {
@@ -55,23 +55,20 @@ func (self *SecurityGroupCacheTask) OnInit(ctx context.Context, obj db.IStandalo
vpc, err := self.getVpc()
if err != nil {
self.taskFailed(ctx, secgroup, jsonutils.NewString(errors.Wrap(err, "self.getVpc()").Error()))
self.taskFailed(ctx, secgroup, errors.Wrapf(err, "getVpc"))
return
}
region, err := vpc.GetRegion()
if err != nil {
self.taskFailed(ctx, secgroup, jsonutils.NewString(errors.Wrap(err, "vpc.GetRegion").Error()))
self.taskFailed(ctx, secgroup, errors.Wrapf(err, "GetRegion"))
return
}
classic, _ := self.GetParams().Bool("classic")
self.SetStage("OnCacheSecurityGroupComplete", nil)
err = region.GetDriver().RequestCacheSecurityGroup(ctx, self.UserCred, region, vpc, secgroup, classic, "", self)
err = region.GetDriver().RequestCacheSecurityGroup(ctx, self.UserCred, region, vpc, secgroup, "", self)
if err != nil {
self.taskFailed(ctx, secgroup, jsonutils.NewString(err.Error()))
self.taskFailed(ctx, secgroup, errors.Wrapf(err, "RequestCacheSecurityGroup"))
return
}
}
@@ -1,101 +0,0 @@
// 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"
"fmt"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"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.ClearRuleDirty()
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.ClearRuleDirty()
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 {
iSecgroup, err := caches[i].GetISecurityGroup(ctx)
if err != nil {
self.taskFailed(ctx, secgroup, errors.Wrapf(err, "GetISecurityGroup"))
return
}
oldRules, _, err := caches[i].GetOldSecuritRuleSet(ctx)
if err != nil {
self.taskFailed(ctx, secgroup, errors.Wrapf(err, "GetOldSecuritRuleSet"))
return
}
rules, err := iSecgroup.GetRules()
if err != nil {
self.taskFailed(ctx, secgroup, errors.Wrapf(err, "GetRules"))
return
}
src := cloudprovider.NewSecRuleInfo(models.GetRegionDriver(api.CLOUD_PROVIDER_ONECLOUD))
src.Rules = oldRules
region, err := caches[i].GetRegion()
if err != nil {
self.taskFailed(ctx, secgroup, errors.Wrapf(err, "GetRegion"))
return
}
dest := cloudprovider.NewSecRuleInfo(models.GetRegionDriver(region.Provider))
dest.Rules = rules
_, inAdds, outAdds, inDels, outDels := cloudprovider.CompareRules(src, dest, false)
if len(inDels)+len(outDels)+len(inAdds)+len(outAdds) > 0 {
self.taskFailed(ctx, secgroup, fmt.Errorf("secgroup rule not equal with cache %s(%s)", caches[i].Name, region.Provider))
return
}
}
for i := range caches {
err := caches[i].SyncRules(ctx, false)
if err != nil {
logclient.AddActionLogWithContext(ctx, secgroup, logclient.ACT_SYNC_CONF, errors.Wrapf(err, "SyncRules"), self.UserCred, false)
}
}
self.taskComplete(ctx, secgroup)
}
+7 -22
View File
@@ -20,7 +20,6 @@ import (
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/cloudmux/pkg/multicloud"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/secrules"
api "yunion.io/x/onecloud/pkg/apis/compute"
@@ -61,11 +60,9 @@ func (self *SSecurityGroup) GetProjectId() string {
func (self *SSecurityGroup) GetRules() ([]cloudprovider.SecurityRule, error) {
ret := []cloudprovider.SecurityRule{}
ret = append(ret, cloudprovider.SecurityRule{SecurityRule: *secrules.MustParseSecurityRule("out:allow any")})
for _, r := range self.Rules {
if len(r.PeerSecgroupId) > 0 {
continue
}
rule := cloudprovider.SecurityRule{ExternalId: r.Id}
rule := cloudprovider.SecurityRule{}
rule.Action = secrules.TSecurityRuleAction(r.Action)
rule.Priority = int(r.Priority)
rule.Protocol = r.Protocol
@@ -130,22 +127,6 @@ func (self *SRegion) CreateSecRule(secId string, rule cloudprovider.SecurityRule
return self.create(&modules.SecGroupRules, input, &ret)
}
func (self *SSecurityGroup) SyncRules(common, inAdds, outAdds, inDels, outDels []cloudprovider.SecurityRule) error {
for _, r := range append(inDels, outDels...) {
err := self.region.DeleteSecRule(r.Id)
if err != nil {
return errors.Wrapf(err, "delete rule %s", r.Id)
}
}
for _, r := range append(inAdds, outAdds...) {
err := self.region.CreateSecRule(self.Id, r)
if err != nil {
return errors.Wrapf(err, "create rule %s", r)
}
}
return nil
}
func (self *SSecurityGroup) Delete() error {
return self.region.cli.delete(&modules.SecGroups, self.Id)
}
@@ -164,10 +145,14 @@ func (self *SRegion) GetSecurityGroup(id string) (*SSecurityGroup, error) {
}
func (self *SRegion) CreateISecurityGroup(opts *cloudprovider.SecurityGroupCreateInput) (cloudprovider.ICloudSecurityGroup, error) {
outRules := opts.OutRules
if len(outRules) > 0 && outRules[0].String() == "out:allow any" {
outRules = outRules[1:]
}
params := map[string]interface{}{
"name": opts.Name,
"description": opts.Desc,
"rules": opts.Rules,
"rules": append(opts.InRules, opts.OutRules...),
}
if len(opts.ProjectId) > 0 {
params["project_id"] = opts.ProjectId
+19 -25
View File
@@ -39,11 +39,10 @@ func (opts *SecGroupRulesListOptions) Params() (jsonutils.JSONObject, error) {
}
type SecGroupRulesCreateOptions struct {
SECGROUP string `help:"Secgroup ID or Name" metavar:"Secgroup"`
RULE string `json:"-"`
Priority int64 `help:"priority of Rule" default:"50"`
Desc string `help:"Description" json:"description"`
PeerSecgroupId string `help:"Peer Secgroup Id" json:"peer_secgroup_id"`
SECGROUP string `help:"Secgroup ID or Name" metavar:"Secgroup"`
RULE string `json:"-"`
Priority int64 `help:"priority of Rule" default:"50"`
Desc string `help:"Description" json:"description"`
}
func (opts *SecGroupRulesCreateOptions) Params() (jsonutils.JSONObject, error) {
@@ -52,28 +51,26 @@ func (opts *SecGroupRulesCreateOptions) Params() (jsonutils.JSONObject, error) {
return nil, errors.Wrapf(err, "invalid rule %s", opts.RULE)
}
return jsonutils.Marshal(map[string]interface{}{
"direction": rule.Direction,
"action": rule.Action,
"protocol": rule.Protocol,
"cidr": rule.IPNet.String(),
"ports": rule.GetPortsString(),
"priority": opts.Priority,
"description": opts.Desc,
"secgroup_id": opts.SECGROUP,
"peer_secgroup_id": opts.PeerSecgroupId,
"direction": rule.Direction,
"action": rule.Action,
"protocol": rule.Protocol,
"cidr": rule.IPNet.String(),
"ports": rule.GetPortsString(),
"priority": opts.Priority,
"description": opts.Desc,
"secgroup_id": opts.SECGROUP,
}), nil
}
type SecGroupRulesUpdateOptions struct {
options.BaseIdOptions
Name string `help:"New name of rule"`
Priority int64 `help:"priority of Rule"`
Protocol string `help:"Protocol of rule" choices:"any|tcp|udp|icmp"`
Ports string `help:"Ports of rule"`
Cidr string `help:"Cidr of rule"`
Action string `help:"filter Actin of rule" choices:"allow|deny"`
Desc string `help:"Description" metavar:"Description"`
PeerSecgroupId string `help:"Peer Secgroup Id" json:"peer_secgroup_id"`
Name string `help:"New name of rule"`
Priority int64 `help:"priority of Rule"`
Protocol string `help:"Protocol of rule" choices:"any|tcp|udp|icmp"`
Ports string `help:"Ports of rule"`
Cidr string `help:"Cidr of rule"`
Action string `help:"filter Actin of rule" choices:"allow|deny"`
Desc string `help:"Description" metavar:"Description"`
}
func (opts *SecGroupRulesUpdateOptions) Params() (jsonutils.JSONObject, error) {
@@ -99,8 +96,5 @@ func (opts *SecGroupRulesUpdateOptions) Params() (jsonutils.JSONObject, error) {
if len(opts.Action) > 0 {
params.Add(jsonutils.NewString(opts.Action), "action")
}
if len(opts.PeerSecgroupId) > 0 {
params.Add(jsonutils.NewString(opts.PeerSecgroupId), "peer_secgroup_id")
}
return params, nil
}
+1 -2
View File
@@ -107,8 +107,7 @@ func (opts *SecgroupsAddRuleOptions) Params() (jsonutils.JSONObject, error) {
type SecurityGroupCacheOptions struct {
SecgroupIdOptions
VPC string `help:"ID or Name of vpc"`
Classic *bool `help:"Is classic vpc"`
VPC_ID string `help:"ID or Name of vpc"`
}
func (opts *SecurityGroupCacheOptions) Params() (jsonutils.JSONObject, error) {
-4
View File
@@ -623,10 +623,6 @@ func (keeper *OVNNorthboundKeeper) ClaimGuestnetwork(ctx context.Context, guestn
sgrs := guest.OrderedSecurityGroupRules()
for _, sgr := range sgrs {
// kvm not support peer secgroup
if len(sgr.PeerSecgroupId) > 0 {
log.Warningf("security group with peer secgroup Id")
continue
}
acl, err := ruleToAcl(lportName, sgr)
if err != nil {
log.Errorf("converting security group rule to acl: %v", err)
+7 -15
View File
@@ -8,7 +8,6 @@ package memory
import (
"bufio"
"compress/gzip"
"errors"
"fmt"
"io"
"io/ioutil"
@@ -65,25 +64,18 @@ func AreaForNode(ctx *context.Context, nodeID int) (*Area, error) {
fmt.Sprintf("node%d", nodeID),
)
totUsable, err := memoryTotalUsableBytesFromPath(filepath.Join(path, "meminfo"))
blockSizeBytes, err := memoryBlockSizeBytes(paths.SysDevicesSystemMemory)
if err != nil {
return nil, err
}
var totPhys int64
if _, err := os.Stat(paths.SysDevicesSystemMemory); err == nil {
blockSizeBytes, err := memoryBlockSizeBytes(paths.SysDevicesSystemMemory)
if err != nil {
return nil, err
}
totPhys, err := memoryTotalPhysicalBytesFromPath(path, blockSizeBytes)
if err != nil {
return nil, err
}
totPhys, err = memoryTotalPhysicalBytesFromPath(path, blockSizeBytes)
if err != nil {
return nil, err
}
} else if errors.Is(err, os.ErrNotExist) {
totPhys = totUsable
} else {
totUsable, err := memoryTotalUsableBytesFromPath(filepath.Join(path, "meminfo"))
if err != nil {
return nil, err
}
+3 -4
View File
@@ -545,7 +545,7 @@ github.com/hugozhu/godingtalk
# github.com/imdario/mergo v0.3.6
## explicit
github.com/imdario/mergo
# github.com/jaypipes/ghw v0.10.1-0.20230329185050-227643e14380 => github.com/wanyaoqi/ghw v0.10.1
# github.com/jaypipes/ghw v0.10.1-0.20230329185050-227643e14380
## explicit; go 1.18
github.com/jaypipes/ghw/pkg/context
github.com/jaypipes/ghw/pkg/cpu
@@ -1457,7 +1457,7 @@ sigs.k8s.io/structured-merge-diff/v4/value
# sigs.k8s.io/yaml v1.2.0
## explicit; go 1.12
sigs.k8s.io/yaml
# yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20230420032540-1c19d25fb1fa
# yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20230428051550-621cd3dd1771
## explicit; go 1.18
yunion.io/x/cloudmux/pkg/apis
yunion.io/x/cloudmux/pkg/apis/billing
@@ -1548,7 +1548,7 @@ yunion.io/x/log/hooks
yunion.io/x/ovsdb/cli_util
yunion.io/x/ovsdb/schema/ovn_nb
yunion.io/x/ovsdb/types
# yunion.io/x/pkg v1.0.1-0.20230420104238-bbd084afbdfe
# yunion.io/x/pkg v1.0.1-0.20230427104242-202edd119017
## explicit; go 1.18
yunion.io/x/pkg/appctx
yunion.io/x/pkg/errors
@@ -1613,4 +1613,3 @@ yunion.io/x/sqlchemy/backends/sqlite
# yunion.io/x/structarg v0.0.0-20220312084958-9c6c79c7d1c6
## explicit; go 1.12
yunion.io/x/structarg
# github.com/jaypipes/ghw => github.com/wanyaoqi/ghw v0.10.1
+1 -1
View File
@@ -469,10 +469,10 @@ type ICloudSecurityGroup interface {
IVirtualResource
GetDescription() string
// 返回的优先级字段(priority)要求数字越大优先级越高, 若有默认不可修改的allow规则依然需要返回
GetRules() ([]SecurityRule, error)
GetVpcId() string
SyncRules(common, inAdds, outAdds, inDels, outDels []SecurityRule) error
GetReferences() ([]SecurityGroupReference, error)
Delete() error
}
+49 -501
View File
@@ -15,15 +15,10 @@
package cloudprovider
import (
"fmt"
"sort"
"strings"
"gopkg.in/fatih/set.v0"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/secrules"
"yunion.io/x/pkg/utils"
)
type SecurityGroupReference struct {
@@ -31,93 +26,6 @@ type SecurityGroupReference struct {
Name string
}
type SecDriver interface {
GetDefaultSecurityGroupInRule() SecurityRule
GetDefaultSecurityGroupOutRule() SecurityRule
GetSecurityGroupRuleMaxPriority() int
GetSecurityGroupRuleMinPriority() int
IsOnlySupportAllowRules() bool
IsSupportPeerSecgroup() bool
}
func NewSecRuleInfo(driver SecDriver) SecRuleInfo {
return SecRuleInfo{
InDefaultRule: driver.GetDefaultSecurityGroupInRule(),
OutDefaultRule: driver.GetDefaultSecurityGroupOutRule(),
MinPriority: driver.GetSecurityGroupRuleMinPriority(),
MaxPriority: driver.GetSecurityGroupRuleMaxPriority(),
IsOnlySupportAllowRules: driver.IsOnlySupportAllowRules(),
IsSupportPeerSecgroup: driver.IsSupportPeerSecgroup(),
}
}
const DEFAULT_DEST_RULE_ID = "default_dest_rule_id"
const DEFAULT_SRC_RULE_ID = "default_src_rule_id"
type SecRuleInfo struct {
InDefaultRule SecurityRule
OutDefaultRule SecurityRule
in SecurityRuleSet
out SecurityRuleSet
rules SecurityRuleSet
Rules SecurityRuleSet
MinPriority int
MaxPriority int
IsOnlySupportAllowRules bool
IsSupportPeerSecgroup bool
}
func (r SecRuleInfo) getOffest(priority int) (int, int) {
if r.MinPriority < r.MaxPriority {
if priority >= r.MaxPriority {
return priority, -1
}
return priority + 1, 0
} else {
if priority <= r.MaxPriority {
return priority, 1
}
return priority - 1, 0
}
}
func (r SecRuleInfo) AddDefaultRule(d SecRuleInfo, inRules, outRules []SecurityRule, isSrc bool) ([]SecurityRule, []SecurityRule) {
min, max := r.MinPriority, r.MaxPriority
r.InDefaultRule.Priority = min + 1
r.OutDefaultRule.Priority = min + 1
r.InDefaultRule.minPriority, r.InDefaultRule.maxPriority = r.MinPriority, r.MaxPriority
r.OutDefaultRule.minPriority, r.OutDefaultRule.maxPriority = r.MinPriority, r.MaxPriority
if max >= min {
r.InDefaultRule.Priority = min - 1
r.OutDefaultRule.Priority = min - 1
}
if isSrc {
r.InDefaultRule.Id = DEFAULT_SRC_RULE_ID
r.OutDefaultRule.Id = DEFAULT_SRC_RULE_ID
} else {
r.InDefaultRule.ExternalId = DEFAULT_DEST_RULE_ID
r.OutDefaultRule.ExternalId = DEFAULT_DEST_RULE_ID
}
var isWideRule = func(rules []SecurityRule) bool {
for _, rule := range rules {
if strings.HasSuffix(rule.String(), "allow any") || strings.HasSuffix(rule.String(), "deny any") {
return true
}
}
return false
}
if !isWideRule(inRules) {
inRules = append(inRules, r.InDefaultRule)
}
if !isWideRule(outRules) {
outRules = append(outRules, r.OutDefaultRule)
}
return inRules, outRules
}
type SecurityGroupFilterOptions struct {
VpcId string
Name string
@@ -129,65 +37,23 @@ type SecurityGroupCreateInput struct {
Desc string
VpcId string
ProjectId string
Rules []secrules.SecurityRule
}
// 安全组刚创建, 但是未设置安全组规则时
OnCreated func(id string)
type SecurityGroupCreateOutput struct {
Return bool
GroupId string
// 默认优先级从低到高排序, 端口会被分离, 不会出现[10,20]这种规则
InRules SecurityRuleSet
// 同上
OutRules SecurityRuleSet
}
type SecurityRule struct {
minPriority int
maxPriority int
offset int
secrules.SecurityRule
Name string
ExternalId string
Id string
PeerSecgroupId string
}
func (self *SecurityRule) addPriority(offset int) {
self.Priority += offset
self.offset += offset
}
func (r SecurityRule) String() string {
if len(r.PeerSecgroupId) == 0 {
return r.SecurityRule.String()
}
return fmt.Sprintf("%s-%s", r.SecurityRule.String(), r.PeerSecgroupId)
Name string
Id string
}
type SecurityRuleSet []SecurityRule
func (self *SecRuleInfo) Split() (in, out SecurityRuleSet) {
self.rules = SecurityRuleSet{}
self.in = SecurityRuleSet{}
self.out = SecurityRuleSet{}
for i := 0; i < len(self.Rules); i++ {
self.rules = append(self.rules, self.Rules[i])
if self.Rules[i].Direction == secrules.DIR_IN {
self.in = append(self.in, self.Rules[i])
} else {
self.out = append(self.out, self.Rules[i])
}
self.Rules[i].minPriority, self.Rules[i].maxPriority = self.MinPriority, self.MaxPriority
if !self.IsSupportPeerSecgroup && len(self.Rules[i].PeerSecgroupId) > 0 {
continue
}
if self.Rules[i].Direction == secrules.DIR_IN {
in = append(in, self.Rules[i])
} else {
out = append(out, self.Rules[i])
}
}
return
}
func (srs SecurityRuleSet) Len() int {
return len(srs)
}
@@ -197,378 +63,60 @@ func (srs SecurityRuleSet) Swap(i, j int) {
}
func (srs SecurityRuleSet) Less(i, j int) bool {
if srs[i].Priority < srs[j].Priority {
return true
}
if srs[i].Priority > srs[j].Priority {
return false
}
if len(srs) > 0 {
if (srs[0].minPriority <= srs[0].maxPriority && srs[i].String() < srs[j].String()) ||
(srs[0].minPriority > srs[0].maxPriority && srs[i].String() > srs[j].String()) {
return true
}
return true
} else if srs[i].Priority == srs[j].Priority {
return srs[i].String() < srs[j].String()
}
return false
}
func (srs SecurityRuleSet) CanBeSplitByProtocol() bool {
firstNormalRuleIndex, find := 0, false
for idx, r := range srs {
if !(strings.HasSuffix(r.String(), "allow any") || strings.HasSuffix(r.String(), "deny any")) && !find {
firstNormalRuleIndex = idx
find = true
} else {
if r.ExternalId == DEFAULT_SRC_RULE_ID || r.ExternalId == DEFAULT_DEST_RULE_ID {
return true
}
if idx > firstNormalRuleIndex {
return false
}
}
}
return true
}
func (srs SecurityRuleSet) AllowList() (secrules.SecurityRuleSet, bool) {
func (srs SecurityRuleSet) String() string {
sort.Sort(srs)
rules := secrules.SecurityRuleSet{}
isOk := true
for _, r := range srs {
if len(r.PeerSecgroupId) > 0 {
isOk = false
}
rules = append(rules, r.SecurityRule)
for i := range srs {
rules = append(rules, srs[i].SecurityRule)
}
return rules.AllowList(), isOk
return rules.String()
}
func (srs SecurityRuleSet) Debug() {
for i := 0; i < len(srs); i++ {
log.Debugf("Name: %s id: %s external_id: %s min: %d max: %d priority: %d %s", srs[i].Name, srs[i].Id, srs[i].ExternalId, srs[i].minPriority, srs[i].maxPriority, srs[i].Priority, srs[i].String())
func (srs SecurityRuleSet) AllowList() secrules.SecurityRuleSet {
sort.Sort(srs)
rules := secrules.SecurityRuleSet{}
for i := range srs {
rules = append(rules, srs[i].SecurityRule)
}
return rules.AllowList()
}
func SortSecurityRule(rules SecurityRuleSet, isAsc bool, info SecRuleInfo) {
if (info.MaxPriority > info.MinPriority && isAsc) || (info.MaxPriority < info.MinPriority && !isAsc) || (info.IsOnlySupportAllowRules && isAsc) {
sort.Sort(rules)
return
func GetSecurityGroupRules(sec ICloudSecurityGroup) (SecurityRuleSet, secrules.SecurityRuleSet, secrules.SecurityRuleSet, error) {
rules, err := sec.GetRules()
if err != nil {
return nil, nil, nil, errors.Wrapf(err, "GetRules")
}
sort.Sort(sort.Reverse(rules))
return
}
func isAllowListEqual(src, dest secrules.SecurityRuleSet) bool {
if len(src) != len(dest) {
return false
}
s1, s2 := set.New(set.ThreadSafe), set.New(set.ThreadSafe)
for i := 0; i < len(src); i++ {
s1.Add(src[i].String())
s2.Add(dest[i].String())
}
return s1.IsEqual(s2)
}
func isPeerListEqual(src, dest SecurityRuleSet) bool {
if len(src) != len(dest) {
return false
}
s1, s2 := set.New(set.ThreadSafe), set.New(set.ThreadSafe)
for i := 0; i < len(src); i++ {
s1.Add(src[i].String())
s2.Add(dest[i].String())
}
return s1.IsEqual(s2)
}
func CompareRules(src, dest SecRuleInfo, debug bool) (common, inAdds, outAdds, inDels, outDels SecurityRuleSet) {
srcInRules, srcOutRules := src.Split()
destInRules, destOutRules := dest.Split()
srcInRules, srcOutRules = src.AddDefaultRule(dest, srcInRules, srcOutRules, true)
destInRules, destOutRules = dest.AddDefaultRule(src, destInRules, destOutRules, false)
// AllowList 需要优先级从高到低排序
SortSecurityRule(srcInRules, false, src)
SortSecurityRule(srcOutRules, false, src)
SortSecurityRule(destInRules, false, dest)
SortSecurityRule(destOutRules, false, dest)
isInAllowSplit := srcInRules.CanBeSplitByProtocol() && destInRules.CanBeSplitByProtocol()
isOutAllowSplit := srcOutRules.CanBeSplitByProtocol() && destOutRules.CanBeSplitByProtocol()
srcInAllowList, srcInOk := srcInRules.AllowList()
srcOutAllowList, srcOutOk := srcOutRules.AllowList()
destInAllowList, destInOk := destInRules.AllowList()
destOutAllowList, destOutOk := destOutRules.AllowList()
inEquals, outEquals, inOk, outOk := isAllowListEqual(srcInAllowList, destInAllowList), isAllowListEqual(srcOutAllowList, destOutAllowList), srcInOk && destInOk, srcOutOk && destOutOk
if inEquals && outEquals && inOk && outOk {
common = dest.rules
return
}
if debug {
log.Debugf("====desc sort====")
log.Debugf("src in rules: ")
srcInRules.Debug()
log.Debugf("src out rules: ")
srcOutRules.Debug()
log.Debugf("dest in rules: ")
destInRules.Debug()
log.Debugf("dest out rules: ")
destOutRules.Debug()
log.Debugf("====desc sort end====")
log.Debugf("isInAllowSplit: %v isOutAllowSplit: %v", isInAllowSplit, isOutAllowSplit)
log.Debugf("AllowList:")
log.Debugf("In: src: %s dest: %s isEquals: %v", srcInAllowList.String(), destInAllowList.String(), inEquals)
log.Debugf("Out: src: %s dest: %s isEquals: %v", srcOutAllowList.String(), destOutAllowList.String(), outEquals)
}
var tryUseAllowList = func(defaultRule SecurityRule, allowList secrules.SecurityRuleSet, rules SecurityRuleSet, isOnlyAllowList bool, isOk bool) SecurityRuleSet {
if isOk && (len(allowList) < len(rules) || isOnlyAllowList) {
rules = SecurityRuleSet{}
for i := range allowList {
rule := SecurityRule{}
rule.SecurityRule = allowList[i]
rules = append(rules, rule)
}
if !utils.IsInStringArray(allowList.String(), []string{
"",
"in:allow any",
"out:allow any",
"in:deny any",
"out:deny any",
}) && strings.HasSuffix(defaultRule.SecurityRule.String(), "deny any") {
rules = append(rules, defaultRule)
}
}
return rules
}
srcInRules = tryUseAllowList(src.InDefaultRule, srcInAllowList, srcInRules, dest.IsOnlySupportAllowRules, inOk)
srcOutRules = tryUseAllowList(src.OutDefaultRule, srcOutAllowList, srcOutRules, dest.IsOnlySupportAllowRules, outOk)
if inEquals && inOk {
common = append(common, dest.in...)
srcInRules, destInRules = []SecurityRule{}, []SecurityRule{}
}
if outEquals && outOk {
common = append(common, dest.out...)
srcOutRules, destOutRules = []SecurityRule{}, []SecurityRule{}
}
// 默认从优先级低到高比较
SortSecurityRule(srcInRules, true, src)
SortSecurityRule(srcOutRules, true, src)
SortSecurityRule(destInRules, true, dest)
SortSecurityRule(destOutRules, true, dest)
if debug {
log.Debugf("====asc sort====")
log.Debugf("src in rules: ")
srcInRules.Debug()
log.Debugf("src out rules: ")
srcOutRules.Debug()
log.Debugf("dest in rules: ")
destInRules.Debug()
log.Debugf("dest out rules: ")
destOutRules.Debug()
log.Debugf("====asc sort end====")
}
var _compare = func(srcRules SecurityRuleSet, destRules SecurityRuleSet) (common, add, del SecurityRuleSet) {
i, j, priority := 0, 0, dest.MinPriority
if len(destRules) > 0 && (destRules[i].ExternalId != DEFAULT_DEST_RULE_ID) {
priority = destRules[0].Priority
}
for i < len(srcRules) || j < len(destRules) {
if i < len(srcRules) && j < len(destRules) {
destRuleStr := destRules[j].String()
srcRuleStr := srcRules[i].String()
if debug {
log.Debugf("compare src %s(%s) priority(%d) %s -> dest name(%s) %s(%s) priority(%d) %s\n",
srcRules[i].Id, srcRules[i].ExternalId, srcRules[i].Priority, srcRules[i].String(),
destRules[j].Name, destRules[j].ExternalId, destRules[j].Id, destRules[j].Priority, destRules[j].String())
}
cmp := strings.Compare(destRuleStr, srcRuleStr)
if cmp == 0 {
destRules[j].Id = srcRules[i].Id
common = append(common, destRules[j])
if destRules[j].ExternalId != DEFAULT_DEST_RULE_ID {
priority = destRules[j].Priority
}
i++
j++
} else if cmp < 0 {
del = append(del, destRules[j])
j++
} else {
offset := 0
if !dest.IsOnlySupportAllowRules && i-1 >= 0 && srcRules[i-1].Priority != srcRules[i].Priority {
priority, offset = dest.getOffest(priority)
}
if offset != 0 {
for r := range add {
add[r].addPriority(offset)
}
for r := range common {
common[r].addPriority(offset)
}
}
srcRules[i].Priority = priority
srcRules[i].minPriority, srcRules[i].maxPriority = dest.MinPriority, dest.MaxPriority
add = append(add, srcRules[i])
i++
}
} else if i >= len(srcRules) {
del = append(del, destRules[j])
j++
} else if j >= len(destRules) {
offset := 0
if !dest.IsOnlySupportAllowRules && i-1 >= 0 && srcRules[i-1].Priority != srcRules[i].Priority {
priority, offset = dest.getOffest(priority)
}
srcRules[i].Priority = priority
srcRules[i].minPriority, srcRules[i].maxPriority = dest.MinPriority, dest.MaxPriority
if offset != 0 {
for r := range add {
add[r].addPriority(offset)
}
for r := range common {
common[r].addPriority(offset)
}
}
add = append(add, srcRules[i])
i++
}
}
return
}
type rulePair struct {
srcRules SecurityRuleSet
destRules SecurityRuleSet
protocol string
}
var splitRules = func(src, dest SecurityRuleSet) []rulePair {
rules := map[string]rulePair{}
for _, r := range src {
pair, ok := rules[r.Protocol]
if !ok {
pair = rulePair{srcRules: SecurityRuleSet{}, destRules: SecurityRuleSet{}, protocol: r.Protocol}
}
pair.srcRules = append(pair.srcRules, r)
rules[r.Protocol] = pair
}
for _, r := range dest {
pair, ok := rules[r.Protocol]
if !ok {
pair = rulePair{srcRules: SecurityRuleSet{}, destRules: SecurityRuleSet{}, protocol: r.Protocol}
}
pair.destRules = append(pair.destRules, r)
rules[r.Protocol] = pair
}
ret := []rulePair{}
for _, r := range rules {
ret = append(ret, r)
}
return ret
}
var compare = func(src, dest SecurityRuleSet) (common, added, dels SecurityRuleSet) {
pairs := splitRules(src, dest)
for _, r := range pairs {
_common, _add, _dels := _compare(r.srcRules, r.destRules)
common = append(common, _common...)
added = append(added, _add...)
dels = append(dels, _dels...)
}
return
}
var inCommon, outCommon SecurityRuleSet
if isInAllowSplit {
inCommon, inAdds, inDels = compare(srcInRules, destInRules)
} else {
inCommon, inAdds, inDels = _compare(srcInRules, destInRules)
}
if isOutAllowSplit {
outCommon, outAdds, outDels = compare(srcOutRules, destOutRules)
} else {
outCommon, outAdds, outDels = _compare(srcOutRules, destOutRules)
}
var handleDefaultRules = func(removed, added []SecurityRule, isOnlyAllowList bool) ([]SecurityRule, []SecurityRule, *SecurityRule) {
ret := []SecurityRule{}
var defaultRule *SecurityRule = nil
for i := range removed {
rule := removed[i]
if rule.ExternalId == DEFAULT_DEST_RULE_ID {
if debug {
log.Debugf("remove dest default rule: %s external id %s priority: %d", rule.String(), rule.ExternalId, rule.Priority)
}
if rule.Action == secrules.SecurityRuleDeny && isOnlyAllowList {
continue
}
switch rule.Action {
case secrules.SecurityRuleDeny:
rule.Action = secrules.SecurityRuleAllow
case secrules.SecurityRuleAllow:
rule.Action = secrules.SecurityRuleDeny
}
rule.Priority = dest.MinPriority
defaultRule = &rule
} else {
ret = append(ret, rule)
}
}
return ret, added, defaultRule
}
var inDefault *SecurityRule
var outDefault *SecurityRule
inDels, inAdds, inDefault = handleDefaultRules(inDels, inAdds, dest.IsOnlySupportAllowRules)
if inDefault != nil {
inAllow, _ := append(inAdds, inCommon...).AllowList()
if len(inAllow.String()) == 0 || (!strings.Contains(inAllow.String(), inDefault.String()) && !srcInAllowList.Equals(inAllow)) {
inAdds = append(inAdds, *inDefault)
}
}
outDels, outAdds, outDefault = handleDefaultRules(outDels, outAdds, dest.IsOnlySupportAllowRules)
if outDefault != nil {
outAllow, _ := append(outAdds, outCommon...).AllowList()
if len(outAllow.String()) == 0 || (!strings.Contains(outAllow.String(), outDefault.String()) && !srcOutAllowList.Equals(outAllow)) {
outAdds = append(outAdds, *outDefault)
}
}
_common, _, _ := handleDefaultRules(append(inCommon, outCommon...), []SecurityRule{}, dest.IsOnlySupportAllowRules)
common = append(common, _common...)
return
}
func SortUniqPriority(rules SecurityRuleSet) []SecurityRule {
sort.Sort(rules)
priMap := map[int]bool{}
for i := range rules {
for {
_, ok := priMap[rules[i].Priority]
if !ok {
priMap[rules[i].Priority] = true
break
}
rules[i].Priority = rules[i].Priority - 1
if err := rules[i].ValidateRule(); err != nil && errors.Cause(err) != secrules.ErrInvalidPriority {
return nil, nil, nil, errors.Wrapf(err, "ValidateRule")
}
}
return rules
in, out := SplitRulesByDirection(rules)
sort.Sort(SecurityRuleSet(rules))
return rules, in, out, nil
}
func SplitRulesByDirection(rules []SecurityRule) (secrules.SecurityRuleSet, secrules.SecurityRuleSet) {
in, out := secrules.SecurityRuleSet{}, secrules.SecurityRuleSet{}
for i := range rules {
switch rules[i].Direction {
case secrules.DIR_IN:
in = append(in, rules[i].SecurityRule)
case secrules.DIR_OUT:
out = append(out, rules[i].SecurityRule)
}
}
// 优先级高到低
sort.Sort(in)
sort.Sort(out)
return in, out
}
+17 -6
View File
@@ -887,11 +887,6 @@ func (region *SRegion) GetISecurityGroupById(secgroupId string) (cloudprovider.I
if err != nil {
return nil, err
}
vpc, err := region.getVpc(secgroup.VpcId)
if err != nil {
return nil, errors.Wrapf(err, "region.getVpc(%s)", secgroup.VpcId)
}
secgroup.vpc = vpc
return secgroup, nil
}
@@ -906,14 +901,30 @@ func (region *SRegion) GetISecurityGroupByName(opts *cloudprovider.SecurityGroup
if total > 1 {
return nil, cloudprovider.ErrDuplicateId
}
secgroups[0].region = region
return &secgroups[0], nil
}
func (region *SRegion) CreateISecurityGroup(conf *cloudprovider.SecurityGroupCreateInput) (cloudprovider.ICloudSecurityGroup, error) {
externalId, err := region.CreateSecurityGroup(conf.VpcId, conf.Name, conf.Desc)
externalId, err := region.CreateSecurityGroup(conf.VpcId, conf.Name, conf.Desc, conf.ProjectId)
if err != nil {
return nil, err
}
if conf.OnCreated != nil {
conf.OnCreated(externalId)
}
outRules := conf.OutRules
if len(outRules) > 0 && outRules[0].String() == "out:allow any" {
outRules = outRules[1:]
}
rules := append(conf.InRules, outRules...)
for _, rule := range rules {
rule.Priority = 101 - rule.Priority
err = region.addSecurityGroupRule(externalId, rule)
if err != nil {
return nil, err
}
}
return region.GetISecurityGroupById(externalId)
}
+23 -44
View File
@@ -66,7 +66,7 @@ type SSecurityGroup struct {
multicloud.SSecurityGroup
AliyunTags
vpc *SVpc
region *SRegion
CreationTime time.Time
Description string
SecurityGroupId string
@@ -95,11 +95,19 @@ func (self *SSecurityGroup) GetDescription() string {
func (self *SSecurityGroup) GetRules() ([]cloudprovider.SecurityRule, error) {
rules := make([]cloudprovider.SecurityRule, 0)
secgrp, err := self.vpc.region.GetSecurityGroupDetails(self.SecurityGroupId)
secgrp, err := self.region.GetSecurityGroupDetails(self.SecurityGroupId)
if err != nil {
return nil, err
}
outAllow := secrules.MustParseSecurityRule("out:allow any")
rules = append(rules, cloudprovider.SecurityRule{SecurityRule: *outAllow})
for _, permission := range secgrp.Permissions.Permission {
if len(permission.SourceGroupId) > 0 || len(permission.DestGroupId) > 0 {
continue
}
if !utils.IsInStringArray(strings.ToLower(permission.IpProtocol), []string{"tcp", "udp", "icmp", "all"}) {
continue
}
rule, err := permission.toRule()
if err != nil {
log.Errorf("convert rule %s for group %s(%s) error: %v", permission.Description, self.SecurityGroupName, self.SecurityGroupId, err)
@@ -126,7 +134,7 @@ func (self *SSecurityGroup) IsEmulated() bool {
}
func (self *SSecurityGroup) Refresh() error {
group, err := self.vpc.region.GetSecurityGroupDetails(self.SecurityGroupId)
group, err := self.region.GetSecurityGroupDetails(self.SecurityGroupId)
if err != nil {
return err
}
@@ -134,7 +142,7 @@ func (self *SSecurityGroup) Refresh() error {
}
func (self *SSecurityGroup) GetReferences() ([]cloudprovider.SecurityGroupReference, error) {
references, err := self.vpc.region.DescribeSecurityGroupReferences(self.SecurityGroupId)
references, err := self.region.DescribeSecurityGroupReferences(self.SecurityGroupId)
if err != nil {
return nil, errors.Wrapf(err, "DescribeSecurityGroupReferences")
}
@@ -224,7 +232,7 @@ func (self *SRegion) GetSecurityGroupDetails(secGroupId string) (*SSecurityGroup
return nil, errors.Wrap(err, "DescribeSecurityGroupAttribute")
}
secgrp := SSecurityGroup{}
secgrp := SSecurityGroup{region: self}
err = body.Unmarshal(&secgrp)
if err != nil {
return nil, errors.Wrap(err, "body.Unmarshal")
@@ -232,14 +240,14 @@ func (self *SRegion) GetSecurityGroupDetails(secGroupId string) (*SSecurityGroup
return &secgrp, nil
}
func (self *SRegion) CreateSecurityGroup(vpcId string, name string, desc string) (string, error) {
func (self *SRegion) CreateSecurityGroup(vpcId string, name string, desc, resourceGroupId string) (string, error) {
params := make(map[string]string)
if len(vpcId) > 0 {
params["VpcId"] = vpcId
}
if name == "Default" {
name = "Default-copy"
if len(resourceGroupId) > 0 {
params["ResourceGroupId"] = resourceGroupId
}
if len(name) > 0 {
@@ -355,15 +363,13 @@ func (self *SRegion) addSecurityGroupRule(secGrpId string, rule cloudprovider.Se
}
// 忽略地址为0.0.0.0/32这样的阿里云规则
if rule.IPNet.IP.String() == "0.0.0.0" && rule.IPNet.String() != "0.0.0.0/0" && len(rule.PeerSecgroupId) == 0 {
if rule.IPNet.IP.String() == "0.0.0.0" && rule.IPNet.String() != "0.0.0.0/0" {
return nil
}
params["Priority"] = fmt.Sprintf("%d", rule.Priority)
if rule.Direction == secrules.SecurityRuleIngress {
if len(rule.PeerSecgroupId) > 0 {
params["SourceGroupId"] = rule.PeerSecgroupId
} else if rule.IPNet != nil {
if rule.IPNet != nil {
params["SourceCidrIp"] = rule.IPNet.String()
} else {
params["SourceCidrIp"] = "0.0.0.0/0"
@@ -371,9 +377,7 @@ func (self *SRegion) addSecurityGroupRule(secGrpId string, rule cloudprovider.Se
_, err := self.ecsRequest("AuthorizeSecurityGroup", params)
return err
} else { // rule.Direction == secrules.SecurityRuleEgress {
if len(rule.PeerSecgroupId) > 0 {
params["DestGroupId"] = rule.PeerSecgroupId
} else if rule.IPNet != nil {
if rule.IPNet != nil {
params["DestCidrIp"] = rule.IPNet.String()
} else {
params["DestCidrIp"] = "0.0.0.0/0"
@@ -408,9 +412,7 @@ func (self *SRegion) DelSecurityGroupRule(secGrpId string, rule cloudprovider.Se
}
params["Priority"] = fmt.Sprintf("%d", rule.Priority)
if rule.Direction == secrules.SecurityRuleIngress {
if len(rule.PeerSecgroupId) > 0 {
params["SourceGroupId"] = rule.PeerSecgroupId
} else if rule.IPNet != nil {
if rule.IPNet != nil {
params["SourceCidrIp"] = rule.IPNet.String()
} else {
params["SourceCidrIp"] = "0.0.0.0/0"
@@ -418,9 +420,7 @@ func (self *SRegion) DelSecurityGroupRule(secGrpId string, rule cloudprovider.Se
_, err := self.ecsRequest("RevokeSecurityGroup", params)
return err
} else { // rule.Direction == secrules.SecurityRuleEgress {
if len(rule.PeerSecgroupId) > 0 {
params["DestGroupId"] = rule.PeerSecgroupId
} else if rule.IPNet != nil {
if rule.IPNet != nil {
params["DestCidrIp"] = rule.IPNet.String()
} else {
params["DestCidrIp"] = "0.0.0.0/0"
@@ -432,11 +432,10 @@ func (self *SRegion) DelSecurityGroupRule(secGrpId string, rule cloudprovider.Se
func (self *SPermission) toRule() (cloudprovider.SecurityRule, error) {
rule := cloudprovider.SecurityRule{
PeerSecgroupId: self.SourceGroupId,
SecurityRule: secrules.SecurityRule{
Action: secrules.SecurityRuleDeny,
Direction: secrules.DIR_IN,
Priority: self.Priority,
Priority: 101 - self.Priority,
Description: self.Description,
PortStart: -1,
PortEnd: -1,
@@ -451,10 +450,6 @@ func (self *SPermission) toRule() (cloudprovider.SecurityRule, error) {
rule.Direction = secrules.DIR_OUT
cidr = self.DestCidrIp
}
if len(self.SourceGroupId) > 0 || len(self.DestGroupId) > 0 {
cidr = "0.0.0.0/0"
rule.PeerSecgroupId = self.SourceGroupId + self.DestGroupId
}
rule.ParseCIDR(cidr)
@@ -527,25 +522,9 @@ func (self *SRegion) DeleteSecurityGroup(secGrpId string) error {
}
func (self *SSecurityGroup) Delete() error {
return self.vpc.region.DeleteSecurityGroup(self.SecurityGroupId)
return self.region.DeleteSecurityGroup(self.SecurityGroupId)
}
func (self *SSecurityGroup) GetProjectId() string {
return ""
}
func (self *SSecurityGroup) SyncRules(common, inAdds, outAdds, inDels, outDels []cloudprovider.SecurityRule) error {
for _, rule := range append(inDels, outDels...) {
err := self.vpc.region.DelSecurityGroupRule(self.SecurityGroupId, rule)
if err != nil {
return errors.Wrapf(err, "DelSecurityGroupRule(Name:%s priority: %d %s)", rule.Name, rule.Priority, rule.String())
}
}
for _, rule := range append(inAdds, outAdds...) {
err := self.vpc.region.AddSecurityGroupRules(self.SecurityGroupId, rule)
if err != nil {
return errors.Wrapf(err, "AddSecurityGroupRules(priority: %d %s)", rule.Priority, rule.String())
}
}
return nil
}
+1 -1
View File
@@ -185,7 +185,7 @@ func (self *SVpc) fetchSecurityGroups() error {
}
self.secgroups = make([]cloudprovider.ICloudSecurityGroup, len(secgroups))
for i := 0; i < len(secgroups); i++ {
secgroups[i].vpc = self
secgroups[i].region = self.region
self.secgroups[i] = &secgroups[i]
}
return nil
+16 -1
View File
@@ -761,10 +761,25 @@ func (region *SRegion) GetISecurityGroupByName(opts *cloudprovider.SecurityGroup
}
func (region *SRegion) CreateISecurityGroup(conf *cloudprovider.SecurityGroupCreateInput) (cloudprovider.ICloudSecurityGroup, error) {
externalId, err := region.CreateSecurityGroup(conf.VpcId, conf.Name, conf.Desc)
externalId, err := region.CreateSecurityGroup(conf.VpcId, conf.Name, conf.Desc, conf.ProjectId)
if err != nil {
return nil, err
}
if conf.OnCreated != nil {
conf.OnCreated(externalId)
}
outRules := conf.OutRules
if len(outRules) > 0 && outRules[0].String() == "out:allow any" {
outRules = outRules[1:]
}
rules := append(conf.InRules, conf.OutRules...)
for _, rule := range rules {
rule.Priority = 101 - rule.Priority
err = region.addSecurityGroupRule(externalId, rule.SecurityRule)
if err != nil {
return nil, err
}
}
return region.GetISecurityGroupById(externalId)
}
+3 -19
View File
@@ -210,14 +210,14 @@ func (self *SRegion) GetSecurityGroupDetails(secGroupId string) (*SSecurityGroup
return &secgrp, nil
}
func (self *SRegion) CreateSecurityGroup(vpcId string, name string, desc string) (string, error) {
func (self *SRegion) CreateSecurityGroup(vpcId string, name string, desc, projectId string) (string, error) {
params := make(map[string]string)
if len(vpcId) > 0 {
params["VpcId"] = vpcId
}
if name == "Default" {
name = "Default-copy"
if len(projectId) > 0 {
params["ResourceGroupId"] = projectId
}
if len(name) > 0 {
@@ -494,19 +494,3 @@ func (self *SRegion) DeleteSecurityGroup(secGrpId string) error {
func (self *SSecurityGroup) Delete() error {
return self.vpc.region.DeleteSecurityGroup(self.SecurityGroupId)
}
func (self *SSecurityGroup) SyncRules(common, inAdds, outAdds, inDels, outDels []cloudprovider.SecurityRule) error {
for _, rule := range append(inDels, outDels...) {
err := self.vpc.region.DelSecurityGroupRule(self.SecurityGroupId, rule.SecurityRule)
if err != nil {
return errors.Wrapf(err, "DelSecurityGroupRule(Name:%s priority: %d %s)", rule.Name, rule.Priority, rule.String())
}
}
for _, rule := range append(inAdds, outAdds...) {
err := self.vpc.region.AddSecurityGroupRules(self.SecurityGroupId, rule.SecurityRule)
if err != nil {
return errors.Wrapf(err, "AddSecurityGroupRules(priority: %d %s)", rule.Priority, rule.String())
}
}
return nil
}
-18
View File
@@ -209,24 +209,6 @@ func (self *SHost) _createVM(name, imgId string, sysDisk cloudprovider.SDiskInfo
return "", fmt.Errorf("wire's vpc is empty")
}
if len(secgroupId) == 0 {
secgroups, err := net.wire.vpc.GetISecurityGroups()
if err != nil {
return "", fmt.Errorf("get security group error %s", err)
}
if len(secgroups) == 0 {
// aws 默认就已经创建好了一个默认安全组。正常情况下并不需要手动创建
secId, err := self.zone.region.createDefaultSecurityGroup(net.wire.vpc.VpcId)
if err != nil {
return "", fmt.Errorf("no secgroup for vpc and failed to create a default One!!")
} else {
secgroupId = secId
}
} else {
secgroupId = secgroups[0].GetId()
}
}
// 同步keypair
var err error
keypair := ""
+28 -18
View File
@@ -33,6 +33,7 @@ import (
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/secrules"
api "yunion.io/x/cloudmux/pkg/apis/compute"
"yunion.io/x/cloudmux/pkg/cloudprovider"
@@ -927,39 +928,48 @@ func (self *SRegion) GetSkus(zoneId string) ([]cloudprovider.ICloudSku, error) {
return nil, cloudprovider.ErrNotImplemented
}
func (self *SRegion) GetISecurityGroupById(secgroupId string) (cloudprovider.ICloudSecurityGroup, error) {
secgroups, total, err := self.GetSecurityGroups("", "", secgroupId, 0, 1)
func (self *SRegion) GetISecurityGroupById(id string) (cloudprovider.ICloudSecurityGroup, error) {
ret, err := self.GetSecurityGroup(id)
if err != nil {
return nil, errors.Wrap(err, "GetSecurityGroups")
}
if total == 0 {
return nil, cloudprovider.ErrNotFound
}
if total > 1 {
return nil, cloudprovider.ErrDuplicateId
}
return &secgroups[0], nil
return ret, nil
}
func (self *SRegion) GetISecurityGroupByName(opts *cloudprovider.SecurityGroupFilterOptions) (cloudprovider.ICloudSecurityGroup, error) {
secgroups, total, err := self.GetSecurityGroups(opts.VpcId, opts.Name, "", 0, 1)
secgroups, err := self.GetSecurityGroups(opts.VpcId, opts.Name, "")
if err != nil {
return nil, errors.Wrap(err, "GetSecurityGroups")
}
if total == 0 {
return nil, cloudprovider.ErrNotFound
for i := range secgroups {
if secgroups[i].GetName() == opts.Name {
secgroups[i].region = self
return &secgroups[i], nil
}
}
if total > 1 {
return nil, cloudprovider.ErrDuplicateId
}
return &secgroups[0], nil
return nil, errors.Wrapf(cloudprovider.ErrNotFound, opts.Name)
}
func (self *SRegion) CreateISecurityGroup(conf *cloudprovider.SecurityGroupCreateInput) (cloudprovider.ICloudSecurityGroup, error) {
groupId, err := self.CreateSecurityGroup(conf.VpcId, conf.Name, "", conf.Desc)
func (self *SRegion) CreateISecurityGroup(opts *cloudprovider.SecurityGroupCreateInput) (cloudprovider.ICloudSecurityGroup, error) {
groupId, err := self.CreateSecurityGroup(opts.VpcId, opts.Name, opts.Desc)
if err != nil {
return nil, errors.Wrap(err, "CreateSecurityGroup")
}
if opts.OnCreated != nil {
opts.OnCreated(groupId)
}
self.RemoveSecurityGroupRule(groupId, *secrules.MustParseSecurityRule("in:allow any"))
self.RemoveSecurityGroupRule(groupId, *secrules.MustParseSecurityRule("out:allow any"))
inRules := opts.InRules.AllowList()
outRules := opts.OutRules.AllowList()
err = self.AddSecurityGroupRule(groupId, secrules.DIR_IN, inRules)
if err != nil {
return nil, errors.Wrapf(err, "AddSecurityGroupRule")
}
err = self.AddSecurityGroupRule(groupId, secrules.DIR_OUT, outRules)
if err != nil {
return nil, errors.Wrapf(err, "AddSecurityGroupRule")
}
return self.GetISecurityGroupById(groupId)
}
+192 -386
View File
@@ -16,49 +16,51 @@ package aws
import (
"fmt"
"math/rand"
"net"
"strings"
"time"
"github.com/aws/aws-sdk-go/service/ec2"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/secrules"
"yunion.io/x/pkg/utils"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/cloudmux/pkg/multicloud"
)
type SSecurityGroupRule struct {
IpProtocol string `xml:"ipProtocol"`
Groups []struct {
GroupId string `xml:"groupId"`
} `xml:"groups>item"`
IpRanges []struct {
CidrIp string `xml:"cidrIp"`
} `xml:"ipRanges>item"`
Ipv6Ranges []struct {
CidrIpv6 string `xml:"cidrIpv6"`
} `xml:"ipv6Ranges>item"`
PrefixListIds []struct {
PrefixListId string `xml:"prefixListId"`
} `xml:"prefixListIds>item"`
FromPort int `xml:"fromPort"`
ToPort int `xml:"toPort"`
}
type SSecurityGroup struct {
multicloud.SSecurityGroup
AwsTags
vpc *SVpc
region *SRegion
RegionId string
VpcId string
SecurityGroupId string
Description string
SecurityGroupName string
Permissions []cloudprovider.SecurityRule
// CreationTime time.Time
// InnerAccessPolicy string
}
func randomString(prefix string, length int) string {
bytes := []byte("0123456789abcdefghijklmnopqrstuvwxyz")
result := []byte{}
r := rand.New(rand.NewSource(time.Now().UnixNano()))
for i := 0; i < length; i++ {
result = append(result, bytes[r.Intn(len(bytes))])
}
return prefix + string(result)
GroupId string `xml:"groupId"`
VpcId string `xml:"vpcId"`
GroupName string `xml:"groupName"`
GroupDescription string `xml:"groupDescription"`
IpPermissions []SSecurityGroupRule `xml:"ipPermissions>item"`
IpPermissionsEgress []SSecurityGroupRule `xml:"ipPermissionsEgress>item"`
}
func (self *SSecurityGroup) GetId() string {
return self.SecurityGroupId
return self.GroupId
}
func (self *SSecurityGroup) GetVpcId() string {
@@ -66,14 +68,14 @@ func (self *SSecurityGroup) GetVpcId() string {
}
func (self *SSecurityGroup) GetName() string {
if len(self.SecurityGroupName) > 0 {
return self.SecurityGroupName
if len(self.GroupName) > 0 {
return self.GroupName
}
return self.SecurityGroupId
return self.GroupId
}
func (self *SSecurityGroup) GetGlobalId() string {
return self.SecurityGroupId
return self.GroupId
}
func (self *SSecurityGroup) GetStatus() string {
@@ -81,410 +83,214 @@ func (self *SSecurityGroup) GetStatus() string {
}
func (self *SSecurityGroup) Refresh() error {
if new, err := self.vpc.region.GetSecurityGroupDetails(self.SecurityGroupId); err != nil {
group, err := self.region.GetSecurityGroup(self.GroupId)
if err != nil {
return err
} else {
return jsonutils.Update(self, new)
}
}
func (self *SSecurityGroup) IsEmulated() bool {
return false
self.IpPermissions = group.IpPermissions
self.IpPermissionsEgress = group.IpPermissionsEgress
return jsonutils.Update(self, group)
}
func (self *SSecurityGroup) GetDescription() string {
return self.Description
return self.GroupDescription
}
func (self *SSecurityGroup) GetRules() ([]cloudprovider.SecurityRule, error) {
secgrp, err := self.vpc.region.GetSecurityGroupDetails(self.SecurityGroupId)
if err != nil {
return nil, errors.Wrap(err, "GetSecurityGroupDetails")
}
return secgrp.Permissions, nil
}
func (self *SRegion) addSecurityGroupRules(secGrpId string, rule cloudprovider.SecurityRule) error {
if len(rule.Ports) != 0 {
for _, port := range rule.Ports {
rule.PortStart, rule.PortEnd = port, port
err := self.addSecurityGroupRule(secGrpId, rule)
if err != nil {
return errors.Wrapf(err, "addSecurityGroupRule(%d %s)", rule.Priority, rule.String())
ret := []cloudprovider.SecurityRule{}
for direction, rules := range map[secrules.TSecurityRuleDirection][]SSecurityGroupRule{
secrules.DIR_IN: self.IpPermissions,
secrules.DIR_OUT: self.IpPermissionsEgress,
} {
for i := range rules {
if len(rules[i].IpRanges) == 0 { // 非cidr安全组规则不支持
continue
}
if !utils.IsInStringArray(rules[i].IpProtocol, []string{"-1", "tcp", "udp", "icmp"}) {
continue
}
protocol := rules[i].IpProtocol
if protocol == "-1" {
protocol = secrules.PROTO_ANY
}
portStart, portEnd := -1, -1
if rules[i].FromPort > 0 && rules[i].ToPort > 0 {
portStart, portEnd = rules[i].FromPort, rules[i].ToPort
}
for _, cidr := range rules[i].IpRanges {
_, ipNet, err := net.ParseCIDR(cidr.CidrIp)
if err != nil {
return nil, errors.Wrapf(err, "net.ParseCIDR(%s)", cidr.CidrIp)
}
ret = append(ret, cloudprovider.SecurityRule{
SecurityRule: secrules.SecurityRule{
Priority: 1,
Action: secrules.SecurityRuleAllow,
Direction: direction,
IPNet: ipNet,
Protocol: protocol,
PortStart: portStart,
PortEnd: portEnd,
},
})
}
}
}
return ret, nil
}
func (self *SRegion) RemoveSecurityGroupRule(secGrpId string, rule secrules.SecurityRule) error {
params := map[string]string{
"GroupId": secGrpId,
}
idx := 1
params[fmt.Sprintf("IpPermissions.%d.IpProtocol", idx)] = "-1"
if rule.Protocol != secrules.PROTO_ANY {
params[fmt.Sprintf("IpPermissions.%d.IpProtocol", idx)] = strings.ToLower(rule.Protocol)
}
if rule.IPNet != nil {
params[fmt.Sprintf("IpPermissions.%d.IpRanges.1.CidrIp", idx)] = rule.IPNet.String()
}
if rule.PortStart > 0 && rule.PortEnd > 0 {
params[fmt.Sprintf("IpPermissions.%d.FromPort", idx)] = fmt.Sprintf("%d", rule.PortStart)
params[fmt.Sprintf("IpPermissions.%d.ToPort", idx)] = fmt.Sprintf("%d", rule.PortEnd)
}
action := "RevokeSecurityGroupIngress"
if rule.Direction == secrules.DIR_OUT {
action = "RevokeSecurityGroupEgress"
}
return self.ec2Request(action, params, nil)
}
func (self *SRegion) AddSecurityGroupRule(secGrpId string, direction secrules.TSecurityRuleDirection, rules []secrules.SecurityRule) error {
if len(rules) == 0 {
return nil
}
return self.addSecurityGroupRule(secGrpId, rule)
}
func (self *SRegion) addSecurityGroupRule(secGrpId string, rule cloudprovider.SecurityRule) error {
ec2Client, err := self.getEc2Client()
if err != nil {
return errors.Wrap(err, "getEc2Client")
params := map[string]string{
"GroupId": secGrpId,
}
ipPermissions, err := YunionSecRuleToAws(rule)
log.Debugf("Aws security group rule: %s", ipPermissions)
if err != nil {
return err
}
if rule.Direction == secrules.SecurityRuleIngress {
params := &ec2.AuthorizeSecurityGroupIngressInput{}
params.SetGroupId(secGrpId)
params.SetIpPermissions(ipPermissions)
_, err = ec2Client.AuthorizeSecurityGroupIngress(params)
}
if rule.Direction == secrules.SecurityRuleEgress {
params := &ec2.AuthorizeSecurityGroupEgressInput{}
params.SetGroupId(secGrpId)
params.SetIpPermissions(ipPermissions)
_, err = ec2Client.AuthorizeSecurityGroupEgress(params)
}
if err != nil && strings.Contains(err.Error(), "InvalidPermission.Duplicate") {
log.Debugf("addSecurityGroupRule %s %s", rule.Direction, err.Error())
return nil
}
return err
}
func (self *SRegion) DelSecurityGroupRule(secGrpId string, rule cloudprovider.SecurityRule) error {
ec2Client, err := self.getEc2Client()
if err != nil {
return errors.Wrap(err, "getEc2Client")
}
ipPermissions, err := YunionSecRuleToAws(rule)
if err != nil {
return err
}
if rule.Direction == secrules.SecurityRuleIngress {
params := &ec2.RevokeSecurityGroupIngressInput{}
params.SetGroupId(secGrpId)
params.SetIpPermissions(ipPermissions)
_, err = ec2Client.RevokeSecurityGroupIngress(params)
}
if rule.Direction == secrules.SecurityRuleEgress {
params := &ec2.RevokeSecurityGroupEgressInput{}
params.SetGroupId(secGrpId)
params.SetIpPermissions(ipPermissions)
_, err = ec2Client.RevokeSecurityGroupEgress(params)
}
if err != nil {
log.Debugf("delSecurityGroupRule %s %s", rule.Direction, err.Error())
return err
}
return nil
}
func (self *SRegion) updateSecurityGroupRuleDescription(secGrpId string, rule cloudprovider.SecurityRule) error {
ipPermissions, err := YunionSecRuleToAws(rule)
if err != nil {
return err
}
ec2Client, err := self.getEc2Client()
if err != nil {
return errors.Wrap(err, "getEc2Client")
}
if rule.Direction == secrules.SecurityRuleIngress {
params := &ec2.UpdateSecurityGroupRuleDescriptionsIngressInput{}
params.SetGroupId(secGrpId)
params.SetIpPermissions(ipPermissions)
ret, err := ec2Client.UpdateSecurityGroupRuleDescriptionsIngress(params)
if err != nil {
return err
} else if ret.Return != nil && *ret.Return == false {
log.Debugf("update security group %s rule description failed: %s", secGrpId, ipPermissions)
idx := 1
for i := range rules {
rule := rules[i]
if len(rule.Ports) > 0 {
for _, port := range rule.Ports {
if rule.Protocol != secrules.PROTO_ANY {
params[fmt.Sprintf("IpPermissions.%d.IpProtocol", idx)] = strings.ToLower(rule.Protocol)
}
if rule.IPNet != nil {
params[fmt.Sprintf("IpPermissions.%d.IpRanges.1.CidrIp", idx)] = rule.IPNet.String()
}
params[fmt.Sprintf("IpPermissions.%d.FromPort", idx)] = fmt.Sprintf("%d", port)
params[fmt.Sprintf("IpPermissions.%d.ToPort", idx)] = fmt.Sprintf("%d", port)
idx++
}
continue
}
}
if rule.Direction == secrules.SecurityRuleEgress {
params := &ec2.UpdateSecurityGroupRuleDescriptionsEgressInput{}
params.SetGroupId(secGrpId)
params.SetIpPermissions(ipPermissions)
ret, err := ec2Client.UpdateSecurityGroupRuleDescriptionsEgress(params)
if err != nil {
return err
} else if ret.Return != nil && *ret.Return == false {
log.Debugf("update security group %s rule description failed: %s", secGrpId, ipPermissions)
if rule.Protocol != secrules.PROTO_ANY {
params[fmt.Sprintf("IpPermissions.%d.IpProtocol", idx)] = strings.ToLower(rule.Protocol)
}
if rule.IPNet != nil {
params[fmt.Sprintf("IpPermissions.%d.IpRanges.1.CidrIp", idx)] = rule.IPNet.String()
}
params[fmt.Sprintf("IpPermissions.%d.FromPort", idx)] = "0"
params[fmt.Sprintf("IpPermissions.%d.ToPort", idx)] = "65535"
if rule.Protocol == secrules.PROTO_ICMP {
params[fmt.Sprintf("IpPermissions.%d.FromPort", idx)] = "-1"
params[fmt.Sprintf("IpPermissions.%d.ToPort", idx)] = "-1"
}
if rule.PortStart > 0 && rule.PortEnd > 0 {
params[fmt.Sprintf("IpPermissions.%d.FromPort", idx)] = fmt.Sprintf("%d", rule.PortStart)
params[fmt.Sprintf("IpPermissions.%d.ToPort", idx)] = fmt.Sprintf("%d", rule.PortEnd)
}
idx++
}
return nil
action := "AuthorizeSecurityGroupIngress"
if direction == secrules.DIR_OUT {
action = "AuthorizeSecurityGroupEgress"
}
return self.ec2Request(action, params, nil)
}
func (self *SRegion) CreateSecurityGroup(vpcId string, name string, secgroupIdTag string, desc string) (string, error) {
ec2Client, err := self.getEc2Client()
if err != nil {
return "", errors.Wrap(err, "getEc2Client")
func (self *SRegion) DelSecurityGroupRule(secGrpId string, ruleId string) error {
params := map[string]string{
"GroupId": secGrpId,
"SecurityGroupRuleId.1": ruleId,
}
return self.ec2Request("RevokeSecurityGroupEgress", params, nil)
}
params := &ec2.CreateSecurityGroupInput{}
params.SetVpcId(vpcId)
// 这里的描述aws 上层代码拼接的描述。并非用户提交的描述,用户描述放置在Yunion本地数据库中。)
func (self *SRegion) CreateSecurityGroup(vpcId string, name string, desc string) (string, error) {
params := map[string]string{
"VpcId": vpcId,
"GroupDescription": desc,
"GroupName": name,
}
if len(desc) == 0 {
desc = "vpc default group"
params["GroupDescription"] = "auto create by cloudpods"
}
params.SetDescription(desc)
if strings.ToLower(name) == "default" {
name = randomString(fmt.Sprintf("%s-", vpcId), 9)
}
params.SetGroupName(name)
group, err := ec2Client.CreateSecurityGroup(params)
ret := struct {
GroupId string `xml:"groupId"`
}{}
err := self.ec2Request("CreateSecurityGroup", params, &ret)
if err != nil {
return "", err
}
tagspec := TagSpec{ResourceType: "security-group"}
if len(secgroupIdTag) > 0 {
tagspec.SetTag("id", secgroupIdTag)
}
tagspec.SetNameTag(name)
tagspec.SetDescTag(desc)
tags, _ := tagspec.GetTagSpecifications()
tagParams := &ec2.CreateTagsInput{}
tagParams.SetResources([]*string{group.GroupId})
tagParams.SetTags(tags.Tags)
_, err = ec2Client.CreateTags(tagParams)
if err != nil {
return "", err
}
return *group.GroupId, nil
return ret.GroupId, nil
}
func (self *SRegion) createDefaultSecurityGroup(vpcId string) (string, error) {
name := randomString(fmt.Sprintf("%s-", vpcId), 9)
secId, err := self.CreateSecurityGroup(vpcId, name, "default", "vpc default group")
func (self *SRegion) GetSecurityGroup(id string) (*SSecurityGroup, error) {
groups, err := self.GetSecurityGroups("", "", id)
if err != nil {
return "", err
return nil, err
}
rule := cloudprovider.SecurityRule{
SecurityRule: secrules.SecurityRule{
Priority: 1,
Action: secrules.SecurityRuleAllow,
Protocol: "",
Direction: secrules.SecurityRuleIngress,
PortStart: -1,
PortEnd: -1,
},
}
err = self.addSecurityGroupRule(secId, rule)
if err != nil {
return "", err
}
return secId, nil
}
func (self *SRegion) GetSecurityGroupDetails(secGroupId string) (*SSecurityGroup, error) {
if len(secGroupId) == 0 {
return nil, fmt.Errorf("GetSecurityGroupDetails security group id should not be empty.")
}
params := &ec2.DescribeSecurityGroupsInput{}
params.SetGroupIds([]*string{&secGroupId})
ec2Client, err := self.getEc2Client()
if err != nil {
return nil, errors.Wrap(err, "getEc2Client")
}
ret, err := ec2Client.DescribeSecurityGroups(params)
err = parseNotFoundError(err)
if err != nil {
return nil, errors.Wrap(err, "DescribeSecurityGroups")
}
if len(ret.SecurityGroups) == 1 {
s := ret.SecurityGroups[0]
vpc, err := self.getVpc(*s.VpcId)
if err != nil {
return nil, fmt.Errorf("vpc %s not found", *s.VpcId)
}
permissions := self.getSecRules(s.IpPermissions, s.IpPermissionsEgress)
return &SSecurityGroup{
vpc: vpc,
Description: *s.Description,
SecurityGroupId: *s.GroupId,
SecurityGroupName: *s.GroupName,
VpcId: *s.VpcId,
Permissions: permissions,
RegionId: self.RegionId,
}, nil
} else {
return nil, fmt.Errorf("required one security group. but found: %d", len(ret.SecurityGroups))
}
}
func (self *SRegion) getSecurityGroupById(vpcId, secgroupId string) (*SSecurityGroup, error) {
if len(secgroupId) == 0 {
return nil, errors.Wrapf(cloudprovider.ErrInputParameter, "security group id should not be empty")
}
secgroups, total, err := self.GetSecurityGroups(vpcId, "", secgroupId, 0, 0)
if err != nil {
log.Errorf("GetSecurityGroups vpc %s secgroupId %s: %s", vpcId, secgroupId, err)
return nil, errors.Wrap(err, "GetSecurityGroups")
}
if total != 1 {
log.Debugf("failed to find SecurityGroup %s: %d found", secgroupId, total)
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "failed to find SecurityGroup %s", secgroupId)
}
return &secgroups[0], nil
}
func (self *SRegion) addTagToSecurityGroup(secgroupId, key, value string, index int) error {
return nil
}
func (self *SRegion) modifySecurityGroup(secGrpId string, name string, desc string) error {
tagspec := TagSpec{ResourceType: "security-group"}
tagspec.SetNameTag(name)
tagspec.SetDescTag(desc)
ec2Tags, _ := tagspec.GetTagSpecifications()
params := &ec2.CreateTagsInput{}
params.SetTags(ec2Tags.Tags)
params.SetResources([]*string{&secGrpId})
ec2Client, err := self.getEc2Client()
if err != nil {
return errors.Wrap(err, "getEc2Client")
}
_, err = ec2Client.CreateTags(params)
if err != nil {
return errors.Wrap(err, "CreateTags")
}
return nil
}
func (self *SRegion) getSecRules(ingress []*ec2.IpPermission, egress []*ec2.IpPermission) []cloudprovider.SecurityRule {
rules := []cloudprovider.SecurityRule{}
for _, p := range ingress {
ret, err := AwsIpPermissionToYunion(secrules.SecurityRuleIngress, *p)
if err != nil {
log.Debugln(err)
}
for _, rule := range ret {
rules = append(rules, rule)
for i := range groups {
if groups[i].GetGlobalId() == id {
groups[i].region = self
return &groups[i], nil
}
}
for _, p := range egress {
ret, err := AwsIpPermissionToYunion(secrules.SecurityRuleEgress, *p)
if err != nil {
log.Debugln(err)
}
for _, rule := range ret {
rules = append(rules, rule)
}
}
return rules
return nil, cloudprovider.ErrNotFound
}
func (self *SRegion) GetSecurityGroups(vpcId string, name string, secgroupId string, offset int, limit int) ([]SSecurityGroup, int, error) {
params := &ec2.DescribeSecurityGroupsInput{}
filters := make([]*ec2.Filter, 0)
func (self *SRegion) GetSecurityGroups(vpcId string, name string, secgroupId string) ([]SSecurityGroup, error) {
params := map[string]string{}
idx := 1
if len(vpcId) > 0 {
filters = AppendSingleValueFilter(filters, "vpc-id", vpcId)
params[fmt.Sprintf("Filter.%d.Name", idx)] = "vpc-id"
params[fmt.Sprintf("Filter.%d.Value.1", idx)] = vpcId
idx++
}
if len(name) > 0 {
filters = AppendSingleValueFilter(filters, "group-name", name)
params[fmt.Sprintf("Filter.%d.Name", idx)] = "group-name"
params[fmt.Sprintf("Filter.%d.Value.1", idx)] = name
idx++
}
if len(secgroupId) > 0 {
params.SetGroupIds([]*string{&secgroupId})
params["GroupId.0"] = secgroupId
}
if len(filters) > 0 {
params.SetFilters(filters)
}
ec2Client, err := self.getEc2Client()
if err != nil {
return nil, 0, errors.Wrap(err, "getEc2Client")
}
ret, err := ec2Client.DescribeSecurityGroups(params)
err = parseNotFoundError(err)
if err != nil {
return nil, 0, err
}
securityGroups := []SSecurityGroup{}
for _, item := range ret.SecurityGroups {
if err := FillZero(item); err != nil {
return nil, 0, err
}
if len(*item.VpcId) == 0 {
log.Debugf("ingored: security group with no vpc binded")
continue
}
vpc, err := self.getVpc(*item.VpcId)
result := []SSecurityGroup{}
for {
ret := struct {
NextToken string `xml:"nextToken"`
SecurityGroupInfo []SSecurityGroup `xml:"securityGroupInfo>item"`
}{}
err := self.ec2Request("DescribeSecurityGroups", params, &ret)
if err != nil {
log.Errorf("vpc %s not found", *item.VpcId)
continue
return nil, err
}
permissions := self.getSecRules(item.IpPermissions, item.IpPermissionsEgress)
group := SSecurityGroup{
vpc: vpc,
Description: *item.Description,
SecurityGroupId: *item.GroupId,
SecurityGroupName: *item.GroupName,
VpcId: *item.VpcId,
Permissions: permissions,
RegionId: self.RegionId,
// Tags: *item.Tags,
result = append(result, ret.SecurityGroupInfo...)
if len(ret.NextToken) == 0 || len(ret.SecurityGroupInfo) == 0 {
break
}
securityGroups = append(securityGroups, group)
params["NextToken"] = ret.NextToken
}
return securityGroups, len(securityGroups), nil
return result, nil
}
func (self *SSecurityGroup) GetProjectId() string {
return ""
}
func (self *SSecurityGroup) SyncRules(common, inAdds, outAdds, inDels, outDels []cloudprovider.SecurityRule) error {
for _, r := range append(inDels, outDels...) {
err := self.vpc.region.DelSecurityGroupRule(self.SecurityGroupId, r)
if err != nil {
if strings.Contains(err.Error(), "InvalidPermission.NotFound") {
continue
}
return errors.Wrapf(err, "delSecurityGroupRule %s %d %s", r.Name, r.Priority, r.String())
}
}
for _, r := range append(inAdds, outAdds...) {
err := self.vpc.region.addSecurityGroupRules(self.SecurityGroupId, r)
if err != nil {
return errors.Wrapf(err, "addSecurityGroupRules %d %s", r.Priority, r.String())
}
}
return nil
}
func (self *SSecurityGroup) Delete() error {
return self.vpc.region.DeleteSecurityGroup(self.SecurityGroupId)
return self.region.DeleteSecurityGroup(self.GroupId)
}
-217
View File
@@ -16,17 +16,13 @@ package aws
import (
"fmt"
"net"
"reflect"
"sort"
"strings"
"github.com/aws/aws-sdk-go/service/ec2"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/secrules"
"yunion.io/x/cloudmux/pkg/cloudprovider"
)
@@ -185,219 +181,6 @@ func IntVal(s *int64) int64 {
return 0
}
// SecurityRuleSet to allow list
// 将安全组规则全部转换为等价的allow规则
func SecurityRuleSetToAllowSet(srs secrules.SecurityRuleSet) secrules.SecurityRuleSet {
inRuleSet := secrules.SecurityRuleSet{}
outRuleSet := secrules.SecurityRuleSet{}
for _, rule := range srs {
if rule.Direction == secrules.SecurityRuleIngress {
inRuleSet = append(inRuleSet, rule)
}
if rule.Direction == secrules.SecurityRuleEgress {
outRuleSet = append(outRuleSet, rule)
}
}
sort.Sort(inRuleSet)
sort.Sort(outRuleSet)
inRuleSet = inRuleSet.AllowList()
outRuleSet = outRuleSet.AllowList()
ret := secrules.SecurityRuleSet{}
ret = append(ret, inRuleSet...)
ret = append(ret, outRuleSet...)
return ret
}
func isAwsPermissionAllPorts(p ec2.IpPermission) bool {
if p.FromPort == nil || p.ToPort == nil {
return false
}
// 全部端口范围: TCP/UDP (0,65535) 其他:(-1,-1)
if (*p.IpProtocol == "tcp" || *p.IpProtocol == "udp") && *p.FromPort == 0 && *p.ToPort == 65535 {
return true
} else if *p.FromPort == -1 && *p.ToPort == -1 {
return true
} else {
return false
}
}
func awsProtocolToYunion(p ec2.IpPermission) string {
if p.IpProtocol != nil && *p.IpProtocol == "-1" {
return secrules.PROTO_ANY
} else {
return *p.IpProtocol
}
}
func yunionProtocolToAws(r cloudprovider.SecurityRule) string {
if r.Protocol == secrules.PROTO_ANY {
return "-1"
} else {
return r.Protocol
}
}
func isYunionRuleAllPorts(r secrules.SecurityRule) bool {
// 全部端口范围: TCP/UDP (0,65535) 其他:(-1,-1)
if (r.Protocol == "tcp" || r.Protocol == "udp") && r.PortStart == 0 && r.PortEnd == 65535 {
return true
} else if r.PortStart == -1 && r.PortEnd == -1 {
return true
} else {
return false
}
}
func yunionPortRangeToAws(r cloudprovider.SecurityRule) []portRange {
// port 0 / -1 都代表所有端口
portranges := []portRange{}
if len(r.Ports) == 0 {
var start, end = 0, 0
if r.PortStart <= 0 {
if r.Protocol == "tcp" || r.Protocol == "udp" {
start = 0
} else {
start = -1
}
} else {
start = r.PortStart
}
if r.PortEnd <= 0 {
if r.Protocol == "tcp" || r.Protocol == "udp" {
end = 65535
} else {
end = -1
}
} else {
end = r.PortEnd
}
portranges = append(portranges, portRange{int64(start), int64(end)})
}
for i := range r.Ports {
port := r.Ports[i]
if port <= 0 && (r.Protocol == "tcp" || r.Protocol == "udp") {
portranges = append(portranges, portRange{0, 65535})
} else if port <= 0 {
portranges = append(portranges, portRange{-1, -1})
} else {
portranges = append(portranges, portRange{int64(port), int64(port)})
}
}
return portranges
}
// Security Rule Transform
func AwsIpPermissionToYunion(direction secrules.TSecurityRuleDirection, p ec2.IpPermission) ([]cloudprovider.SecurityRule, error) {
if len(p.UserIdGroupPairs) > 0 {
return nil, fmt.Errorf("AwsIpPermissionToYunion not supported aws rule: UserIdGroupPairs specified")
}
if len(p.PrefixListIds) > 0 {
return nil, fmt.Errorf("AwsIpPermissionToYunion not supported aws rule: PrefixListIds specified")
}
if len(p.Ipv6Ranges) > 0 {
log.Debugf("AwsIpPermissionToYunion ignored IPV6 rule: %s", p.Ipv6Ranges)
}
rules := []cloudprovider.SecurityRule{}
isAllPorts := isAwsPermissionAllPorts(p)
protocol := awsProtocolToYunion(p)
for _, ip := range p.IpRanges {
_, ipNet, err := net.ParseCIDR(*ip.CidrIp)
if err != nil {
log.Errorf("ParseCIDR failed, ignored IPV4 rule: %s", *ip.CidrIp)
continue
}
var rule cloudprovider.SecurityRule
if isAllPorts {
rule = cloudprovider.SecurityRule{
SecurityRule: secrules.SecurityRule{
Action: secrules.SecurityRuleAllow,
IPNet: ipNet,
Protocol: protocol,
Direction: direction,
Priority: 1,
Description: StrVal(ip.Description),
},
}
} else {
rule = cloudprovider.SecurityRule{
SecurityRule: secrules.SecurityRule{
Action: secrules.SecurityRuleAllow,
IPNet: ipNet,
Protocol: protocol,
Direction: direction,
Priority: 1,
Description: StrVal(ip.Description),
},
}
if p.FromPort != nil {
rule.PortStart = int(*p.FromPort)
}
if p.ToPort != nil {
rule.PortEnd = int(*p.ToPort)
}
}
rules = append(rules, rule)
}
return rules, nil
}
// YunionSecRuleToAws 不能保证无损转换
// 规则描述如果包含中文等字符,将被丢弃掉
func YunionSecRuleToAws(rule cloudprovider.SecurityRule) ([]*ec2.IpPermission, error) {
iprange := rule.IPNet.String()
if iprange == "<nil>" {
return nil, fmt.Errorf("YunionSecRuleToAws ignored ipnet should not be empty")
}
ipranges := []*ec2.IpRange{}
ipranges = append(ipranges, &ec2.IpRange{CidrIp: &iprange})
portranges := yunionPortRangeToAws(rule)
protocol := yunionProtocolToAws(rule)
permissions := []*ec2.IpPermission{}
if rule.Protocol != secrules.PROTO_ANY {
for i := range portranges {
port := portranges[i]
permission := ec2.IpPermission{
FromPort: &port.Start,
IpProtocol: &protocol,
IpRanges: ipranges,
ToPort: &port.End,
}
permissions = append(permissions, &permission)
}
} else {
permissions = append(permissions, &ec2.IpPermission{
IpProtocol: &protocol,
IpRanges: ipranges,
})
}
return permissions, nil
}
// fill a pointer struct with zero value.
func FillZero(i interface{}) error {
V := reflect.Indirect(reflect.ValueOf(i))
+10 -27
View File
@@ -40,8 +40,7 @@ type SVpc struct {
region *SRegion
iwires []cloudprovider.ICloudWire
secgroups []cloudprovider.ICloudSecurityGroup
iwires []cloudprovider.ICloudWire
RegionId string
VpcId string
@@ -118,15 +117,17 @@ func (self *SVpc) GetIWires() ([]cloudprovider.ICloudWire, error) {
}
func (self *SVpc) GetISecurityGroups() ([]cloudprovider.ICloudSecurityGroup, error) {
if self.secgroups == nil {
err := self.fetchSecurityGroups()
if err != nil {
return nil, errors.Wrap(err, "fetchSecurityGroups")
}
secgroups, err := self.region.GetSecurityGroups(self.VpcId, "", "")
if err != nil {
return nil, errors.Wrap(err, "GetSecurityGroups")
}
return self.secgroups, nil
ret := []cloudprovider.ICloudSecurityGroup{}
for i := range secgroups {
secgroups[i].region = self.region
ret = append(ret, &secgroups[i])
}
return ret, nil
}
func (self *SVpc) GetIRouteTables() ([]cloudprovider.ICloudRouteTable, error) {
tables, err := self.region.GetRouteTables(self.GetId(), false)
if err != nil {
@@ -243,24 +244,6 @@ func (self *SVpc) assignSecurityGroup(secgroupId string, instanceId string) erro
return self.region.assignSecurityGroup(secgroupId, instanceId)
}
func (self *SVpc) fetchSecurityGroups() error {
if len(self.VpcId) == 0 {
return fmt.Errorf("fetchSecurityGroups vpc id is empty")
}
secgroups, _, err := self.region.GetSecurityGroups(self.VpcId, "", "", 0, 0)
if err != nil {
return errors.Wrap(err, "GetSecurityGroups")
}
self.secgroups = make([]cloudprovider.ICloudSecurityGroup, len(secgroups))
for i := 0; i < len(secgroups); i++ {
secgroups[i].vpc = self
self.secgroups[i] = &secgroups[i]
}
return nil
}
func (self *SVpc) GetICloudVpcPeeringConnections() ([]cloudprovider.ICloudVpcPeeringConnection, error) {
svpcPCs, err := self.getRequesterVpcPeeringConnections()
if err != nil {
@@ -152,7 +152,6 @@ func (self *SClassicSecurityGroup) GetRules() ([]cloudprovider.SecurityRule, err
continue
}
rule.Name = secgrouprules[i].Name
rule.ExternalId = secgrouprules[i].ID
if err := rule.ValidateRule(); err != nil && err != secrules.ErrInvalidPriority {
return nil, errors.Wrap(err, "rule.ValidateRule")
}
@@ -301,33 +300,3 @@ func (self *SRegion) addClassicSecgroupRule(secgroupId string, rule SClassicSecu
func (self *SClassicSecurityGroup) GetProjectId() string {
return getResourceGroup(self.ID)
}
func (self *SClassicSecurityGroup) SyncRules(common, inAdds, outAdds, inDels, outDels []cloudprovider.SecurityRule) error {
for _, r := range append(inDels, outDels...) {
err := self.region.del(r.ExternalId)
if err != nil {
return errors.Wrapf(err, "Delete(%s)", r.ExternalId)
}
for _, r := range append(inAdds, outAdds...) {
_rules, err := convertClassicSecurityGroupRules(r)
if err != nil {
return errors.Wrapf(err, "convertClassicSecurityGroupRules(%s)", r.String())
}
names := []string{}
for _, r := range _rules {
for {
if !utils.IsInStringArray(r.Name, names) {
names = append(names, r.Name)
break
}
r.Name = fmt.Sprintf("%s_", r.Name)
}
err = self.region.addClassicSecgroupRule(self.ID, r)
if err != nil {
return errors.Wrap(err, "addClassicSecgroupRule")
}
}
}
}
return nil
}
+1 -10
View File
@@ -88,16 +88,7 @@ func (self *SClassicVpc) Delete() error {
}
func (self *SClassicVpc) GetISecurityGroups() ([]cloudprovider.ICloudSecurityGroup, error) {
secgroups, err := self.region.ListSecgroups()
if err != nil {
return nil, errors.Wrapf(err, "ListSecgroups")
}
ret := []cloudprovider.ICloudSecurityGroup{}
for i := range secgroups {
secgroups[i].region = self.region
ret = append(ret, &secgroups[i])
}
return ret, nil
return []cloudprovider.ICloudSecurityGroup{}, nil
}
func (self *SClassicVpc) GetIRouteTables() ([]cloudprovider.ICloudRouteTable, error) {
+4 -4
View File
@@ -431,11 +431,11 @@ func (region *SRegion) GetISecurityGroupByName(opts *cloudprovider.SecurityGroup
return secgroup, nil
}
func (region *SRegion) CreateISecurityGroup(conf *cloudprovider.SecurityGroupCreateInput) (cloudprovider.ICloudSecurityGroup, error) {
if conf.VpcId == "classic" {
return region.CreateClassicSecurityGroup(conf.Name)
func (region *SRegion) CreateISecurityGroup(opts *cloudprovider.SecurityGroupCreateInput) (cloudprovider.ICloudSecurityGroup, error) {
if opts.VpcId == "classic" {
return region.CreateClassicSecurityGroup(opts.Name)
}
return region.CreateSecurityGroup(conf.Name)
return region.CreateSecurityGroup(opts)
}
func (region *SRegion) getIAppLBs() ([]cloudprovider.ICloudLoadbalancer, error) {
+44 -54
View File
@@ -190,7 +190,7 @@ func (self *SecurityRulePropertiesFormat) toRules() ([]cloudprovider.SecurityRul
Action: secrules.TSecurityRuleAction(strings.ToLower(self.Access)),
Direction: secrules.TSecurityRuleDirection(strings.Replace(strings.ToLower(self.Direction), "bound", "", -1)),
Protocol: strings.ToLower(self.Protocol),
Priority: int(self.Priority),
Priority: 4096 - int(self.Priority),
Description: self.Description,
}}
@@ -224,10 +224,6 @@ func (self *SecurityRulePropertiesFormat) toRules() ([]cloudprovider.SecurityRul
rule.Ports = ports[j].ports
rule.PortStart = ports[j].portStart
rule.PortEnd = ports[j].portEnd
err := rule.ValidateRule()
if err != nil && err != secrules.ErrInvalidPriority {
return nil, err
}
result = append(result, rule)
}
}
@@ -266,6 +262,8 @@ func (self *SSecurityGroup) GetName() string {
func (self *SSecurityGroup) GetRules() ([]cloudprovider.SecurityRule, error) {
rules := make([]cloudprovider.SecurityRule, 0)
outAllow := secrules.MustParseSecurityRule("out:allow any")
rules = append(rules, cloudprovider.SecurityRule{SecurityRule: *outAllow})
if self.Properties == nil || self.Properties.SecurityRules == nil {
return rules, nil
}
@@ -294,17 +292,51 @@ func (self *SSecurityGroup) GetVpcId() string {
return "normal"
}
func (region *SRegion) CreateSecurityGroup(secName string) (*SSecurityGroup, error) {
if secName == "Default" {
secName = "Default-copy"
}
func (region *SRegion) CreateSecurityGroup(opts *cloudprovider.SecurityGroupCreateInput) (*SSecurityGroup, error) {
secgroup := &SSecurityGroup{region: region}
params := map[string]string{
"Name": secName,
params := map[string]interface{}{
"Name": opts.Name,
"Type": "Microsoft.Network/networkSecurityGroups",
"Location": region.Name,
}
return secgroup, region.create("", jsonutils.Marshal(params), secgroup)
outRules := opts.OutRules
if len(outRules) > 0 && outRules[0].String() == "out:allow any" {
outRules = outRules[1:]
}
sortRules := func(rules []cloudprovider.SecurityRule) []SecurityRules {
names := []string{}
securityRules := []SecurityRules{}
offset := (4096-100)/len(rules) - 1
for i := 0; i < len(rules); i++ {
rules[i].Priority = 4096 - offset*i
rule := convertSecurityGroupRule(rules[i])
if rule != nil {
for {
if !utils.IsInStringArray(rule.Name, names) {
names = append(names, rule.Name)
break
}
rule.Name = fmt.Sprintf("%s_", rule.Name)
}
securityRules = append(securityRules, *rule)
}
}
return securityRules
}
rules := sortRules(opts.InRules)
rules = append(rules, sortRules(outRules)...)
params["properties"] = map[string]interface{}{
"securityRules": rules,
}
err := region.create("", jsonutils.Marshal(params), secgroup)
if err != nil {
return nil, errors.Wrapf(err, "create")
}
return secgroup, nil
}
func (region *SRegion) ListSecgroups() ([]SSecurityGroup, error) {
@@ -445,45 +477,3 @@ func (self *SSecurityGroup) Delete() error {
}
return self.region.del(self.ID)
}
func (self *SSecurityGroup) SetRules(rules []cloudprovider.SecurityRule) error {
names := []string{}
securityRules := []SecurityRules{}
for i := 0; i < len(rules); i++ {
rule := convertSecurityGroupRule(rules[i])
if rule != nil {
for {
if !utils.IsInStringArray(rule.Name, names) {
names = append(names, rule.Name)
break
}
rule.Name = fmt.Sprintf("%s_", rule.Name)
}
securityRules = append(securityRules, *rule)
}
}
if self.Properties == nil {
self.Properties = &SecurityGroupPropertiesFormat{}
}
self.Properties.SecurityRules = securityRules
self.Properties.ProvisioningState = ""
return self.region.update(jsonutils.Marshal(self), nil)
}
func (self *SSecurityGroup) SyncRules(common, inAdds, outAdds, inDels, outDels []cloudprovider.SecurityRule) error {
for i := range common {
switch common[i].Direction {
case secrules.DIR_IN:
inAdds = append(inAdds, common[i])
case secrules.DIR_OUT:
outAdds = append(outAdds, common[i])
default:
return fmt.Errorf("invalid rule %s direction %s", common[i].String(), common[i].Direction)
}
}
// Azure 不允许同方向的规则优先级相同
inRules := cloudprovider.SortUniqPriority(inAdds)
outRules := cloudprovider.SortUniqPriority(outAdds)
rules := append(inRules, outRules...)
return self.SetRules(rules)
}
+10 -1
View File
@@ -262,6 +262,11 @@ func (self *SRegion) deleteSecurityGroup(id string) error {
return err
}
type SecurityGroupCreateOutput struct {
Return bool
GroupId string
}
func (self *SRegion) CreateISecurityGroup(conf *cloudprovider.SecurityGroupCreateInput) (cloudprovider.ICloudSecurityGroup, error) {
params := map[string]string{}
if len(conf.Name) > 0 {
@@ -272,9 +277,13 @@ func (self *SRegion) CreateISecurityGroup(conf *cloudprovider.SecurityGroupCreat
return nil, err
}
ret := &cloudprovider.SecurityGroupCreateOutput{}
ret := &SecurityGroupCreateOutput{}
_ = resp.Unmarshal(&ret)
if conf.OnCreated != nil {
conf.OnCreated(ret.GroupId)
}
if ret.Return {
//rule := cloudprovider.SecurityRule{
// ExternalId: ret.GroupId,
+2 -2
View File
@@ -147,8 +147,8 @@ func (self *SRegion) GetISecurityGroupByName(opts *cloudprovider.SecurityGroupFi
return nil, errors.Wrap(cloudprovider.ErrNotFound, "SRegion.GetISecurityGroupByName.GetSecurityGroups")
}
func (self *SRegion) CreateISecurityGroup(conf *cloudprovider.SecurityGroupCreateInput) (cloudprovider.ICloudSecurityGroup, error) {
secgroup, err := self.CreateSecurityGroup(conf.VpcId, conf.Name)
func (self *SRegion) CreateISecurityGroup(opts *cloudprovider.SecurityGroupCreateInput) (cloudprovider.ICloudSecurityGroup, error) {
secgroup, err := self.CreateSecurityGroup(opts)
if err != nil {
return nil, errors.Wrap(err, "Region.CreateISecurityGroup")
}
+29 -25
View File
@@ -47,7 +47,7 @@ func (self *SRegion) delSecurityGroupRule(secGrpRuleId string) error {
return self.DeleteSecurityGroupRule(secGrpRuleId)
}
func (self *SRegion) AddSecurityGroupRules(secGrpId string, rule cloudprovider.SecurityRule) error {
func (self *SRegion) AddSecurityGroupRules(secGrpId string, rule secrules.SecurityRule) error {
direction := ""
if rule.Direction == secrules.SecurityRuleIngress {
direction = "ingress"
@@ -85,22 +85,6 @@ func (self *SRegion) AddSecurityGroupRules(secGrpId string, rule cloudprovider.S
return nil
}
func (self *SSecurityGroup) SyncRules(common, inAdds, outAdds, inDels, outDels []cloudprovider.SecurityRule) error {
for _, r := range append(inDels, outDels...) {
err := self.region.delSecurityGroupRule(r.ExternalId)
if err != nil {
return errors.Wrapf(err, "delSecurityGroupRule(%s)", r.ExternalId)
}
}
for _, r := range append(inAdds, outAdds...) {
err := self.region.AddSecurityGroupRules(self.ResSecurityGroupID, r)
if err != nil {
return errors.Wrapf(err, "addSecurityGroupRule(%d %s)", r.Priority, r.String())
}
}
return nil
}
func (self *SSecurityGroup) Delete() error {
return self.region.DeleteSecurityGroup(self.GetId())
}
@@ -214,7 +198,6 @@ func (self *SSecurityGroup) GetSecurityRule(remoteRule SSecurityGroupRule) (clou
}
rule := cloudprovider.SecurityRule{
ExternalId: remoteRule.ID,
SecurityRule: secrules.SecurityRule{
Priority: 1,
Action: secrules.SecurityRuleAllow,
@@ -247,13 +230,12 @@ func (self *SRegion) GetSecurityGroupDetails(groupId string) (*SSecurityGroup, e
return nil, errors.Wrap(err, "SRegion.GetSecurityGroupDetails")
}
ret := &SSecurityGroup{}
ret := &SSecurityGroup{region: self}
err = resp.Unmarshal(&ret, "returnObj")
if err != nil {
return nil, errors.Wrap(err, "SRegion.GetSecurityGroupDetails.Unmarshal")
}
ret.region = self
return ret, nil
}
@@ -284,14 +266,14 @@ func (self *SRegion) GetSecurityGroups(vpcId string) ([]SSecurityGroup, error) {
return ret, nil
}
func (self *SRegion) CreateSecurityGroup(vpcId, name string) (*SSecurityGroup, error) {
func (self *SRegion) CreateSecurityGroup(opts *cloudprovider.SecurityGroupCreateInput) (*SSecurityGroup, error) {
params := map[string]jsonutils.JSONObject{
"regionId": jsonutils.NewString(self.GetId()),
"name": jsonutils.NewString(name),
"name": jsonutils.NewString(opts.Name),
}
if len(vpcId) > 0 && vpcId != apis.NORMAL_VPC_ID {
params["vpcId"] = jsonutils.NewString(vpcId)
if len(opts.VpcId) > 0 && opts.VpcId != apis.NORMAL_VPC_ID {
params["vpcId"] = jsonutils.NewString(opts.VpcId)
}
resp, err := self.client.DoPost("/apiproxy/v3/createSecurityGroup", params)
@@ -304,12 +286,34 @@ func (self *SRegion) CreateSecurityGroup(vpcId, name string) (*SSecurityGroup, e
return nil, errors.Wrap(err, "SRegion.CreateSecurityGroup.GetSecgroupId")
}
if opts.OnCreated != nil {
opts.OnCreated(secgroupId)
}
secgroup, err := self.GetSecurityGroupDetails(secgroupId)
if err != nil {
return nil, errors.Wrap(err, "SRegion.CreateSecurityGroup.GetISecurityGroupById")
}
secgroup.region = self
secRules, _ := self.GetSecurityGroupRules(secgroup.GetId())
for _, rule := range secRules {
if len(rule.RemoteGroupId) > 0 || rule.Ethertype != "IPv4" {
continue
}
err := self.delSecurityGroupRule(rule.ID)
if err != nil {
return nil, errors.Wrapf(err, "delete rule %s", rule.ID)
}
}
rules := opts.InRules.AllowList()
rules = append(rules, opts.OutRules.AllowList()...)
for _, r := range rules {
err := self.AddSecurityGroupRules(secgroup.ResSecurityGroupID, r)
if err != nil {
return nil, errors.Wrapf(err, "addSecurityGroupRule(%d %s)", r.Priority, r.String())
}
}
return secgroup, nil
}
+40 -75
View File
@@ -90,11 +90,10 @@ func (firewall *SFirewall) _toRules(action secrules.TSecurityRuleAction) ([]clou
}
for _, allow := range list {
rule := cloudprovider.SecurityRule{
ExternalId: firewall.SelfLink,
SecurityRule: secrules.SecurityRule{
Action: action,
Direction: secrules.DIR_IN,
Priority: firewall.Priority,
Priority: 65535 - firewall.Priority,
},
}
if firewall.Direction == "EGRESS" {
@@ -117,7 +116,9 @@ func (firewall *SFirewall) _toRules(action secrules.TSecurityRuleAction) ([]clou
ports := []int{}
for _, port := range allow.Ports {
if strings.Index(port, "-") > 0 {
port = strings.Replace(port, "0-", "1-", 1)
if strings.HasPrefix(port, "0-") {
port = strings.Replace(port, "0-", "1-", 1)
}
err := rule.ParsePorts(port)
if err != nil {
return nil, errors.Wrapf(err, "Parse port %s", port)
@@ -203,15 +204,17 @@ func (secgroup *SSecurityGroup) Refresh() error {
return nil
}
func (secgroup *SSecurityGroup) Delete() error {
rules, err := secgroup.GetRules()
func (self *SSecurityGroup) Delete() error {
firewalls, err := self.gvpc.client.GetFirewalls(self.gvpc.SelfLink, 0, "")
if err != nil {
return errors.Wrap(err, "GetRules")
return err
}
for _, rule := range rules {
err = secgroup.gvpc.client.DeleteSecgroupRule(rule)
if err != nil {
return errors.Wrapf(err, "DeleteSecgroupRule(%s)", rule.Description)
for _, firewall := range firewalls {
if len(self.Tag) > 0 && utils.IsInStringArray(self.Tag, firewall.TargetTags) || len(self.ServiceAccount) > 0 && utils.IsInStringArray(self.ServiceAccount, firewall.TargetServiceAccounts) {
err = self.gvpc.client.ecsDelete(firewall.SelfLink, nil)
if err != nil {
return errors.Wrapf(err, "delete rule %s", firewall.SelfLink)
}
}
}
return nil
@@ -244,9 +247,6 @@ func (self *SSecurityGroup) GetRules() ([]cloudprovider.SecurityRule, error) {
}
rules := []cloudprovider.SecurityRule{}
for _, firewall := range firewalls {
if firewall.Priority == 65535 { // skip 65535 rule, because it not work
continue
}
_rules, err := firewall.toRules()
if err != nil {
return nil, err
@@ -256,58 +256,6 @@ func (self *SSecurityGroup) GetRules() ([]cloudprovider.SecurityRule, error) {
return rules, nil
}
func (self *SGoogleClient) DeleteSecgroupRule(rule cloudprovider.SecurityRule) error {
firwall, err := self.GetFirewall(rule.ExternalId)
if err != nil {
return errors.Wrap(err, "region.GetFirewall")
}
currentRule, err := firwall.toRules()
if err != nil {
return errors.Wrap(err, "firwall.toRules")
}
if len(currentRule) > 1 {
for _, _rule := range currentRule {
if _rule.String() != rule.String() {
for _, tag := range firwall.TargetTags {
err = self.CreateSecurityGroupRule(_rule, firwall.Network, tag, "")
if err != nil {
return errors.Wrap(err, "region.CreateSecurityGroupRule")
}
}
for _, serviceAccount := range firwall.TargetServiceAccounts {
err = self.CreateSecurityGroupRule(_rule, firwall.Network, "", serviceAccount)
if err != nil {
return errors.Wrap(err, "region.CreateSecurityGroupRule")
}
}
if len(firwall.TargetTags)+len(firwall.TargetServiceAccounts) == 0 {
err = self.CreateSecurityGroupRule(_rule, firwall.Network, "", "")
if err != nil {
return errors.Wrap(err, "region.CreateSecurityGroupRule")
}
}
}
}
}
return self.ecsDelete(firwall.SelfLink, nil)
}
func (secgroup *SSecurityGroup) SyncRules(common, inAdds, outAdds, inDels, outDels []cloudprovider.SecurityRule) error {
for _, r := range append(inDels, outDels...) {
err := secgroup.gvpc.client.DeleteSecgroupRule(r)
if err != nil {
return errors.Wrap(err, "DeleteSecgroupRule")
}
}
for _, r := range append(inAdds, outAdds...) {
err := secgroup.gvpc.client.CreateSecurityGroupRule(r, secgroup.gvpc.SelfLink, secgroup.Tag, secgroup.ServiceAccount)
if err != nil {
return errors.Wrapf(err, "CreateSecurityGroupRule(%s)", r.String())
}
}
return nil
}
func (region *SRegion) GetISecurityGroupById(id string) (cloudprovider.ICloudSecurityGroup, error) {
vpcs, err := region.GetIVpcs()
if err != nil {
@@ -369,6 +317,7 @@ func (self *SGoogleClient) CreateSecurityGroupRule(rule cloudprovider.SecurityRu
}
if rule.Direction == secrules.DIR_OUT {
body["direction"] = "EGRESS"
body["destinationRanges"] = []string{rule.IPNet.String()}
} else {
body["sourceRanges"] = []string{rule.IPNet.String()}
}
@@ -418,17 +367,33 @@ func (self *SGoogleClient) CreateSecurityGroupRule(rule cloudprovider.SecurityRu
return nil
}
func (region *SRegion) CreateISecurityGroup(conf *cloudprovider.SecurityGroupCreateInput) (cloudprovider.ICloudSecurityGroup, error) {
gvpc, err := region.client.GetGlobalNetwork(conf.VpcId)
func (region *SRegion) CreateISecurityGroup(opts *cloudprovider.SecurityGroupCreateInput) (cloudprovider.ICloudSecurityGroup, error) {
gvpc, err := region.client.GetGlobalNetwork(opts.VpcId)
if err != nil {
return nil, errors.Wrapf(err, "region.GetIVpcById(%s)", conf.VpcId)
return nil, errors.Wrapf(err, "region.GetIVpcById(%s)", opts.VpcId)
}
secgroup := &SSecurityGroup{gvpc: gvpc, Tag: strings.ToLower(conf.Name)}
r := *secrules.MustParseSecurityRule("out:allow any")
r.Priority = 1000
rule := cloudprovider.SecurityRule{
Name: "default-rule",
SecurityRule: r,
secgroup := &SSecurityGroup{gvpc: gvpc, Tag: strings.ToLower(opts.Name)}
var syncRules = func(rules []cloudprovider.SecurityRule) error {
if len(rules) == 0 {
return nil
}
offset := 65534 / (len(rules) + 1)
for i := range rules {
rules[i].Priority = 65533 - i*offset
err := secgroup.gvpc.client.CreateSecurityGroupRule(rules[i], secgroup.gvpc.SelfLink, secgroup.Tag, secgroup.ServiceAccount)
if err != nil {
return errors.Wrapf(err, "CreateSecurityGroupRule")
}
}
return nil
}
return secgroup, secgroup.gvpc.client.CreateSecurityGroupRule(rule, secgroup.gvpc.SelfLink, secgroup.Tag, secgroup.ServiceAccount)
err = syncRules(opts.InRules)
if err != nil {
return nil, err
}
err = syncRules(opts.OutRules)
if err != nil {
return nil, err
}
return secgroup, nil
}
+32 -14
View File
@@ -556,8 +556,8 @@ func (self *SRegion) GetISecurityGroupByName(opts *cloudprovider.SecurityGroupFi
return &secgroups[0], nil
}
func (self *SRegion) CreateISecurityGroup(conf *cloudprovider.SecurityGroupCreateInput) (cloudprovider.ICloudSecurityGroup, error) {
return self.CreateSecurityGroup(conf.VpcId, conf.Name, conf.Desc)
func (self *SRegion) CreateISecurityGroup(opts *cloudprovider.SecurityGroupCreateInput) (cloudprovider.ICloudSecurityGroup, error) {
return self.CreateSecurityGroup(opts)
}
// https://support.huaweicloud.com/api-vpc/zh-cn_topic_0020090608.html
@@ -709,23 +709,41 @@ func (self *SRegion) GetCloudEnv() string {
// https://support.huaweicloud.com/api-vpc/zh-cn_topic_0020090615.html
// 目前desc字段并没有用到
func (self *SRegion) CreateSecurityGroup(vpcId string, name string, desc string) (*SSecurityGroup, error) {
// 华为不允许创建名称为default的安全组
if strings.ToLower(name) == "default" {
name = fmt.Sprintf("%s-%s", vpcId, name)
}
func (self *SRegion) CreateSecurityGroup(opts *cloudprovider.SecurityGroupCreateInput) (*SSecurityGroup, error) {
params := jsonutils.NewDict()
secgroupObj := jsonutils.NewDict()
secgroupObj.Add(jsonutils.NewString(name), "name")
if len(vpcId) > 0 && vpcId != api.NORMAL_VPC_ID {
secgroupObj.Add(jsonutils.NewString(vpcId), "vpc_id")
secgroupObj.Add(jsonutils.NewString(opts.Name), "name")
if len(opts.VpcId) > 0 && opts.VpcId != api.NORMAL_VPC_ID {
secgroupObj.Add(jsonutils.NewString(opts.VpcId), "vpc_id")
}
params.Add(secgroupObj, "security_group")
secgroup := SSecurityGroup{region: self}
err := DoCreate(self.ecsClient.SecurityGroups.Create, params, &secgroup)
return &secgroup, err
if err != nil {
return nil, errors.Wrapf(err, "CreateSecgroup")
}
if opts.OnCreated != nil {
opts.OnCreated(secgroup.ID)
}
for _, rule := range secgroup.SecurityGroupRules {
if len(rule.RemoteGroupID) > 0 || rule.Ethertype != "IPv4" {
continue
}
err := self.delSecurityGroupRule(rule.ID)
if err != nil {
return nil, errors.Wrapf(err, "delete rule %s", rule.ID)
}
}
rules := opts.InRules.AllowList()
rules = append(rules, opts.OutRules.AllowList()...)
for i := range rules {
err := self.addSecurityGroupRules(secgroup.ID, rules[i])
if err != nil {
return nil, errors.Wrapf(err, "")
}
}
return &secgroup, nil
}
// https://support.huaweicloud.com/api-vpc/zh-cn_topic_0087467071.html
@@ -738,13 +756,13 @@ func (self *SRegion) DeleteSecurityGroupRule(ruleId string) error {
return self.delSecurityGroupRule(ruleId)
}
func (self *SRegion) CreateSecurityGroupRule(secgroupId string, rule cloudprovider.SecurityRule) error {
func (self *SRegion) CreateSecurityGroupRule(secgroupId string, rule secrules.SecurityRule) error {
return self.addSecurityGroupRules(secgroupId, rule)
}
// https://support.huaweicloud.com/api-vpc/zh-cn_topic_0087451723.html
// icmp port对应关系:https://support.huaweicloud.com/api-vpc/zh-cn_topic_0024109590.html
func (self *SRegion) addSecurityGroupRules(secGrpId string, rule cloudprovider.SecurityRule) error {
func (self *SRegion) addSecurityGroupRules(secGrpId string, rule secrules.SecurityRule) error {
direction := ""
if rule.Direction == secrules.SecurityRuleIngress {
direction = "ingress"
-18
View File
@@ -29,7 +29,6 @@ import (
"net"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/secrules"
"yunion.io/x/pkg/utils"
@@ -193,7 +192,6 @@ func (self *SSecurityGroup) GetSecurityRule(ruleId string) (cloudprovider.Securi
}
rule := cloudprovider.SecurityRule{
ExternalId: ruleId,
SecurityRule: secrules.SecurityRule{
Priority: 1,
Action: secrules.SecurityRuleAllow,
@@ -258,19 +256,3 @@ func (self *SSecurityGroup) GetProjectId() string {
func (self *SSecurityGroup) Delete() error {
return self.region.DeleteSecurityGroup(self.ID)
}
func (self *SSecurityGroup) SyncRules(common, inAdds, outAdds, inDels, outDels []cloudprovider.SecurityRule) error {
for _, r := range append(inDels, outDels...) {
err := self.region.delSecurityGroupRule(r.ExternalId)
if err != nil {
return errors.Wrapf(err, "delSecurityGroupRule(%s %s)", r.ExternalId, r.String())
}
}
for _, r := range append(inAdds, outAdds...) {
err := self.region.addSecurityGroupRules(self.ID, r)
if err != nil {
return errors.Wrapf(err, "addSecurityGroupRule(%d %s)", r.Priority, r.String())
}
}
return nil
}
+32 -14
View File
@@ -408,8 +408,8 @@ func (self *SRegion) GetISecurityGroupByName(opts *cloudprovider.SecurityGroupFi
return &secgroups[0], nil
}
func (self *SRegion) CreateISecurityGroup(conf *cloudprovider.SecurityGroupCreateInput) (cloudprovider.ICloudSecurityGroup, error) {
return self.CreateSecurityGroup(conf.VpcId, conf.Name, conf.Desc)
func (self *SRegion) CreateISecurityGroup(opts *cloudprovider.SecurityGroupCreateInput) (cloudprovider.ICloudSecurityGroup, error) {
return self.CreateSecurityGroup(opts)
}
// https://support.huaweicloud.com/api-vpc/zh-cn_topic_0020090608.html
@@ -573,23 +573,41 @@ func (self *SRegion) GetCloudEnv() string {
// https://support.huaweicloud.com/api-vpc/zh-cn_topic_0020090615.html
// 目前desc字段并没有用到
func (self *SRegion) CreateSecurityGroup(vpcId string, name string, desc string) (*SSecurityGroup, error) {
// 华为不允许创建名称为default的安全组
if strings.ToLower(name) == "default" {
name = fmt.Sprintf("%s-%s", vpcId, name)
}
func (self *SRegion) CreateSecurityGroup(opts *cloudprovider.SecurityGroupCreateInput) (*SSecurityGroup, error) {
params := jsonutils.NewDict()
secgroupObj := jsonutils.NewDict()
secgroupObj.Add(jsonutils.NewString(name), "name")
if len(vpcId) > 0 && vpcId != api.NORMAL_VPC_ID {
secgroupObj.Add(jsonutils.NewString(vpcId), "vpc_id")
secgroupObj.Add(jsonutils.NewString(opts.Name), "name")
if len(opts.VpcId) > 0 && opts.VpcId != api.NORMAL_VPC_ID {
secgroupObj.Add(jsonutils.NewString(opts.VpcId), "vpc_id")
}
params.Add(secgroupObj, "security_group")
secgroup := SSecurityGroup{region: self}
err := DoCreate(self.ecsClient.SecurityGroups.Create, params, &secgroup)
return &secgroup, err
if err != nil {
return nil, err
}
if opts.OnCreated != nil {
opts.OnCreated(secgroup.ID)
}
for _, rule := range secgroup.SecurityGroupRules {
if len(rule.RemoteGroupID) > 0 || rule.Ethertype != "IPv4" {
continue
}
err := self.delSecurityGroupRule(rule.ID)
if err != nil {
return nil, errors.Wrapf(err, "delete rule %s", rule.ID)
}
}
rules := opts.InRules.AllowList()
rules = append(rules, opts.OutRules.AllowList()...)
for i := range rules {
err := self.addSecurityGroupRules(secgroup.ID, rules[i])
if err != nil {
return nil, errors.Wrapf(err, "addSecurityGroupRules")
}
}
return &secgroup, nil
}
// https://support.huaweicloud.com/api-vpc/zh-cn_topic_0087467071.html
@@ -602,13 +620,13 @@ func (self *SRegion) DeleteSecurityGroupRule(ruleId string) error {
return self.delSecurityGroupRule(ruleId)
}
func (self *SRegion) CreateSecurityGroupRule(secgroupId string, rule cloudprovider.SecurityRule) error {
func (self *SRegion) CreateSecurityGroupRule(secgroupId string, rule secrules.SecurityRule) error {
return self.addSecurityGroupRules(secgroupId, rule)
}
// https://support.huaweicloud.com/api-vpc/zh-cn_topic_0087451723.html
// icmp port对应关系:https://support.huaweicloud.com/api-vpc/zh-cn_topic_0024109590.html
func (self *SRegion) addSecurityGroupRules(secGrpId string, rule cloudprovider.SecurityRule) error {
func (self *SRegion) addSecurityGroupRules(secGrpId string, rule secrules.SecurityRule) error {
direction := ""
if rule.Direction == secrules.SecurityRuleIngress {
direction = "ingress"
-18
View File
@@ -29,7 +29,6 @@ import (
"net"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/secrules"
"yunion.io/x/pkg/utils"
@@ -192,7 +191,6 @@ func (self *SSecurityGroup) GetSecurityRule(ruleId string) (cloudprovider.Securi
}
rule := cloudprovider.SecurityRule{
ExternalId: ruleId,
SecurityRule: secrules.SecurityRule{
Priority: 1,
Action: secrules.SecurityRuleAllow,
@@ -257,19 +255,3 @@ func (self *SSecurityGroup) GetProjectId() string {
func (self *SSecurityGroup) Delete() error {
return self.region.DeleteSecurityGroup(self.ID)
}
func (self *SSecurityGroup) SyncRules(common, inAdds, outAdds, inDels, outDels []cloudprovider.SecurityRule) error {
for _, r := range append(inDels, outDels...) {
err := self.region.delSecurityGroupRule(r.ExternalId)
if err != nil {
return errors.Wrapf(err, "delSecurityGroupRule(%s %s)", r.ExternalId, r.String())
}
}
for _, r := range append(inAdds, outAdds...) {
err := self.region.addSecurityGroupRules(self.ID, r)
if err != nil {
return errors.Wrapf(err, "addSecurityGroupRule(%d %s)", r.Priority, r.String())
}
}
return nil
}
-1
View File
@@ -94,7 +94,6 @@ func (sg *SSecurityGroup) GetRules() ([]cloudprovider.SecurityRule, error) {
sr := cloudprovider.SecurityRule{
Id: rules[i].RuleId,
ExternalId: rules[i].RuleId,
SecurityRule: rule,
}
srs = append(srs, sr)
+2 -2
View File
@@ -566,8 +566,8 @@ func (region *SRegion) GetISecurityGroupByName(opts *cloudprovider.SecurityGroup
return &secgroups[0], nil
}
func (region *SRegion) CreateISecurityGroup(conf *cloudprovider.SecurityGroupCreateInput) (cloudprovider.ICloudSecurityGroup, error) {
return region.CreateSecurityGroup(conf.ProjectId, conf.Name, conf.Desc)
func (region *SRegion) CreateISecurityGroup(opts *cloudprovider.SecurityGroupCreateInput) (cloudprovider.ICloudSecurityGroup, error) {
return region.CreateSecurityGroup(opts)
}
func (region *SRegion) GetCapabilities() []string {
+24 -33
View File
@@ -15,7 +15,6 @@
package openstack
import (
"fmt"
"net/url"
"time"
@@ -142,12 +141,7 @@ func (secgroup *SSecurityGroup) GetName() string {
func (secgrouprule *SSecurityGroupRule) toRules() ([]cloudprovider.SecurityRule, error) {
rules := []cloudprovider.SecurityRule{}
// 暂时忽略IPv6安全组规则,忽略远端也是安全组的规则
if secgrouprule.Ethertype != "IPv4" || len(secgrouprule.RemoteGroupId) > 0 {
return rules, fmt.Errorf("ethertype: %s remoteGroupId: %s", secgrouprule.Ethertype, secgrouprule.RemoteGroupId)
}
rule := cloudprovider.SecurityRule{
ExternalId: secgrouprule.Id,
SecurityRule: secrules.SecurityRule{
Direction: secrules.DIR_IN,
Action: secrules.SecurityRuleAllow,
@@ -181,16 +175,15 @@ func (secgrouprule *SSecurityGroupRule) toRules() ([]cloudprovider.SecurityRule,
rule.PortEnd = secgrouprule.PortRangeMax
}
}
err := rule.ValidateRule()
if err != nil && err != secrules.ErrInvalidPriority {
return rules, errors.Wrap(err, "rule.ValidateRule")
}
return []cloudprovider.SecurityRule{rule}, nil
}
func (secgroup *SSecurityGroup) GetRules() ([]cloudprovider.SecurityRule, error) {
rules := []cloudprovider.SecurityRule{}
for _, rule := range secgroup.SecurityGroupRules {
if rule.Ethertype != "IPv4" || len(rule.RemoteGroupId) > 0 {
continue
}
subRules, err := rule.toRules()
if err != nil {
log.Errorf("failed to convert rule %s for secgroup %s(%s) error: %v", rule.Id, secgroup.Name, secgroup.Id, err)
@@ -223,7 +216,7 @@ func (region *SRegion) delSecurityGroupRule(ruleId string) error {
return err
}
func (region *SRegion) addSecurityGroupRules(secgroupId string, rule cloudprovider.SecurityRule) error {
func (region *SRegion) addSecurityGroupRules(secgroupId string, rule secrules.SecurityRule) error {
direction := "ingress"
if rule.Direction == secrules.SecurityRuleEgress {
direction = "egress"
@@ -275,15 +268,15 @@ func (secgroup *SSecurityGroup) Delete() error {
return secgroup.region.DeleteSecurityGroup(secgroup.Id)
}
func (region *SRegion) CreateSecurityGroup(projectId, name, description string) (*SSecurityGroup, error) {
func (region *SRegion) CreateSecurityGroup(opts *cloudprovider.SecurityGroupCreateInput) (*SSecurityGroup, error) {
params := map[string]map[string]interface{}{
"security_group": {
"name": name,
"description": description,
"name": opts.Name,
"description": opts.Desc,
},
}
if len(projectId) > 0 {
params["security_group"]["project_id"] = projectId
if len(opts.ProjectId) > 0 {
params["security_group"]["project_id"] = opts.ProjectId
}
resp, err := region.vpcPost("/v2.0/security-groups", params)
if err != nil {
@@ -294,30 +287,28 @@ func (region *SRegion) CreateSecurityGroup(projectId, name, description string)
if err != nil {
return nil, errors.Wrap(err, "resp.Unmarshal")
}
return secgroup, nil
}
func (secgroup *SSecurityGroup) GetProjectId() string {
return secgroup.TenantId
}
func (secgroup *SSecurityGroup) SyncRules(common, inAdds, outAdds, inDels, outDels []cloudprovider.SecurityRule) error {
for _, r := range append(inDels, outDels...) {
err := secgroup.region.delSecurityGroupRule(r.ExternalId)
if err != nil {
return errors.Wrapf(err, "delSecurityGroupRule(%s)", r.ExternalId)
}
if opts.OnCreated != nil {
opts.OnCreated(secgroup.Id)
}
for _, r := range append(inAdds, outAdds...) {
err := secgroup.region.addSecurityGroupRules(secgroup.Id, r)
for _, rule := range secgroup.SecurityGroupRules {
region.delSecurityGroupRule(rule.Id)
}
rules := opts.InRules.AllowList()
rules = append(rules, opts.OutRules.AllowList()...)
for i := range rules {
err := secgroup.region.addSecurityGroupRules(secgroup.Id, rules[i])
if err != nil {
if jsonError, ok := err.(*httputils.JSONClientError); ok {
if jsonError.Class == "SecurityGroupRuleExists" {
continue
}
}
return errors.Wrapf(err, "addSecgroupRules(%s)", r.String())
return nil, errors.Wrapf(err, "addSecgroupRules(%s)", rules[i].String())
}
}
return nil
return secgroup, nil
}
func (secgroup *SSecurityGroup) GetProjectId() string {
return secgroup.TenantId
}
+2 -2
View File
@@ -834,8 +834,8 @@ func (self *SRegion) GetISecurityGroupByName(opts *cloudprovider.SecurityGroupFi
return &secgroups[0], nil
}
func (self *SRegion) CreateISecurityGroup(conf *cloudprovider.SecurityGroupCreateInput) (cloudprovider.ICloudSecurityGroup, error) {
return self.CreateSecurityGroup(conf.Name, conf.ProjectId, conf.Desc)
func (self *SRegion) CreateISecurityGroup(opts *cloudprovider.SecurityGroupCreateInput) (cloudprovider.ICloudSecurityGroup, error) {
return self.CreateSecurityGroup(opts)
}
func (region *SRegion) GetCapabilities() []string {
+72 -176
View File
@@ -16,8 +16,6 @@ package qcloud
import (
"fmt"
"sort"
"strconv"
"strings"
"time"
@@ -32,7 +30,6 @@ import (
)
type SecurityGroupPolicy struct {
region *SRegion
PolicyIndex int // 安全组规则索引号。
Protocol string // 协议, 取值: TCP,UDP, ICMP。
Port string // 端口(all, 离散port, range)。
@@ -42,7 +39,16 @@ type SecurityGroupPolicy struct {
AddressTemplate AddressTemplateSpecification // IP地址ID或者ID地址组ID。
Action string // ACCEPT 或 DROP。
PolicyDescription string // 安全组规则描述。
direction string
}
func (self *SecurityGroupPolicy) IsNeedSkip() bool {
if len(self.SecurityGroupId) > 0 || len(self.AddressTemplate.AddressGroupId) > 0 || len(self.AddressTemplate.AddressId) > 0 {
return true
}
if len(self.ServiceTemplate.ServiceId) > 0 || len(self.ServiceTemplate.ServiceGroupId) > 0 {
return true
}
return false
}
type ServiceTemplateSpecification struct {
@@ -129,15 +135,6 @@ func (self *SSecurityGroup) GetName() string {
return self.SecurityGroupId
}
func (self *SecurityGroupPolicy) String() string {
rules := self.toRules()
result := []string{}
for _, rule := range rules {
result = append(result, rule.String())
}
return strings.Join(result, ";")
}
type ReferredSecurityGroup struct {
SecurityGroupId string
ReferredSecurityGroupIds []string
@@ -178,131 +175,52 @@ func (self *SRegion) DescribeSecurityGroupReferences(id string) ([]ReferredSecur
return ret, nil
}
func (self *SecurityGroupPolicy) toRules() []cloudprovider.SecurityRule {
result := []cloudprovider.SecurityRule{}
func (self *SecurityGroupPolicy) toRule(direction secrules.TSecurityRuleDirection) cloudprovider.SecurityRule {
rule := cloudprovider.SecurityRule{
ExternalId: fmt.Sprintf("%d", self.PolicyIndex),
SecurityRule: secrules.SecurityRule{
Action: secrules.SecurityRuleAllow,
Protocol: secrules.PROTO_ANY,
Direction: secrules.TSecurityRuleDirection(self.direction),
Priority: self.PolicyIndex,
Ports: []int{},
PortStart: -1,
PortEnd: -1,
Action: secrules.SecurityRuleAllow,
Protocol: secrules.PROTO_ANY,
Direction: direction,
Priority: 100000 - self.PolicyIndex,
Description: self.PolicyDescription,
Ports: []int{},
PortStart: -1,
PortEnd: -1,
},
}
if len(self.SecurityGroupId) != 0 {
rule.ParseCIDR("0.0.0.0/0")
rule.PeerSecgroupId = self.SecurityGroupId
}
if strings.ToLower(self.Action) == "drop" {
rule.Action = secrules.SecurityRuleDeny
}
if utils.IsInStringArray(strings.ToLower(self.Protocol), []string{"tcp", "udp", "icmp"}) {
rule.Protocol = strings.ToLower(self.Protocol)
}
if strings.Index(self.Port, ",") > 0 {
for _, _port := range strings.Split(self.Port, ",") {
port, err := strconv.Atoi(_port)
if err != nil {
log.Errorf("parse secgroup port %s %s error %v", self.Port, _port, err)
continue
}
rule.Ports = append(rule.Ports, port)
}
} else if strings.Index(self.Port, "-") > 0 {
ports := strings.Split(self.Port, "-")
if len(ports) == 2 {
portStart, err := strconv.Atoi(ports[0])
if err != nil {
return nil
}
portEnd, err := strconv.Atoi(ports[1])
if err != nil {
return nil
}
rule.PortStart, rule.PortEnd = portStart, portEnd
}
} else if strings.ToLower(self.Port) != "all" {
port, err := strconv.Atoi(self.Port)
if err != nil {
return nil
}
rule.PortStart, rule.PortEnd = port, port
if strings.ToLower(self.Port) != "all" {
rule.ParsePorts(self.Port)
}
if len(self.AddressTemplate.AddressGroupId) > 0 {
addressGroup, total, err := self.region.AddressGroupList(self.AddressTemplate.AddressGroupId, "", 0, 1)
if err != nil {
log.Errorf("Get AddressList %s failed %v", self.AddressTemplate.AddressId, err)
return nil
}
if total != 1 {
return nil
}
for i := 0; i < len(addressGroup[0].AddressTemplateIdSet); i++ {
rules, err := self.getAddressRules(rule, addressGroup[0].AddressTemplateIdSet[i])
if err != nil {
return nil
}
result = append(result, rules...)
}
} else if len(self.AddressTemplate.AddressId) > 0 {
rules, err := self.getAddressRules(rule, self.AddressTemplate.AddressId)
if err != nil {
return nil
}
result = append(result, rules...)
} else if len(self.SecurityGroupId) > 0 {
rule.PeerSecgroupId = self.SecurityGroupId
result = append(result, rule)
} else if len(self.CidrBlock) > 0 {
rule.ParseCIDR(self.CidrBlock)
result = append(result, rule)
}
return result
}
func (self *SecurityGroupPolicy) getAddressRules(rule cloudprovider.SecurityRule, addressId string) ([]cloudprovider.SecurityRule, error) {
result := []cloudprovider.SecurityRule{}
address, total, err := self.region.AddressList(addressId, "", 0, 1)
if err != nil {
log.Errorf("Get AddressList %s failed %v", self.AddressTemplate.AddressId, err)
return nil, err
}
if total != 1 {
return nil, fmt.Errorf("failed to find address %s", addressId)
}
for _, ip := range address[0].AddressSet {
rule.ParseCIDR(ip)
result = append(result, rule)
}
return result, nil
rule.ParseCIDR(self.CidrBlock)
return rule
}
func (self *SSecurityGroup) GetRules() ([]cloudprovider.SecurityRule, error) {
policySet, err := self.region.DescribeSecurityGroupPolicies(self.SecurityGroupId)
if err != nil {
return nil, err
return nil, errors.Wrapf(err, "DescribeSecurityGroupPolicies")
}
for i := 0; i < len(policySet.Egress); i++ {
policySet.Egress[i].direction = "out"
}
for i := 0; i < len(policySet.Ingress); i++ {
policySet.Ingress[i].direction = "in"
}
originRules := []SecurityGroupPolicy{}
originRules = append(originRules, policySet.Egress...)
originRules = append(originRules, policySet.Ingress...)
for i := 0; i < len(originRules); i++ {
originRules[i].region = self.region
var toRules = func(policy []SecurityGroupPolicy, direction secrules.TSecurityRuleDirection) []cloudprovider.SecurityRule {
ret := []cloudprovider.SecurityRule{}
for i := 0; i < len(policy); i++ {
rule := policy[i]
if rule.IsNeedSkip() {
continue
}
subRule := rule.toRule(direction)
ret = append(ret, subRule)
}
return ret
}
rules := []cloudprovider.SecurityRule{}
for _, rule := range originRules {
subRules := rule.toRules()
rules = append(rules, subRules...)
}
rules = append(rules, toRules(policySet.Egress, secrules.DIR_OUT)...)
rules = append(rules, toRules(policySet.Ingress, secrules.DIR_IN)...)
return rules, nil
}
@@ -315,67 +233,46 @@ func (self *SSecurityGroup) IsEmulated() bool {
}
func (self *SSecurityGroup) Refresh() error {
groups, total, err := self.region.GetSecurityGroups([]string{self.SecurityGroupId}, "", "", 0, 0)
group, err := self.region.GetSecurityGroup(self.SecurityGroupId)
if err != nil {
return err
}
if total < 1 {
return cloudprovider.ErrNotFound
return jsonutils.Update(self, group)
}
func (self *SRegion) GetSecurityGroup(id string) (*SSecurityGroup, error) {
groups, _, err := self.GetSecurityGroups([]string{id}, "", "", 0, 1)
if err != nil {
return nil, err
}
return jsonutils.Update(self, groups[0])
for i := range groups {
if groups[i].SecurityGroupId == id {
groups[i].region = self
return &groups[i], nil
}
}
return nil, errors.Wrapf(cloudprovider.ErrNotFound, id)
}
func (self *SSecurityGroup) SyncRules(common, inAdds, outAdds, inDels, outDels []cloudprovider.SecurityRule) error {
rules := append(common, append(inAdds, outAdds...)...)
sort.Sort(cloudprovider.SecurityRuleSet(rules))
return self.region.syncSecgroupRules(self.SecurityGroupId, rules)
}
func (self *SRegion) syncSecgroupRules(secgroupId string, rules []cloudprovider.SecurityRule) error {
func (self *SRegion) addSecgroupRules(secgroupId string, in, out []cloudprovider.SecurityRule) error {
if len(in)+len(out) == 0 {
return nil
}
params := map[string]string{
"SecurityGroupId": secgroupId,
"SortPolicys": "True",
}
egressIndex, ingressIndex := 0, 0
for _, rule := range rules {
switch rule.Direction {
case secrules.DIR_IN:
params = convertSecgroupRule(ingressIndex, rule, params)
ingressIndex++
case secrules.DIR_OUT:
params = convertSecgroupRule(egressIndex, rule, params)
egressIndex++
var addParams = func(direction secrules.TSecurityRuleDirection, rules []cloudprovider.SecurityRule) {
for idx := 0; idx < len(rules); idx++ {
params = convertSecgroupRule(idx, rules[len(rules)-1-idx], params)
}
}
addParams(secrules.DIR_IN, in)
addParams(secrules.DIR_OUT, out)
_, err := self.vpcRequest("ModifySecurityGroupPolicies", params)
if err != nil {
return errors.Wrapf(err, "ModifySecurityGroupPolicies")
}
if egressIndex == 0 || ingressIndex == 0 {
ruleSet, err := self.DescribeSecurityGroupPolicies(secgroupId)
if err != nil {
return errors.Wrapf(err, "DescribeSecurityGroupPolicies")
}
params = map[string]string{
"SecurityGroupId": secgroupId,
}
if egressIndex == 0 && len(ruleSet.Egress) > 0 {
for idx, rule := range ruleSet.Egress {
params[fmt.Sprintf("SecurityGroupPolicySet.Egress.%d.PolicyIndex", idx)] = fmt.Sprintf("%d", rule.PolicyIndex)
}
}
if ingressIndex == 0 && len(ruleSet.Ingress) > 0 {
for idx, rule := range ruleSet.Ingress {
params[fmt.Sprintf("SecurityGroupPolicySet.Ingress.%d.PolicyIndex", idx)] = fmt.Sprintf("%d", rule.PolicyIndex)
}
}
if len(params) > 1 {
_, err = self.vpcRequest("DeleteSecurityGroupPolicies", params)
if err != nil {
return errors.Wrapf(err, "DeleteSecurityGroupPolicies")
}
}
}
return nil
}
@@ -395,11 +292,7 @@ func convertSecgroupRule(policyIndex int, rule cloudprovider.SecurityRule, param
params[fmt.Sprintf("SecurityGroupPolicySet.%s.%d.Action", direction, policyIndex)] = action
params[fmt.Sprintf("SecurityGroupPolicySet.%s.%d.PolicyDescription", direction, policyIndex)] = rule.Description
params[fmt.Sprintf("SecurityGroupPolicySet.%s.%d.Protocol", direction, policyIndex)] = protocol
if len(rule.PeerSecgroupId) > 0 {
params[fmt.Sprintf("SecurityGroupPolicySet.%s.%d.SecurityGroupId", direction, policyIndex)] = rule.PeerSecgroupId
} else {
params[fmt.Sprintf("SecurityGroupPolicySet.%s.%d.CidrBlock", direction, policyIndex)] = rule.IPNet.String()
}
params[fmt.Sprintf("SecurityGroupPolicySet.%s.%d.CidrBlock", direction, policyIndex)] = rule.IPNet.String()
if rule.Protocol == secrules.PROTO_TCP || rule.Protocol == secrules.PROTO_UDP {
port := "ALL"
if rule.PortEnd > 0 && rule.PortStart > 0 {
@@ -537,16 +430,16 @@ func (self *SRegion) DeleteSecgroupRule(secId string, direction string, index in
return errors.Wrapf(err, "DeleteSecurityGroupPolicies")
}
func (self *SRegion) CreateSecurityGroup(name, projectId, description string) (*SSecurityGroup, error) {
func (self *SRegion) CreateSecurityGroup(opts *cloudprovider.SecurityGroupCreateInput) (*SSecurityGroup, error) {
params := make(map[string]string)
params["Region"] = self.Region
params["GroupName"] = name
params["GroupDescription"] = description
if len(projectId) > 0 {
params["ProjectId"] = projectId
params["GroupName"] = opts.Name
params["GroupDescription"] = opts.Desc
if len(opts.ProjectId) > 0 {
params["ProjectId"] = opts.ProjectId
}
if len(description) == 0 {
if len(opts.Desc) == 0 {
params["GroupDescription"] = "Customize Create"
}
secgroup := SSecurityGroup{region: self}
@@ -558,7 +451,10 @@ func (self *SRegion) CreateSecurityGroup(name, projectId, description string) (*
if err != nil {
return nil, errors.Wrap(err, "body.Unmarshal")
}
return &secgroup, nil
if opts.OnCreated != nil {
opts.OnCreated(secgroup.SecurityGroupId)
}
return &secgroup, self.addSecgroupRules(secgroup.SecurityGroupId, opts.InRules, opts.OutRules)
}
func (self *SSecurityGroup) GetProjectId() string {
+11 -12
View File
@@ -219,11 +219,18 @@ func (self *SRegion) GetISecurityGroupByName(opts *cloudprovider.SecurityGroupFi
return &secgroups[0], nil
}
func (self *SRegion) CreateISecurityGroup(conf *cloudprovider.SecurityGroupCreateInput) (cloudprovider.ICloudSecurityGroup, error) {
externalId, err := self.CreateDefaultSecurityGroup(conf.Name, conf.Desc)
func (self *SRegion) CreateISecurityGroup(opts *cloudprovider.SecurityGroupCreateInput) (cloudprovider.ICloudSecurityGroup, error) {
externalId, err := self.CreateDefaultSecurityGroup(opts.Name, opts.Desc, opts.InRules)
if err != nil {
return nil, err
}
if opts.OnCreated != nil {
opts.OnCreated(externalId)
}
err = self.syncSecgroupRules(externalId, opts.InRules)
if err != nil {
return nil, errors.Wrapf(err, "syncSecgroupRules")
}
return self.GetISecurityGroupById(externalId)
}
@@ -502,16 +509,8 @@ func toUcloudSecRule(rule cloudprovider.SecurityRule) []string {
}
rules := make([]string, 0)
if len(rule.Ports) > 0 {
for _, port := range rule.Ports {
_rules := generatorRule(rule.Protocol, net, action, port, port, rule.Priority)
rules = append(rules, _rules...)
}
} else {
_rules := generatorRule(rule.Protocol, net, action, rule.PortStart, rule.PortEnd, rule.Priority)
rules = append(rules, _rules...)
}
_rules := generatorRule(rule.Protocol, net, action, rule.PortStart, rule.PortEnd, rule.Priority)
rules = append(rules, _rules...)
return rules
}
+1 -1
View File
@@ -175,7 +175,7 @@ func randomString(prefix string, length int) string {
return prefix + string(result)
}
func (self *SRegion) CreateDefaultSecurityGroup(name, description string) (string, error) {
func (self *SRegion) CreateDefaultSecurityGroup(name, description string, rules []cloudprovider.SecurityRule) (string, error) {
// 减少安全组名称冲突
name = randomString(name, 4)
return self.CreateSecurityGroup(name, description, []string{"TCP|1-65535|0.0.0.0/0|ACCEPT|LOW", "UDP|1-65535|0.0.0.0/0|ACCEPT|LOW", "ICMP||0.0.0.0/0|ACCEPT|LOW"})
+2 -2
View File
@@ -338,8 +338,8 @@ func (region *SRegion) GetISecurityGroupByName(opts *cloudprovider.SecurityGroup
return &secgroups[0], nil
}
func (region *SRegion) CreateISecurityGroup(conf *cloudprovider.SecurityGroupCreateInput) (cloudprovider.ICloudSecurityGroup, error) {
return region.CreateSecurityGroup(conf.Name, conf.Desc)
func (region *SRegion) CreateISecurityGroup(opts *cloudprovider.SecurityGroupCreateInput) (cloudprovider.ICloudSecurityGroup, error) {
return region.CreateSecurityGroup(opts)
}
func (region *SRegion) GetCapabilities() []string {
+13 -21
View File
@@ -20,7 +20,6 @@ import (
"strings"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/secrules"
api "yunion.io/x/cloudmux/pkg/apis/compute"
@@ -101,7 +100,6 @@ func (self *SSecurityGroup) GetDescription() string {
func (rule *SSecurityGroupRule) toRule() (cloudprovider.SecurityRule, error) {
r := cloudprovider.SecurityRule{
ExternalId: rule.UUID,
SecurityRule: secrules.SecurityRule{
Direction: secrules.DIR_IN,
Action: secrules.SecurityRuleAllow,
@@ -118,15 +116,12 @@ func (rule *SSecurityGroupRule) toRule() (cloudprovider.SecurityRule, error) {
if rule.Protocol != "ALL" {
r.Protocol = strings.ToLower(rule.Protocol)
}
err := r.ValidateRule()
if err != nil {
return r, errors.Wrap(err, "invalid rule")
}
return r, nil
}
func (self *SSecurityGroup) GetRules() ([]cloudprovider.SecurityRule, error) {
rules := []cloudprovider.SecurityRule{}
rules = append(rules, cloudprovider.SecurityRule{SecurityRule: *secrules.MustParseSecurityRule("out:allow any")})
for i := 0; i < len(self.Rules); i++ {
if self.Rules[i].IPVersion == 4 {
rule, err := self.Rules[i].toRule()
@@ -163,7 +158,7 @@ func (self *SSecurityGroup) GetProjectId() string {
return ""
}
func (region *SRegion) AddSecurityGroupRule(secgroupId string, rules []cloudprovider.SecurityRule) error {
func (region *SRegion) AddSecurityGroupRule(secgroupId string, rules []secrules.SecurityRule) error {
ruleParam := []map[string]interface{}{}
for _, rule := range rules {
Type := "Ingress"
@@ -236,27 +231,24 @@ func (region *SRegion) DeleteSecurityGroupRules(ruleIds []string) error {
return nil
}
func (region *SRegion) CreateSecurityGroup(name, desc string) (*SSecurityGroup, error) {
func (region *SRegion) CreateSecurityGroup(opts *cloudprovider.SecurityGroupCreateInput) (*SSecurityGroup, error) {
secgroup := &SSecurityGroup{region: region}
params := map[string]map[string]string{
"params": {
"name": name,
"description": desc,
"name": opts.Name,
"description": opts.Desc,
},
}
return secgroup, region.client.create("security-groups", jsonutils.Marshal(params), secgroup)
}
func (self *SSecurityGroup) SyncRules(common, inAdds, outAdds, inDels, outDels []cloudprovider.SecurityRule) error {
deleteIds := []string{}
for _, r := range append(inDels, outDels...) {
deleteIds = append(deleteIds, r.ExternalId)
}
err := self.region.DeleteSecurityGroupRules(deleteIds)
err := region.client.create("security-groups", jsonutils.Marshal(params), secgroup)
if err != nil {
return errors.Wrapf(err, "DeleteSecurityGroupRules(%s)", deleteIds)
return nil, err
}
return self.region.AddSecurityGroupRule(self.UUID, append(inAdds, outAdds...))
if opts.OnCreated != nil {
opts.OnCreated(secgroup.UUID)
}
rules := opts.InRules.AllowList()
rules = append(rules, opts.OutRules.AllowList()...)
return secgroup, region.AddSecurityGroupRule(secgroup.UUID, rules)
}
func (self *SSecurityGroup) Delete() error {
+18 -3
View File
@@ -101,10 +101,15 @@ func (srcs securityRuleCuts) cutOutProtocol(protocol string) securityRuleCuts {
return r
}
func (srcs securityRuleCuts) cutOutIPNet(n *net.IPNet) securityRuleCuts {
func (srcs securityRuleCuts) cutOutIPNet(protocol string, n *net.IPNet) securityRuleCuts {
r := securityRuleCuts{}
ar2 := netutils.NewIPV4AddrRangeFromIPNet(n)
for _, src := range srcs {
if src.r.Protocol != protocol && protocol != PROTO_ANY {
src_ := src
r = append(r, src_)
continue
}
sr := src.r
ar := netutils.NewIPV4AddrRangeFromIPNet(sr.IPNet)
left, subs := ar.Substract(ar2)
@@ -131,13 +136,18 @@ func (srcs securityRuleCuts) cutOutIPNet(n *net.IPNet) securityRuleCuts {
return r
}
func (srcs securityRuleCuts) cutOutPortRange(portStart, portEnd uint16) securityRuleCuts {
func (srcs securityRuleCuts) cutOutPortRange(protocol string, portStart, portEnd uint16) securityRuleCuts {
pr1 := &portRange{
start: portStart,
end: portEnd,
}
r := securityRuleCuts{}
for _, src := range srcs {
if src.r.Protocol != protocol {
src_ := src
r = append(r, src_)
continue
}
sr := src.r
if len(sr.Ports) > 0 {
ps := newPortsFromInts(sr.Ports...)
@@ -196,9 +206,14 @@ func (srcs securityRuleCuts) cutOutPortRange(portStart, portEnd uint16) security
return r
}
func (srcs securityRuleCuts) cutOutPorts(ps1 []uint16) securityRuleCuts {
func (srcs securityRuleCuts) cutOutPorts(protocol string, ps1 []uint16) securityRuleCuts {
r := securityRuleCuts{}
for _, src := range srcs {
if src.r.Protocol != protocol {
src_ := src
r = append(r, src_)
continue
}
sr := src.r
if len(sr.Ports) > 0 {
ps0 := newPortsFromInts(sr.Ports...)
+3 -3
View File
@@ -432,11 +432,11 @@ func (rule *SecurityRule) cutOut(r *SecurityRule) SecurityRuleSet {
srcs := securityRuleCuts{securityRuleCut{r: *rule}}
//a := srcs
srcs = srcs.cutOutProtocol(r.Protocol)
srcs = srcs.cutOutIPNet(r.IPNet)
srcs = srcs.cutOutIPNet(r.Protocol, r.IPNet)
if len(r.Ports) > 0 {
srcs = srcs.cutOutPorts([]uint16(newPortsFromInts(r.Ports...)))
srcs = srcs.cutOutPorts(r.Protocol, []uint16(newPortsFromInts(r.Ports...)))
} else if r.PortStart > 0 && r.PortEnd > 0 {
srcs = srcs.cutOutPortRange(uint16(r.PortStart), uint16(r.PortEnd))
srcs = srcs.cutOutPortRange(r.Protocol, uint16(r.PortStart), uint16(r.PortEnd))
} else {
srcs = srcs.cutOutPortsAll()
}
+29 -1
View File
@@ -84,6 +84,7 @@ func (srs SecurityRuleSet) equals(srs1 SecurityRuleSet) bool {
// - same direction
//
func (srs SecurityRuleSet) AllowList() SecurityRuleSet {
srs = srs.uniq()
r := SecurityRuleSet{}
wq := make(SecurityRuleSet, len(srs))
copy(wq, srs)
@@ -120,6 +121,19 @@ func (srs SecurityRuleSet) cutOutFirst() SecurityRuleSet {
return r
}
// remove duplicate rules
func (srs SecurityRuleSet) uniq() SecurityRuleSet {
for i := len(srs) - 1; i > 0; i-- {
sr0 := &srs[i-1]
sr1 := &srs[i]
if sr0.String() != sr1.String() {
continue
}
srs = append(srs[:i], srs[i+1:]...)
}
return srs
}
// collapse result of AllowList
//
// - same direction
@@ -181,11 +195,18 @@ func (srs SecurityRuleSet) collapse() SecurityRuleSet {
if !sr0.netEquals(sr1) {
continue
}
if len(sr0.Ports) > 0 && len(sr1.Ports) > 0 {
if (len(sr0.Ports) > 0 || (sr0.PortStart == sr0.PortEnd && sr0.PortStart > 0)) && (len(sr1.Ports) > 0 || (sr1.PortStart == sr1.PortEnd && sr1.PortStart > 0)) {
ps := newPortsFromInts(sr0.Ports...)
ps = append(ps, newPortsFromInts(sr1.Ports...)...)
if sr0.PortStart == sr0.PortEnd && sr0.PortStart > 0 {
ps = append(ps, uint16(sr0.PortStart))
}
if sr1.PortStart == sr1.PortEnd && sr1.PortStart > 0 {
ps = append(ps, uint16(sr1.PortStart))
}
ps = ps.dedup()
sr0.Ports = ps.IntSlice()
sr0.PortStart, sr0.PortEnd = -1, -1
srs1 = append(srs1[:i], srs1[i+1:]...)
} else if sr0.PortStart > 0 && sr1.PortStart > 0 && sr0.PortEnd > 0 && sr1.PortEnd > 0 {
if sr0.PortEnd == sr1.PortStart-1 {
@@ -200,6 +221,7 @@ func (srs SecurityRuleSet) collapse() SecurityRuleSet {
// save that contains, intersects
}
}
for i := range srs1 {
sr := &srs1[i]
if sr.PortStart <= 1 && sr.PortEnd >= 65535 {
@@ -250,6 +272,12 @@ func (srs SecurityRuleSet) collapse() SecurityRuleSet {
for _, srs := range needMerged {
result = append(result, srs.mergeNet()...)
}
result = result.uniq()
for i := range result {
sr := &result[i]
sr.Priority = 1
}
return result
}