diff --git a/cmd/climc/shell/compute/secgroups.go b/cmd/climc/shell/compute/secgroups.go index 93c5531f2e..8140e72120 100644 --- a/cmd/climc/shell/compute/secgroups.go +++ b/cmd/climc/shell/compute/secgroups.go @@ -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{}) } diff --git a/go.mod b/go.mod index ae4a9b17ca..c5a9bca065 100644 --- a/go.mod +++ b/go.mod @@ -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 diff --git a/go.sum b/go.sum index 7b361a6239..c1c3008a24 100644 --- a/go.sum +++ b/go.sum @@ -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= diff --git a/pkg/apis/compute/secgroup.go b/pkg/apis/compute/secgroup.go index bfae458236..4db9ecb2e8 100644 --- a/pkg/apis/compute/secgroup.go +++ b/pkg/apis/compute/secgroup.go @@ -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"` +} diff --git a/pkg/apis/compute/secgroupcache_const.go b/pkg/apis/compute/secgroupcache_const.go index 7410b32e75..c1becc2eef 100644 --- a/pkg/apis/compute/secgroupcache_const.go +++ b/pkg/apis/compute/secgroupcache_const.go @@ -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" ) diff --git a/pkg/apis/compute/secgrouprule.go b/pkg/apis/compute/secgrouprule.go index 7d48953221..74ba469e96 100644 --- a/pkg/apis/compute/secgrouprule.go +++ b/pkg/apis/compute/secgrouprule.go @@ -22,6 +22,5 @@ type SecgroupRuleDetails struct { SSecurityGroupRule SecurityGroupResourceInfo - ProjectId string `json:"tenant_id"` - PeerSecgroup string `json:"peer_secgroup"` + ProjectId string `json:"tenant_id"` } diff --git a/pkg/apis/compute/zz_generated.model.go b/pkg/apis/compute/zz_generated.model.go index 5c044af23f..0e6409c9fa 100644 --- a/pkg/apis/compute/zz_generated.model.go +++ b/pkg/apis/compute/zz_generated.model.go @@ -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. diff --git a/pkg/compute/guestdrivers/managedvirtual.go b/pkg/compute/guestdrivers/managedvirtual.go index 0431349441..ff029ebc3c 100644 --- a/pkg/compute/guestdrivers/managedvirtual.go +++ b/pkg/compute/guestdrivers/managedvirtual.go @@ -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") } diff --git a/pkg/compute/models/cloudsync.go b/pkg/compute/models/cloudsync.go index 00129e3b6e..4f10bad9d4 100644 --- a/pkg/compute/models/cloudsync.go +++ b/pkg/compute/models/cloudsync.go @@ -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) } diff --git a/pkg/compute/models/guest_secgroups.go b/pkg/compute/models/guest_secgroups.go index 978b3ea8cf..5d62e184e1 100644 --- a/pkg/compute/models/guest_secgroups.go +++ b/pkg/compute/models/guest_secgroups.go @@ -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")) } diff --git a/pkg/compute/models/regiondrivers.go b/pkg/compute/models/regiondrivers.go index 41ce101b51..89f2c8b145 100644 --- a/pkg/compute/models/regiondrivers.go +++ b/pkg/compute/models/regiondrivers.go @@ -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 diff --git a/pkg/compute/models/secgroupcache.go b/pkg/compute/models/secgroupcache.go index 927c556f9a..c705a4bdb6 100644 --- a/pkg/compute/models/secgroupcache.go +++ b/pkg/compute/models/secgroupcache.go @@ -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 -} diff --git a/pkg/compute/models/secgrouprules.go b/pkg/compute/models/secgrouprules.go index 986487a788..63bcd4b32f 100644 --- a/pkg/compute/models/secgrouprules.go +++ b/pkg/compute/models/secgrouprules.go @@ -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() != "" { - 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 { diff --git a/pkg/compute/models/secgroups.go b/pkg/compute/models/secgroups.go index bf8b14e1d6..d7c15403c0 100644 --- a/pkg/compute/models/secgroups.go +++ b/pkg/compute/models/secgroups.go @@ -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() != "" { + 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 { diff --git a/pkg/compute/options/options.go b/pkg/compute/options/options.go index ac05ae5115..3e24e9be69 100644 --- a/pkg/compute/options/options.go +++ b/pkg/compute/options/options.go @@ -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"` diff --git a/pkg/compute/regiondrivers/aliyun.go b/pkg/compute/regiondrivers/aliyun.go index c2164858ac..50a72d03f1 100644 --- a/pkg/compute/regiondrivers/aliyun.go +++ b/pkg/compute/regiondrivers/aliyun.go @@ -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 } diff --git a/pkg/compute/regiondrivers/aws.go b/pkg/compute/regiondrivers/aws.go index cdbd830b71..ec277c84aa 100644 --- a/pkg/compute/regiondrivers/aws.go +++ b/pkg/compute/regiondrivers/aws.go @@ -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 } diff --git a/pkg/compute/regiondrivers/azure.go b/pkg/compute/regiondrivers/azure.go index bb265f11b1..08790b2feb 100644 --- a/pkg/compute/regiondrivers/azure.go +++ b/pkg/compute/regiondrivers/azure.go @@ -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 { diff --git a/pkg/compute/regiondrivers/base.go b/pkg/compute/regiondrivers/base.go index c0aebbeea5..3378191281 100644 --- a/pkg/compute/regiondrivers/base.go +++ b/pkg/compute/regiondrivers/base.go @@ -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) { diff --git a/pkg/compute/regiondrivers/bingocloud.go b/pkg/compute/regiondrivers/bingocloud.go index 4a2f6088c1..14110e8264 100644 --- a/pkg/compute/regiondrivers/bingocloud.go +++ b/pkg/compute/regiondrivers/bingocloud.go @@ -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 } diff --git a/pkg/compute/regiondrivers/cloudpods.go b/pkg/compute/regiondrivers/cloudpods.go index c424400a19..31d6bcfe98 100644 --- a/pkg/compute/regiondrivers/cloudpods.go +++ b/pkg/compute/regiondrivers/cloudpods.go @@ -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) diff --git a/pkg/compute/regiondrivers/ctyun.go b/pkg/compute/regiondrivers/ctyun.go index 9a78aa51f0..6f8543c5e1 100644 --- a/pkg/compute/regiondrivers/ctyun.go +++ b/pkg/compute/regiondrivers/ctyun.go @@ -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 } diff --git a/pkg/compute/regiondrivers/huawei.go b/pkg/compute/regiondrivers/huawei.go index 7a95b3dabe..bec8545092 100644 --- a/pkg/compute/regiondrivers/huawei.go +++ b/pkg/compute/regiondrivers/huawei.go @@ -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 } diff --git a/pkg/compute/regiondrivers/jdcloud.go b/pkg/compute/regiondrivers/jdcloud.go index 618fe041fa..1b9c9a8419 100644 --- a/pkg/compute/regiondrivers/jdcloud.go +++ b/pkg/compute/regiondrivers/jdcloud.go @@ -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")} -} diff --git a/pkg/compute/regiondrivers/kvm.go b/pkg/compute/regiondrivers/kvm.go index 144fc501e0..920c2b7030 100644 --- a/pkg/compute/regiondrivers/kvm.go +++ b/pkg/compute/regiondrivers/kvm.go @@ -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 } diff --git a/pkg/compute/regiondrivers/managedvirtual.go b/pkg/compute/regiondrivers/managedvirtual.go index 47d101d56a..fd89db6cde 100644 --- a/pkg/compute/regiondrivers/managedvirtual.go +++ b/pkg/compute/regiondrivers/managedvirtual.go @@ -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") } diff --git a/pkg/compute/regiondrivers/openstack.go b/pkg/compute/regiondrivers/openstack.go index 2b84efbe3c..1625e223a7 100644 --- a/pkg/compute/regiondrivers/openstack.go +++ b/pkg/compute/regiondrivers/openstack.go @@ -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 } diff --git a/pkg/compute/regiondrivers/qcloud.go b/pkg/compute/regiondrivers/qcloud.go index 1105bcc434..e805af51ba 100644 --- a/pkg/compute/regiondrivers/qcloud.go +++ b/pkg/compute/regiondrivers/qcloud.go @@ -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 } diff --git a/pkg/compute/regiondrivers/secgroup_aliyun_test.go b/pkg/compute/regiondrivers/secgroup_aliyun_test.go deleted file mode 100644 index 12452ca60c..0000000000 --- a/pkg/compute/regiondrivers/secgroup_aliyun_test.go +++ /dev/null @@ -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{}) - } -} diff --git a/pkg/compute/regiondrivers/secgroup_aws_test.go b/pkg/compute/regiondrivers/secgroup_aws_test.go deleted file mode 100644 index 830227f326..0000000000 --- a/pkg/compute/regiondrivers/secgroup_aws_test.go +++ /dev/null @@ -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{}) - } -} diff --git a/pkg/compute/regiondrivers/secgroup_azure_test.go b/pkg/compute/regiondrivers/secgroup_azure_test.go deleted file mode 100644 index 5f3d8656df..0000000000 --- a/pkg/compute/regiondrivers/secgroup_azure_test.go +++ /dev/null @@ -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) - } - } - } - -} diff --git a/pkg/compute/regiondrivers/secgroup_ctyun_test.go b/pkg/compute/regiondrivers/secgroup_ctyun_test.go deleted file mode 100644 index 979992db1c..0000000000 --- a/pkg/compute/regiondrivers/secgroup_ctyun_test.go +++ /dev/null @@ -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{}) - } -} diff --git a/pkg/compute/regiondrivers/secgroup_kvm_test.go b/pkg/compute/regiondrivers/secgroup_kvm_test.go deleted file mode 100644 index e200bba3b1..0000000000 --- a/pkg/compute/regiondrivers/secgroup_kvm_test.go +++ /dev/null @@ -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{}) - } - -} diff --git a/pkg/compute/regiondrivers/secgroup_openstack_test.go b/pkg/compute/regiondrivers/secgroup_openstack_test.go deleted file mode 100644 index c271092b74..0000000000 --- a/pkg/compute/regiondrivers/secgroup_openstack_test.go +++ /dev/null @@ -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{}) - } -} diff --git a/pkg/compute/regiondrivers/secgroup_qcloud_test.go b/pkg/compute/regiondrivers/secgroup_qcloud_test.go deleted file mode 100644 index 20c448609d..0000000000 --- a/pkg/compute/regiondrivers/secgroup_qcloud_test.go +++ /dev/null @@ -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{}) - } -} diff --git a/pkg/compute/regiondrivers/secgroup_test.go b/pkg/compute/regiondrivers/secgroup_test.go deleted file mode 100644 index 752b5eb0d9..0000000000 --- a/pkg/compute/regiondrivers/secgroup_test.go +++ /dev/null @@ -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()) - } - - } -} diff --git a/pkg/compute/regiondrivers/ucloud.go b/pkg/compute/regiondrivers/ucloud.go index 6868260181..caf52c2cc7 100644 --- a/pkg/compute/regiondrivers/ucloud.go +++ b/pkg/compute/regiondrivers/ucloud.go @@ -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 } diff --git a/pkg/compute/regiondrivers/zstack.go b/pkg/compute/regiondrivers/zstack.go index 24cbdfaf3e..5596afc61c 100644 --- a/pkg/compute/regiondrivers/zstack.go +++ b/pkg/compute/regiondrivers/zstack.go @@ -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 } diff --git a/pkg/compute/tasks/secgroup_group_cache_task.go b/pkg/compute/tasks/secgroup_group_cache_task.go index 68755e12eb..65aabfa576 100644 --- a/pkg/compute/tasks/secgroup_group_cache_task.go +++ b/pkg/compute/tasks/secgroup_group_cache_task.go @@ -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 } } diff --git a/pkg/compute/tasks/security_group_sync_rules_task.go b/pkg/compute/tasks/security_group_sync_rules_task.go deleted file mode 100644 index 2c1ee841a1..0000000000 --- a/pkg/compute/tasks/security_group_sync_rules_task.go +++ /dev/null @@ -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) -} diff --git a/pkg/mcclient/cloudpods/secgroup.go b/pkg/mcclient/cloudpods/secgroup.go index 6e4f4ce433..31e2628892 100644 --- a/pkg/mcclient/cloudpods/secgroup.go +++ b/pkg/mcclient/cloudpods/secgroup.go @@ -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 diff --git a/pkg/mcclient/options/compute/secgrouprule.go b/pkg/mcclient/options/compute/secgrouprule.go index 3061d17e04..1cde0e9f6e 100644 --- a/pkg/mcclient/options/compute/secgrouprule.go +++ b/pkg/mcclient/options/compute/secgrouprule.go @@ -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 } diff --git a/pkg/mcclient/options/secgroup.go b/pkg/mcclient/options/secgroup.go index d479aa79a6..d5abf873ee 100644 --- a/pkg/mcclient/options/secgroup.go +++ b/pkg/mcclient/options/secgroup.go @@ -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) { diff --git a/pkg/vpcagent/ovn/keeper.go b/pkg/vpcagent/ovn/keeper.go index 58b82adbcf..473af3fe62 100644 --- a/pkg/vpcagent/ovn/keeper.go +++ b/pkg/vpcagent/ovn/keeper.go @@ -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) diff --git a/vendor/github.com/jaypipes/ghw/pkg/memory/memory_linux.go b/vendor/github.com/jaypipes/ghw/pkg/memory/memory_linux.go index f4bb73c1c5..4b7631a195 100644 --- a/vendor/github.com/jaypipes/ghw/pkg/memory/memory_linux.go +++ b/vendor/github.com/jaypipes/ghw/pkg/memory/memory_linux.go @@ -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 } diff --git a/vendor/modules.txt b/vendor/modules.txt index 9e1939e8fb..9e3e9da011 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -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 diff --git a/vendor/yunion.io/x/cloudmux/pkg/cloudprovider/resources.go b/vendor/yunion.io/x/cloudmux/pkg/cloudprovider/resources.go index a1a8d22ad6..2f7f3b1d2a 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/cloudprovider/resources.go +++ b/vendor/yunion.io/x/cloudmux/pkg/cloudprovider/resources.go @@ -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 } diff --git a/vendor/yunion.io/x/cloudmux/pkg/cloudprovider/securitygroup.go b/vendor/yunion.io/x/cloudmux/pkg/cloudprovider/securitygroup.go index 55ab35c42d..8d8e9bf939 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/cloudprovider/securitygroup.go +++ b/vendor/yunion.io/x/cloudmux/pkg/cloudprovider/securitygroup.go @@ -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 } diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/aliyun/region.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/aliyun/region.go index c792236dae..cd38ad350b 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/aliyun/region.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/aliyun/region.go @@ -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) } diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/aliyun/securitygroup.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/aliyun/securitygroup.go index 7bf7fb7f87..1bab9f5b7b 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/aliyun/securitygroup.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/aliyun/securitygroup.go @@ -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 -} diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/aliyun/vpc.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/aliyun/vpc.go index 6767872584..119270dad0 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/aliyun/vpc.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/aliyun/vpc.go @@ -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 diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/apsara/region.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/apsara/region.go index 7e694a603f..f543a4df7d 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/apsara/region.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/apsara/region.go @@ -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) } diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/apsara/securitygroup.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/apsara/securitygroup.go index 97fed78ee0..2e025968a2 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/apsara/securitygroup.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/apsara/securitygroup.go @@ -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 -} diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/aws/host.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/aws/host.go index 1b795b4528..40ccb848c5 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/aws/host.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/aws/host.go @@ -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 := "" diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/aws/region.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/aws/region.go index 32aab88271..4720f73c79 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/aws/region.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/aws/region.go @@ -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) } diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/aws/securitygroup.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/aws/securitygroup.go index 9823a91d8b..be8b44aedc 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/aws/securitygroup.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/aws/securitygroup.go @@ -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) } diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/aws/utils.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/aws/utils.go index bc7cacc33c..a627d3970b 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/aws/utils.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/aws/utils.go @@ -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 == "" { - 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)) diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/aws/vpc.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/aws/vpc.go index 4c8b5b8e58..2aa1f0c73b 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/aws/vpc.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/aws/vpc.go @@ -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 { diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/azure/classic_secruitygroup.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/azure/classic_secruitygroup.go index 51c2a4fca8..6d589d99dd 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/azure/classic_secruitygroup.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/azure/classic_secruitygroup.go @@ -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 -} diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/azure/classic_vpc.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/azure/classic_vpc.go index e3d672aec5..b94f853f74 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/azure/classic_vpc.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/azure/classic_vpc.go @@ -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) { diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/azure/region.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/azure/region.go index 8dfdbb41fb..4847d8a43f 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/azure/region.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/azure/region.go @@ -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) { diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/azure/securitygroup.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/azure/securitygroup.go index 307a1d7f62..c9b7c56ac5 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/azure/securitygroup.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/azure/securitygroup.go @@ -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) -} diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/securitygroup.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/securitygroup.go index ec95efa1c8..608e5f488d 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/securitygroup.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/securitygroup.go @@ -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, diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/ctyun/region.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ctyun/region.go index e07bc96ded..0a29e84386 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/ctyun/region.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ctyun/region.go @@ -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") } diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/ctyun/securitygroup.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ctyun/securitygroup.go index 8ae88f4b1a..6b3992f376 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/ctyun/securitygroup.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ctyun/securitygroup.go @@ -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 } diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/google/securitygroup.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/google/securitygroup.go index 8d3f18f03d..5a4da7d5c2 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/google/securitygroup.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/google/securitygroup.go @@ -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 } diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/hcso/region.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/hcso/region.go index 560ba352f0..083c717b87 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/hcso/region.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/hcso/region.go @@ -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" diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/hcso/securitygroup.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/hcso/securitygroup.go index 77dd73782c..f367b29b92 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/hcso/securitygroup.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/hcso/securitygroup.go @@ -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 -} diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/region.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/region.go index 4b8cab52df..9fa33e1269 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/region.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/region.go @@ -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" diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/securitygroup.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/securitygroup.go index 869e5537d8..7ec2e2aa18 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/securitygroup.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/securitygroup.go @@ -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 -} diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/jdcloud/securitygroup.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/jdcloud/securitygroup.go index c8f6725f15..669b7a68b0 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/jdcloud/securitygroup.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/jdcloud/securitygroup.go @@ -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) diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/openstack/region.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/openstack/region.go index 096d134efe..1196789715 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/openstack/region.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/openstack/region.go @@ -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 { diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/openstack/securitygroup.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/openstack/securitygroup.go index 6f5e8b5dee..c4539a1e50 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/openstack/securitygroup.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/openstack/securitygroup.go @@ -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 } diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/qcloud/region.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/qcloud/region.go index 00e6fddac2..7c6846c17a 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/qcloud/region.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/qcloud/region.go @@ -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 { diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/qcloud/securitygroup.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/qcloud/securitygroup.go index 5527f00e87..4dfbccb4cd 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/qcloud/securitygroup.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/qcloud/securitygroup.go @@ -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 { diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/ucloud/region.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ucloud/region.go index 43f9dad5d9..56b50b16fd 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/ucloud/region.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ucloud/region.go @@ -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 } diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/ucloud/securitygroup.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ucloud/securitygroup.go index 0ddea31e89..869390f668 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/ucloud/securitygroup.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/ucloud/securitygroup.go @@ -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"}) diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/zstack/region.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/zstack/region.go index 143e5acd63..dcdb0201ca 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/zstack/region.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/zstack/region.go @@ -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 { diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/zstack/securitygroup.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/zstack/securitygroup.go index d7167a6cbc..76a94537d4 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/zstack/securitygroup.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/zstack/securitygroup.go @@ -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 { diff --git a/vendor/yunion.io/x/pkg/util/secrules/cut.go b/vendor/yunion.io/x/pkg/util/secrules/cut.go index d500b82e6c..cf954a179d 100644 --- a/vendor/yunion.io/x/pkg/util/secrules/cut.go +++ b/vendor/yunion.io/x/pkg/util/secrules/cut.go @@ -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...) diff --git a/vendor/yunion.io/x/pkg/util/secrules/secrules.go b/vendor/yunion.io/x/pkg/util/secrules/secrules.go index 35adda7630..6a026e4157 100644 --- a/vendor/yunion.io/x/pkg/util/secrules/secrules.go +++ b/vendor/yunion.io/x/pkg/util/secrules/secrules.go @@ -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() } diff --git a/vendor/yunion.io/x/pkg/util/secrules/secruleset.go b/vendor/yunion.io/x/pkg/util/secrules/secruleset.go index ba4a1247da..cf6cd27696 100644 --- a/vendor/yunion.io/x/pkg/util/secrules/secruleset.go +++ b/vendor/yunion.io/x/pkg/util/secrules/secruleset.go @@ -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 }