fix(region): secgroup rule fix (#18414)

This commit is contained in:
屈轩
2023-10-25 17:49:44 +08:00
committed by GitHub
parent 22608b4b9d
commit 025b5fc289
204 changed files with 7161 additions and 6658 deletions
-30
View File
@@ -1,30 +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 compute
import (
"yunion.io/x/onecloud/cmd/climc/shell"
modules "yunion.io/x/onecloud/pkg/mcclient/modules/compute"
"yunion.io/x/onecloud/pkg/mcclient/options/compute"
)
func init() {
cmd := shell.NewResourceCmd(&modules.SecGroupCaches).WithKeyword("secgroup-cache")
cmd.List(&compute.SecGroupCacheListOptions{})
cmd.Show(&compute.SecGroupCacheIdOptions{})
cmd.Delete(&compute.SecGroupCacheIdOptions{})
cmd.Perform("syncstatus", &compute.SecGroupCacheIdOptions{})
cmd.Get("references", &compute.SecGroupCacheIdOptions{})
}
+1 -4
View File
@@ -27,13 +27,10 @@ func init() {
cmd.Show(&options.SecgroupIdOptions{})
cmd.Update(&options.BaseUpdateOptions{})
cmd.Delete(&options.SecgroupIdOptions{})
cmd.Perform("merge", &options.SecgroupMergeOptions{})
cmd.Perform("public", &options.SecgroupIdOptions{})
cmd.Perform("syncstatus", &options.SecgroupIdOptions{})
cmd.Perform("private", &options.SecgroupIdOptions{})
cmd.Perform("add-rule", &options.SecgroupsAddRuleOptions{})
cmd.Perform("cache-secgroup", &options.SecurityGroupCacheOptions{})
cmd.Perform("uncache-secgroup", &options.SecurityGroupUncacheSecurityGroup{})
cmd.Perform("purge", &options.SecgroupIdOptions{})
cmd.Perform("change-owner", &options.SecgroupChangeOwnerOptions{})
cmd.Perform("import-rules", &options.SecgroupImportRulesOptions{})
}
+1 -1
View File
@@ -83,7 +83,7 @@ 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.20231024052127-016e22c73e9f
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20231025082024-ea24588e7245
yunion.io/x/executor v0.0.0-20230705125604-c5ac3141db32
yunion.io/x/jsonutils v1.0.1-0.20230613121553-0f3b41e2ef19
yunion.io/x/log v1.0.1-0.20230411060016-feb3f46ab361
+2 -4
View File
@@ -1179,8 +1179,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.20231024052127-016e22c73e9f h1:Ly28cvpMTrJRMFgHBrU/NU0mALJyePlNG0hQdGalth4=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20231024052127-016e22c73e9f/go.mod h1:McRjoG2gaOUisB+Qa41kLCNZhr0lsCu4apEjTiphXVY=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20231025082024-ea24588e7245 h1:fvPqSf6afBEa1oqCoYsmADY3Gg9Hi92TlF9skTfNloE=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20231025082024-ea24588e7245/go.mod h1:McRjoG2gaOUisB+Qa41kLCNZhr0lsCu4apEjTiphXVY=
yunion.io/x/executor v0.0.0-20230705125604-c5ac3141db32 h1:v7POYkQwo1XzOxBoIoRVr/k0V9Y5JyjpshlIFa9raug=
yunion.io/x/executor v0.0.0-20230705125604-c5ac3141db32/go.mod h1:Uxuou9WQIeJXNpy7t2fPLL0BYLvLiMvGQwY7Qc6aSws=
yunion.io/x/jsonutils v0.0.0-20190625054549-a964e1e8a051/go.mod h1:4N0/RVzsYL3kH3WE/H1BjUQdFiWu50JGCFQuuy+Z634=
@@ -1194,8 +1194,6 @@ yunion.io/x/ovsdb v0.0.0-20230306173834-f164f413a900 h1:Hu/4ERvoWaN6aiFs4h4/yvVB
yunion.io/x/ovsdb v0.0.0-20230306173834-f164f413a900/go.mod h1:0vLkNEhlmA64HViPBAnSTUMrx5QP1CLsxXmxDKQ80tc=
yunion.io/x/pkg v0.0.0-20190620104149-945c25821dbf/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E=
yunion.io/x/pkg v0.0.0-20190628082551-f4033ba2ea30/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E=
yunion.io/x/pkg v1.0.1-0.20231012131524-8a175238485b h1:0eDqhMiGCPcbYLXRuCprsNCOsj0cQ09swUmGkXatlBk=
yunion.io/x/pkg v1.0.1-0.20231012131524-8a175238485b/go.mod h1:ksCJVQ+DwKrJ5QBEoU8pzrDFfDaZVAFH/iJ6yQCYxJk=
yunion.io/x/pkg v1.0.1-0.20231024115515-6dc7eade60ad h1:AoulsTEDSJbQgWeJdYW6qILEvnFJwWbsDb3YeSmZXm0=
yunion.io/x/pkg v1.0.1-0.20231024115515-6dc7eade60ad/go.mod h1:ksCJVQ+DwKrJ5QBEoU8pzrDFfDaZVAFH/iJ6yQCYxJk=
yunion.io/x/s3cli v0.0.0-20190917004522-13ac36d8687e h1:v+EzIadodSwkdZ/7bremd7J8J50Cise/HCylsOJngmo=
+28 -27
View File
@@ -17,33 +17,34 @@ package compute
import "yunion.io/x/cloudmux/pkg/apis/compute"
const (
VM_INIT = compute.VM_INIT
VM_UNKNOWN = compute.VM_UNKNOWN
VM_SCHEDULE = "schedule"
VM_SCHEDULE_FAILED = "sched_fail"
VM_CREATE_NETWORK = "network"
VM_NETWORK_FAILED = "net_fail"
VM_DEVICE_FAILED = "dev_fail"
VM_CREATE_FAILED = compute.VM_CREATE_FAILED
VM_CREATE_DISK = "disk"
VM_DISK_FAILED = "disk_fail"
VM_IMAGE_CACHING = "image_caching" // 缓存镜像中
VM_START_DEPLOY = "start_deploy"
VM_DEPLOYING = compute.VM_DEPLOYING
VM_DEPLOY_FAILED = compute.VM_DEPLOY_FAILED
VM_READY = compute.VM_READY
VM_START_START = compute.VM_START_START
VM_STARTING = compute.VM_STARTING
VM_START_FAILED = "start_fail" // # = ready
VM_RUNNING = compute.VM_RUNNING
VM_START_STOP = compute.VM_START_STOP
VM_STOPPING = compute.VM_STOPPING
VM_STOP_FAILED = "stop_fail" // # = running
VM_RENEWING = "renewing"
VM_RENEW_FAILED = "renew_failed"
VM_ATTACH_DISK = "attach_disk"
VM_DETACH_DISK = "detach_disk"
VM_UNSYNC = "unsync"
VM_INIT = compute.VM_INIT
VM_UNKNOWN = compute.VM_UNKNOWN
VM_SCHEDULE = "schedule"
VM_SCHEDULE_FAILED = "sched_fail"
VM_CREATE_NETWORK = "network"
VM_NETWORK_FAILED = "net_fail"
VM_DEVICE_FAILED = "dev_fail"
VM_CREATE_FAILED = compute.VM_CREATE_FAILED
VM_CREATE_DISK = "disk"
VM_DISK_FAILED = "disk_fail"
VM_SECURITY_GROUP_FAILED = "security_group_fail"
VM_IMAGE_CACHING = "image_caching" // 缓存镜像中
VM_START_DEPLOY = "start_deploy"
VM_DEPLOYING = compute.VM_DEPLOYING
VM_DEPLOY_FAILED = compute.VM_DEPLOY_FAILED
VM_READY = compute.VM_READY
VM_START_START = compute.VM_START_START
VM_STARTING = compute.VM_STARTING
VM_START_FAILED = "start_fail" // # = ready
VM_RUNNING = compute.VM_RUNNING
VM_START_STOP = compute.VM_START_STOP
VM_STOPPING = compute.VM_STOPPING
VM_STOP_FAILED = "stop_fail" // # = running
VM_RENEWING = "renewing"
VM_RENEW_FAILED = "renew_failed"
VM_ATTACH_DISK = "attach_disk"
VM_DETACH_DISK = "detach_disk"
VM_UNSYNC = "unsync"
VM_BACKUP_STARTING = "backup_starting"
VM_BACKUP_STOPING = "backup_stopping"
+54 -44
View File
@@ -83,6 +83,8 @@ type SSecgroupRuleResource struct {
Description string `json:"description"`
}
type SSecgroupRuleResourceSet []SSecgroupRuleResource
type SSecgroupRuleCreateInput struct {
apis.ResourceBaseCreateInput
SSecgroupRuleResource
@@ -90,6 +92,9 @@ type SSecgroupRuleCreateInput struct {
// swagger:ignore
Secgroup string `json:"secgroup" yunion-deprecated-by:"secgroup_id"`
// swagger: ignore
Status string `json:"status"`
// 安全组ID
// required: true
SecgroupId string `json:"secgroup_id"`
@@ -98,7 +103,37 @@ type SSecgroupRuleCreateInput struct {
type SSecgroupRuleUpdateInput struct {
apis.ResourceBaseUpdateInput
SSecgroupRuleResource
Priority *int `json:"priority"`
Ports *string `json:"ports"`
// ip或cidr地址, 若指定peer_secgroup_id此参数不生效
// example: 192.168.222.121
CIDR *string `json:"cidr"`
// 协议
// required: true
//
//
//
// | protocol | name |
// | -------- | ---- |
// | any | 所有协议|
// | tcp | TCP |
// | icmp | ICMP |
// | udp | UDP |
// enum: any, tcp, udp, icmp
Protocol *string `json:"protocol"`
// 行为
// deny: 拒绝
// allow: 允许
// enum: deny, allow
// required: true
Action *string `json:"action"`
// 规则描述信息
// requried: false
// example: test to create rule
Description string `json:"description"`
}
func (input *SSecgroupRuleResource) Check() error {
@@ -137,6 +172,17 @@ func (input *SSecgroupRuleResource) Check() error {
type SSecgroupCreateInput struct {
apis.SharableVirtualResourceCreateInput
// vpc id
// defualt: default
VpcResourceInput
// swagger: ignore
CloudproviderResourceInput
// swagger: ignore
CloudregionResourceInput
// swagger: ignore
GlobalvpcId string `json:"globalvpc_id"`
// 规则列表
// required: false
Rules []SSecgroupRuleCreateInput `json:"rules"`
@@ -144,19 +190,13 @@ type SSecgroupCreateInput struct {
type SecgroupListInput struct {
apis.SharableVirtualResourceListInput
apis.ExternalizedResourceBaseListInput
ServerResourceInput
DBInstanceResourceInput
ELasticcacheResourceInput
// equals
Equals string
// 按缓存数量排序
// pattern:asc|desc
OrderByCacheCnt string `json:"order_by_cache_cnt"`
// 按缓存关联主机数排序
// pattern:asc|desc
OrderByGuestCnt string `json:"order_by_guest_cnt"`
@@ -174,25 +214,14 @@ type SecgroupListInput struct {
// example: in
Direction string `json:"direction"`
VpcId string `json:"vpc_id"`
RegionalFilterListInput
ManagedResourceListInput
WithCache bool `json:"witch_cache"`
}
type SecurityGroupCacheListInput struct {
apis.StatusStandaloneResourceListInput
apis.ExternalizedResourceBaseListInput
ManagedResourceListInput
RegionalFilterListInput
VpcFilterListInput
SecgroupFilterListInput
}
type SecurityGroupRuleListInput struct {
apis.ResourceBaseListInput
apis.ExternalizedResourceBaseListInput
SecgroupFilterListInput
Projects []string `json:"projects"`
@@ -232,6 +261,9 @@ type SecgroupDetails struct {
apis.SharableVirtualResourceDetails
SSecurityGroup
VpcResourceInfo
GlobalVpcResourceInfo
// 关联云主机数量, 不包含回收站云主机
GuestCnt int `json:"guest_cnt,allowempty"`
@@ -243,15 +275,6 @@ type SecgroupDetails struct {
// 所有关联的资源数量
TotalCnt int `json:"total_cnt,allowempty"`
// 安全组缓存数量
CacheCnt int `json:"cache_cnt,allowempty"`
// 规则信息
Rules []SecgroupRuleDetails `json:"rules"`
// 入方向规则信息
InRules []SecgroupRuleDetails `json:"in_rules"`
// 出方向规则信息
OutRules []SecgroupRuleDetails `json:"out_rules"`
}
type SecurityGroupResourceInfo struct {
@@ -292,18 +315,6 @@ type ElasticcachesecgroupDetails struct {
Secgroup string `json:"secgroup"`
}
type SecgroupMergeInput struct {
// 安全组id列表
SecgroupIds []string `json:"secgroup_ids"`
// swagger:ignore
// Deprecated
Secgroups []string `json:"secgroup" yunion-deprecated-by:"secgroup_ids"`
}
type SecurityGroupPurgeInput struct {
}
type SecurityGroupCloneInput struct {
Name string
Description string
@@ -330,6 +341,5 @@ func (self *SSecurityGroupRef) Sum() {
self.TotalCnt = self.GuestCnt + self.AdminGuestCnt + self.RdsCnt + self.RedisCnt
}
type SecurityGroupCacheInput struct {
VpcId string `json:"vpc_id"`
type SecurityGroupSyncstatusInput struct {
}
+1 -3
View File
@@ -17,9 +17,7 @@ package compute
import "yunion.io/x/cloudmux/pkg/apis/compute"
const (
SECGROUP_STATUS_READY = compute.SECGROUP_STATUS_READY
SECGROUP_STATUS_DELETING = "deleting" // 删除中
SECGROUP_STATUS_SYNC_RULES = "sync_rules" // 同步规则中
SECGROUP_STATUS_READY = compute.SECGROUP_STATUS_READY
SECGROUP_DEFAULT_ID = "default"
)
-31
View File
@@ -1,31 +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 compute
import "yunion.io/x/onecloud/pkg/apis"
type SecurityGroupCacheDetails struct {
apis.StatusStandaloneResourceDetails
apis.ProjectizedResourceInfo
ManagedResourceInfo
CloudregionResourceInfo
SSecurityGroupCache
// 虚拟私有网络名称
Vpc string `json:"vpc"`
ProjectId string `json:"tenant_id"`
}
-24
View File
@@ -1,24 +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 compute
const (
SECGROUP_CACHE_STATUS_READY = "ready"
SECGROUP_CACHE_STATUS_UNKNOWN = "unknown"
SECGROUP_CACHE_STATUS_DELETING = "deleting"
SECGROUP_CACHE_STATUS_CACHING = "caching"
SECGROUP_CACHE_STATUS_CACHE_FAILED = "cache_failed"
SECGROUP_CACHE_STATUS_DELETE_FAILED = "delete_failed"
)
+1
View File
@@ -51,6 +51,7 @@ const (
STATUS_DELETE_FAILED = "delete_failed"
STATUS_UNKNOWN = "unknown"
STATUS_CREATING = "creating"
STATUS_AVAILABLE = "available"
STATUS_CREATE_FAILED = "create_failed"
CLOUD_TAG_PREFIX = "ext:"
+16
View File
@@ -38,6 +38,7 @@ import (
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudcommon/db/quotas"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudcommon/validators"
guestdriver_types "yunion.io/x/onecloud/pkg/compute/guestdrivers/types"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/compute/options"
@@ -989,6 +990,21 @@ func (self *SKVMGuestDriver) ValidateCreateData(ctx context.Context, userCred mc
return nil, errors.Wrap(err, "validateMachineType")
}
}
for i := range input.Secgroups {
if input.Secgroups[i] == api.SECGROUP_DEFAULT_ID {
continue
}
secObj, err := validators.ValidateModel(userCred, models.SecurityGroupManager, &input.Secgroups[i])
if err != nil {
return nil, err
}
secgroup := secObj.(*models.SSecurityGroup)
if secgroup.CloudregionId != api.DEFAULT_REGION_ID {
return nil, httperrors.NewInputParameterError("invalid secgroup %s", secgroup.Name)
}
}
return input, nil
}
+48 -62
View File
@@ -25,6 +25,7 @@ import (
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/gotypes"
"yunion.io/x/pkg/util/billing"
"yunion.io/x/pkg/util/pinyinutils"
"yunion.io/x/pkg/utils"
@@ -36,6 +37,7 @@ import (
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudcommon/validators"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/compute/options"
"yunion.io/x/onecloud/pkg/httperrors"
@@ -316,6 +318,34 @@ func (drv *SManagedVirtualizedGuestDriver) ValidateCreateData(ctx context.Contex
if input.Cdrom != "" {
return nil, httperrors.NewInputParameterError("%s not support cdrom params", input.Hypervisor)
}
var vpc *models.SVpc = nil
for _, network := range input.Networks {
netObj, err := validators.ValidateModel(userCred, models.NetworkManager, &network.Network)
if err == nil {
net := netObj.(*models.SNetwork)
vpc, err = net.GetVpc()
if err != nil {
return nil, errors.Wrapf(err, "GetVpc")
}
}
}
for i := range input.Secgroups {
if input.Secgroups[i] == api.SECGROUP_DEFAULT_ID {
continue
}
if gotypes.IsNil(vpc) {
return nil, httperrors.NewMissingParameterError("nets")
}
secObj, err := validators.ValidateModel(userCred, models.SecurityGroupManager, &input.Secgroups[i])
if err != nil {
return nil, err
}
secgroup := secObj.(*models.SSecurityGroup)
err = vpc.CheckSecurityGroupConsistent(secgroup)
if err != nil {
return nil, err
}
}
return input, nil
}
@@ -475,39 +505,6 @@ func (drv *SManagedVirtualizedGuestDriver) RequestDeployGuestOnHost(ctx context.
desc.Tags, _ = guest.GetAllUserMetadata()
//创建并同步安全组规则, 仅新建的安全组会同步规则
{
vpc, err := guest.GetVpc()
if err != nil {
return errors.Wrap(err, "guest.GetVpc")
}
region, err := vpc.GetRegion()
if err != nil {
return errors.Wrap(err, "vpc.GetRegion")
}
vpcId, err := region.GetDriver().GetSecurityGroupVpcId(ctx, task.GetUserCred(), region, host, vpc)
if err != nil {
return errors.Wrap(err, "GetSecurityGroupVpcId")
}
secgroups, err := guest.GetSecgroups()
if err != nil {
return errors.Wrap(err, "GetSecgroups")
}
for i, secgroup := range secgroups {
externalId, err := region.GetDriver().RequestSyncSecurityGroup(ctx, task.GetUserCred(), vpcId, vpc, &secgroup, desc.ProjectId, "")
if err != nil {
return errors.Wrap(err, "RequestSyncSecurityGroup")
}
desc.ExternalSecgroupIds = append(desc.ExternalSecgroupIds, externalId)
if i == 0 {
desc.ExternalSecgroupId = externalId
}
}
}
desc.UserData, err = desc.GetUserData()
if err != nil {
return errors.Wrapf(err, "GetUserData")
@@ -571,6 +568,17 @@ func (drv *SManagedVirtualizedGuestDriver) RemoteDeployGuestForCreate(ctx contex
return nil, errors.Wrapf(err, "RemoteDeployGuestForCreate.GetIHost")
}
secgroups, err := guest.GetSecgroups()
if err != nil {
return nil, errors.Wrap(err, "GetSecgroups")
}
desc.ExternalSecgroupIds = []string{}
for _, secgroup := range secgroups {
if len(secgroup.ExternalId) > 0 {
desc.ExternalSecgroupIds = append(desc.ExternalSecgroupIds, secgroup.ExternalId)
}
}
var iVM cloudprovider.ICloudVM = nil
iVM, err = func() (cloudprovider.ICloudVM, error) {
lockman.LockObject(ctx, guest)
@@ -1181,43 +1189,21 @@ func (drv *SManagedVirtualizedGuestDriver) OnGuestDeployTaskDataReceived(ctx con
}
func (drv *SManagedVirtualizedGuestDriver) RequestSyncSecgroupsOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error {
secgroups, err := guest.GetSecgroups()
if err != nil {
return errors.Wrapf(err, "GetSecgroups")
}
iVM, err := guest.GetIVM(ctx)
if err != nil {
return err
}
vpc, err := guest.GetVpc()
if err != nil {
return errors.Wrap(err, "guest.GetVpc")
}
region, _ := host.GetRegion()
vpcId, err := region.GetDriver().GetSecurityGroupVpcId(ctx, task.GetUserCred(), region, host, vpc)
if err != nil {
return errors.Wrap(err, "GetSecurityGroupVpcId")
}
remoteProjectId := ""
provider := host.GetCloudprovider()
if provider != nil {
remoteProjectId, err = provider.SyncProject(ctx, task.GetUserCred(), guest.ProjectId)
if err != nil {
logclient.AddSimpleActionLog(guest, logclient.ACT_SYNC_CLOUD_PROJECT, err, task.GetUserCred(), false)
}
}
secgroups, err := guest.GetSecgroups()
if err != nil {
return errors.Wrap(err, "GetSecgroups")
}
externalIds := []string{}
for _, secgroup := range secgroups {
externalId, err := region.GetDriver().RequestSyncSecurityGroup(ctx, task.GetUserCred(), vpcId, vpc, &secgroup, remoteProjectId, "")
if err != nil {
return errors.Wrap(err, "RequestSyncSecurityGroup")
if len(secgroup.ExternalId) > 0 {
externalIds = append(externalIds, secgroup.ExternalId)
}
externalIds = append(externalIds, externalId)
}
return iVM.SetSecurityGroups(externalIds)
}
+8
View File
@@ -77,6 +77,9 @@ type SCapabilities struct {
VpcPeerBrands []string `json:",allowempty"`
DisabledVpcPeerBrands []string `json:",allowempty"`
SecurityGroupBrands []string `json:",allowempty"`
DisabledSecurityGroupBrands []string `json:",allowempty"`
ReadOnlyBrands []string `json:",allowempty"`
ReadOnlyDisabledBrands []string `json:",allowempty"`
ReadOnlyComputeEngineBrands []string `json:",allowempty"`
@@ -113,6 +116,9 @@ type SCapabilities struct {
ReadOnlyVpcPeerBrands []string `json:",allowempty"`
ReadOnlyDisabledVpcPeerBrands []string `json:",allowempty"`
ReadOnlySecurityGroupBrands []string `json:",allowempty"`
ReadOnlyDisabledSecurityGroupBrands []string `json:",allowempty"`
ResourceTypes []string `json:",allowempty"`
StorageTypes []string `json:",allowempty"` // going to remove on 2.14
DataStorageTypes []string `json:",allowempty"` // going to remove on 2.14
@@ -454,6 +460,8 @@ func getBrands(region *SCloudregion, zone *SZone, domainId string, capa *SCapabi
appendBrand(&capa.ContainerBrands, &capa.DisabledContainerBrands, &capa.ReadOnlyContainerBrands, &capa.ReadOnlyDisabledContainerBrands, brand, capability, enabled, readOnly)
case cloudprovider.CLOUD_CAPABILITY_VPC_PEER:
appendBrand(&capa.VpcPeerBrands, &capa.DisabledVpcPeerBrands, &capa.ReadOnlyVpcPeerBrands, &capa.ReadOnlyDisabledVpcPeerBrands, brand, capability, enabled, readOnly)
case cloudprovider.CLOUD_CAPABILITY_SECURITY_GROUP:
appendBrand(&capa.SecurityGroupBrands, &capa.DisabledSecurityGroupBrands, &capa.ReadOnlySecurityGroupBrands, &capa.ReadOnlyDisabledSecurityGroupBrands, brand, capability, enabled, readOnly)
default:
}
}
+1 -1
View File
@@ -2283,7 +2283,7 @@ func (account *SCloudaccount) probeAccountStatus(ctx context.Context, userCred m
return nil
})
if err != nil {
log.Errorf("Failed to update db %s", err)
log.Errorf("Failed to update db %s for account %s", err, account.Name)
} else {
db.OpsLog.LogSyncUpdate(account, diff, userCred)
}
+91 -15
View File
@@ -292,7 +292,6 @@ func syncRegionVPCs(
return
}
db.OpsLog.LogEvent(provider, db.ACT_SYNC_HOST_COMPLETE, msg, userCred)
globalVpcIds := []string{}
for j := 0; j < len(localVpcs); j += 1 {
func() {
// lock vpc
@@ -304,14 +303,8 @@ func syncRegionVPCs(
}
syncVpcWires(ctx, userCred, syncResults, provider, &localVpcs[j], remoteVpcs[j], nil, syncRange)
if localRegion.GetDriver().IsSecurityGroupBelongVpc() ||
(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)
}
if syncRange.IsNotSkipSyncResource(SecurityGroupManager) {
syncVpcSecGroup(ctx, userCred, syncResults, provider, &localVpcs[j], remoteVpcs[j], syncRange)
}
if syncRange.IsNotSkipSyncResource(SecurityGroupManager) {
syncVpcSecGroup(ctx, userCred, syncResults, provider, localRegion, &localVpcs[j], remoteVpcs[j], syncRange)
}
syncVpcNatgateways(ctx, userCred, syncResults, provider, &localVpcs[j], remoteVpcs[j], syncRange)
syncVpcPeerConnections(ctx, userCred, syncResults, provider, &localVpcs[j], remoteVpcs[j], syncRange)
@@ -464,7 +457,58 @@ func syncVpcPeerConnections(
}
}
func syncVpcSecGroup(ctx context.Context, userCred mcclient.TokenCredential, syncResults SSyncResultSet, provider *SCloudprovider, localVpc *SVpc, remoteVpc cloudprovider.ICloudVpc, syncRange *SSyncRange) {
func syncRegionSecGroup(
ctx context.Context,
userCred mcclient.TokenCredential,
syncResults SSyncResultSet,
provider *SCloudprovider,
localRegion *SCloudregion,
remoteRegion cloudprovider.ICloudRegion,
syncRange *SSyncRange,
) {
secgroups, err := func() ([]cloudprovider.ICloudSecurityGroup, error) {
defer syncResults.AddRequestCost(SecurityGroupManager)()
return remoteRegion.GetISecurityGroups()
}()
if err != nil {
msg := fmt.Sprintf("GetISecurityGroups for region %s failed %s", localRegion.Name, err)
log.Errorf(msg)
return
}
groups := []cloudprovider.ICloudSecurityGroup{}
for i := range secgroups {
// skip vpc secgroup
if len(secgroups[i].GetVpcId()) > 0 {
continue
}
groups = append(groups, secgroups[i])
}
result := func() compare.SyncResult {
defer syncResults.AddSqlCost(SecurityGroupManager)()
return localRegion.SyncSecgroups(ctx, userCred, provider, nil, groups, syncRange.Xor)
}()
syncResults.Add(SecurityGroupManager, result)
msg := result.Result()
notes := fmt.Sprintf("SyncSecurityGroup for region %s result: %s", localRegion.Name, msg)
log.Infof(notes)
provider.SyncError(result, notes, userCred)
if result.IsError() {
return
}
}
func syncVpcSecGroup(
ctx context.Context,
userCred mcclient.TokenCredential,
syncResults SSyncResultSet,
provider *SCloudprovider,
localRegion *SCloudregion,
localVpc *SVpc,
remoteVpc cloudprovider.ICloudVpc,
syncRange *SSyncRange,
) {
secgroups, err := func() ([]cloudprovider.ICloudSecurityGroup, error) {
defer syncResults.AddRequestCost(SecurityGroupManager)()
return remoteVpc.GetISecurityGroups()
@@ -475,14 +519,23 @@ func syncVpcSecGroup(ctx context.Context, userCred mcclient.TokenCredential, syn
return
}
_, _, result := func() ([]SSecurityGroup, []cloudprovider.ICloudSecurityGroup, compare.SyncResult) {
groups := []cloudprovider.ICloudSecurityGroup{}
for i := range secgroups {
// skip vpc secgroup
if len(secgroups[i].GetVpcId()) == 0 {
continue
}
groups = append(groups, secgroups[i])
}
result := func() compare.SyncResult {
defer syncResults.AddSqlCost(SecurityGroupManager)()
return SecurityGroupCacheManager.SyncSecurityGroupCaches(ctx, userCred, provider, secgroups, localVpc, syncRange.Xor)
return localRegion.SyncSecgroups(ctx, userCred, provider, localVpc, groups, syncRange.Xor)
}()
syncResults.Add(SecurityGroupCacheManager, result)
syncResults.Add(SecurityGroupManager, result)
msg := result.Result()
notes := fmt.Sprintf("SyncSecurityGroupCaches for VPC %s result: %s", localVpc.Name, msg)
notes := fmt.Sprintf("SyncSecurityGroup for VPC %s result: %s", localVpc.Name, msg)
log.Infof(notes)
provider.SyncError(result, notes, userCred)
if result.IsError() {
@@ -2108,6 +2161,11 @@ func syncPublicCloudProviderInfo(
if syncRange.IsNotSkipSyncResource(ElasticipManager) {
syncRegionEips(ctx, userCred, syncResults, provider, localRegion, remoteRegion, syncRange)
}
if syncRange.IsNotSkipSyncResource(SecurityGroupManager) {
syncRegionSecGroup(ctx, userCred, syncResults, provider, localRegion, remoteRegion, syncRange)
}
}
if syncRange.NeedSyncResource(cloudprovider.CLOUD_CAPABILITY_COMPUTE) {
@@ -2728,10 +2786,28 @@ func syncGlobalVpcs(ctx context.Context, userCred mcclient.TokenCredential, sync
return err
}
result := provider.SyncGlobalVpcs(ctx, userCred, gvpcs, xor)
localVpcs, remoteVpcs, result := provider.SyncGlobalVpcs(ctx, userCred, gvpcs, xor)
notes := fmt.Sprintf("Sync global vpcs for cloudprovider %s result: %s", provider.GetName(), result.Result())
log.Infof(notes)
provider.SyncError(result, notes, userCred)
for i := range localVpcs {
lockman.LockObject(ctx, &localVpcs[i])
defer lockman.ReleaseObject(ctx, &localVpcs[i])
if localVpcs[i].Deleted {
continue
}
secgroups, err := remoteVpcs[i].GetISecurityGroups()
if err != nil {
log.Errorf("GetISecurityGroup for global vpc %s error: %v", localVpcs[i].Name, err)
continue
}
result := localVpcs[i].SyncSecgroups(ctx, userCred, secgroups, xor)
notes := fmt.Sprintf("Sync security group for global vpc %s result: %s", localVpcs[i].Name, result.Result())
log.Infof(notes)
}
return nil
}
+1 -2
View File
@@ -755,8 +755,7 @@ func fetchDBInstanceZones(rdsIds []string) map[string][]sDBInstanceZone {
}
func (self *SDBInstance) getSecgroupsByExternalIds(externalIds []string) ([]SSecurityGroup, error) {
sq := SecurityGroupCacheManager.Query("secgroup_id").In("external_id", externalIds).Equals("manager_id", self.ManagerId)
q := SecurityGroupManager.Query().In("id", sq.SubQuery())
q := SecurityGroupManager.Query().In("external_id", externalIds).Equals("manager_id", self.ManagerId)
secgroups := []SSecurityGroup{}
err := db.FetchModelObjects(SecurityGroupManager, q, &secgroups)
if err != nil {
+30 -4
View File
@@ -1713,12 +1713,27 @@ func (self *SElasticcache) OnMetadataUpdated(ctx context.Context, userCred mccli
}
func (self *SElasticcache) getSecgroupsBySecgroupExternalIds(externalIds []string) ([]SSecurityGroup, error) {
vpc, _ := self.GetVpc()
if vpc == nil {
return nil, errors.Wrap(errors.ErrNotFound, "GetVpc")
vpc, err := self.GetVpc()
if err != nil {
return nil, errors.Wrapf(err, "GetVpc")
}
region, err := vpc.GetRegion()
if err != nil {
return nil, errors.Wrapf(err, "GetRegion")
}
filter, err := region.GetDriver().GetSecurityGroupFilter(vpc)
if err != nil {
return nil, errors.Wrapf(err, "GetSecurityGroupFilter")
}
return getSecgroupsBySecgroupExternalIds(vpc.ManagerId, externalIds)
q := SecurityGroupManager.Query().In("external_id", externalIds)
q = filter(q)
secgroups := []SSecurityGroup{}
err = db.FetchModelObjects(SecurityGroupManager, q, &secgroups)
if err != nil {
return nil, errors.Wrapf(err, "db.FetchModelObjects")
}
return secgroups, nil
}
func (self *SElasticcache) GetElasticcacheSecgroups() ([]SElasticcachesecgroup, error) {
@@ -1731,6 +1746,17 @@ func (self *SElasticcache) GetElasticcacheSecgroups() ([]SElasticcachesecgroup,
return ess, nil
}
func (self *SElasticcache) GetSecgroups() ([]SSecurityGroup, error) {
ret := []SSecurityGroup{}
sq := ElasticcachesecgroupManager.Query("secgroup_id").Equals("elasticcache_id", self.Id)
q := SecurityGroupManager.Query().In("id", sq.SubQuery())
err := db.FetchModelObjects(SecurityGroupManager, q, &ret)
if err != nil {
return nil, errors.Wrapf(err, "db.FetchModelObjects")
}
return ret, nil
}
func (self *SElasticcache) validateSecgroupInput(secgroups []string) error {
if !utils.IsInStringArray(self.Status, []string{api.ELASTIC_CACHE_STATUS_RUNNING, api.ELASTIC_CACHE_STATUS_DEPLOYING}) {
return httperrors.NewInputParameterError("Cannot add security groups in status %s", self.Status)
+121 -13
View File
@@ -36,6 +36,7 @@ import (
"yunion.io/x/onecloud/pkg/cloudcommon/validators"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/logclient"
"yunion.io/x/onecloud/pkg/util/stringutils2"
)
@@ -304,16 +305,19 @@ func (self *SCloudprovider) GetGlobalVpcs() ([]SGlobalVpc, error) {
return vpcs, nil
}
func (self *SCloudprovider) SyncGlobalVpcs(ctx context.Context, userCred mcclient.TokenCredential, exts []cloudprovider.ICloudGlobalVpc, xor bool) compare.SyncResult {
func (self *SCloudprovider) SyncGlobalVpcs(ctx context.Context, userCred mcclient.TokenCredential, exts []cloudprovider.ICloudGlobalVpc, xor bool) ([]SGlobalVpc, []cloudprovider.ICloudGlobalVpc, compare.SyncResult) {
lockman.LockRawObject(ctx, GlobalVpcManager.Keyword(), self.Id)
defer lockman.ReleaseRawObject(ctx, GlobalVpcManager.Keyword(), self.Id)
result := compare.SyncResult{}
localVpcs := make([]SGlobalVpc, 0)
remoteVpcs := make([]cloudprovider.ICloudGlobalVpc, 0)
dbVpcs, err := self.GetGlobalVpcs()
if err != nil {
result.Error(err)
return result
return nil, nil, result
}
removed := make([]SGlobalVpc, 0)
@@ -324,7 +328,7 @@ func (self *SCloudprovider) SyncGlobalVpcs(ctx context.Context, userCred mcclien
err = compare.CompareSets(dbVpcs, exts, &removed, &commondb, &commonext, &added)
if err != nil {
result.Error(err)
return result
return nil, nil, result
}
for i := 0; i < len(removed); i += 1 {
@@ -336,26 +340,28 @@ func (self *SCloudprovider) SyncGlobalVpcs(ctx context.Context, userCred mcclien
result.Delete()
}
if !xor {
for i := 0; i < len(commondb); i += 1 {
err = commondb[i].SyncWithCloudGlobalVpc(ctx, userCred, commonext[i])
if err != nil {
result.UpdateError(err)
continue
}
result.Update()
for i := 0; i < len(commondb); i += 1 {
err = commondb[i].SyncWithCloudGlobalVpc(ctx, userCred, commonext[i])
if err != nil {
result.UpdateError(err)
continue
}
localVpcs = append(localVpcs, commondb[i])
remoteVpcs = append(remoteVpcs, commonext[i])
result.Update()
}
for i := 0; i < len(added); i += 1 {
_, err := self.newFromCloudGlobalVpc(ctx, userCred, added[i])
vpc, err := self.newFromCloudGlobalVpc(ctx, userCred, added[i])
if err != nil {
result.AddError(err)
continue
}
localVpcs = append(localVpcs, *vpc)
remoteVpcs = append(remoteVpcs, added[i])
result.Add()
}
return result
return localVpcs, remoteVpcs, result
}
func (self *SGlobalVpc) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
@@ -437,3 +443,105 @@ func (self *SGlobalVpc) PerformSyncstatus(ctx context.Context, userCred mcclient
func (self *SGlobalVpc) StartSyncstatusTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
return StartResourceSyncStatusTask(ctx, userCred, self, "GlobalVpcSyncstatusTask", parentTaskId)
}
func (self *SGlobalVpc) GetSecgroups() ([]SSecurityGroup, error) {
q := SecurityGroupManager.Query().Equals("globalvpc_id", self.Id)
ret := []SSecurityGroup{}
return ret, db.FetchModelObjects(SecurityGroupManager, q, &ret)
}
func (self *SGlobalVpc) SyncSecgroups(ctx context.Context, userCred mcclient.TokenCredential, exts []cloudprovider.ICloudSecurityGroup, xor bool) compare.SyncResult {
lockman.LockRawObject(ctx, SecurityGroupManager.Keyword(), self.Id)
defer lockman.ReleaseRawObject(ctx, SecurityGroupManager.Keyword(), self.Id)
result := compare.SyncResult{}
dbSecs, err := self.GetSecgroups()
if err != nil {
result.Error(err)
return result
}
provider := self.GetCloudprovider()
syncOwnerId := provider.GetOwnerId()
removed := make([]SSecurityGroup, 0)
commondb := make([]SSecurityGroup, 0)
commonext := make([]cloudprovider.ICloudSecurityGroup, 0)
added := make([]cloudprovider.ICloudSecurityGroup, 0)
err = compare.CompareSets(dbSecs, exts, &removed, &commondb, &commonext, &added)
if err != nil {
result.Error(err)
return result
}
for i := 0; i < len(removed); i += 1 {
err = removed[i].RealDelete(ctx, userCred)
if err != nil {
result.DeleteError(err)
continue
}
result.Delete()
}
for i := 0; i < len(commondb); i += 1 {
if !xor {
err = commondb[i].SyncWithCloudSecurityGroup(ctx, userCred, commonext[i], syncOwnerId, true)
if err != nil {
result.UpdateError(err)
continue
}
}
result.Update()
}
for i := 0; i < len(added); i += 1 {
err := self.newFromCloudSecurityGroup(ctx, userCred, added[i], syncOwnerId)
if err != nil {
result.AddError(err)
continue
}
result.Add()
}
return result
}
func (self *SGlobalVpc) newFromCloudSecurityGroup(
ctx context.Context,
userCred mcclient.TokenCredential,
ext cloudprovider.ICloudSecurityGroup,
syncOwnerId mcclient.IIdentityProvider,
) error {
ret := &SSecurityGroup{}
ret.SetModelManager(SecurityGroupManager, ret)
ret.Name = ext.GetName()
ret.Description = ext.GetDescription()
ret.ExternalId = ext.GetGlobalId()
ret.ManagerId = self.ManagerId
ret.GlobalvpcId = self.Id
ret.Status = api.SECGROUP_STATUS_READY
err := SecurityGroupManager.TableSpec().Insert(ctx, ret)
if err != nil {
return errors.Wrapf(err, "Insert")
}
db.Update(ret, func() error {
ret.CloudregionId = "-"
return nil
})
syncVirtualResourceMetadata(ctx, userCred, ret, ext)
SyncCloudProject(ctx, userCred, ret, syncOwnerId, ext, ret.ManagerId)
rules, err := ext.GetRules()
if err != nil {
return errors.Wrapf(err, "GetRules")
}
result := ret.SyncRules(ctx, userCred, rules)
if result.IsError() {
logclient.AddSimpleActionLog(ret, logclient.ACT_CLOUD_SYNC, result, userCred, false)
}
return nil
}
+51 -42
View File
@@ -16,7 +16,6 @@ package models
import (
"context"
"database/sql"
"fmt"
"gopkg.in/fatih/set.v0"
@@ -67,30 +66,33 @@ func (self *SGuest) PerformAddSecgroup(
secgroupIds = append(secgroupIds, secgroup.Id)
}
secgroupNames := []string{}
for _, secgroupId := range input.SecgroupIds {
secgrp, err := SecurityGroupManager.FetchByIdOrName(userCred, secgroupId)
if err != nil {
if errors.Cause(err) == sql.ErrNoRows {
return nil, httperrors.NewResourceNotFoundError2("secgroup", secgroupId)
}
return nil, httperrors.NewGeneralError(errors.Wrapf(err, "SecurityGroupManager.FetchByIdOrName(%s)", secgroupId))
}
err = SecurityGroupManager.ValidateName(secgrp.GetName())
if err != nil {
return nil, httperrors.NewInputParameterError("The secgroup name %s does not meet the requirements, please change the name", secgrp.GetName())
}
if utils.IsInStringArray(secgrp.GetId(), secgroupIds) {
return nil, httperrors.NewInputParameterError("security group %s has already been assigned to guest %s", secgrp.GetName(), self.Name)
}
secgroupIds = append(secgroupIds, secgrp.GetId())
secgroupNames = append(secgroupNames, secgrp.GetName())
vpc, err := self.GetVpc()
if err != nil {
return nil, errors.Wrapf(err, "GetVpc")
}
err = self.saveSecgroups(ctx, userCred, secgroupIds)
secgroupNames := []string{}
for i := range input.SecgroupIds {
secObj, err := validators.ValidateModel(userCred, SecurityGroupManager, &input.SecgroupIds[i])
if err != nil {
return nil, err
}
secgroup := secObj.(*SSecurityGroup)
if utils.IsInStringArray(secObj.GetId(), secgroupIds) {
return nil, httperrors.NewInputParameterError("security group %s has already been assigned to guest %s", secObj.GetName(), self.Name)
}
err = vpc.CheckSecurityGroupConsistent(secgroup)
if err != nil {
return nil, err
}
secgroupIds = append(secgroupIds, secgroup.GetId())
secgroupNames = append(secgroupNames, secgroup.Name)
}
err = self.SaveSecgroups(ctx, userCred, secgroupIds)
if err != nil {
return nil, httperrors.NewGeneralError(errors.Wrap(err, "saveSecgroups"))
}
@@ -142,14 +144,12 @@ func (self *SGuest) PerformRevokeSecgroup(
}
secgroupNames := []string{}
for _, secgroupId := range input.SecgroupIds {
secgrp, err := SecurityGroupManager.FetchByIdOrName(userCred, secgroupId)
for i := range input.SecgroupIds {
secObj, err := validators.ValidateModel(userCred, SecurityGroupManager, &input.SecgroupIds[i])
if err != nil {
if errors.Cause(err) == sql.ErrNoRows {
return nil, httperrors.NewResourceNotFoundError2("secgroup", secgroupId)
}
return nil, httperrors.NewGeneralError(errors.Wrapf(err, "SecurityGroupManager.FetchByIdOrName(%s)", secgroupId))
return nil, err
}
secgrp := secObj.(*SSecurityGroup)
_, ok := secgroupMaps[secgrp.GetId()]
if !ok {
return nil, httperrors.NewInputParameterError("security group %s not assigned to guest %s", secgrp.GetName(), self.Name)
@@ -163,7 +163,7 @@ func (self *SGuest) PerformRevokeSecgroup(
secgrpIds = append(secgrpIds, secgroupId)
}
err = self.saveSecgroups(ctx, userCred, secgrpIds)
err = self.SaveSecgroups(ctx, userCred, secgrpIds)
if err != nil {
return nil, httperrors.NewGeneralError(errors.Wrap(err, "saveSecgroups"))
}
@@ -247,14 +247,20 @@ func (self *SGuest) performAssignSecgroup(
return nil, httperrors.NewMissingParameterError("secgroup_id")
}
vpc, err := self.GetVpc()
if err != nil {
return nil, errors.Wrapf(err, "GetVpc")
}
secObj, err := validators.ValidateModel(userCred, SecurityGroupManager, &input.SecgroupId)
if err != nil {
return nil, err
}
secgroup := secObj.(*SSecurityGroup)
err = SecurityGroupManager.ValidateName(secObj.GetName())
err = vpc.CheckSecurityGroupConsistent(secgroup)
if err != nil {
return nil, httperrors.NewInputParameterError("The secgroup name %s does not meet the requirements, please change the name", secObj.GetName())
return nil, err
}
err = self.saveDefaultSecgroupId(userCred, input.SecgroupId, isAdmin)
@@ -290,20 +296,23 @@ func (self *SGuest) PerformSetSecgroup(
return nil, httperrors.NewUnsupportOperationError("guest %s band to up to %d security groups", self.Name, maxCount)
}
vpc, err := self.GetVpc()
if err != nil {
return nil, errors.Wrapf(err, "GetVpc")
}
secgroupIds := []string{}
secgroupNames := []string{}
for _, secgroupId := range input.SecgroupIds {
secgrp, err := SecurityGroupManager.FetchByIdOrName(userCred, secgroupId)
for i := range input.SecgroupIds {
secObj, err := validators.ValidateModel(userCred, SecurityGroupManager, &input.SecgroupIds[i])
if err != nil {
if errors.Cause(err) == sql.ErrNoRows {
return nil, httperrors.NewResourceNotFoundError2("secgroup", secgroupId)
}
return nil, httperrors.NewGeneralError(errors.Wrapf(err, "FetchByIdOrName(%s)", secgroupId))
return nil, err
}
secgrp := secObj.(*SSecurityGroup)
err = SecurityGroupManager.ValidateName(secgrp.GetName())
err = vpc.CheckSecurityGroupConsistent(secgrp)
if err != nil {
return nil, httperrors.NewInputParameterError("The secgroup name %s does not meet the requirements, please change the name", secgrp.GetName())
return nil, err
}
if !utils.IsInStringArray(secgrp.GetId(), secgroupIds) {
@@ -312,7 +321,7 @@ func (self *SGuest) PerformSetSecgroup(
}
}
err := self.saveSecgroups(ctx, userCred, secgroupIds)
err = self.SaveSecgroups(ctx, userCred, secgroupIds)
if err != nil {
return nil, httperrors.NewGeneralError(errors.Wrapf(err, "saveSecgroups"))
}
@@ -332,7 +341,7 @@ func (self *SGuest) GetGuestSecgroups() ([]SGuestsecgroup, error) {
return gss, nil
}
func (self *SGuest) saveSecgroups(ctx context.Context, userCred mcclient.TokenCredential, secgroupIds []string) error {
func (self *SGuest) SaveSecgroups(ctx context.Context, userCred mcclient.TokenCredential, secgroupIds []string) error {
if len(secgroupIds) == 0 {
return self.RevokeAllSecgroups(ctx, userCred)
}
+15 -11
View File
@@ -5743,19 +5743,23 @@ func (self *SGuest) SyncVMEip(ctx context.Context, userCred mcclient.TokenCreden
}
func (self *SGuest) getSecgroupsBySecgroupExternalIds(externalIds []string) ([]SSecurityGroup, error) {
host, _ := self.GetHost()
if host == nil {
return nil, errors.Error("not found host for guest")
vpc, err := self.GetVpc()
if err != nil {
return nil, errors.Wrapf(err, "GetVpc")
}
region, err := vpc.GetRegion()
if err != nil {
return nil, errors.Wrapf(err, "GetRegion")
}
filter, err := region.GetDriver().GetSecurityGroupFilter(vpc)
if err != nil {
return nil, errors.Wrapf(err, "GetSecurityGroupFilter")
}
return getSecgroupsBySecgroupExternalIds(host.ManagerId, externalIds)
}
func getSecgroupsBySecgroupExternalIds(managerId string, externalIds []string) ([]SSecurityGroup, error) {
sq := SecurityGroupCacheManager.Query("secgroup_id").In("external_id", externalIds).Equals("manager_id", managerId)
q := SecurityGroupManager.Query().In("id", sq.SubQuery())
q := SecurityGroupManager.Query().In("external_id", externalIds)
q = filter(q)
secgroups := []SSecurityGroup{}
err := db.FetchModelObjects(SecurityGroupManager, q, &secgroups)
err = db.FetchModelObjects(SecurityGroupManager, q, &secgroups)
if err != nil {
return nil, errors.Wrapf(err, "db.FetchModelObjects")
}
@@ -5782,7 +5786,7 @@ func (self *SGuest) SyncVMSecgroups(ctx context.Context, userCred mcclient.Token
secgroupIds = append(secgroupIds, secgroup.Id)
}
return self.saveSecgroups(ctx, userCred, secgroupIds)
return self.SaveSecgroups(ctx, userCred, secgroupIds)
}
func (self *SGuest) GetIVM(ctx context.Context) (cloudprovider.ICloudVM, error) {
-1
View File
@@ -40,7 +40,6 @@ func InitDB() error {
WireManager,
StorageManager,
SecurityGroupManager,
SecurityGroupCacheManager,
NetworkManager,
NetworkAddressManager,
NetworkIpMacManager,
+21 -2
View File
@@ -138,6 +138,8 @@ func (self *SCloudregion) purgeVpcs(ctx context.Context, managerId string) error
schedtags := NetworkschedtagManager.Query("row_id").In("network_id", networks.SubQuery())
nats := NatGatewayManager.Query("id").In("vpc_id", vpcs.SubQuery())
stables := NatSEntryManager.Query("id").In("natgateway_id", nats.SubQuery())
secgroups := SecurityGroupManager.Query("id").In("vpc_id", vpcs.SubQuery())
rules := SecurityGroupRuleManager.Query("id").In("secgroup_id", secgroups.SubQuery())
dtables := NatDEntryManager.Query("id").In("natgateway_id", nats.SubQuery())
routes := RouteTableManager.Query("id").In("vpc_id", vpcs.SubQuery())
@@ -146,6 +148,8 @@ func (self *SCloudregion) purgeVpcs(ctx context.Context, managerId string) error
ipv6 := IPv6GatewayManager.Query("id").In("vpc_id", vpcs.SubQuery())
pairs := []purgePair{
{manager: SecurityGroupRuleManager, key: "id", q: rules},
{manager: SecurityGroupManager, key: "id", q: secgroups},
{manager: IPv6GatewayManager, key: "id", q: ipv6},
{manager: VpcPeeringConnectionManager, key: "id", q: peers},
{manager: InterVpcNetworkRouteSetManager, key: "id", q: intervpcroutes},
@@ -196,8 +200,12 @@ func (self *SVpc) purge(ctx context.Context, userCred mcclient.TokenCredential)
dnszones := DnsZoneVpcManager.Query("row_id").Equals("vpc_id", self.Id)
intervpcroutes := InterVpcNetworkRouteSetManager.Query("id").Equals("vpc_id", self.Id)
ipv6 := IPv6GatewayManager.Query("id").Equals("vpc_id", self.Id)
secgroups := SecurityGroupManager.Query("id").Equals("vpc_id", self.Id)
rules := SecurityGroupRuleManager.Query("id").In("secgroup_id", secgroups.SubQuery())
pairs := []purgePair{
{manager: SecurityGroupRuleManager, key: "id", q: rules},
{manager: SecurityGroupManager, key: "id", q: secgroups},
{manager: IPv6GatewayManager, key: "id", q: ipv6},
{manager: InterVpcNetworkRouteSetManager, key: "id", q: intervpcroutes},
{manager: DnsZoneVpcManager, key: "row_id", q: dnszones},
@@ -268,7 +276,8 @@ func (self *SCloudregion) purgeResources(ctx context.Context, managerId string)
mongodbs := MongoDBManager.Query("id").Equals("manager_id", managerId).Equals("cloudregion_id", self.Id)
nics := NetworkInterfaceManager.Query("id").Equals("manager_id", managerId).Equals("cloudregion_id", self.Id)
nicips := NetworkinterfacenetworkManager.Query("row_id").In("networkinterface_id", nics.SubQuery())
seccaches := SecurityGroupCacheManager.Query("id").Equals("manager_id", managerId).Equals("cloudregion_id", self.Id)
secgroups := SecurityGroupManager.Query("id").Equals("manager_id", managerId).Equals("cloudregion_id", self.Id)
rules := SecurityGroupRuleManager.Query("id").In("secgroup_id", secgroups.SubQuery())
policycaches := SnapshotPolicyCacheManager.Query("id").Equals("manager_id", managerId).Equals("cloudregion_id", self.Id)
snapshots := SnapshotManager.Query("id").Equals("manager_id", managerId).Equals("cloudregion_id", self.Id)
tables := TablestoreManager.Query("id").Equals("manager_id", managerId).Equals("cloudregion_id", self.Id)
@@ -287,7 +296,8 @@ func (self *SCloudregion) purgeResources(ctx context.Context, managerId string)
{manager: TablestoreManager, key: "id", q: tables},
{manager: SnapshotManager, key: "id", q: snapshots},
{manager: SnapshotPolicyCacheManager, key: "id", q: policycaches},
{manager: SecurityGroupCacheManager, key: "id", q: seccaches},
{manager: SecurityGroupRuleManager, key: "id", q: rules},
{manager: SecurityGroupManager, key: "id", q: secgroups},
{manager: NetworkinterfacenetworkManager, key: "row_id", q: nicips},
{manager: NetworkInterfaceManager, key: "id", q: nics},
{manager: MongoDBManager, key: "id", q: mongodbs},
@@ -561,6 +571,11 @@ func (self *purgePair) purgeAll(ctx context.Context) error {
"delete from %s where %s in (%s)",
self.manager.TableSpec().Name(), self.key, placeholder,
)
case SecurityGroupRuleManager.Keyword():
sql = fmt.Sprintf(
"delete from %s where %s in (%s)",
self.manager.TableSpec().Name(), self.key, placeholder,
)
case NetworkAdditionalWireManager.Keyword():
sql = fmt.Sprintf("delete from `%s` where `wire_id` in (%s)",
self.manager.TableSpec().Name(), placeholder,
@@ -870,6 +885,8 @@ func (cprvd *SCloudprovider) purge(ctx context.Context, userCred mcclient.TokenC
capability := CloudproviderCapabilityManager.Query("cloudprovider_id").Equals("cloudprovider_id", cprvd.Id)
cdn := CDNDomainManager.Query("id").Equals("manager_id", cprvd.Id)
vpcs := GlobalVpcManager.Query("id").Equals("manager_id", cprvd.Id)
secgroups := SecurityGroupManager.Query("id").In("globalvpc_id", vpcs.SubQuery())
rules := SecurityGroupRuleManager.Query("id").In("secgroup_id", secgroups.SubQuery())
intervpcs := InterVpcNetworkManager.Query("id").Equals("manager_id", cprvd.Id)
intervpcnetworks := InterVpcNetworkVpcManager.Query("row_id").In("inter_vpc_network_id", intervpcs.SubQuery())
dnszones := DnsZoneManager.Query("id").Equals("manager_id", cprvd.Id)
@@ -882,6 +899,8 @@ func (cprvd *SCloudprovider) purge(ctx context.Context, userCred mcclient.TokenC
{manager: DnsZoneManager, key: "id", q: dnszones},
{manager: InterVpcNetworkVpcManager, key: "row_id", q: intervpcnetworks},
{manager: InterVpcNetworkManager, key: "id", q: intervpcs},
{manager: SecurityGroupRuleManager, key: "id", q: rules},
{manager: SecurityGroupManager, key: "id", q: secgroups},
{manager: GlobalVpcManager, key: "id", q: vpcs},
{manager: CDNDomainManager, key: "id", q: cdn},
{manager: CloudproviderRegionManager, key: "row_id", q: cprs},
+82 -67
View File
@@ -22,7 +22,7 @@ import (
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/util/billing"
"yunion.io/x/pkg/util/rbacscope"
"yunion.io/x/sqlchemy"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
@@ -42,6 +42,87 @@ type IRegionDriver interface {
IKafkaDriver
IKubeClusterDriver
ILoadbalancerDriver
IVpcDriver
IEipDriver
ISnapshotDriver
ISecurityGroupDriver
GetDiskResetParams(snapshot *SSnapshot) *jsonutils.JSONDict
OnDiskReset(ctx context.Context, userCred mcclient.TokenCredential, disk *SDisk, snapshot *SSnapshot, data jsonutils.JSONObject) error
OnSnapshotDelete(ctx context.Context, snapshot *SSnapshot, task taskman.ITask, data jsonutils.JSONObject) error
RequestSyncDiskBackupStatus(ctx context.Context, userCred mcclient.TokenCredential, backup *SDiskBackup, task taskman.ITask) error
RequestCreateBackup(ctx context.Context, backup *SDiskBackup, snapshotId string, task taskman.ITask) error
RequestDeleteBackup(ctx context.Context, backup *SDiskBackup, task taskman.ITask) error
RequestCreateInstanceBackup(ctx context.Context, guest *SGuest, ib *SInstanceBackup, task taskman.ITask, params *jsonutils.JSONDict) error
RequestDeleteInstanceBackup(ctx context.Context, ib *SInstanceBackup, task taskman.ITask) error
RequestSyncInstanceBackupStatus(ctx context.Context, userCred mcclient.TokenCredential, ib *SInstanceBackup, task taskman.ITask) error
RequestSyncBackupStorageStatus(ctx context.Context, userCred mcclient.TokenCredential, bs *SBackupStorage, task taskman.ITask) error
RequestCreateInstanceSnapshot(ctx context.Context, guest *SGuest, isp *SInstanceSnapshot, task taskman.ITask, params *jsonutils.JSONDict) error
RequestDeleteInstanceSnapshot(ctx context.Context, isp *SInstanceSnapshot, task taskman.ITask) error
RequestResetToInstanceSnapshot(ctx context.Context, guest *SGuest, isp *SInstanceSnapshot, task taskman.ITask, params *jsonutils.JSONDict) error
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
IsSupportedBillingCycle(bc billing.SBillingCycle, resource string) bool
GetSecgroupVpcid(vpcId string) string
RequestSyncDiskStatus(ctx context.Context, userCred mcclient.TokenCredential, disk *SDisk, task taskman.ITask) error
RequestSyncSnapshotStatus(ctx context.Context, userCred mcclient.TokenCredential, snapshot *SSnapshot, task taskman.ITask) error
RequestSyncNatGatewayStatus(ctx context.Context, userCred mcclient.TokenCredential, natgateway *SNatGateway, task taskman.ITask) error
RequestSyncBucketStatus(ctx context.Context, userCred mcclient.TokenCredential, bucket *SBucket, task taskman.ITask) error
RequestSyncDBInstanceBackupStatus(ctx context.Context, userCred mcclient.TokenCredential, backup *SDBInstanceBackup, task taskman.ITask) error
RequestCreateNetwork(ctx context.Context, userCred mcclient.TokenCredential, network *SNetwork, task taskman.ITask) error
ValidateCreateCdnData(ctx context.Context, userCred mcclient.TokenCredential, input api.CDNDomainCreateInput) (api.CDNDomainCreateInput, error)
}
type ISnapshotDriver interface {
// Region Driver Snapshot Policy Apis
RequestUpdateSnapshotPolicy(ctx context.Context, userCred mcclient.TokenCredential, sp *SSnapshotPolicy, input cloudprovider.SnapshotPolicyInput, task taskman.ITask) error
RequestApplySnapshotPolicy(ctx context.Context, userCred mcclient.TokenCredential, task taskman.ITask, disk *SDisk, sp *SSnapshotPolicy, data jsonutils.JSONObject) error
RequestCancelSnapshotPolicy(ctx context.Context, userCred mcclient.TokenCredential, task taskman.ITask, disk *SDisk, sp *SSnapshotPolicy, data jsonutils.JSONObject) error
RequestPreSnapshotPolicyApply(ctx context.Context, userCred mcclient.TokenCredential, task taskman.ITask, disk *SDisk, sp *SSnapshotPolicy, data jsonutils.JSONObject) error
// Region Driver Snapshot Policy joint Disk Apis
ValidateCreateSnapshopolicyDiskData(ctx context.Context, userCred mcclient.TokenCredential, disk *SDisk, snapshotPolicy *SSnapshotPolicy) error
// Region Driver Snapshot Apis
ValidateSnapshotDelete(ctx context.Context, snapshot *SSnapshot) error
ValidateCreateSnapshotData(ctx context.Context, userCred mcclient.TokenCredential, disk *SDisk, storage *SStorage, input *api.SnapshotCreateInput) error
RequestCreateSnapshot(ctx context.Context, snapshot *SSnapshot, task taskman.ITask) error
RequestDeleteSnapshot(ctx context.Context, snapshot *SSnapshot, task taskman.ITask) error
SnapshotIsOutOfChain(disk *SDisk) bool
}
type ISecurityGroupDriver interface {
RequestCreateSecurityGroup(ctx context.Context, userCred mcclient.TokenCredential, secgroup *SSecurityGroup, rules api.SSecgroupRuleResourceSet) error
// 根据安全组归属vpc还是region进行过滤
GetSecurityGroupFilter(vpc *SVpc) (func(q *sqlchemy.SQuery) *sqlchemy.SQuery, error)
CreateDefaultSecurityGroup(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, vpc *SVpc) (*SSecurityGroup, error)
RequestPrepareSecurityGroups(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, secgroups []SSecurityGroup, vpc *SVpc, callback func(ids []string) error, task taskman.ITask) error
RequestDeleteSecurityGroup(ctx context.Context, userCred mcclient.TokenCredential, secgroup *SSecurityGroup, task taskman.ITask) error
ValidateCreateSecurityGroupInput(ctx context.Context, userCred mcclient.TokenCredential, input *api.SSecgroupCreateInput) (*api.SSecgroupCreateInput, error)
ValidateUpdateSecurityGroupRuleInput(ctx context.Context, userCred mcclient.TokenCredential, input *api.SSecgroupRuleUpdateInput) (*api.SSecgroupRuleUpdateInput, error)
}
type IEipDriver interface {
GetEipDefaultChargeType() string
ValidateEipChargeType(chargeType string) error
ValidateCreateEipData(ctx context.Context, userCred mcclient.TokenCredential, input *api.SElasticipCreateInput) error
}
type IVpcDriver interface {
ValidateCreateVpcData(ctx context.Context, userCred mcclient.TokenCredential, input api.VpcCreateInput) (api.VpcCreateInput, error)
IsVpcCreateNeedInputCidr() bool
RequestCreateVpc(ctx context.Context, userCred mcclient.TokenCredential, region *SCloudregion, vpc *SVpc, task taskman.ITask) error
RequestDeleteVpc(ctx context.Context, userCred mcclient.TokenCredential, region *SCloudregion, vpc *SVpc, task taskman.ITask) error
}
type ILoadbalancerDriver interface {
ValidateCreateLoadbalancerData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, data *api.LoadbalancerCreateInput) (*api.LoadbalancerCreateInput, error)
RequestCreateLoadbalancerInstance(ctx context.Context, userCred mcclient.TokenCredential, lb *SLoadbalancer, input *api.LoadbalancerCreateInput, task taskman.ITask) error
RequestDeleteLoadbalancer(ctx context.Context, userCred mcclient.TokenCredential, lb *SLoadbalancer, task taskman.ITask) error
@@ -83,72 +164,6 @@ type IRegionDriver interface {
ValidateUpdateLoadbalancerListenerRuleData(ctx context.Context, userCred mcclient.TokenCredential, input *api.LoadbalancerListenerRuleUpdateInput) (*api.LoadbalancerListenerRuleUpdateInput, error)
RequestCreateLoadbalancerListenerRule(ctx context.Context, userCred mcclient.TokenCredential, lbr *SLoadbalancerListenerRule, task taskman.ITask) error
RequestDeleteLoadbalancerListenerRule(ctx context.Context, userCred mcclient.TokenCredential, lbr *SLoadbalancerListenerRule, task taskman.ITask) error
ValidateCreateVpcData(ctx context.Context, userCred mcclient.TokenCredential, input api.VpcCreateInput) (api.VpcCreateInput, error)
IsVpcCreateNeedInputCidr() bool
GetEipDefaultChargeType() string
ValidateEipChargeType(chargeType string) error
ValidateCreateEipData(ctx context.Context, userCred mcclient.TokenCredential, input *api.SElasticipCreateInput) error
RequestCreateVpc(ctx context.Context, userCred mcclient.TokenCredential, region *SCloudregion, vpc *SVpc, task taskman.ITask) error
RequestDeleteVpc(ctx context.Context, userCred mcclient.TokenCredential, region *SCloudregion, vpc *SVpc, task taskman.ITask) error
// Region Driver Snapshot Policy Apis
//ValidateCreateSnapshotPolicyData(context.Context, mcclient.TokenCredential, *compute.SSnapshotPolicyCreateInput, mcclient.IIdentityProvider, *jsonutils.JSONDict) error
RequestUpdateSnapshotPolicy(ctx context.Context, userCred mcclient.TokenCredential, sp *SSnapshotPolicy, input cloudprovider.SnapshotPolicyInput, task taskman.ITask) error
RequestApplySnapshotPolicy(ctx context.Context, userCred mcclient.TokenCredential, task taskman.ITask, disk *SDisk, sp *SSnapshotPolicy, data jsonutils.JSONObject) error
RequestCancelSnapshotPolicy(ctx context.Context, userCred mcclient.TokenCredential, task taskman.ITask, disk *SDisk, sp *SSnapshotPolicy, data jsonutils.JSONObject) error
RequestPreSnapshotPolicyApply(ctx context.Context, userCred mcclient.TokenCredential, task taskman.ITask, disk *SDisk, sp *SSnapshotPolicy, data jsonutils.JSONObject) error
// Region Driver Snapshot Policy joint Disk Apis
ValidateCreateSnapshopolicyDiskData(ctx context.Context, userCred mcclient.TokenCredential, disk *SDisk, snapshotPolicy *SSnapshotPolicy) error
// Region Driver Snapshot Apis
ValidateSnapshotDelete(ctx context.Context, snapshot *SSnapshot) error
ValidateCreateSnapshotData(ctx context.Context, userCred mcclient.TokenCredential, disk *SDisk, storage *SStorage, input *api.SnapshotCreateInput) error
RequestCreateSnapshot(ctx context.Context, snapshot *SSnapshot, task taskman.ITask) error
RequestDeleteSnapshot(ctx context.Context, snapshot *SSnapshot, task taskman.ITask) error
SnapshotIsOutOfChain(disk *SDisk) bool
GetDiskResetParams(snapshot *SSnapshot) *jsonutils.JSONDict
OnDiskReset(ctx context.Context, userCred mcclient.TokenCredential, disk *SDisk, snapshot *SSnapshot, data jsonutils.JSONObject) error
OnSnapshotDelete(ctx context.Context, snapshot *SSnapshot, task taskman.ITask, data jsonutils.JSONObject) error
RequestSyncDiskBackupStatus(ctx context.Context, userCred mcclient.TokenCredential, backup *SDiskBackup, task taskman.ITask) error
RequestCreateBackup(ctx context.Context, backup *SDiskBackup, snapshotId string, task taskman.ITask) error
RequestDeleteBackup(ctx context.Context, backup *SDiskBackup, task taskman.ITask) error
RequestCreateInstanceBackup(ctx context.Context, guest *SGuest, ib *SInstanceBackup, task taskman.ITask, params *jsonutils.JSONDict) error
RequestDeleteInstanceBackup(ctx context.Context, ib *SInstanceBackup, task taskman.ITask) error
RequestSyncInstanceBackupStatus(ctx context.Context, userCred mcclient.TokenCredential, ib *SInstanceBackup, task taskman.ITask) error
RequestSyncBackupStorageStatus(ctx context.Context, userCred mcclient.TokenCredential, bs *SBackupStorage, task taskman.ITask) error
RequestCreateInstanceSnapshot(ctx context.Context, guest *SGuest, isp *SInstanceSnapshot, task taskman.ITask, params *jsonutils.JSONDict) error
RequestDeleteInstanceSnapshot(ctx context.Context, isp *SInstanceSnapshot, task taskman.ITask) error
RequestResetToInstanceSnapshot(ctx context.Context, guest *SGuest, isp *SInstanceSnapshot, task taskman.ITask, params *jsonutils.JSONDict) error
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, 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
IsSecurityGroupBelongVpc() bool
IsVpcBelongGlobalVpc() bool
IsSecurityGroupBelongGlobalVpc() bool //安全组子账号范围内可用
GetDefaultSecurityGroupVpcId() string
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
GetSecgroupVpcid(vpcId string) string
RequestSyncDiskStatus(ctx context.Context, userCred mcclient.TokenCredential, disk *SDisk, task taskman.ITask) error
RequestSyncSnapshotStatus(ctx context.Context, userCred mcclient.TokenCredential, snapshot *SSnapshot, task taskman.ITask) error
RequestSyncNatGatewayStatus(ctx context.Context, userCred mcclient.TokenCredential, natgateway *SNatGateway, task taskman.ITask) error
RequestSyncBucketStatus(ctx context.Context, userCred mcclient.TokenCredential, bucket *SBucket, task taskman.ITask) error
RequestSyncDBInstanceBackupStatus(ctx context.Context, userCred mcclient.TokenCredential, backup *SDBInstanceBackup, task taskman.ITask) error
RequestCreateNetwork(ctx context.Context, userCred mcclient.TokenCredential, network *SNetwork, task taskman.ITask) error
ValidateCreateCdnData(ctx context.Context, userCred mcclient.TokenCredential, input api.CDNDomainCreateInput) (api.CDNDomainCreateInput, error)
}
type IDBInstanceDriver interface {
-785
View File
@@ -1,785 +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 models
import (
"context"
"database/sql"
"fmt"
"sort"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/compare"
"yunion.io/x/pkg/util/rand"
"yunion.io/x/pkg/util/rbacscope"
"yunion.io/x/sqlchemy"
"yunion.io/x/onecloud/pkg/apis"
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/db/taskman"
"yunion.io/x/onecloud/pkg/cloudcommon/notifyclient"
"yunion.io/x/onecloud/pkg/compute/options"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/stringutils2"
)
type SSecurityGroupCacheManager struct {
db.SStatusStandaloneResourceBaseManager
db.SExternalizedResourceBaseManager
SManagedResourceBaseManager
SCloudregionResourceBaseManager
SVpcResourceBaseManager
SSecurityGroupResourceBaseManager
}
type SSecurityGroupCache struct {
db.SStatusStandaloneResourceBase
db.SExternalizedResourceBase
SCloudregionResourceBase
SManagedResourceBase
SSecurityGroupResourceBase
// 被其他安全组引用的次数
ReferenceCount int `nullable:"false" list:"user" json:"reference_count"`
// 虚拟私有网络外部Id
VpcId string `width:"128" charset:"ascii" list:"user" create:"required"`
ExternalProjectId string `width:"128" charset:"ascii" list:"user" create:"optional"`
}
var SecurityGroupCacheManager *SSecurityGroupCacheManager
func init() {
SecurityGroupCacheManager = &SSecurityGroupCacheManager{
SStatusStandaloneResourceBaseManager: db.NewStatusStandaloneResourceBaseManager(
SSecurityGroupCache{},
"secgroupcache_tbl",
"secgroupcache",
"secgroupcaches",
),
}
SecurityGroupCacheManager.SetVirtualObject(SecurityGroupCacheManager)
}
func (self *SSecurityGroupCache) GetOwnerId() mcclient.IIdentityProvider {
sec, err := self.GetSecgroup()
if err != nil {
return &db.SOwnerId{}
}
return &db.SOwnerId{DomainId: sec.DomainId, ProjectId: sec.ProjectId}
}
func (manager *SSecurityGroupCacheManager) ResourceScope() rbacscope.TRbacScope {
return rbacscope.ScopeProject
}
// 安全组缓存列表
func (manager *SSecurityGroupCacheManager) ListItemFilter(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.SecurityGroupCacheListInput,
) (*sqlchemy.SQuery, error) {
q, err := manager.SStatusStandaloneResourceBaseManager.ListItemFilter(ctx, q, userCred, query.StatusStandaloneResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SStatusStandaloneResourceBaseManager.ListItemFilter")
}
q, err = manager.SExternalizedResourceBaseManager.ListItemFilter(ctx, q, userCred, query.ExternalizedResourceBaseListInput)
if err != nil {
return nil, errors.Wrap(err, "SExternalizedResourceBaseManager.ListItemFilter")
}
q, err = manager.SManagedResourceBaseManager.ListItemFilter(ctx, q, userCred, query.ManagedResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SManagedResourceBaseManager.ListItemFilter")
}
q, err = manager.SCloudregionResourceBaseManager.ListItemFilter(ctx, q, userCred, query.RegionalFilterListInput)
if err != nil {
return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.ListItemFilter")
}
q, err = manager.SSecurityGroupResourceBaseManager.ListItemFilter(ctx, q, userCred, query.SecgroupFilterListInput)
if err != nil {
return nil, errors.Wrap(err, "SSecurityGroupResourceBaseManager.ListItemFilter")
}
return q, nil
}
func (manager *SSecurityGroupCacheManager) OrderByExtraFields(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.SecurityGroupCacheListInput,
) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SStatusStandaloneResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.StatusStandaloneResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SStatusStandaloneResourceBaseManager.OrderByExtraFields")
}
q, err = manager.SManagedResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.ManagedResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SManagedResourceBaseManager.OrderByExtraFields")
}
q, err = manager.SCloudregionResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.RegionalFilterListInput)
if err != nil {
return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.OrderByExtraFields")
}
q, err = manager.SSecurityGroupResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.SecgroupFilterListInput)
if err != nil {
return nil, errors.Wrap(err, "SSecurityGroupResourceBaseManager.OrderByExtraFields")
}
return q, nil
}
func (manager *SSecurityGroupCacheManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SSecurityGroupResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
q, err = manager.SStatusStandaloneResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
q, err = manager.SManagedResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
q, err = manager.SCloudregionResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
return q, httperrors.ErrNotFound
}
func (self *SSecurityGroupCache) GetIRegion(ctx context.Context) (cloudprovider.ICloudRegion, error) {
provider, err := self.GetDriver(ctx)
if err != nil {
return nil, err
}
region, err := self.GetRegion()
if err != nil {
return nil, errors.Wrapf(err, "GetRegion")
}
return provider.GetIRegionById(region.ExternalId)
}
func (manager *SSecurityGroupCacheManager) FilterByOwner(q *sqlchemy.SQuery, man db.FilterByOwnerProvider, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, scope rbacscope.TRbacScope) *sqlchemy.SQuery {
if ownerId != nil {
sq := SecurityGroupManager.Query("id")
switch scope {
case rbacscope.ScopeProject:
if len(ownerId.GetProjectId()) > 0 {
sq = sq.Equals("tenant_id", ownerId.GetProjectId())
return q.In("secgroup_id", sq)
}
case rbacscope.ScopeDomain:
if len(ownerId.GetProjectDomainId()) > 0 {
sq = sq.Equals("domain_id", ownerId.GetProjectDomainId())
return q.In("secgroup_id", sq)
}
}
}
return q
}
func (self *SSecurityGroupCache) GetVpc() (*SVpc, error) {
vpc, err := VpcManager.FetchById(self.VpcId)
if err != nil {
return nil, err
}
return vpc.(*SVpc), nil
}
func (manager *SSecurityGroupCacheManager) FetchCustomizeColumns(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
objs []interface{},
fields stringutils2.SSortedStrings,
isList bool,
) []api.SecurityGroupCacheDetails {
rows := make([]api.SecurityGroupCacheDetails, len(objs))
stdRows := manager.SStatusStandaloneResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
manRows := manager.SManagedResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
regRows := manager.SCloudregionResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
cacheIds := make([]string, len(objs))
secIds := make([]string, len(objs))
vpcIds := make([]string, len(objs))
for i := range rows {
rows[i] = api.SecurityGroupCacheDetails{
StatusStandaloneResourceDetails: stdRows[i],
ManagedResourceInfo: manRows[i],
CloudregionResourceInfo: regRows[i],
}
cache := objs[i].(*SSecurityGroupCache)
cacheIds[i] = cache.Id
vpcIds[i] = cache.VpcId
secIds[i] = cache.SecgroupId
}
vpcMaps, _ := db.FetchIdNameMap2(VpcManager, vpcIds)
for i := range rows {
rows[i].Vpc = vpcMaps[vpcIds[i]]
}
secgroups := make(map[string]SSecurityGroup)
err := db.FetchStandaloneObjectsByIds(SecurityGroupManager, secIds, &secgroups)
if err != nil {
log.Errorf("FetchStandaloneObjectsByIds fail: %v", err)
return rows
}
virObjs := make([]interface{}, len(objs))
for i := range rows {
if secgroup, ok := secgroups[secIds[i]]; ok {
virObjs[i] = &secgroup
rows[i].ProjectId = secgroup.ProjectId
}
}
projRows := SecurityGroupManager.SProjectizedResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, virObjs, fields, isList)
for i := range rows {
rows[i].ProjectizedResourceInfo = projRows[i]
}
return rows
}
func (manager *SSecurityGroupCacheManager) GetSecgroupCache(ctx context.Context, userCred mcclient.TokenCredential, secgroupId, vpcId string, regionId string, providerId string, projectId string) (*SSecurityGroupCache, error) {
secgroupCache := SSecurityGroupCache{}
query := manager.Query()
conds := []sqlchemy.ICondition{
sqlchemy.Equals(query.Field("secgroup_id"), secgroupId),
sqlchemy.Equals(query.Field("vpc_id"), vpcId),
sqlchemy.Equals(query.Field("manager_id"), providerId),
}
if len(projectId) > 0 {
conds = append(conds, sqlchemy.Equals(query.Field("external_project_id"), projectId))
}
_region, err := CloudregionManager.FetchById(regionId)
if err != nil {
return nil, errors.Wrapf(err, "CloudregionManager.FetchById(%s)", regionId)
}
region := _region.(*SCloudregion)
if !region.GetDriver().IsSecurityGroupBelongGlobalVpc() {
conds = append(conds, sqlchemy.Equals(query.Field("cloudregion_id"), regionId))
}
query = query.Filter(sqlchemy.AND(conds...))
count, err := query.CountWithError()
if err != nil {
return nil, err
}
if count == 0 {
return nil, nil
}
query.First(&secgroupCache)
secgroupCache.SetModelManager(manager, &secgroupCache)
return &secgroupCache, nil
}
func (manager *SSecurityGroupCacheManager) NewCache(ctx context.Context, userCred mcclient.TokenCredential, secgroupId, vpcId, regionId string, providerId string, projectId string) (*SSecurityGroupCache, error) {
lockman.LockClass(ctx, manager, userCred.GetProjectId())
defer lockman.ReleaseClass(ctx, manager, userCred.GetProjectId())
secgroup, err := SecurityGroupManager.FetchById(secgroupId)
if err != nil {
return nil, errors.Wrapf(err, "SecurityGroupManager.FetchById(%s)", secgroupId)
}
return manager.newCache(ctx, secgroupId, secgroup.GetName(), vpcId, regionId, providerId, projectId)
}
func (manager *SSecurityGroupCacheManager) newCache(ctx context.Context, secgroupId, secgroupName, vpcId, regionId string, providerId string, projectId string) (*SSecurityGroupCache, error) {
secgroupCache := &SSecurityGroupCache{}
secgroupCache.SecgroupId = secgroupId
secgroupCache.VpcId = vpcId
secgroupCache.ManagerId = providerId
secgroupCache.Status = api.SECGROUP_CACHE_STATUS_CACHING
secgroupCache.CloudregionId = regionId
secgroupCache.Name = secgroupName
secgroupCache.ExternalProjectId = projectId
secgroupCache.SetModelManager(manager, secgroupCache)
err := manager.TableSpec().Insert(ctx, secgroupCache)
if err != nil {
return nil, errors.Wrapf(err, "Insert")
}
return secgroupCache, nil
}
func (manager *SSecurityGroupCacheManager) Register(ctx context.Context, userCred mcclient.TokenCredential, secgroupId, vpcId, regionId string, providerId string, projectId string) (*SSecurityGroupCache, error) {
secgroupCache, err := manager.GetSecgroupCache(ctx, userCred, secgroupId, vpcId, regionId, providerId, projectId)
if err != nil {
return nil, err
}
if secgroupCache != nil {
return secgroupCache, nil
}
return manager.NewCache(ctx, userCred, secgroupId, vpcId, regionId, providerId, projectId)
}
func (manager *SSecurityGroupCacheManager) getSecgroupcachesByProvider(provider *SCloudprovider, region *SCloudregion, vpcId string) ([]SSecurityGroupCache, error) {
q := manager.Query().Equals("manager_id", provider.Id)
if region != nil {
q = q.Equals("cloudregion_id", region.Id)
}
if len(vpcId) > 0 {
q = q.Equals("vpc_id", vpcId)
}
caches := []SSecurityGroupCache{}
if err := db.FetchModelObjects(manager, q, &caches); err != nil {
return nil, err
}
return caches, nil
}
func (self *SSecurityGroupCache) GetSecgroup() (*SSecurityGroup, error) {
model, err := SecurityGroupManager.FetchById(self.SecgroupId)
if err != nil {
return nil, errors.Wrapf(err, "SecurityGroupManager.FetchById(%s)", self.SecgroupId)
}
return model.(*SSecurityGroup), nil
}
func (self *SSecurityGroupCache) SyncBaseInfo(ctx context.Context, userCred mcclient.TokenCredential, ext cloudprovider.ICloudSecurityGroup) error {
_, err := db.Update(self, func() error {
self.Status = api.SECGROUP_CACHE_STATUS_READY
if options.Options.EnableSyncName {
self.Name = ext.GetName()
}
self.Description = ext.GetDescription()
self.ExternalProjectId = ext.GetProjectId()
references, err := ext.GetReferences()
if err == nil {
self.ReferenceCount = len(references)
}
if createdAt := ext.GetCreatedAt(); !createdAt.IsZero() {
self.CreatedAt = createdAt
}
return nil
})
if err != nil {
return errors.Wrapf(err, "db.Update")
}
return nil
}
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 errors.Wrapf(err, "db.Update")
}
secgroup, err := self.GetSecgroup()
if err != nil {
return errors.Wrapf(err, "GetSecurity")
}
return secgroup.SyncSecurityGroupRules(ctx, userCred, self, provider, ext)
}
func (manager *SSecurityGroupCacheManager) SyncSecurityGroupCaches(
ctx context.Context,
userCred mcclient.TokenCredential,
provider *SCloudprovider,
secgroups []cloudprovider.ICloudSecurityGroup,
vpc *SVpc,
xor bool,
) ([]SSecurityGroup, []cloudprovider.ICloudSecurityGroup, compare.SyncResult) {
lockman.LockRawObject(ctx, manager.Keyword(), vpc.Id)
defer lockman.ReleaseRawObject(ctx, manager.Keyword(), vpc.Id)
localSecgroups := []SSecurityGroup{}
remoteSecgroups := []cloudprovider.ICloudSecurityGroup{}
syncResult := compare.SyncResult{}
region, err := vpc.GetRegion()
if err != nil {
syncResult.Error(err)
return localSecgroups, remoteSecgroups, syncResult
}
vpcId := ""
if region.GetDriver().IsSecurityGroupBelongGlobalVpc() {
vpcId, err = region.GetDriver().GetSecurityGroupVpcId(ctx, userCred, region, nil, vpc)
if err != nil {
syncResult.Error(errors.Wrap(err, "GetSecurityGroupVpcId"))
return localSecgroups, remoteSecgroups, syncResult
}
region = nil
} else if region.GetDriver().IsSecurityGroupBelongVpc() {
vpcId = vpc.ExternalId
} else {
vpcId = region.GetDriver().GetDefaultSecurityGroupVpcId()
}
dbSecgroupcaches, err := manager.getSecgroupcachesByProvider(provider, region, vpcId)
if err != nil {
syncResult.Error(err)
return nil, nil, syncResult
}
removed := []SSecurityGroupCache{}
commondb := []SSecurityGroupCache{}
commonext := []cloudprovider.ICloudSecurityGroup{}
added := []cloudprovider.ICloudSecurityGroup{}
if err := compare.CompareSets(dbSecgroupcaches, secgroups, &removed, &commondb, &commonext, &added); err != nil {
syncResult.Error(err)
return nil, nil, syncResult
}
for i := 0; i < len(removed); i++ {
err = removed[i].RealDelete(ctx, userCred)
if err != nil {
syncResult.DeleteError(err)
} else {
syncResult.Delete()
notifyclient.EventNotify(ctx, userCred, notifyclient.SEventNotifyParam{
Obj: &removed[i],
Action: notifyclient.ActionSyncDelete,
})
}
}
if !xor {
for i := 0; i < len(commondb); i++ {
err := commondb[i].syncWithCloudSecurityGroup(ctx, userCred, provider, commonext[i])
if err != nil {
syncResult.UpdateError(errors.Wrapf(err, "syncWithCloudSecurityGroup"))
continue
}
syncResult.Update()
}
}
for i := 0; i < len(added); i++ {
secgroup, err := SecurityGroupManager.newFromCloudSecgroup(ctx, userCred, provider, added[i])
if err != nil {
syncResult.AddError(errors.Wrapf(err, "newFromCloudSecgroup"))
continue
}
if secgroup.ProjectId != provider.ProjectId {
_, err = secgroup.PerformPublic(ctx, userCred, nil,
apis.PerformPublicProjectInput{
PerformPublicDomainInput: apis.PerformPublicDomainInput{
Scope: "domain",
SharedDomainIds: []string{provider.DomainId},
},
})
if err != nil {
log.Warningf("failed to set secgroup %s(%s) project sharable", secgroup.Name, secgroup.Id)
}
}
cache, err := manager.NewCache(ctx, userCred, secgroup.Id, vpcId, vpc.CloudregionId, provider.Id, added[i].GetProjectId())
if err != nil {
syncResult.AddError(errors.Wrapf(err, "NewCache for secgroup %s provider %s", secgroup.Name, provider.Name))
continue
}
_, err = db.Update(cache, func() error {
cache.Status = api.SECGROUP_CACHE_STATUS_READY
cache.Name = added[i].GetName()
cache.Description = added[i].GetDescription()
cache.ExternalId = added[i].GetGlobalId()
references, _ := added[i].GetReferences()
cache.ReferenceCount = len(references)
if createdAt := added[i].GetCreatedAt(); !createdAt.IsZero() {
cache.CreatedAt = createdAt
}
return nil
})
if err != nil {
syncResult.AddError(errors.Wrapf(err, "db.Update"))
continue
}
localSecgroups = append(localSecgroups, *secgroup)
remoteSecgroups = append(remoteSecgroups, added[i])
syncResult.Add()
}
return localSecgroups, remoteSecgroups, syncResult
}
// 同步安全组缓存状态
func (self *SSecurityGroupCache) PerformSyncstatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.DiskSyncstatusInput) (jsonutils.JSONObject, error) {
return nil, self.StartSyncstatusTask(ctx, userCred, "")
}
// 获取引用信息
func (self *SSecurityGroupCache) GetDetailsReferences(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) ([]cloudprovider.SecurityGroupReference, error) {
iSecgroup, err := self.GetISecurityGroup(ctx)
if err != nil {
return nil, errors.Wrapf(err, "GetISecurityGroup")
}
return iSecgroup.GetReferences()
}
func (self *SSecurityGroupCache) StartSyncstatusTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
return StartResourceSyncStatusTask(ctx, userCred, self, "SecurityGroupCacheSyncstatusTask", "")
}
func (self *SSecurityGroupCache) ValidateDeleteCondition(ctx context.Context, info jsonutils.JSONObject) error {
if self.ReferenceCount > 0 && self.Status == api.SECGROUP_CACHE_STATUS_READY {
return httperrors.NewNotEmptyError("security group has been reference in %d security group", self.ReferenceCount)
}
return self.SStatusStandaloneResourceBase.ValidateDeleteCondition(ctx, nil)
}
func (self *SSecurityGroupCache) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
log.Infof("do nothing for delete secgroup cache")
return nil
}
func (self *SSecurityGroupCache) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
return self.SStatusStandaloneResourceBase.Delete(ctx, userCred)
}
func (self *SSecurityGroupCache) purge(ctx context.Context, userCred mcclient.TokenCredential) error {
lockman.LockObject(ctx, self)
defer lockman.ReleaseObject(ctx, self)
if secgroup, _ := self.GetSecgroup(); secgroup != nil {
caches, err := secgroup.GetSecurityGroupCaches()
if err != nil {
return errors.Wrapf(err, "secgroup.GetSecurityGroupCaches")
}
if len(caches) == 1 {
err := secgroup.ValidateDeleteCondition(ctx, nil)
if err == nil {
secgroup.RealDelete(ctx, userCred)
}
}
}
return self.RealDelete(ctx, userCred)
}
func (self *SSecurityGroupCache) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
return self.StartSecurityGroupCacheDeleteTask(ctx, userCred, "")
}
func (self *SSecurityGroupCache) StartSecurityGroupCacheDeleteTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
self.SetStatus(userCred, api.SECGROUP_CACHE_STATUS_DELETING, "")
task, err := taskman.TaskManager.NewTask(ctx, "SecurityGroupCacheDeleteTask", self, userCred, nil, parentTaskId, "", nil)
if err != nil {
return err
}
return task.ScheduleRun(nil)
}
func (manager *SSecurityGroupCacheManager) InitializeData() error {
providerIds := CloudproviderManager.Query("id").In("provider", []string{api.CLOUD_PROVIDER_HUAWEI, api.CLOUD_PROVIDER_HCSO, api.CLOUD_PROVIDER_HCS, api.CLOUD_PROVIDER_CTYUN, api.CLOUD_PROVIDER_QCLOUD}).SubQuery()
deprecatedSecgroups := []SSecurityGroupCache{}
q := manager.Query().In("manager_id", providerIds).NotEquals("vpc_id", api.NORMAL_VPC_ID)
err := db.FetchModelObjects(manager, q, &deprecatedSecgroups)
if err != nil && err != sql.ErrNoRows {
return errors.Wrap(err, "SSecurityGroupCacheManager.InitializeData.Query")
}
for i := range deprecatedSecgroups {
cache := &deprecatedSecgroups[i]
_, err := db.Update(cache, func() error {
return cache.MarkDelete()
})
if err != nil {
return errors.Wrap(err, "SSecurityGroupCacheManager.InitializeData.Query")
}
}
log.Debugf("SSecurityGroupCacheManager cleaned %d deprecated security group cache.", len(deprecatedSecgroups))
return nil
}
func (manager *SSecurityGroupCacheManager) ListItemExportKeys(ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
keys stringutils2.SSortedStrings,
) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SStatusStandaloneResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SStatusStandaloneResourceBaseManager.ListItemExportKeys")
}
if keys.ContainsAny(manager.SManagedResourceBaseManager.GetExportKeys()...) {
q, err = manager.SManagedResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SManagedResourceBaseManager.ListItemExportKeys")
}
}
if keys.ContainsAny(manager.SCloudregionResourceBaseManager.GetExportKeys()...) {
q, err = manager.SCloudregionResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.ListItemExportKeys")
}
}
if keys.ContainsAny(manager.SVpcResourceBaseManager.GetExportKeys()...) {
q, err = manager.SVpcResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SVpcResourceBaseManager.ListItemExportKeys")
}
}
if keys.ContainsAny(manager.SSecurityGroupResourceBaseManager.GetExportKeys()...) {
q, err = manager.SSecurityGroupResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SSecurityGroupResourceBaseManager.ListItemExportKey")
}
}
return q, nil
}
func (self *SSecurityGroupCache) GetISecurityGroup(ctx context.Context) (cloudprovider.ICloudSecurityGroup, error) {
if len(self.ExternalId) == 0 {
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "empty external id")
}
manager := self.GetCloudprovider()
if manager == nil {
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "failed to found manager")
}
iRegion, err := self.GetIRegion(ctx)
if err != nil {
return nil, errors.Wrapf(err, "GetIRegion")
}
return iRegion.GetISecurityGroupById(self.ExternalId)
}
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, errors.Wrapf(err, "CreateISecurityGroup")
}
return secgroup, nil
}
return nil, errors.Wrapf(err, "GetIISecurityGroup")
}
return secgroup, nil
}
func (self *SSecurityGroupCache) CreateISecurityGroup(ctx context.Context) (cloudprovider.ICloudSecurityGroup, error) {
iRegion, err := self.GetIRegion(ctx)
if err != nil {
return nil, errors.Wrapf(err, "self.GetIRegion")
}
regionDriver, err := self.GetRegionDriver()
if err != nil {
return nil, errors.Wrapf(err, "GetRegionDriver")
}
self.Name = regionDriver.GenerateSecurityGroupName(self.Name)
// 避免有的云不支持重名安全组
if !regionDriver.IsAllowSecurityGroupNameRepeat() {
randomString := func(prefix string, length int) string {
return fmt.Sprintf("%s-%s", prefix, rand.String(length))
}
opts := &cloudprovider.SecurityGroupFilterOptions{
Name: randomString(self.Name, 1),
VpcId: self.VpcId,
ProjectId: self.ExternalProjectId,
}
for i := 2; i < 30; i++ {
_, err := iRegion.GetISecurityGroupByName(opts)
if err != nil {
if errors.Cause(err) == cloudprovider.ErrNotFound {
break
}
if errors.Cause(err) != cloudprovider.ErrDuplicateId {
return nil, errors.Wrapf(err, "GetISecurityGroupByName")
}
}
opts.Name = randomString(self.Name, i)
}
self.Name = opts.Name
}
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{},
}
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 {
self.ExternalId = iSecgroup.GetGlobalId()
self.Name = iSecgroup.GetName()
self.Status = api.SECGROUP_CACHE_STATUS_READY
return nil
})
return iSecgroup, nil
}
+3 -4
View File
@@ -51,13 +51,12 @@ func ValidateSecurityGroupResourceInput(userCred mcclient.TokenCredential, query
return secgrpObj.(*SSecurityGroup), query, nil
}
func (self *SSecurityGroupResourceBase) GetSecGroup() *SSecurityGroup {
func (self *SSecurityGroupResourceBase) GetSecGroup() (*SSecurityGroup, error) {
secgrp, err := SecurityGroupManager.FetchById(self.SecgroupId)
if err != nil {
log.Errorf("failed to find secgroup %s error: %v", self.SecgroupId, err)
return nil
return nil, errors.Wrapf(err, "FetchById %s", self.SecgroupId)
}
return secgrp.(*SSecurityGroup)
return secgrp.(*SSecurityGroup), nil
}
func (manager *SSecurityGroupResourceBaseManager) FetchCustomizeColumns(
+202 -52
View File
@@ -17,18 +17,24 @@ package models
import (
"context"
"net"
"strings"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/compare"
"yunion.io/x/pkg/util/rbacscope"
"yunion.io/x/pkg/util/regutils"
"yunion.io/x/pkg/util/secrules"
"yunion.io/x/pkg/util/stringutils"
"yunion.io/x/sqlchemy"
"yunion.io/x/onecloud/pkg/apis"
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/db/taskman"
"yunion.io/x/onecloud/pkg/cloudcommon/validators"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
@@ -38,6 +44,8 @@ import (
type SSecurityGroupRuleManager struct {
db.SResourceBaseManager
db.SStatusResourceBaseManager
db.SExternalizedResourceBaseManager
SSecurityGroupResourceBaseManager
}
@@ -57,11 +65,13 @@ func init() {
type SSecurityGroupRule struct {
db.SResourceBase
db.SStatusResourceBase `default:"available"`
db.SExternalizedResourceBase
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"`
Priority int `list:"user" update:"user" list:"user"`
Protocol string `width:"32" 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"`
@@ -123,6 +133,12 @@ func (manager *SSecurityGroupRuleManager) ListItemFilter(
if err != nil {
return nil, errors.Wrap(err, "SResourceBaseManager.ListItemFilter")
}
q, err = manager.SExternalizedResourceBaseManager.ListItemFilter(ctx, q, userCred, query.ExternalizedResourceBaseListInput)
if err != nil {
return nil, errors.Wrap(err, "SExternalizedResourceBaseManager.ListItemFilter")
}
sql, err = manager.SSecurityGroupResourceBaseManager.ListItemFilter(ctx, q, userCred, query.SecgroupFilterListInput)
if err != nil {
return nil, errors.Wrap(err, "SSecurityGroupResourceBaseManager.ListItemFilter")
@@ -236,6 +252,10 @@ func (manager *SSecurityGroupRuleManager) QueryDistinctExtraField(q *sqlchemy.SQ
}
func (self *SSecurityGroupRule) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
return nil
}
func (self *SSecurityGroupRule) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
return db.DeleteModel(ctx, userCred, self)
}
@@ -245,30 +265,32 @@ func (self *SSecurityGroupRule) BeforeInsert() {
}
}
func (manager *SSecurityGroupRuleManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, input api.SSecgroupRuleCreateInput) (api.SSecgroupRuleCreateInput, error) {
if input.Priority == nil {
return input, httperrors.NewMissingParameterError("priority")
}
if *input.Priority < 1 || *input.Priority > 100 {
return input, httperrors.NewOutOfRangeError("Invalid priority %d, must be in range or 1 ~ 100", input.Priority)
}
func (manager *SSecurityGroupRuleManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, input *api.SSecgroupRuleCreateInput) (*api.SSecgroupRuleCreateInput, error) {
_secgroup, err := validators.ValidateModel(userCred, SecurityGroupManager, &input.SecgroupId)
if err != nil {
return input, err
}
input.Status = apis.STATUS_CREATING
secgroup := _secgroup.(*SSecurityGroup)
driver, err := secgroup.GetRegionDriver()
if err != nil {
return nil, err
}
opts := &api.SSecgroupCreateInput{}
opts.Rules = []api.SSecgroupRuleCreateInput{*input}
_, err = driver.ValidateCreateSecurityGroupInput(ctx, userCred, opts)
if err != nil {
return nil, err
}
if !secgroup.IsOwner(userCred) && !userCred.HasSystemAdminPrivilege() {
return input, httperrors.NewForbiddenError("not enough privilege")
}
err = input.Check()
if err != nil {
return input, err
}
input.ResourceBaseCreateInput, err = manager.SResourceBaseManager.ValidateCreateData(ctx, userCred, ownerId, query, input.ResourceBaseCreateInput)
if err != nil {
return input, err
@@ -276,35 +298,24 @@ func (manager *SSecurityGroupRuleManager) ValidateCreateData(ctx context.Context
return input, nil
}
func (self *SSecurityGroupRule) ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.SSecgroupRuleUpdateInput) (api.SSecgroupRuleUpdateInput, error) {
priority := int(self.Priority)
if input.Priority == nil {
input.Priority = &priority
}
if len(input.Direction) == 0 {
input.Direction = self.Direction
}
if len(input.Action) == 0 {
input.Action = self.Action
}
if len(input.Protocol) == 0 {
input.Protocol = self.Protocol
}
if len(input.Ports) == 0 && input.Protocol != string(secrules.PROTO_ANY) && input.Protocol != string(secrules.PROTO_ICMP) {
input.Ports = self.Ports
}
if *input.Priority < 1 || *input.Priority > 100 {
return input, httperrors.NewOutOfRangeError("Invalid priority %d, must be in range or 1 ~ 100", input.Priority)
}
if len(input.CIDR) == 0 {
input.CIDR = self.CIDR
}
err := input.Check()
func (self *SSecurityGroupRule) ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input *api.SSecgroupRuleUpdateInput) (*api.SSecgroupRuleUpdateInput, error) {
secgrp, err := self.GetSecGroup()
if err != nil {
return input, err
return nil, err
}
if input.CIDR == nil {
input.CIDR = &self.CIDR
}
driver, err := secgrp.GetRegionDriver()
if err != nil {
return nil, err
}
input, err = driver.ValidateUpdateSecurityGroupRuleInput(ctx, userCred, input)
if err != nil {
return nil, err
}
input.ResourceBaseUpdateInput, err = self.SResourceBase.ValidateUpdateData(ctx, userCred, query, input.ResourceBaseUpdateInput)
@@ -357,29 +368,61 @@ func (self *SSecurityGroupRule) PostCreate(ctx context.Context, userCred mcclien
self.SResourceBase.PostCreate(ctx, userCred, ownerId, query, data)
log.Debugf("POST Create %s", data)
if secgroup := self.GetSecGroup(); secgroup != nil {
if secgroup, _ := self.GetSecGroup(); secgroup != nil {
logclient.AddSimpleActionLog(secgroup, logclient.ACT_ALLOCATE, data, userCred, true)
secgroup.DoSync(ctx, userCred)
if len(secgroup.ManagerId) == 0 {
secgroup.DoSync(ctx, userCred)
return
}
secgroup.StartSecurityGroupRuleCreateTask(ctx, userCred, self.Id, "")
}
}
func (self *SSecurityGroupRule) PreDelete(ctx context.Context, userCred mcclient.TokenCredential) {
self.SResourceBase.PreDelete(ctx, userCred)
if secgroup := self.GetSecGroup(); secgroup != nil {
if secgroup, _ := self.GetSecGroup(); secgroup != nil {
logclient.AddSimpleActionLog(secgroup, logclient.ACT_DELETE, jsonutils.Marshal(self), userCred, true)
secgroup.DoSync(ctx, userCred)
if len(secgroup.ManagerId) == 0 {
self.RealDelete(ctx, userCred)
secgroup.DoSync(ctx, userCred)
return
}
self.SetStatus(userCred, apis.STATUS_DELETING, "")
secgroup.StartSecurityGroupRuleDeleteTask(ctx, userCred, self.Id, "")
}
}
func (self *SSecurityGroupRule) PostUpdate(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) {
self.SResourceBase.PostUpdate(ctx, userCred, query, data)
log.Debugf("POST Update %s", data)
if secgroup := self.GetSecGroup(); secgroup != nil {
logclient.AddSimpleActionLog(secgroup, logclient.ACT_UPDATE, data, userCred, true)
secgroup.DoSync(ctx, userCred)
if self.Protocol == secrules.PROTO_ICMP || self.Protocol == secrules.PROTO_ANY {
db.Update(self, func() error {
self.Ports = ""
return nil
})
}
log.Debugf("POST Update %s", data)
if secgroup, _ := self.GetSecGroup(); secgroup != nil {
logclient.AddSimpleActionLog(secgroup, logclient.ACT_UPDATE, data, userCred, true)
if len(secgroup.ManagerId) == 0 {
secgroup.DoSync(ctx, userCred)
return
}
self.SetStatus(userCred, apis.STATUS_SYNC_STATUS, "")
secgroup.StartSecurityGroupRuleUpdateTask(ctx, userCred, self.Id, "")
}
}
func (self *SSecurityGroup) StartSecurityGroupRuleUpdateTask(ctx context.Context, userCred mcclient.TokenCredential, ruleId, parentTaskId string) error {
params := jsonutils.NewDict()
params.Set("rule_id", jsonutils.NewString(ruleId))
task, err := taskman.TaskManager.NewTask(ctx, "SecurityGroupRuleUpdateTask", self, userCred, params, parentTaskId, "", nil)
if err != nil {
return errors.Wrapf(err, "NewTask")
}
return task.ScheduleRun(nil)
}
func (manager *SSecurityGroupRuleManager) getRulesBySecurityGroup(secgroup *SSecurityGroup) ([]SSecurityGroupRule, error) {
@@ -392,7 +435,7 @@ func (manager *SSecurityGroupRuleManager) getRulesBySecurityGroup(secgroup *SSec
}
func (self *SSecurityGroupRule) GetOwnerId() mcclient.IIdentityProvider {
secgrp := self.GetSecGroup()
secgrp, _ := self.GetSecGroup()
if secgrp != nil {
return secgrp.GetOwnerId()
}
@@ -419,3 +462,110 @@ func (manager *SSecurityGroupRuleManager) ListItemExportKeys(ctx context.Context
}
return q, nil
}
func (self *SSecurityGroup) SyncRules(
ctx context.Context,
userCred mcclient.TokenCredential,
exts []cloudprovider.ISecurityGroupRule,
) compare.SyncResult {
lockman.LockRawObject(ctx, SecurityGroupManager.Keyword(), self.Id)
defer lockman.ReleaseRawObject(ctx, SecurityGroupManager.Keyword(), self.Id)
result := compare.SyncResult{}
dbRules, err := self.GetSecurityRules()
if err != nil {
result.Error(err)
return result
}
removed := make([]SSecurityGroupRule, 0)
commondb := make([]SSecurityGroupRule, 0)
commonext := make([]cloudprovider.ISecurityGroupRule, 0)
added := make([]cloudprovider.ISecurityGroupRule, 0)
err = compare.CompareSets(dbRules, exts, &removed, &commondb, &commonext, &added)
if err != nil {
result.Error(err)
return result
}
for i := 0; i < len(removed); i += 1 {
err = removed[i].RealDelete(ctx, userCred)
if err != nil {
result.DeleteError(err)
continue
}
result.Delete()
}
for i := 0; i < len(commondb); i += 1 {
err = commondb[i].syncWithCloudRule(ctx, userCred, commonext[i])
if err != nil {
result.UpdateError(err)
continue
}
result.Update()
}
for i := 0; i < len(added); i += 1 {
err := self.newFromCloudRule(ctx, userCred, added[i])
if err != nil {
result.AddError(err)
continue
}
result.Add()
}
return result
}
func (rule *SSecurityGroupRule) syncWithCloudRule(ctx context.Context, userCred mcclient.TokenCredential, ext cloudprovider.ISecurityGroupRule) error {
_, err := db.Update(rule, func() error {
rule.Action = string(ext.GetAction())
rule.Direction = string(ext.GetDirection())
rule.Protocol = string(ext.GetProtocol())
rule.Description = string(ext.GetDescription())
rule.CIDR = strings.Join(ext.GetCIDRs(), ",")
rule.Priority = ext.GetPriority()
rule.Ports = ext.GetPorts()
rule.Status = apis.STATUS_AVAILABLE
return nil
})
return err
}
func (self *SSecurityGroup) newFromCloudRule(ctx context.Context, userCred mcclient.TokenCredential, ext cloudprovider.ISecurityGroupRule) error {
rule := &SSecurityGroupRule{}
rule.SetModelManager(SecurityGroupRuleManager, rule)
rule.SecgroupId = self.Id
rule.Action = string(ext.GetAction())
rule.Direction = string(ext.GetDirection())
rule.Protocol = string(ext.GetProtocol())
rule.Description = string(ext.GetDescription())
rule.CIDR = strings.Join(ext.GetCIDRs(), ",")
rule.Priority = ext.GetPriority()
rule.Ports = ext.GetPorts()
rule.ExternalId = ext.GetGlobalId()
rule.Status = apis.STATUS_AVAILABLE
return SecurityGroupRuleManager.TableSpec().Insert(ctx, rule)
}
func (self *SSecurityGroupRule) SetStatus(userCred mcclient.TokenCredential, status, reason string) error {
if self.Status == status {
return nil
}
_, err := db.Update(self, func() error {
self.Status = status
return nil
})
return err
}
func (manager *SSecurityGroupRuleManager) FetchRuleById(id string) (*SSecurityGroupRule, error) {
rule, err := db.FetchById(manager, id)
if err != nil {
return nil, errors.Wrapf(err, "FetchById(%s)", id)
}
return rule.(*SSecurityGroupRule), nil
}
File diff suppressed because it is too large Load Diff
+49
View File
@@ -1905,6 +1905,55 @@ func (svpc *SVpc) GetDetailsTopology(ctx context.Context, userCred mcclient.Toke
return ret, nil
}
func (self *SVpc) CheckSecurityGroupConsistent(secgroup *SSecurityGroup) error {
if secgroup.Status != api.SECGROUP_STATUS_READY {
return httperrors.NewInvalidStatusError("security group %s status is not ready", secgroup.Name)
}
if len(secgroup.ExternalId) == 0 {
return httperrors.NewInvalidStatusError("The security group %s does not have an external id", secgroup.Name)
}
if len(secgroup.VpcId) > 0 {
if secgroup.VpcId != self.Id {
return httperrors.NewInvalidStatusError("The security group does not belong to the vpc")
}
} else if len(secgroup.CloudregionId) > 0 {
if secgroup.CloudregionId != self.CloudregionId {
return httperrors.NewInvalidStatusError("The security group and vpc are in different areas")
}
} else if len(secgroup.GlobalvpcId) > 0 {
if secgroup.GlobalvpcId != self.GlobalvpcId {
return httperrors.NewInvalidStatusError("The security group and vpc are in different global vpc")
}
}
return nil
}
func (self *SVpc) GetDefaultSecurityGroup(ownerId mcclient.IIdentityProvider, filter func(q *sqlchemy.SQuery) *sqlchemy.SQuery) (*SSecurityGroup, error) {
q := SecurityGroupManager.Query().Equals("status", api.SECGROUP_STATUS_READY).Like("name", "default%")
q = filter(q)
q = q.Filter(
sqlchemy.OR(
sqlchemy.AND(
sqlchemy.Equals(q.Field("public_scope"), "system"),
sqlchemy.Equals(q.Field("is_public"), true),
),
sqlchemy.AND(
sqlchemy.Equals(q.Field("tenant_id"), ownerId.GetProjectId()),
sqlchemy.Equals(q.Field("domain_id"), ownerId.GetProjectDomainId()),
),
),
)
ret := &SSecurityGroup{}
ret.SetModelManager(SecurityGroupManager, ret)
err := q.First(ret)
if err != nil {
return nil, err
}
return ret, nil
}
func (manager *SVpcManager) FetchVpcById(id string) *SVpc {
obj, err := manager.FetchById(id)
if err != nil {
+3 -4
View File
@@ -33,8 +33,9 @@ type ComputeOptions struct {
DefaultMemoryOvercommitBound float32 `default:"1.0" help:"Default memory overcommit bound for host, default to 1"`
DefaultStorageOvercommitBound float32 `default:"1.0" help:"Default storage overcommit bound for storage, default to 1"`
DefaultSecurityGroupId string `help:"Default security rules" default:"default"`
DefaultAdminSecurityGroupId string `help:"Default admin security rules" default:""`
DefaultSecurityGroupId string `help:"Default security rules" default:"default"`
DefaultAdminSecurityGroupId string `help:"Default admin security rules" default:""`
CleanUselessKvmSecurityGroup bool `help:"Clean useless kvm security groups when service start"`
DefaultDiskSizeMB int `default:"10240" help:"Default disk size in MB if not specified, default to 10GiB" json:"default_disk_size"`
@@ -171,8 +172,6 @@ type ComputeOptions struct {
common_options.CommonOptions
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"`
+30 -8
View File
@@ -49,14 +49,6 @@ func init() {
models.RegisterRegionDriver(&driver)
}
func (self *SAliyunRegionDriver) IsAllowSecurityGroupNameRepeat() bool {
return true
}
func (self *SAliyunRegionDriver) GenerateSecurityGroupName(name string) string {
return name
}
func (self *SAliyunRegionDriver) GetProvider() string {
return api.CLOUD_PROVIDER_ALIYUN
}
@@ -752,3 +744,33 @@ func (self *SAliyunRegionDriver) ValidateCreateWafInstanceData(ctx context.Conte
func (self *SAliyunRegionDriver) ValidateCreateWafRuleData(ctx context.Context, userCred mcclient.TokenCredential, waf *models.SWafInstance, input api.WafRuleCreateInput) (api.WafRuleCreateInput, error) {
return input, httperrors.NewUnsupportOperationError("not supported create rule")
}
func (self *SAliyunRegionDriver) ValidateCreateSecurityGroupInput(ctx context.Context, userCred mcclient.TokenCredential, input *api.SSecgroupCreateInput) (*api.SSecgroupCreateInput, error) {
for i := range input.Rules {
rule := input.Rules[i]
if rule.Priority == nil {
return nil, httperrors.NewMissingParameterError("priority")
}
if *rule.Priority < 1 || *rule.Priority > 100 {
return nil, httperrors.NewInputParameterError("invalid priority %d, range 1-100", *rule.Priority)
}
if len(rule.Ports) > 0 && strings.Contains(input.Rules[i].Ports, ",") {
return nil, httperrors.NewInputParameterError("invalid ports %s", input.Rules[i].Ports)
}
}
return self.SManagedVirtualizationRegionDriver.ValidateCreateSecurityGroupInput(ctx, userCred, input)
}
func (self *SAliyunRegionDriver) ValidateUpdateSecurityGroupRuleInput(ctx context.Context, userCred mcclient.TokenCredential, input *api.SSecgroupRuleUpdateInput) (*api.SSecgroupRuleUpdateInput, error) {
if input.Priority != nil && *input.Priority < 1 || *input.Priority > 100 {
return nil, httperrors.NewInputParameterError("invalid priority %d, range 1-100", *input.Priority)
}
if input.Ports != nil && strings.Contains(*input.Ports, ",") {
return nil, httperrors.NewInputParameterError("invalid ports %s", *input.Ports)
}
return self.SManagedVirtualizationRegionDriver.ValidateUpdateSecurityGroupRuleInput(ctx, userCred, input)
}
+30 -51
View File
@@ -23,9 +23,8 @@ import (
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/jsonutils"
"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"
@@ -47,14 +46,6 @@ func init() {
models.RegisterRegionDriver(&driver)
}
func (self *SAwsRegionDriver) IsAllowSecurityGroupNameRepeat() bool {
return false
}
func (self *SAwsRegionDriver) GenerateSecurityGroupName(name string) string {
return pinyinutils.Text2Pinyin(name)
}
func (self *SAwsRegionDriver) GetProvider() string {
return api.CLOUD_PROVIDER_AWS
}
@@ -310,10 +301,6 @@ func (self *SAwsRegionDriver) RequestCreateLoadbalancerBackendGroup(ctx context.
return task.ScheduleRun(nil)
}
func (self *SAwsRegionDriver) IsSecurityGroupBelongVpc() bool {
return true
}
func (self *SAwsRegionDriver) IsCertificateBelongToRegion() bool {
return false
}
@@ -331,57 +318,23 @@ func (self *SAwsRegionDriver) ValidateCreateVpcData(ctx context.Context, userCre
func (self *SAwsRegionDriver) RequestDeleteVpc(ctx context.Context, userCred mcclient.TokenCredential, region *models.SCloudregion, vpc *models.SVpc, task taskman.ITask) error {
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
provider := vpc.GetCloudprovider()
if provider == nil {
return nil, fmt.Errorf("vpc %s(%s) related provider not found", vpc.GetName(), vpc.GetName())
}
region, err := vpc.GetIRegion(ctx)
if err != nil {
return nil, errors.Wrap(err, "vpc.GetIRegion")
}
ivpc, err := region.GetIVpcById(vpc.GetExternalId())
ivpc, err := vpc.GetIVpc(ctx)
if err != nil {
if errors.Cause(err) == cloudprovider.ErrNotFound {
// already deleted, do nothing
return nil, nil
}
return nil, errors.Wrap(err, "region.GetIVpcById")
}
// remove related secgroups
segs, err := ivpc.GetISecurityGroups()
if err != nil {
return nil, errors.Wrap(err, "GetISecurityGroups")
}
for i := range segs {
// 默认安全组不需要删除
if segs[i].GetName() == "default" {
log.Debugf("RequestDeleteVpc delete secgroup skipped default secgroups %s(%s)", segs[i].GetName(), segs[i].GetId())
continue
}
err = segs[i].Delete()
if err != nil {
return nil, errors.Wrap(err, "DeleteSecurityGroup")
}
}
_, _, result := models.SecurityGroupCacheManager.SyncSecurityGroupCaches(ctx, userCred, provider, []cloudprovider.ICloudSecurityGroup{}, vpc, true)
if result.IsError() {
return nil, fmt.Errorf("SyncSecurityGroupCaches %s", result.Result())
return nil, errors.Wrap(err, "GetIVpc")
}
err = ivpc.Delete()
if err != nil {
return nil, errors.Wrap(err, "ivpc.Delete")
return nil, errors.Wrap(err, "Delete")
}
err = cloudprovider.WaitDeleted(ivpc, 10*time.Second, 300*time.Second)
if err != nil {
return nil, errors.Wrap(err, "cloudprovider.WaitDeleted")
}
return nil, nil
})
return nil
@@ -472,3 +425,29 @@ func (self *SAwsRegionDriver) ValidateCreateWafInstanceData(ctx context.Context,
func (self *SAwsRegionDriver) ValidateCreateWafRuleData(ctx context.Context, userCred mcclient.TokenCredential, waf *models.SWafInstance, input api.WafRuleCreateInput) (api.WafRuleCreateInput, error) {
return input, nil
}
func (self *SAwsRegionDriver) ValidateCreateSecurityGroupInput(ctx context.Context, userCred mcclient.TokenCredential, input *api.SSecgroupCreateInput) (*api.SSecgroupCreateInput, error) {
for i := range input.Rules {
if input.Rules[i].Action != string(secrules.SecurityRuleAllow) {
return nil, httperrors.NewInputParameterError("invalid action %s, only support allow", input.Rules[i].Action)
}
if len(input.Rules[i].Ports) > 0 && strings.Contains(input.Rules[i].Ports, ",") {
return nil, httperrors.NewInputParameterError("invalid ports %s", input.Rules[i].Ports)
}
}
return self.SManagedVirtualizationRegionDriver.ValidateCreateSecurityGroupInput(ctx, userCred, input)
}
func (self *SAwsRegionDriver) ValidateUpdateSecurityGroupRuleInput(ctx context.Context, userCred mcclient.TokenCredential, input *api.SSecgroupRuleUpdateInput) (*api.SSecgroupRuleUpdateInput, error) {
if input.Action != nil && *input.Action != string(secrules.SecurityRuleAllow) {
return nil, httperrors.NewInputParameterError("invalid action %s", *input.Action)
}
if input.Ports != nil && strings.Contains(*input.Ports, ",") {
return nil, httperrors.NewInputParameterError("invalid ports %s", *input.Ports)
}
return self.SManagedVirtualizationRegionDriver.ValidateUpdateSecurityGroupRuleInput(ctx, userCred, input)
}
+63 -9
View File
@@ -16,10 +16,13 @@ package regiondrivers
import (
"context"
"fmt"
"time"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/util/pinyinutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/sqlchemy"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/validators"
@@ -41,14 +44,6 @@ func (self *SAzureRegionDriver) GetProvider() string {
return api.CLOUD_PROVIDER_AZURE
}
func (self *SAzureRegionDriver) IsAllowSecurityGroupNameRepeat() bool {
return false
}
func (self *SAzureRegionDriver) GenerateSecurityGroupName(name string) string {
return pinyinutils.Text2Pinyin(name)
}
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 {
@@ -87,3 +82,62 @@ func (self *SAzureRegionDriver) ValidateCreateWafInstanceData(ctx context.Contex
func (self *SAzureRegionDriver) ValidateCreateWafRuleData(ctx context.Context, userCred mcclient.TokenCredential, waf *models.SWafInstance, input api.WafRuleCreateInput) (api.WafRuleCreateInput, error) {
return input, nil
}
func (self *SAzureRegionDriver) ValidateCreateSecurityGroupInput(ctx context.Context, userCred mcclient.TokenCredential, input *api.SSecgroupCreateInput) (*api.SSecgroupCreateInput, error) {
for i := range input.Rules {
rule := input.Rules[i]
if rule.Priority == nil {
return nil, httperrors.NewMissingParameterError("priority")
}
if *rule.Priority < 100 || *rule.Priority > 4096 {
return nil, httperrors.NewInputParameterError("invalid priority %d, range 100-4096", *rule.Priority)
}
}
return self.SManagedVirtualizationRegionDriver.ValidateCreateSecurityGroupInput(ctx, userCred, input)
}
func (self *SAzureRegionDriver) ValidateUpdateSecurityGroupRuleInput(ctx context.Context, userCred mcclient.TokenCredential, input *api.SSecgroupRuleUpdateInput) (*api.SSecgroupRuleUpdateInput, error) {
if input.Priority != nil && *input.Priority < 100 || *input.Priority > 4096 {
return nil, httperrors.NewInputParameterError("invalid priority %d, range 100-4096", *input.Priority)
}
return self.SManagedVirtualizationRegionDriver.ValidateUpdateSecurityGroupRuleInput(ctx, userCred, input)
}
func (self *SAzureRegionDriver) GetSecurityGroupFilter(vpc *models.SVpc) (func(q *sqlchemy.SQuery) *sqlchemy.SQuery, error) {
return func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
return q.Equals("cloudregion_id", vpc.CloudregionId)
}, nil
}
func (self *SAzureRegionDriver) CreateDefaultSecurityGroup(
ctx context.Context,
userCred mcclient.TokenCredential,
ownerId mcclient.IIdentityProvider,
vpc *models.SVpc,
) (*models.SSecurityGroup, error) {
newGroup := &models.SSecurityGroup{}
newGroup.SetModelManager(models.SecurityGroupManager, newGroup)
newGroup.Name = fmt.Sprintf("default-auto-%d", time.Now().Unix())
newGroup.Description = "auto generage"
newGroup.ManagerId = vpc.ManagerId
newGroup.CloudregionId = vpc.CloudregionId
newGroup.DomainId = ownerId.GetDomainId()
newGroup.ProjectId = ownerId.GetProjectId()
err := models.SecurityGroupManager.TableSpec().Insert(ctx, newGroup)
if err != nil {
return nil, errors.Wrapf(err, "insert")
}
region, err := vpc.GetRegion()
if err != nil {
return nil, errors.Wrapf(err, "GetRegion")
}
driver := region.GetDriver()
err = driver.RequestCreateSecurityGroup(ctx, userCred, newGroup, api.SSecgroupRuleResourceSet{})
if err != nil {
return nil, errors.Wrapf(err, "RequestCreateSecurityGroup")
}
return newGroup, nil
}
-12
View File
@@ -35,18 +35,6 @@ func (self *SBaiduRegionDriver) GetProvider() string {
return api.CLOUD_PROVIDER_BAIDU
}
func (self *SBaiduRegionDriver) IsAllowSecurityGroupNameRepeat() bool {
return true
}
func (self *SBaiduRegionDriver) GenerateSecurityGroupName(name string) string {
return name
}
func (self *SBaiduRegionDriver) IsSecurityGroupBelongVpc() bool {
return true
}
func (self *SBaiduRegionDriver) ValidateCreateSnapshotData(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, storage *models.SStorage, input *api.SnapshotCreateInput) error {
return nil
}
+36 -36
View File
@@ -23,8 +23,7 @@ import (
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/billing"
"yunion.io/x/pkg/util/pinyinutils"
"yunion.io/x/pkg/util/rbacscope"
"yunion.io/x/sqlchemy"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
@@ -228,44 +227,21 @@ func (self *SBaseRegionDriver) RequestDeleteVpc(ctx context.Context, userCred mc
return fmt.Errorf("Not implement RequestDeleteVpc")
}
func (self *SBaseRegionDriver) IsAllowSecurityGroupNameRepeat() bool {
return false
func (self *SBaseRegionDriver) ValidateCreateSecurityGroupInput(ctx context.Context, userCred mcclient.TokenCredential, input *api.SSecgroupCreateInput) (*api.SSecgroupCreateInput, error) {
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "ValidateCreateSecurityGroupInput")
}
func (self *SBaseRegionDriver) GenerateSecurityGroupName(name string) string {
return pinyinutils.Text2Pinyin(name)
func (self *SBaseRegionDriver) RequestCreateSecurityGroup(
ctx context.Context,
userCred mcclient.TokenCredential,
secgroup *models.SSecurityGroup,
rules api.SSecgroupRuleResourceSet,
) error {
return errors.Wrapf(cloudprovider.ErrNotImplemented, "RequestCreateSecurityGroup")
}
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 {
return false
}
func (self *SBaseRegionDriver) IsVpcBelongGlobalVpc() bool {
return false
}
func (self *SBaseRegionDriver) IsSecurityGroupBelongGlobalVpc() bool {
return false
}
func (self *SBaseRegionDriver) GetDefaultSecurityGroupVpcId() string {
return api.NORMAL_VPC_ID
}
func (self *SBaseRegionDriver) GetSecurityGroupPublicScope(service string) rbacscope.TRbacScope {
return rbacscope.ScopeSystem
}
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) (string, error) {
return "", errors.Wrapf(cloudprovider.ErrNotImplemented, "RequestSyncSecurityGroup")
func (self *SBaseRegionDriver) RequestDeleteSecurityGroup(ctx context.Context, userCred mcclient.TokenCredential, secgroup *models.SSecurityGroup, task taskman.ITask) error {
return errors.Wrapf(cloudprovider.ErrNotImplemented, "RequestDeleteSecurityGroup")
}
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) {
@@ -509,3 +485,27 @@ func (self *SBaseRegionDriver) RequestCreateKubeCluster(ctx context.Context, use
func (self *SBaseRegionDriver) RequestCreateKubeNodePool(ctx context.Context, userCred mcclient.TokenCredential, pool *models.SKubeNodePool, task taskman.ITask) error {
return errors.Wrapf(cloudprovider.ErrNotImplemented, "RequestCreateKubeNodePool")
}
func (drv *SBaseRegionDriver) RequestPrepareSecurityGroups(
ctx context.Context,
userCred mcclient.TokenCredential,
ownerId mcclient.IIdentityProvider,
secgroups []models.SSecurityGroup,
vpc *models.SVpc,
callback func(ids []string) error,
task taskman.ITask,
) error {
return errors.Wrapf(cloudprovider.ErrNotImplemented, "RequestPrepareSecurityGroups")
}
func (drv *SBaseRegionDriver) CreateDefaultSecurityGroup(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, vpc *models.SVpc) (*models.SSecurityGroup, error) {
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "CreateDefaultSecurityGroup")
}
func (drv *SBaseRegionDriver) GetSecurityGroupFilter(vpc *models.SVpc) (func(q *sqlchemy.SQuery) *sqlchemy.SQuery, error) {
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetSecurityGroupFilter")
}
func (self *SBaseRegionDriver) ValidateUpdateSecurityGroupRuleInput(ctx context.Context, userCred mcclient.TokenCredential, input *api.SSecgroupRuleUpdateInput) (*api.SSecgroupRuleUpdateInput, error) {
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "ValidateUpdateSecurityGroupInput")
}
+61 -15
View File
@@ -16,10 +16,16 @@ package regiondrivers
import (
"context"
"fmt"
"strings"
"time"
"yunion.io/x/pkg/errors"
"yunion.io/x/sqlchemy"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
)
@@ -36,21 +42,61 @@ func (self *SBingoCloudRegionDriver) GetProvider() string {
return api.CLOUD_PROVIDER_BINGO_CLOUD
}
func (self *SBingoCloudRegionDriver) IsAllowSecurityGroupNameRepeat() bool {
return false
}
func (self *SBingoCloudRegionDriver) GenerateSecurityGroupName(name string) string {
if strings.ToLower(name) == "default" {
return "default"
}
return name
}
func (self *SBingoCloudRegionDriver) IsSecurityGroupBelongVpc() bool {
return false
}
func (self *SBingoCloudRegionDriver) ValidateCreateSnapshotData(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, storage *models.SStorage, input *api.SnapshotCreateInput) error {
return nil
}
func (self *SBingoCloudRegionDriver) ValidateCreateSecurityGroupInput(ctx context.Context, userCred mcclient.TokenCredential, input *api.SSecgroupCreateInput) (*api.SSecgroupCreateInput, error) {
for i := range input.Rules {
rule := input.Rules[i]
if len(rule.Ports) > 0 && strings.Contains(rule.Ports, ",") {
return nil, httperrors.NewInputParameterError("invalid ports %s", rule.Ports)
}
}
return self.SManagedVirtualizationRegionDriver.ValidateCreateSecurityGroupInput(ctx, userCred, input)
}
func (self *SBingoCloudRegionDriver) ValidateUpdateSecurityGroupRuleInput(ctx context.Context, userCred mcclient.TokenCredential, input *api.SSecgroupRuleUpdateInput) (*api.SSecgroupRuleUpdateInput, error) {
if input.Ports != nil && strings.Contains(*input.Ports, ",") {
return nil, httperrors.NewInputParameterError("invalid ports %s", *input.Ports)
}
return self.SManagedVirtualizationRegionDriver.ValidateUpdateSecurityGroupRuleInput(ctx, userCred, input)
}
func (self *SBingoCloudRegionDriver) GetSecurityGroupFilter(vpc *models.SVpc) (func(q *sqlchemy.SQuery) *sqlchemy.SQuery, error) {
return func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
return q.Equals("cloudregion_id", vpc.CloudregionId)
}, nil
}
func (self *SBingoCloudRegionDriver) CreateDefaultSecurityGroup(
ctx context.Context,
userCred mcclient.TokenCredential,
ownerId mcclient.IIdentityProvider,
vpc *models.SVpc,
) (*models.SSecurityGroup, error) {
newGroup := &models.SSecurityGroup{}
newGroup.SetModelManager(models.SecurityGroupManager, newGroup)
newGroup.Name = fmt.Sprintf("default-auto-%d", time.Now().Unix())
newGroup.Description = "auto generage"
newGroup.ManagerId = vpc.ManagerId
newGroup.CloudregionId = vpc.CloudregionId
newGroup.DomainId = ownerId.GetDomainId()
newGroup.ProjectId = ownerId.GetProjectId()
err := models.SecurityGroupManager.TableSpec().Insert(ctx, newGroup)
if err != nil {
return nil, errors.Wrapf(err, "insert")
}
region, err := vpc.GetRegion()
if err != nil {
return nil, errors.Wrapf(err, "GetRegion")
}
driver := region.GetDriver()
err = driver.RequestCreateSecurityGroup(ctx, userCred, newGroup, api.SSecgroupRuleResourceSet{})
if err != nil {
return nil, errors.Wrapf(err, "RequestCreateSecurityGroup")
}
return newGroup, nil
}
+64 -8
View File
@@ -16,8 +16,12 @@ package regiondrivers
import (
"context"
"fmt"
"time"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/utils"
"yunion.io/x/sqlchemy"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/compute/models"
@@ -38,17 +42,69 @@ func (self *SCloudpodsRegionDriver) GetProvider() string {
return api.CLOUD_PROVIDER_CLOUDPODS
}
func (self *SCloudpodsRegionDriver) IsAllowSecurityGroupNameRepeat() bool {
return false
}
func (self *SCloudpodsRegionDriver) GenerateSecurityGroupName(name string) string {
return name
}
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)
}
return input, nil
}
func (self *SCloudpodsRegionDriver) ValidateCreateSecurityGroupInput(ctx context.Context, userCred mcclient.TokenCredential, input *api.SSecgroupCreateInput) (*api.SSecgroupCreateInput, error) {
for i := range input.Rules {
rule := input.Rules[i]
if rule.Priority == nil {
return nil, httperrors.NewMissingParameterError("priority")
}
if *rule.Priority < 1 || *rule.Priority > 100 {
return nil, httperrors.NewInputParameterError("invalid priority %d, range 1-100", *rule.Priority)
}
}
return self.SManagedVirtualizationRegionDriver.ValidateCreateSecurityGroupInput(ctx, userCred, input)
}
func (self *SCloudpodsRegionDriver) ValidateUpdateSecurityGroupRuleInput(ctx context.Context, userCred mcclient.TokenCredential, input *api.SSecgroupRuleUpdateInput) (*api.SSecgroupRuleUpdateInput, error) {
if input.Priority != nil && *input.Priority < 1 || *input.Priority > 100 {
return nil, httperrors.NewInputParameterError("invalid priority %d, range 1-100", *input.Priority)
}
return self.SManagedVirtualizationRegionDriver.ValidateUpdateSecurityGroupRuleInput(ctx, userCred, input)
}
func (self *SCloudpodsRegionDriver) GetSecurityGroupFilter(vpc *models.SVpc) (func(q *sqlchemy.SQuery) *sqlchemy.SQuery, error) {
return func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
return q.Equals("cloudregion_id", vpc.CloudregionId)
}, nil
}
func (self *SCloudpodsRegionDriver) CreateDefaultSecurityGroup(
ctx context.Context,
userCred mcclient.TokenCredential,
ownerId mcclient.IIdentityProvider,
vpc *models.SVpc,
) (*models.SSecurityGroup, error) {
newGroup := &models.SSecurityGroup{}
newGroup.SetModelManager(models.SecurityGroupManager, newGroup)
newGroup.Name = fmt.Sprintf("default-auto-%d", time.Now().Unix())
newGroup.Description = "auto generage"
newGroup.ManagerId = vpc.ManagerId
newGroup.CloudregionId = vpc.CloudregionId
newGroup.DomainId = ownerId.GetDomainId()
newGroup.ProjectId = ownerId.GetProjectId()
err := models.SecurityGroupManager.TableSpec().Insert(ctx, newGroup)
if err != nil {
return nil, errors.Wrapf(err, "insert")
}
region, err := vpc.GetRegion()
if err != nil {
return nil, errors.Wrapf(err, "GetRegion")
}
driver := region.GetDriver()
err = driver.RequestCreateSecurityGroup(ctx, userCred, newGroup, api.SSecgroupRuleResourceSet{})
if err != nil {
return nil, errors.Wrapf(err, "RequestCreateSecurityGroup")
}
return newGroup, nil
}
+65 -15
View File
@@ -16,9 +16,13 @@ package regiondrivers
import (
"context"
"fmt"
"strings"
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/sqlchemy"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/validators"
@@ -36,21 +40,6 @@ func init() {
models.RegisterRegionDriver(&driver)
}
func (self *SCtyunRegionDriver) IsAllowSecurityGroupNameRepeat() bool {
return false
}
func (self *SCtyunRegionDriver) IsSecurityGroupBelongVpc() bool {
return true
}
func (self *SCtyunRegionDriver) GenerateSecurityGroupName(name string) string {
if strings.ToLower(name) == "default" {
return "DefaultGroup"
}
return name
}
func (self *SCtyunRegionDriver) GetProvider() string {
return api.CLOUD_PROVIDER_CTYUN
}
@@ -71,3 +60,64 @@ func (self *SCtyunRegionDriver) ValidateCreateVpcData(ctx context.Context, userC
}
return input, nil
}
func (self *SCtyunRegionDriver) ValidateCreateSecurityGroupInput(ctx context.Context, userCred mcclient.TokenCredential, input *api.SSecgroupCreateInput) (*api.SSecgroupCreateInput, error) {
for i := range input.Rules {
if input.Rules[i].Priority == nil {
return nil, httperrors.NewMissingParameterError("priority")
}
if *input.Rules[i].Priority < 1 || *input.Rules[i].Priority > 100 {
return nil, httperrors.NewInputParameterError("invalid priority %d, range 1-100", *input.Rules[i].Priority)
}
}
return input, nil
}
func (self *SCtyunRegionDriver) ValidateUpdateSecurityGroupRuleInput(ctx context.Context, userCred mcclient.TokenCredential, input *api.SSecgroupRuleUpdateInput) (*api.SSecgroupRuleUpdateInput, error) {
if input.Priority != nil && *input.Priority < 1 || *input.Priority > 100 {
return nil, httperrors.NewInputParameterError("invalid priority %d, range 1-100", *input.Priority)
}
if input.Ports != nil && strings.Contains(*input.Ports, ",") {
return nil, httperrors.NewInputParameterError("invalid ports %s", *input.Ports)
}
return self.SManagedVirtualizationRegionDriver.ValidateUpdateSecurityGroupRuleInput(ctx, userCred, input)
}
func (self *SCtyunRegionDriver) GetSecurityGroupFilter(vpc *models.SVpc) (func(q *sqlchemy.SQuery) *sqlchemy.SQuery, error) {
return func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
return q.Equals("cloudregion_id", vpc.CloudregionId)
}, nil
}
func (self *SCtyunRegionDriver) CreateDefaultSecurityGroup(
ctx context.Context,
userCred mcclient.TokenCredential,
ownerId mcclient.IIdentityProvider,
vpc *models.SVpc,
) (*models.SSecurityGroup, error) {
newGroup := &models.SSecurityGroup{}
newGroup.SetModelManager(models.SecurityGroupManager, newGroup)
newGroup.Name = fmt.Sprintf("default-auto-%d", time.Now().Unix())
newGroup.Description = "auto generage"
newGroup.ManagerId = vpc.ManagerId
newGroup.CloudregionId = vpc.CloudregionId
newGroup.DomainId = ownerId.GetDomainId()
newGroup.ProjectId = ownerId.GetProjectId()
err := models.SecurityGroupManager.TableSpec().Insert(ctx, newGroup)
if err != nil {
return nil, errors.Wrapf(err, "insert")
}
region, err := vpc.GetRegion()
if err != nil {
return nil, errors.Wrapf(err, "GetRegion")
}
driver := region.GetDriver()
err = driver.RequestCreateSecurityGroup(ctx, userCred, newGroup, api.SSecgroupRuleResourceSet{})
if err != nil {
return nil, errors.Wrapf(err, "RequestCreateSecurityGroup")
}
return newGroup, nil
}
-12
View File
@@ -35,18 +35,6 @@ func (self *SCucloudRegionDriver) GetProvider() string {
return api.CLOUD_PROVIDER_CUCLOUD
}
func (self *SCucloudRegionDriver) IsAllowSecurityGroupNameRepeat() bool {
return true
}
func (self *SCucloudRegionDriver) GenerateSecurityGroupName(name string) string {
return name
}
func (self *SCucloudRegionDriver) IsSecurityGroupBelongVpc() bool {
return true
}
func (self *SCucloudRegionDriver) ValidateCreateSnapshotData(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, storage *models.SStorage, input *api.SnapshotCreateInput) error {
return nil
}
-10
View File
@@ -15,8 +15,6 @@
package regiondrivers
import (
"yunion.io/x/pkg/util/pinyinutils"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/compute/models"
)
@@ -33,11 +31,3 @@ func init() {
func (self *SEcloudRegionDriver) GetProvider() string {
return api.CLOUD_PROVIDER_ECLOUD
}
func (self *SEcloudRegionDriver) IsAllowSecurityGroupNameRepeat() bool {
return false
}
func (self *SEcloudRegionDriver) GenerateSecurityGroupName(name string) string {
return pinyinutils.Text2Pinyin(name)
}
+133 -43
View File
@@ -18,13 +18,14 @@ import (
"context"
"fmt"
"strings"
"time"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/pinyinutils"
"yunion.io/x/pkg/util/secrules"
"yunion.io/x/sqlchemy"
billing_api "yunion.io/x/onecloud/pkg/apis/billing"
api "yunion.io/x/onecloud/pkg/apis/compute"
@@ -45,52 +46,10 @@ func init() {
models.RegisterRegionDriver(&driver)
}
func (self *SGoogleRegionDriver) IsAllowSecurityGroupNameRepeat() bool {
return false
}
// 名称必须以小写字母开头,后面最多可跟 62 个小写字母、数字或连字符,但不能以连字符结尾
func (self *SGoogleRegionDriver) GenerateSecurityGroupName(name string) string {
ret := ""
for _, s := range strings.ToLower(pinyinutils.Text2Pinyin(name)) {
if (s >= 'a' && s <= 'z') || (s >= '0' && s <= '9') || (s == '-') {
ret = fmt.Sprintf("%s%s", ret, string(s))
}
}
if len(ret) > 0 && (ret[0] < 'a' || ret[0] > 'z') {
ret = fmt.Sprintf("sg-%s", ret)
}
return ret
}
func (self *SGoogleRegionDriver) GetDefaultSecurityGroupInRule() cloudprovider.SecurityRule {
return cloudprovider.SecurityRule{SecurityRule: *secrules.MustParseSecurityRule("in:deny any")}
}
func (self *SGoogleRegionDriver) GetDefaultSecurityGroupOutRule() cloudprovider.SecurityRule {
return cloudprovider.SecurityRule{SecurityRule: *secrules.MustParseSecurityRule("out:allow any")}
}
func (self *SGoogleRegionDriver) GetSecurityGroupRuleMaxPriority() int {
return 0
}
func (self *SGoogleRegionDriver) GetSecurityGroupRuleMinPriority() int {
return 65534
}
func (self *SGoogleRegionDriver) GetProvider() string {
return api.CLOUD_PROVIDER_GOOGLE
}
func (self *SGoogleRegionDriver) IsSecurityGroupBelongGlobalVpc() bool {
return true
}
func (self *SGoogleRegionDriver) IsVpcBelongGlobalVpc() bool {
return true
}
func (self *SGoogleRegionDriver) RequestCreateVpc(ctx context.Context, userCred mcclient.TokenCredential, region *models.SCloudregion, vpc *models.SVpc, task taskman.ITask) error {
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
provider := vpc.GetCloudprovider()
@@ -268,3 +227,134 @@ func (self *SGoogleRegionDriver) ValidateCreateVpcData(ctx context.Context, user
}
return input, nil
}
func (self *SGoogleRegionDriver) ValidateCreateSecurityGroupInput(ctx context.Context, userCred mcclient.TokenCredential, input *api.SSecgroupCreateInput) (*api.SSecgroupCreateInput, error) {
for i := range input.Rules {
rule := input.Rules[i]
if rule.Priority == nil {
return nil, httperrors.NewMissingParameterError("priority")
}
if *rule.Priority < 0 || *rule.Priority > 65535 {
return nil, httperrors.NewInputParameterError("invalid priority %d, range 0-65535", *rule.Priority)
}
if len(rule.Ports) > 0 && strings.Contains(input.Rules[i].Ports, ",") {
return nil, httperrors.NewInputParameterError("invalid ports %s", input.Rules[i].Ports)
}
}
return input, nil
}
func (self *SGoogleRegionDriver) RequestCreateSecurityGroup(
ctx context.Context,
userCred mcclient.TokenCredential,
secgroup *models.SSecurityGroup,
rules api.SSecgroupRuleResourceSet,
) error {
vpc, err := secgroup.GetGlobalVpc()
if err != nil {
return errors.Wrapf(err, "GetVpc")
}
iVpc, err := vpc.GetICloudGlobalVpc(ctx)
if err != nil {
return errors.Wrapf(err, "GetICloudGlobalVpc")
}
opts := &cloudprovider.SecurityGroupCreateInput{
Name: secgroup.Name,
}
opts.Tags, _ = secgroup.GetAllUserMetadata()
iGroup, err := iVpc.CreateISecurityGroup(opts)
if err != nil {
return errors.Wrapf(err, "CreateISecurityGroup")
}
_, err = db.Update(secgroup, func() error {
secgroup.ExternalId = iGroup.GetGlobalId()
secgroup.VpcId = ""
secgroup.CloudregionId = "-"
return nil
})
if err != nil {
return errors.Wrapf(err, "SetExternalId")
}
for i := range rules {
opts := cloudprovider.SecurityGroupRuleCreateOptions{
Desc: rules[i].Description,
Direction: secrules.TSecurityRuleDirection(rules[i].Direction),
Action: secrules.TSecurityRuleAction(rules[i].Action),
Protocol: rules[i].Protocol,
CIDR: rules[i].CIDR,
Ports: rules[i].Ports,
}
_, err := iGroup.CreateRule(&opts)
if err != nil {
return errors.Wrapf(err, "CreateRule")
}
}
iRules, err := iGroup.GetRules()
if err != nil {
return errors.Wrapf(err, "GetRules")
}
result := secgroup.SyncRules(ctx, userCred, iRules)
if result.IsError() {
return result.AllError()
}
secgroup.SetStatus(userCred, api.SECGROUP_STATUS_READY, "")
return nil
}
func (self *SGoogleRegionDriver) ValidateUpdateSecurityGroupRuleInput(ctx context.Context, userCred mcclient.TokenCredential, input *api.SSecgroupRuleUpdateInput) (*api.SSecgroupRuleUpdateInput, error) {
if input.Priority != nil && *input.Priority < 0 || *input.Priority > 65535 {
return nil, httperrors.NewInputParameterError("invalid priority %d, range 0-65535", *input.Priority)
}
if input.Ports != nil && strings.Contains(*input.Ports, ",") {
return nil, httperrors.NewInputParameterError("invalid ports %s", *input.Ports)
}
return self.SManagedVirtualizationRegionDriver.ValidateUpdateSecurityGroupRuleInput(ctx, userCred, input)
}
func (self *SGoogleRegionDriver) GetSecurityGroupFilter(vpc *models.SVpc) (func(q *sqlchemy.SQuery) *sqlchemy.SQuery, error) {
return func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
return q.Equals("globalvpc_id", vpc.GlobalvpcId)
}, nil
}
func (self *SGoogleRegionDriver) CreateDefaultSecurityGroup(
ctx context.Context,
userCred mcclient.TokenCredential,
ownerId mcclient.IIdentityProvider,
vpc *models.SVpc,
) (*models.SSecurityGroup, error) {
newGroup := &models.SSecurityGroup{}
newGroup.SetModelManager(models.SecurityGroupManager, newGroup)
newGroup.Name = fmt.Sprintf("default-auto-%d", time.Now().Unix())
newGroup.Description = "auto generage"
newGroup.ManagerId = vpc.ManagerId
newGroup.DomainId = ownerId.GetDomainId()
newGroup.GlobalvpcId = vpc.GlobalvpcId
newGroup.ProjectId = ownerId.GetProjectId()
err := models.SecurityGroupManager.TableSpec().Insert(ctx, newGroup)
if err != nil {
return nil, errors.Wrapf(err, "insert")
}
region, err := vpc.GetRegion()
if err != nil {
return nil, errors.Wrapf(err, "GetRegion")
}
driver := region.GetDriver()
err = driver.RequestCreateSecurityGroup(ctx, userCred, newGroup, api.SSecgroupRuleResourceSet{})
if err != nil {
return nil, errors.Wrapf(err, "RequestCreateSecurityGroup")
}
return newGroup, nil
}
-4
View File
@@ -32,10 +32,6 @@ func (self *SH3CRegionDriver) GetProvider() string {
return api.CLOUD_PROVIDER_H3C
}
func (self *SH3CRegionDriver) IsSecurityGroupBelongVpc() bool {
return true
}
func (self *SH3CRegionDriver) IsSupportedElasticcacheSecgroup() bool {
return false
}
+69 -11
View File
@@ -18,12 +18,14 @@ import (
"context"
"fmt"
"strings"
"time"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/billing"
"yunion.io/x/pkg/utils"
"yunion.io/x/sqlchemy"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
@@ -43,17 +45,6 @@ func init() {
models.RegisterRegionDriver(&driver)
}
func (self *SHuaWeiRegionDriver) IsAllowSecurityGroupNameRepeat() bool {
return true
}
func (self *SHuaWeiRegionDriver) GenerateSecurityGroupName(name string) string {
if strings.ToLower(name) == "default" {
return "DefaultGroup"
}
return name
}
func (self *SHuaWeiRegionDriver) GetProvider() string {
return api.CLOUD_PROVIDER_HUAWEI
}
@@ -608,3 +599,70 @@ func (self *SHuaWeiRegionDriver) IsSupportedNatGateway() bool {
func (self *SHuaWeiRegionDriver) IsSupportedNas() bool {
return true
}
func (self *SHuaWeiRegionDriver) ValidateCreateSecurityGroupInput(ctx context.Context, userCred mcclient.TokenCredential, input *api.SSecgroupCreateInput) (*api.SSecgroupCreateInput, error) {
for i := range input.Rules {
rule := input.Rules[i]
if input.Rules[i].Priority == nil {
return nil, httperrors.NewMissingParameterError("priority")
}
if *input.Rules[i].Priority < 1 || *input.Rules[i].Priority > 100 {
return nil, httperrors.NewInputParameterError("invalid priority %d, range 1-100", *input.Rules[i].Priority)
}
if len(rule.Ports) > 0 && strings.Contains(input.Rules[i].Ports, ",") {
return nil, httperrors.NewInputParameterError("invalid ports %s", input.Rules[i].Ports)
}
}
return input, nil
}
func (self *SHuaWeiRegionDriver) ValidateUpdateSecurityGroupRuleInput(ctx context.Context, userCred mcclient.TokenCredential, input *api.SSecgroupRuleUpdateInput) (*api.SSecgroupRuleUpdateInput, error) {
if input.Priority != nil && *input.Priority < 1 || *input.Priority > 100 {
return nil, httperrors.NewInputParameterError("invalid priority %d, range 1-100", *input.Priority)
}
if input.Ports != nil && strings.Contains(*input.Ports, ",") {
return nil, httperrors.NewInputParameterError("invalid ports %s", *input.Ports)
}
return self.SManagedVirtualizationRegionDriver.ValidateUpdateSecurityGroupRuleInput(ctx, userCred, input)
}
func (self *SHuaWeiRegionDriver) GetSecurityGroupFilter(vpc *models.SVpc) (func(q *sqlchemy.SQuery) *sqlchemy.SQuery, error) {
return func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
return q.Equals("cloudregion_id", vpc.CloudregionId).Equals("manager_id", vpc.ManagerId)
}, nil
}
func (self *SHuaWeiRegionDriver) CreateDefaultSecurityGroup(
ctx context.Context,
userCred mcclient.TokenCredential,
ownerId mcclient.IIdentityProvider,
vpc *models.SVpc,
) (*models.SSecurityGroup, error) {
newGroup := &models.SSecurityGroup{}
newGroup.SetModelManager(models.SecurityGroupManager, newGroup)
newGroup.Name = fmt.Sprintf("default-auto-%d", time.Now().Unix())
newGroup.Description = "auto generage"
newGroup.ManagerId = vpc.ManagerId
newGroup.CloudregionId = vpc.CloudregionId
newGroup.DomainId = ownerId.GetDomainId()
newGroup.ProjectId = ownerId.GetProjectId()
err := models.SecurityGroupManager.TableSpec().Insert(ctx, newGroup)
if err != nil {
return nil, errors.Wrapf(err, "insert")
}
region, err := vpc.GetRegion()
if err != nil {
return nil, errors.Wrapf(err, "GetRegion")
}
driver := region.GetDriver()
err = driver.RequestCreateSecurityGroup(ctx, userCred, newGroup, api.SSecgroupRuleResourceSet{})
if err != nil {
return nil, errors.Wrapf(err, "RequestCreateSecurityGroup")
}
return newGroup, nil
}
-4
View File
@@ -36,7 +36,3 @@ func (self *SJDcloudRegionDriver) GetProvider() string {
func (self *SJDcloudRegionDriver) IsCertificateBelongToRegion() bool {
return false
}
func (self *SJDcloudRegionDriver) IsSecurityGroupBelongVpc() bool {
return true
}
-12
View File
@@ -35,18 +35,6 @@ func (self *SKsyunRegionDriver) GetProvider() string {
return api.CLOUD_PROVIDER_KSYUN
}
func (self *SKsyunRegionDriver) IsAllowSecurityGroupNameRepeat() bool {
return true
}
func (self *SKsyunRegionDriver) GenerateSecurityGroupName(name string) string {
return name
}
func (self *SKsyunRegionDriver) IsSecurityGroupBelongVpc() bool {
return true
}
func (self *SKsyunRegionDriver) ValidateCreateSnapshotData(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, storage *models.SStorage, input *api.SnapshotCreateInput) error {
return nil
}
+88 -6
View File
@@ -18,6 +18,7 @@ import (
"context"
"database/sql"
"fmt"
"net"
"sort"
"strconv"
@@ -27,6 +28,7 @@ import (
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/httputils"
randutil "yunion.io/x/pkg/util/rand"
"yunion.io/x/pkg/util/secrules"
"yunion.io/x/pkg/utils"
"yunion.io/x/sqlchemy"
@@ -69,12 +71,14 @@ func (self *SKVMRegionDriver) GetProvider() string {
return api.CLOUD_PROVIDER_ONECLOUD
}
func (self *SKVMRegionDriver) IsAllowSecurityGroupNameRepeat() bool {
return false
}
func (self *SKVMRegionDriver) GenerateSecurityGroupName(name string) string {
return name
func (self *SKVMRegionDriver) ValidateCreateSecurityGroupInput(ctx context.Context, userCred mcclient.TokenCredential, input *api.SSecgroupCreateInput) (*api.SSecgroupCreateInput, error) {
for i := range input.Rules {
err := input.Rules[i].Check()
if err != nil {
return input, httperrors.NewInputParameterError("rule %d is invalid: %s", i, err)
}
}
return input, nil
}
func (self *SKVMRegionDriver) ValidateCreateLoadbalancerData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, input *api.LoadbalancerCreateInput) (*api.LoadbalancerCreateInput, error) {
@@ -1530,3 +1534,81 @@ func (self *SKVMRegionDriver) requestAssociateEipWithLoadbalancer(
}
return nil
}
func (self *SKVMRegionDriver) RequestCreateSecurityGroup(
ctx context.Context,
userCred mcclient.TokenCredential,
secgroup *models.SSecurityGroup,
rules api.SSecgroupRuleResourceSet,
) error {
_, err := db.Update(secgroup, func() error {
secgroup.VpcId = ""
return nil
})
if err != nil {
return err
}
for _, r := range rules {
rule := &models.SSecurityGroupRule{
Priority: int(*r.Priority),
Protocol: r.Protocol,
Ports: r.Ports,
Direction: r.Direction,
CIDR: r.CIDR,
Action: r.Action,
Description: r.Description,
}
rule.SecgroupId = secgroup.Id
models.SecurityGroupRuleManager.TableSpec().Insert(ctx, rule)
}
secgroup.SetStatus(userCred, api.SECGROUP_STATUS_READY, "")
return nil
}
func (self *SKVMRegionDriver) RequestPrepareSecurityGroups(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, secgroups []models.SSecurityGroup, vpc *models.SVpc, callback func(ids []string) error, task taskman.ITask) error {
return task.ScheduleRun(nil)
}
func (self *SKVMRegionDriver) RequestDeleteSecurityGroup(ctx context.Context, userCred mcclient.TokenCredential, secgroup *models.SSecurityGroup, task taskman.ITask) error {
return task.ScheduleRun(nil)
}
func (self *SKVMRegionDriver) ValidateUpdateSecurityGroupRuleInput(ctx context.Context, userCred mcclient.TokenCredential, input *api.SSecgroupRuleUpdateInput) (*api.SSecgroupRuleUpdateInput, error) {
if input.Priority != nil {
if *input.Priority < 1 || *input.Priority > 100 {
return nil, httperrors.NewInputParameterError("invalid priority %d", input.Priority)
}
}
if input.Action != nil {
if !utils.IsInStringArray(*input.Action, []string{string(secrules.SecurityRuleAllow), string(secrules.SecurityRuleDeny)}) {
return nil, httperrors.NewInputParameterError("invalid action %s", *input.Action)
}
}
if input.Protocol != nil {
if !utils.IsInStringArray(*input.Protocol, []string{
secrules.PROTO_ANY,
secrules.PROTO_UDP,
secrules.PROTO_TCP,
secrules.PROTO_ICMP,
}) {
return nil, httperrors.NewInputParameterError("invalid protocol %s", *input.Protocol)
}
}
if input.Ports != nil {
rule := secrules.SecurityRule{}
err := rule.ParsePorts(*input.Ports)
if err != nil {
return nil, httperrors.NewInputParameterError("invalid ports %s", *input.Ports)
}
}
if input.CIDR != nil {
_, _, err := net.ParseCIDR(*input.CIDR)
if err != nil {
return nil, httperrors.NewInputParameterError("invalid cidr %s", *input.CIDR)
}
}
return input, nil
}
+365 -105
View File
@@ -18,6 +18,7 @@ import (
"context"
"database/sql"
"fmt"
"net"
"strings"
"time"
@@ -25,11 +26,12 @@ import (
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/gotypes"
"yunion.io/x/pkg/util/billing"
"yunion.io/x/pkg/util/netutils"
"yunion.io/x/pkg/util/pinyinutils"
"yunion.io/x/pkg/util/rbacscope"
"yunion.io/x/pkg/util/secrules"
"yunion.io/x/pkg/utils"
"yunion.io/x/sqlchemy"
billing_api "yunion.io/x/onecloud/pkg/apis/billing"
api "yunion.io/x/onecloud/pkg/apis/compute"
@@ -49,14 +51,6 @@ type SManagedVirtualizationRegionDriver struct {
SVirtualizationRegionDriver
}
func (self *SManagedVirtualizationRegionDriver) IsAllowSecurityGroupNameRepeat() bool {
return true
}
func (self *SManagedVirtualizationRegionDriver) GenerateSecurityGroupName(name string) string {
return pinyinutils.Text2Pinyin(name)
}
func (self *SManagedVirtualizationRegionDriver) IsSupportedElasticcacheSecgroup() bool {
return false
}
@@ -1233,57 +1227,6 @@ 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) (string, error) {
if region.GetDriver().IsSecurityGroupBelongGlobalVpc() {
gvpc, err := vpc.GetGlobalVpc()
if err != nil {
return "", err
}
return gvpc.ExternalId, 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) (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 {
return "", errors.Wrap(err, "vpc.GetRegon")
}
if region.GetDriver().GetSecurityGroupPublicScope(service) == rbacscope.ScopeSystem {
remoteProjectId = ""
}
cache, err := models.SecurityGroupCacheManager.Register(ctx, userCred, secgroup.Id, vpcId, region.Id, vpc.ManagerId, remoteProjectId)
if err != nil {
return "", errors.Wrap(err, "SSecurityGroupCache.Register")
}
_, err = cache.GetOrCreateISecurityGroup(ctx)
if err != nil {
return "", errors.Wrapf(err, "GetOrCreateISecurityGroup")
}
return cache.ExternalId, nil
}
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, "")
return nil, err
})
return nil
}
func (self *SManagedVirtualizationRegionDriver) RequestCreateDBInstance(ctx context.Context, userCred mcclient.TokenCredential, dbinstance *models.SDBInstance, task taskman.ITask) error {
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
iregion, err := dbinstance.GetIRegion(ctx)
@@ -1351,16 +1294,32 @@ func (self *SManagedVirtualizationRegionDriver) RequestCreateDBInstance(ctx cont
if err != nil {
return nil, errors.Wrapf(err, "GetSecgroups")
}
driver := region.GetDriver()
ownerId := dbinstance.GetOwnerId()
for i := range secgroups {
vpcId, err := region.GetDriver().GetSecurityGroupVpcId(ctx, userCred, region, nil, vpc)
if err != nil {
return nil, errors.Wrap(err, "GetSecurityGroupVpcId")
if secgroups[i].Id == api.SECGROUP_DEFAULT_ID {
filter, err := driver.GetSecurityGroupFilter(vpc)
if err != nil {
return nil, errors.Wrapf(err, "GetSecurityGroupFilter")
}
group, err := vpc.GetDefaultSecurityGroup(ownerId, filter)
if err != nil && errors.Cause(err) != sql.ErrNoRows {
return nil, err
}
if gotypes.IsNil(group) {
group, err = driver.CreateDefaultSecurityGroup(ctx, userCred, ownerId, vpc)
if err != nil {
return nil, errors.Wrapf(err, "CreateDefaultSecurityGroup")
}
}
if !utils.IsInStringArray(group.ExternalId, desc.SecgroupIds) {
desc.SecgroupIds = append(desc.SecgroupIds, group.ExternalId)
}
continue
}
secId, err := region.GetDriver().RequestSyncSecurityGroup(ctx, userCred, vpcId, vpc, &secgroups[i], desc.ProjectId, "")
if err != nil {
return nil, errors.Wrap(err, "SyncSecurityGroup")
if !utils.IsInStringArray(secgroups[i].ExternalId, desc.SecgroupIds) {
desc.SecgroupIds = append(desc.SecgroupIds, secgroups[i].ExternalId)
}
desc.SecgroupIds = append(desc.SecgroupIds, secId)
}
if dbinstance.BillingType == billing_api.BILLING_TYPE_PREPAID {
@@ -1513,16 +1472,32 @@ func (self *SManagedVirtualizationRegionDriver) RequestCreateDBInstanceFromBacku
if err != nil {
return nil, errors.Wrapf(err, "GetSecgroups")
}
driver := region.GetDriver()
ownerId := rds.GetOwnerId()
for i := range secgroups {
vpcId, err := region.GetDriver().GetSecurityGroupVpcId(ctx, userCred, region, nil, vpc)
if err != nil {
return nil, errors.Wrap(err, "GetSecurityGroupVpcId")
if secgroups[i].Id == api.SECGROUP_DEFAULT_ID {
filter, err := driver.GetSecurityGroupFilter(vpc)
if err != nil {
return nil, errors.Wrapf(err, "GetSecurityGroupFilter")
}
group, err := vpc.GetDefaultSecurityGroup(ownerId, filter)
if err != nil && errors.Cause(err) != sql.ErrNoRows {
return nil, err
}
if gotypes.IsNil(group) {
group, err = driver.CreateDefaultSecurityGroup(ctx, userCred, ownerId, vpc)
if err != nil {
return nil, errors.Wrapf(err, "CreateDefaultSecurityGroup")
}
}
if !utils.IsInStringArray(group.ExternalId, desc.SecgroupIds) {
desc.SecgroupIds = append(desc.SecgroupIds, group.ExternalId)
}
continue
}
secId, err := region.GetDriver().RequestSyncSecurityGroup(ctx, userCred, vpcId, vpc, &secgroups[i], desc.ProjectId, "")
if err != nil {
return nil, errors.Wrap(err, "SyncSecurityGroup")
if !utils.IsInStringArray(secgroups[i].ExternalId, desc.SecgroupIds) {
desc.SecgroupIds = append(desc.SecgroupIds, secgroups[i].ExternalId)
}
desc.SecgroupIds = append(desc.SecgroupIds, secId)
}
if rds.BillingType == billing_api.BILLING_TYPE_PREPAID {
@@ -2847,16 +2822,6 @@ func (self *SManagedVirtualizationRegionDriver) RequestSyncSecgroupsForElasticca
// sync secgroups to cloud
secgroupExternalIds := []string{}
{
ess, err := ec.GetElasticcacheSecgroups()
if err != nil {
return nil, errors.Wrap(err, "GetElasticcacheSecgroups")
}
provider := ec.GetCloudprovider()
if provider == nil {
return nil, errors.Wrap(httperrors.ErrInvalidStatus, "GetCloudprovider")
}
vpc, err := ec.GetVpc()
if err != nil {
return nil, errors.Wrapf(err, "GetVpc")
@@ -2865,17 +2830,36 @@ func (self *SManagedVirtualizationRegionDriver) RequestSyncSecgroupsForElasticca
if err != nil {
return nil, errors.Wrapf(err, "GetRegion")
}
vpcId, err := self.GetSecurityGroupVpcId(ctx, userCred, region, nil, vpc)
secgroups, err := ec.GetSecgroups()
if err != nil {
return nil, errors.Wrap(err, "GetSecurityGroupVpcId")
return nil, errors.Wrapf(err, "GetSecgroups")
}
for i := range ess {
externalId, err := self.RequestSyncSecurityGroup(ctx, task.GetUserCred(), vpcId, vpc, ess[i].GetSecGroup(), "", "redis")
if err != nil {
return nil, errors.Wrap(err, "RequestSyncSecurityGroup")
driver := region.GetDriver()
ownerId := ec.GetOwnerId()
for i := range secgroups {
if secgroups[i].Id == api.SECGROUP_DEFAULT_ID {
filter, err := driver.GetSecurityGroupFilter(vpc)
if err != nil {
return nil, errors.Wrapf(err, "GetSecurityGroupFilter")
}
group, err := vpc.GetDefaultSecurityGroup(ownerId, filter)
if err != nil && errors.Cause(err) != sql.ErrNoRows {
return nil, err
}
if gotypes.IsNil(group) {
group, err = driver.CreateDefaultSecurityGroup(ctx, userCred, ownerId, vpc)
if err != nil {
return nil, errors.Wrapf(err, "CreateDefaultSecurityGroup")
}
}
if !utils.IsInStringArray(group.ExternalId, secgroupExternalIds) {
secgroupExternalIds = append(secgroupExternalIds, group.ExternalId)
}
continue
}
if !utils.IsInStringArray(secgroups[i].ExternalId, secgroupExternalIds) {
secgroupExternalIds = append(secgroupExternalIds, secgroups[i].ExternalId)
}
secgroupExternalIds = append(secgroupExternalIds, externalId)
}
}
@@ -2969,26 +2953,51 @@ func IsInPrivateIpRange(ar netutils.IPV4AddrRange) error {
func (self *SManagedVirtualizationRegionDriver) RequestSyncRdsSecurityGroups(ctx context.Context, userCred mcclient.TokenCredential, rds *models.SDBInstance, task taskman.ITask) error {
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
vpc, err := rds.GetVpc()
if err != nil {
return nil, errors.Wrapf(err, "rds.GetVpc")
}
secgroups, err := rds.GetSecgroups()
if err != nil {
return nil, errors.Wrapf(err, "GetSecgroups")
}
vpc, err := rds.GetVpc()
if err != nil {
return nil, errors.Wrapf(err, "GetVpc")
}
region, err := vpc.GetRegion()
if err != nil {
return nil, errors.Wrapf(err, "GetRegion")
}
driver := region.GetDriver()
ownerId := rds.GetOwnerId()
secgroupIds := []string{}
for i := range secgroups {
if secgroups[i].Id == api.SECGROUP_DEFAULT_ID {
filter, err := driver.GetSecurityGroupFilter(vpc)
if err != nil {
return nil, errors.Wrapf(err, "GetSecurityGroupFilter")
}
group, err := vpc.GetDefaultSecurityGroup(ownerId, filter)
if err != nil && errors.Cause(err) != sql.ErrNoRows {
return nil, err
}
if gotypes.IsNil(group) {
group, err = driver.CreateDefaultSecurityGroup(ctx, userCred, ownerId, vpc)
if err != nil {
return nil, errors.Wrapf(err, "CreateDefaultSecurityGroup")
}
}
if !utils.IsInStringArray(group.ExternalId, secgroupIds) {
secgroupIds = append(secgroupIds, group.ExternalId)
}
continue
}
if !utils.IsInStringArray(secgroups[i].ExternalId, secgroupIds) {
secgroupIds = append(secgroupIds, secgroups[i].ExternalId)
}
}
iRds, err := rds.GetIDBInstance(ctx)
if err != nil {
return nil, errors.Wrapf(err, "GetIDBInstance")
}
secgroupIds := []string{}
for i := range secgroups {
secgroupId, err := self.RequestSyncSecurityGroup(ctx, userCred, vpc.ExternalId, vpc, &secgroups[i], iRds.GetProjectId(), "rds")
if err != nil {
return nil, errors.Wrapf(err, "RequestSyncSecurityGroup")
}
secgroupIds = append(secgroupIds, secgroupId)
}
err = iRds.SetSecurityGroups(secgroupIds)
if err != nil {
return nil, errors.Wrapf(err, "SetSecurityGroups")
@@ -3258,3 +3267,254 @@ func (self *SManagedVirtualizationRegionDriver) RequestCreateKubeNodePool(ctx co
})
return nil
}
func (self *SManagedVirtualizationRegionDriver) RequestDeleteSecurityGroup(ctx context.Context, userCred mcclient.TokenCredential, secgroup *models.SSecurityGroup, task taskman.ITask) error {
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
iGroup, err := secgroup.GetISecurityGroup(ctx)
if err != nil {
if errors.Cause(err) == cloudprovider.ErrNotFound || errors.Cause(err) == sql.ErrNoRows {
return nil, nil
}
return nil, errors.Wrapf(err, "GetISecurityGroup")
}
return nil, iGroup.Delete()
})
return nil
}
func (self *SManagedVirtualizationRegionDriver) RequestCreateSecurityGroup(
ctx context.Context,
userCred mcclient.TokenCredential,
secgroup *models.SSecurityGroup,
rules api.SSecgroupRuleResourceSet,
) error {
vpcId := ""
if len(secgroup.VpcId) > 0 {
vpc, err := secgroup.GetVpc()
if err != nil {
return errors.Wrapf(err, "GetVpc")
}
vpcId = vpc.ExternalId
}
provider, err := secgroup.GetCloudprovider()
if err != nil {
return errors.Wrapf(err, "GetCloudprovider")
}
iRegion, err := secgroup.GetIRegion(ctx)
if err != nil {
return errors.Wrapf(err, "GetIRegion")
}
opts := &cloudprovider.SecurityGroupCreateInput{
Name: secgroup.Name,
Desc: secgroup.Description,
VpcId: vpcId,
}
opts.Tags, _ = secgroup.GetAllUserMetadata()
opts.ProjectId, err = provider.SyncProject(ctx, userCred, secgroup.ProjectId)
if err != nil {
logclient.AddSimpleActionLog(secgroup, logclient.ACT_SYNC_CLOUD_PROJECT, err, userCred, false)
}
iGroup, err := iRegion.CreateISecurityGroup(opts)
if err != nil {
return errors.Wrapf(err, "CreateISecurityGroup")
}
_, err = db.Update(secgroup, func() error {
secgroup.ExternalId = iGroup.GetGlobalId()
if len(iGroup.GetVpcId()) == 0 {
secgroup.VpcId = ""
}
return nil
})
if err != nil {
return errors.Wrapf(err, "SetExternalId")
}
for i := range rules {
opts := cloudprovider.SecurityGroupRuleCreateOptions{
Desc: rules[i].Description,
Direction: secrules.TSecurityRuleDirection(rules[i].Direction),
Action: secrules.TSecurityRuleAction(rules[i].Action),
Protocol: rules[i].Protocol,
CIDR: rules[i].CIDR,
Ports: rules[i].Ports,
}
_, err := iGroup.CreateRule(&opts)
if err != nil {
return errors.Wrapf(err, "CreateRule")
}
}
iRules, err := iGroup.GetRules()
if err != nil {
return errors.Wrapf(err, "GetRules")
}
result := secgroup.SyncRules(ctx, userCred, iRules)
if result.IsError() {
return result.AllError()
}
secgroup.SetStatus(userCred, api.SECGROUP_STATUS_READY, "")
return nil
}
func (self *SManagedVirtualizationRegionDriver) ValidateCreateSecurityGroupInput(ctx context.Context, userCred mcclient.TokenCredential, input *api.SSecgroupCreateInput) (*api.SSecgroupCreateInput, error) {
for i := range input.Rules {
rule := input.Rules[i]
if !utils.IsInStringArray(rule.Action, []string{string(secrules.SecurityRuleAllow), string(secrules.SecurityRuleDeny)}) {
return nil, httperrors.NewInputParameterError("invalid action %s", rule.Action)
}
if !utils.IsInStringArray(rule.Protocol, []string{
secrules.PROTO_ANY,
secrules.PROTO_UDP,
secrules.PROTO_TCP,
secrules.PROTO_ICMP,
}) {
return nil, httperrors.NewInputParameterError("invalid protocol %s", rule.Protocol)
}
if len(rule.Ports) > 0 {
r := secrules.SecurityRule{}
err := r.ParsePorts(rule.Ports)
if err != nil {
return nil, httperrors.NewInputParameterError("invalid ports %s", rule.Ports)
}
}
if len(rule.CIDR) > 0 {
_, _, err := net.ParseCIDR(rule.CIDR)
if err != nil {
return nil, httperrors.NewInputParameterError("invalid cidr %s", rule.CIDR)
}
}
}
return input, nil
}
func (self *SManagedVirtualizationRegionDriver) ValidateUpdateSecurityGroupRuleInput(ctx context.Context, userCred mcclient.TokenCredential, input *api.SSecgroupRuleUpdateInput) (*api.SSecgroupRuleUpdateInput, error) {
if input.Action != nil {
if !utils.IsInStringArray(*input.Action, []string{string(secrules.SecurityRuleAllow), string(secrules.SecurityRuleDeny)}) {
return nil, httperrors.NewInputParameterError("invalid action %s", *input.Action)
}
}
if input.Protocol != nil {
if !utils.IsInStringArray(*input.Protocol, []string{
secrules.PROTO_ANY,
secrules.PROTO_UDP,
secrules.PROTO_TCP,
secrules.PROTO_ICMP,
}) {
return nil, httperrors.NewInputParameterError("invalid protocol %s", *input.Protocol)
}
}
if input.Ports != nil {
rule := secrules.SecurityRule{}
err := rule.ParsePorts(*input.Ports)
if err != nil {
return nil, httperrors.NewInputParameterError("invalid ports %s", *input.Ports)
}
}
if input.CIDR != nil {
_, _, err := net.ParseCIDR(*input.CIDR)
if err != nil {
return nil, httperrors.NewInputParameterError("invalid cidr %s", *input.CIDR)
}
}
return input, nil
}
func (self *SManagedVirtualizationRegionDriver) RequestPrepareSecurityGroups(
ctx context.Context,
userCred mcclient.TokenCredential,
ownerId mcclient.IIdentityProvider,
secgroups []models.SSecurityGroup,
vpc *models.SVpc,
callback func(ids []string) error,
task taskman.ITask,
) error {
region, err := vpc.GetRegion()
if err != nil {
return errors.Wrapf(err, "GetRegion")
}
driver := region.GetDriver()
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
groupIds := []string{}
for i := range secgroups {
if secgroups[i].Id == api.SECGROUP_DEFAULT_ID {
filter, err := driver.GetSecurityGroupFilter(vpc)
if err != nil {
return nil, errors.Wrapf(err, "GetSecurityGroupFilter")
}
group, err := vpc.GetDefaultSecurityGroup(ownerId, filter)
if err != nil && errors.Cause(err) != sql.ErrNoRows {
return nil, err
}
if gotypes.IsNil(group) {
group, err = driver.CreateDefaultSecurityGroup(ctx, userCred, ownerId, vpc)
if err != nil {
return nil, errors.Wrapf(err, "CreateDefaultSecurityGroup")
}
}
if !utils.IsInStringArray(group.Id, groupIds) {
groupIds = append(groupIds, group.Id)
}
continue
}
if len(secgroups[i].ExternalId) > 0 && !utils.IsInStringArray(secgroups[i].Id, groupIds) {
groupIds = append(groupIds, secgroups[i].Id)
}
}
if callback != nil {
return nil, callback(groupIds)
}
return nil, nil
})
return nil
}
func (self *SManagedVirtualizationRegionDriver) GetSecurityGroupFilter(vpc *models.SVpc) (func(q *sqlchemy.SQuery) *sqlchemy.SQuery, error) {
return func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
return q.Equals("vpc_id", vpc.Id)
}, nil
}
func (self *SManagedVirtualizationRegionDriver) CreateDefaultSecurityGroup(
ctx context.Context,
userCred mcclient.TokenCredential,
ownerId mcclient.IIdentityProvider,
vpc *models.SVpc,
) (*models.SSecurityGroup, error) {
newGroup := &models.SSecurityGroup{}
newGroup.SetModelManager(models.SecurityGroupManager, newGroup)
newGroup.Name = fmt.Sprintf("default-auto-%d", time.Now().Unix())
newGroup.Description = "auto generage"
newGroup.VpcId = vpc.Id
newGroup.ManagerId = vpc.ManagerId
newGroup.CloudregionId = vpc.CloudregionId
newGroup.DomainId = ownerId.GetDomainId()
newGroup.ProjectId = ownerId.GetProjectId()
err := models.SecurityGroupManager.TableSpec().Insert(ctx, newGroup)
if err != nil {
return nil, errors.Wrapf(err, "insert")
}
region, err := vpc.GetRegion()
if err != nil {
return nil, errors.Wrapf(err, "GetRegion")
}
driver := region.GetDriver()
err = driver.RequestCreateSecurityGroup(ctx, userCred, newGroup, api.SSecgroupRuleResourceSet{})
if err != nil {
return nil, errors.Wrapf(err, "RequestCreateSecurityGroup")
}
return newGroup, nil
}
+41 -17
View File
@@ -17,11 +17,13 @@ package regiondrivers
import (
"context"
"database/sql"
"strings"
"fmt"
"time"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/util/rbacscope"
"yunion.io/x/pkg/errors"
"yunion.io/x/sqlchemy"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
@@ -39,21 +41,6 @@ func init() {
models.RegisterRegionDriver(&driver)
}
func (self *SOpenStackRegionDriver) IsAllowSecurityGroupNameRepeat() bool {
return true
}
func (self *SOpenStackRegionDriver) GenerateSecurityGroupName(name string) string {
if strings.ToLower(name) == "default" {
return "DefaultGroup"
}
return name
}
func (self *SOpenStackRegionDriver) GetSecurityGroupPublicScope(service string) rbacscope.TRbacScope {
return rbacscope.ScopeProject
}
func (self *SOpenStackRegionDriver) GetProvider() string {
return api.CLOUD_PROVIDER_OPENSTACK
}
@@ -140,3 +127,40 @@ func (self *SOpenStackRegionDriver) RequestDeleteLoadbalancerBackend(ctx context
})
return nil
}
func (self *SOpenStackRegionDriver) GetSecurityGroupFilter(vpc *models.SVpc) (func(q *sqlchemy.SQuery) *sqlchemy.SQuery, error) {
return func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
return q.Equals("cloudregion_id", vpc.CloudregionId)
}, nil
}
func (self *SOpenStackRegionDriver) CreateDefaultSecurityGroup(
ctx context.Context,
userCred mcclient.TokenCredential,
ownerId mcclient.IIdentityProvider,
vpc *models.SVpc,
) (*models.SSecurityGroup, error) {
newGroup := &models.SSecurityGroup{}
newGroup.SetModelManager(models.SecurityGroupManager, newGroup)
newGroup.Name = fmt.Sprintf("default-auto-%d", time.Now().Unix())
newGroup.Description = "auto generage"
newGroup.ManagerId = vpc.ManagerId
newGroup.CloudregionId = vpc.CloudregionId
newGroup.DomainId = ownerId.GetDomainId()
newGroup.ProjectId = ownerId.GetProjectId()
err := models.SecurityGroupManager.TableSpec().Insert(ctx, newGroup)
if err != nil {
return nil, errors.Wrapf(err, "insert")
}
region, err := vpc.GetRegion()
if err != nil {
return nil, errors.Wrapf(err, "GetRegion")
}
driver := region.GetDriver()
err = driver.RequestCreateSecurityGroup(ctx, userCred, newGroup, api.SSecgroupRuleResourceSet{})
if err != nil {
return nil, errors.Wrapf(err, "RequestCreateSecurityGroup")
}
return newGroup, nil
}
+61 -16
View File
@@ -23,8 +23,8 @@ import (
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/billing"
"yunion.io/x/pkg/util/rbacscope"
"yunion.io/x/pkg/utils"
"yunion.io/x/sqlchemy"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
@@ -46,14 +46,6 @@ func init() {
models.RegisterRegionDriver(&driver)
}
func (self *SQcloudRegionDriver) IsAllowSecurityGroupNameRepeat() bool {
return true
}
func (self *SQcloudRegionDriver) GenerateSecurityGroupName(name string) string {
return name
}
func (self *SQcloudRegionDriver) GetProvider() string {
return api.CLOUD_PROVIDER_QCLOUD
}
@@ -407,13 +399,6 @@ func (self *SQcloudRegionDriver) IsSupportedElasticcache() bool {
return true
}
func (self *SQcloudRegionDriver) GetSecurityGroupPublicScope(service string) rbacscope.TRbacScope {
if service == "redis" {
return rbacscope.ScopeProject
}
return rbacscope.ScopeSystem
}
func (self *SQcloudRegionDriver) ValidateCreateElasticcacheAccountData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
elasticCacheV := validators.NewModelIdOrNameValidator("elasticcache", "elasticcache", ownerId)
accountTypeV := validators.NewStringChoicesValidator("account_type", choices.NewChoices("normal")).Default("normal")
@@ -612,3 +597,63 @@ func (self *SQcloudRegionDriver) ValidateCreateCdnData(ctx context.Context, user
}
return input, nil
}
func (self *SQcloudRegionDriver) ValidateCreateSecurityGroupInput(ctx context.Context, userCred mcclient.TokenCredential, input *api.SSecgroupCreateInput) (*api.SSecgroupCreateInput, error) {
for i := range input.Rules {
rule := input.Rules[i]
if rule.Priority == nil {
return nil, httperrors.NewMissingParameterError("priority")
}
if *rule.Priority < 1 || *rule.Priority > 100 {
return nil, httperrors.NewInputParameterError("invalid priority %d, range 1-100", *rule.Priority)
}
}
return input, nil
}
func (self *SQcloudRegionDriver) ValidateUpdateSecurityGroupRuleInput(ctx context.Context, userCred mcclient.TokenCredential, input *api.SSecgroupRuleUpdateInput) (*api.SSecgroupRuleUpdateInput, error) {
if input.Priority != nil && *input.Priority < 1 || *input.Priority > 100 {
return nil, httperrors.NewInputParameterError("invalid priority %d, range 1-100", *input.Priority)
}
return self.SManagedVirtualizationRegionDriver.ValidateUpdateSecurityGroupRuleInput(ctx, userCred, input)
}
func (self *SQcloudRegionDriver) GetSecurityGroupFilter(vpc *models.SVpc) (func(q *sqlchemy.SQuery) *sqlchemy.SQuery, error) {
return func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
return q.Equals("cloudregion_id", vpc.CloudregionId)
}, nil
}
func (self *SQcloudRegionDriver) CreateDefaultSecurityGroup(
ctx context.Context,
userCred mcclient.TokenCredential,
ownerId mcclient.IIdentityProvider,
vpc *models.SVpc,
) (*models.SSecurityGroup, error) {
newGroup := &models.SSecurityGroup{}
newGroup.SetModelManager(models.SecurityGroupManager, newGroup)
newGroup.Name = fmt.Sprintf("default-auto-%d", time.Now().Unix())
newGroup.Description = "auto generage"
newGroup.ManagerId = vpc.ManagerId
newGroup.CloudregionId = vpc.CloudregionId
newGroup.DomainId = ownerId.GetDomainId()
newGroup.ProjectId = ownerId.GetProjectId()
err := models.SecurityGroupManager.TableSpec().Insert(ctx, newGroup)
if err != nil {
return nil, errors.Wrapf(err, "insert")
}
region, err := vpc.GetRegion()
if err != nil {
return nil, errors.Wrapf(err, "GetRegion")
}
driver := region.GetDriver()
err = driver.RequestCreateSecurityGroup(ctx, userCred, newGroup, api.SSecgroupRuleResourceSet{})
if err != nil {
return nil, errors.Wrapf(err, "RequestCreateSecurityGroup")
}
return newGroup, nil
}
-12
View File
@@ -35,18 +35,6 @@ func (self *SQingCloudRegionDriver) GetProvider() string {
return api.CLOUD_PROVIDER_QINGCLOUD
}
func (self *SQingCloudRegionDriver) IsAllowSecurityGroupNameRepeat() bool {
return true
}
func (self *SQingCloudRegionDriver) GenerateSecurityGroupName(name string) string {
return name
}
func (self *SQingCloudRegionDriver) IsSecurityGroupBelongVpc() bool {
return true
}
func (self *SQingCloudRegionDriver) ValidateCreateSnapshotData(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, storage *models.SStorage, input *api.SnapshotCreateInput) error {
return nil
}
+74 -8
View File
@@ -16,8 +16,14 @@ package regiondrivers
import (
"context"
"fmt"
"strings"
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/secrules"
"yunion.io/x/sqlchemy"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/validators"
@@ -35,14 +41,6 @@ func init() {
models.RegisterRegionDriver(&driver)
}
func (self *SUcloudRegionDriver) IsAllowSecurityGroupNameRepeat() bool {
return false
}
func (self *SUcloudRegionDriver) GenerateSecurityGroupName(name string) string {
return name
}
func (self *SUcloudRegionDriver) GetProvider() string {
return api.CLOUD_PROVIDER_UCLOUD
}
@@ -62,3 +60,71 @@ func (self *SUcloudRegionDriver) ValidateCreateVpcData(ctx context.Context, user
}
return input, nil
}
func (self *SUcloudRegionDriver) ValidateCreateSecurityGroupInput(ctx context.Context, userCred mcclient.TokenCredential, input *api.SSecgroupCreateInput) (*api.SSecgroupCreateInput, error) {
for i := range input.Rules {
if input.Rules[i].Protocol == secrules.PROTO_ANY {
return nil, httperrors.NewNotSupportedError("protocol %s", input.Rules[i].Protocol)
}
if input.Rules[i].Priority == nil {
return nil, httperrors.NewMissingParameterError("priority")
}
if *input.Rules[i].Priority < 1 || *input.Rules[i].Priority > 3 {
return nil, httperrors.NewInputParameterError("invalid priority %d, range 1-3", *input.Rules[i].Priority)
}
}
return self.SManagedVirtualizationRegionDriver.ValidateCreateSecurityGroupInput(ctx, userCred, input)
}
func (self *SUcloudRegionDriver) ValidateUpdateSecurityGroupRuleInput(ctx context.Context, userCred mcclient.TokenCredential, input *api.SSecgroupRuleUpdateInput) (*api.SSecgroupRuleUpdateInput, error) {
if input.Priority != nil && *input.Priority < 1 || *input.Priority > 3 {
return nil, httperrors.NewInputParameterError("invalid priority %d, range 1-3", *input.Priority)
}
if input.Protocol != nil && *input.Protocol == secrules.PROTO_ANY {
return nil, httperrors.NewNotSupportedError("protocol %s", *input.Protocol)
}
if input.Ports != nil && strings.Contains(*input.Ports, ",") {
return nil, httperrors.NewInputParameterError("invalid ports %s", *input.Ports)
}
return self.SManagedVirtualizationRegionDriver.ValidateUpdateSecurityGroupRuleInput(ctx, userCred, input)
}
func (self *SUcloudRegionDriver) GetSecurityGroupFilter(vpc *models.SVpc) (func(q *sqlchemy.SQuery) *sqlchemy.SQuery, error) {
return func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
return q.Equals("cloudregion_id", vpc.CloudregionId)
}, nil
}
func (self *SUcloudRegionDriver) CreateDefaultSecurityGroup(
ctx context.Context,
userCred mcclient.TokenCredential,
ownerId mcclient.IIdentityProvider,
vpc *models.SVpc,
) (*models.SSecurityGroup, error) {
newGroup := &models.SSecurityGroup{}
newGroup.SetModelManager(models.SecurityGroupManager, newGroup)
newGroup.Name = fmt.Sprintf("default-auto-%d", time.Now().Unix())
newGroup.Description = "auto generage"
newGroup.ManagerId = vpc.ManagerId
newGroup.CloudregionId = vpc.CloudregionId
newGroup.DomainId = ownerId.GetDomainId()
newGroup.ProjectId = ownerId.GetProjectId()
err := models.SecurityGroupManager.TableSpec().Insert(ctx, newGroup)
if err != nil {
return nil, errors.Wrapf(err, "insert")
}
region, err := vpc.GetRegion()
if err != nil {
return nil, errors.Wrapf(err, "GetRegion")
}
driver := region.GetDriver()
err = driver.RequestCreateSecurityGroup(ctx, userCred, newGroup, api.SSecgroupRuleResourceSet{})
if err != nil {
return nil, errors.Wrapf(err, "RequestCreateSecurityGroup")
}
return newGroup, nil
}
+25 -12
View File
@@ -16,6 +16,7 @@ package regiondrivers
import (
"context"
"strings"
"yunion.io/x/jsonutils"
@@ -35,18 +36,6 @@ func init() {
models.RegisterRegionDriver(&driver)
}
func (self *SVolcengineRegionDriver) IsSecurityGroupBelongVpc() bool {
return true
}
func (self *SVolcengineRegionDriver) IsAllowSecurityGroupNameRepeat() bool {
return false
}
func (self *SVolcengineRegionDriver) GenerateSecurityGroupName(name string) string {
return name
}
func (self *SVolcengineRegionDriver) GetProvider() string {
return api.CLOUD_PROVIDER_VOLCENGINE
}
@@ -66,3 +55,27 @@ func (self *SVolcengineRegionDriver) ValidateCreateVpcData(ctx context.Context,
}
return input, nil
}
func (self *SVolcengineRegionDriver) ValidateCreateSecurityGroupInput(ctx context.Context, userCred mcclient.TokenCredential, input *api.SSecgroupCreateInput) (*api.SSecgroupCreateInput, error) {
for i := range input.Rules {
if input.Rules[i].Priority == nil {
return nil, httperrors.NewMissingParameterError("priority")
}
if *input.Rules[i].Priority < 1 || *input.Rules[i].Priority > 100 {
return nil, httperrors.NewInputParameterError("invalid priority %d, range 1-100", *input.Rules[i].Priority)
}
}
return input, nil
}
func (self *SVolcengineRegionDriver) ValidateUpdateSecurityGroupRuleInput(ctx context.Context, userCred mcclient.TokenCredential, input *api.SSecgroupRuleUpdateInput) (*api.SSecgroupRuleUpdateInput, error) {
if input.Priority != nil && *input.Priority < 1 || *input.Priority > 100 {
return nil, httperrors.NewInputParameterError("invalid priority %d, range 1-100", *input.Priority)
}
if input.Ports != nil && strings.Contains(*input.Ports, ",") {
return nil, httperrors.NewInputParameterError("invalid ports %s", *input.Ports)
}
return self.SManagedVirtualizationRegionDriver.ValidateUpdateSecurityGroupRuleInput(ctx, userCred, input)
}
+60 -8
View File
@@ -17,6 +17,12 @@ package regiondrivers
import (
"context"
"database/sql"
"fmt"
"strings"
"time"
"yunion.io/x/pkg/errors"
"yunion.io/x/sqlchemy"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/compute/models"
@@ -33,14 +39,6 @@ func init() {
models.RegisterRegionDriver(&driver)
}
func (self *SZStackRegionDriver) IsAllowSecurityGroupNameRepeat() bool {
return true
}
func (self *SZStackRegionDriver) GenerateSecurityGroupName(name string) string {
return name
}
func (self *SZStackRegionDriver) GetProvider() string {
return api.CLOUD_PROVIDER_ZSTACK
}
@@ -73,3 +71,57 @@ func (self *SZStackRegionDriver) ValidateCreateEipData(ctx context.Context, user
}
return nil
}
func (self *SZStackRegionDriver) ValidateCreateSecurityGroupInput(ctx context.Context, userCred mcclient.TokenCredential, input *api.SSecgroupCreateInput) (*api.SSecgroupCreateInput, error) {
for i := range input.Rules {
rule := input.Rules[i]
if len(rule.Ports) > 0 && strings.Contains(input.Rules[i].Ports, ",") {
return nil, httperrors.NewInputParameterError("invalid ports %s", input.Rules[i].Ports)
}
}
return self.SManagedVirtualizationRegionDriver.ValidateCreateSecurityGroupInput(ctx, userCred, input)
}
func (self *SZStackRegionDriver) ValidateUpdateSecurityGroupRuleInput(ctx context.Context, userCred mcclient.TokenCredential, input *api.SSecgroupRuleUpdateInput) (*api.SSecgroupRuleUpdateInput, error) {
if input.Ports != nil && strings.Contains(*input.Ports, ",") {
return nil, httperrors.NewInputParameterError("invalid ports %s", *input.Ports)
}
return self.SManagedVirtualizationRegionDriver.ValidateUpdateSecurityGroupRuleInput(ctx, userCred, input)
}
func (self *SZStackRegionDriver) GetSecurityGroupFilter(vpc *models.SVpc) (func(q *sqlchemy.SQuery) *sqlchemy.SQuery, error) {
return func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
return q.Equals("cloudregion_id", vpc.CloudregionId)
}, nil
}
func (self *SZStackRegionDriver) CreateDefaultSecurityGroup(
ctx context.Context,
userCred mcclient.TokenCredential,
ownerId mcclient.IIdentityProvider,
vpc *models.SVpc,
) (*models.SSecurityGroup, error) {
newGroup := &models.SSecurityGroup{}
newGroup.SetModelManager(models.SecurityGroupManager, newGroup)
newGroup.Name = fmt.Sprintf("default-auto-%d", time.Now().Unix())
newGroup.Description = "auto generage"
newGroup.ManagerId = vpc.ManagerId
newGroup.CloudregionId = vpc.CloudregionId
newGroup.DomainId = ownerId.GetDomainId()
newGroup.ProjectId = ownerId.GetProjectId()
err := models.SecurityGroupManager.TableSpec().Insert(ctx, newGroup)
if err != nil {
return nil, errors.Wrapf(err, "insert")
}
region, err := vpc.GetRegion()
if err != nil {
return nil, errors.Wrapf(err, "GetRegion")
}
driver := region.GetDriver()
err = driver.RequestCreateSecurityGroup(ctx, userCred, newGroup, api.SSecgroupRuleResourceSet{})
if err != nil {
return nil, errors.Wrapf(err, "RequestCreateSecurityGroup")
}
return newGroup, nil
}
-1
View File
@@ -131,7 +131,6 @@ func InitHandlers(app *appsrv.Application) {
models.IsolatedDeviceManager,
models.IsolatedDeviceModelManager,
models.SecurityGroupManager,
models.SecurityGroupCacheManager,
models.SecurityGroupRuleManager,
models.ElasticipManager,
models.NatGatewayManager,
+48 -7
View File
@@ -68,8 +68,7 @@ func (self *GuestCreateTask) OnGuestNetworkReady(ctx context.Context, guest *mod
}
}
func (self *GuestCreateTask) OnDiskPreparedFailed(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
guest := obj.(*models.SGuest)
func (self *GuestCreateTask) OnDiskPreparedFailed(ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject) {
guest.SetStatus(self.UserCred, api.VM_DISK_FAILED, "allocation failed")
db.OpsLog.LogEvent(guest, db.ACT_ALLOCATE_FAIL, data, self.UserCred)
logclient.AddActionLogWithStartable(self, guest, logclient.ACT_ALLOCATE, data, self.UserCred, false)
@@ -82,8 +81,51 @@ func (self *GuestCreateTask) OnDiskPreparedFailed(ctx context.Context, obj db.IS
self.SetStageFailed(ctx, data)
}
func (self *GuestCreateTask) OnDiskPrepared(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
guest := obj.(*models.SGuest)
func (self *GuestCreateTask) OnDiskPrepared(ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject) {
secgroups, err := guest.GetSecgroups()
if err != nil {
self.OnSecurityGroupPreparedFailed(ctx, guest, jsonutils.NewString(errors.Wrapf(err, "GetSecgroups").Error()))
return
}
if len(secgroups) == 0 {
self.OnSecurityGroupPrepared(ctx, guest, nil)
return
}
vpc, err := guest.GetVpc()
if err != nil {
self.OnSecurityGroupPreparedFailed(ctx, guest, jsonutils.NewString(errors.Wrapf(err, "GetVpc").Error()))
return
}
region, err := vpc.GetRegion()
if err != nil {
self.OnSecurityGroupPreparedFailed(ctx, guest, jsonutils.NewString(errors.Wrapf(err, "GetRegion").Error()))
return
}
self.SetStage("OnSecurityGroupPrepared", nil)
err = region.GetDriver().RequestPrepareSecurityGroups(ctx, self.UserCred, guest.GetOwnerId(), secgroups, vpc, func(ids []string) error {
return guest.SaveSecgroups(ctx, self.UserCred, ids)
}, self)
if err != nil {
self.OnSecurityGroupPreparedFailed(ctx, guest, jsonutils.NewString(err.Error()))
return
}
}
func (self *GuestCreateTask) OnSecurityGroupPreparedFailed(ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject) {
guest.SetStatus(self.UserCred, api.VM_SECURITY_GROUP_FAILED, "prepare security group failed")
db.OpsLog.LogEvent(guest, db.ACT_ALLOCATE_FAIL, data, self.UserCred)
logclient.AddActionLogWithStartable(self, guest, logclient.ACT_ALLOCATE, data, self.UserCred, false)
notifyclient.EventNotify(ctx, self.GetUserCred(), notifyclient.SEventNotifyParam{
Obj: guest,
Action: notifyclient.ActionCreate,
IsFail: true,
})
self.SetStageFailed(ctx, data)
}
func (self *GuestCreateTask) OnSecurityGroupPrepared(ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject) {
cdrom, _ := self.Params.GetString("cdrom")
var bootIndex *int8
if self.Params.Contains("cdrom_boot_index") {
@@ -96,12 +138,11 @@ func (self *GuestCreateTask) OnDiskPrepared(ctx context.Context, obj db.IStandal
self.SetStage("OnCdromPrepared", nil)
guest.GetDriver().RequestGuestCreateInsertIso(ctx, cdrom, bootIndex, self, guest)
} else {
self.OnCdromPrepared(ctx, obj, data)
self.OnCdromPrepared(ctx, guest, data)
}
}
func (self *GuestCreateTask) OnCdromPrepared(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
guest := obj.(*models.SGuest)
func (self *GuestCreateTask) OnCdromPrepared(ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject) {
log.Infof("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
log.Infof("DEPLOY GUEST %s", guest.Name)
log.Infof("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
@@ -1,82 +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/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/compute/models"
)
type SecurityGroupCacheTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(SecurityGroupCacheTask{})
}
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) {
vpcId, _ := self.GetParams().GetString("vpc_id")
if len(vpcId) == 0 {
return nil, fmt.Errorf("Missing vpc_id params")
}
vpc, err := models.VpcManager.FetchById(vpcId)
if err != nil {
return nil, errors.Wrap(err, "VpcManager.FetchById")
}
return vpc.(*models.SVpc), nil
}
func (self *SecurityGroupCacheTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
secgroup := obj.(*models.SSecurityGroup)
vpc, err := self.getVpc()
if err != nil {
self.taskFailed(ctx, secgroup, errors.Wrapf(err, "getVpc"))
return
}
region, err := vpc.GetRegion()
if err != nil {
self.taskFailed(ctx, secgroup, errors.Wrapf(err, "GetRegion"))
return
}
self.SetStage("OnCacheSecurityGroupComplete", nil)
err = region.GetDriver().RequestCacheSecurityGroup(ctx, self.UserCred, region, vpc, secgroup, "", self)
if err != nil {
self.taskFailed(ctx, secgroup, errors.Wrapf(err, "RequestCacheSecurityGroup"))
return
}
}
func (self *SecurityGroupCacheTask) OnCacheSecurityGroupComplete(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
self.SetStageComplete(ctx, nil)
}
func (self *SecurityGroupCacheTask) OnCacheSecurityGroupCompleteFailed(ctx context.Context, obj db.IStandaloneModel, err jsonutils.JSONObject) {
self.SetStageFailed(ctx, err)
}
@@ -1,66 +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"
"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"
)
type SecurityGroupCacheDeleteTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(SecurityGroupCacheDeleteTask{})
}
func (self *SecurityGroupCacheDeleteTask) taskFailed(ctx context.Context, cache *models.SSecurityGroupCache, err error) {
cache.SetStatus(self.UserCred, api.SECGROUP_CACHE_STATUS_DELETE_FAILED, err.Error())
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *SecurityGroupCacheDeleteTask) taskComplete(ctx context.Context, cache *models.SSecurityGroupCache) {
cache.RealDelete(ctx, self.UserCred)
self.SetStageComplete(ctx, nil)
}
func (self *SecurityGroupCacheDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
cache := obj.(*models.SSecurityGroupCache)
iSecgroup, err := cache.GetISecurityGroup(ctx)
if err != nil {
if errors.Cause(err) == cloudprovider.ErrNotFound {
self.taskComplete(ctx, cache)
return
}
self.taskFailed(ctx, cache, errors.Wrapf(err, "GetISecurityGroup"))
return
}
err = iSecgroup.Delete()
if err != nil {
self.taskFailed(ctx, cache, errors.Wrapf(err, "iSecgroup.Delete"))
return
}
self.taskComplete(ctx, cache)
}
@@ -1,54 +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"
"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"
)
type SecurityGroupCacheSyncstatusTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(SecurityGroupCacheSyncstatusTask{})
}
func (self *SecurityGroupCacheSyncstatusTask) taskFailed(ctx context.Context, cache *models.SSecurityGroupCache, err error) {
cache.SetStatus(self.UserCred, api.SECGROUP_CACHE_STATUS_UNKNOWN, err.Error())
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *SecurityGroupCacheSyncstatusTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
cache := obj.(*models.SSecurityGroupCache)
iSecgroup, err := cache.GetISecurityGroup(ctx)
if err != nil {
self.taskFailed(ctx, cache, errors.Wrapf(err, "GetISecurityGroup"))
return
}
cache.SyncBaseInfo(ctx, self.GetUserCred(), iSecgroup)
self.SetStageComplete(ctx, nil)
}
@@ -0,0 +1,70 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tasks
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/apis"
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/cloudcommon/notifyclient"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type SecurityGroupCreateTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(SecurityGroupCreateTask{})
}
func (self *SecurityGroupCreateTask) taskFailed(ctx context.Context, secgroup *models.SSecurityGroup, err error) {
secgroup.SetStatus(self.UserCred, apis.STATUS_CREATE_FAILED, "")
logclient.AddActionLogWithContext(ctx, secgroup, logclient.ACT_ALLOCATE, err, self.UserCred, false)
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *SecurityGroupCreateTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
secgroup := obj.(*models.SSecurityGroup)
region, err := secgroup.GetRegion()
if err != nil {
self.taskFailed(ctx, secgroup, errors.Wrapf(err, "GetRegion"))
return
}
rules := api.SSecgroupRuleResourceSet{}
self.GetParams().Unmarshal(&rules)
driver := region.GetDriver()
err = driver.RequestCreateSecurityGroup(ctx, self.GetUserCred(), secgroup, rules)
if err != nil {
self.taskFailed(ctx, secgroup, errors.Wrapf(err, "RequestCreateSecurityGroup"))
return
}
notifyclient.EventNotify(ctx, self.UserCred, notifyclient.SEventNotifyParam{
Obj: secgroup,
Action: notifyclient.ActionCreate,
})
self.SetStageComplete(ctx, nil)
}
+18 -25
View File
@@ -17,11 +17,10 @@ package tasks
import (
"context"
"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/apis"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudcommon/notifyclient"
@@ -38,41 +37,31 @@ func init() {
}
func (self *SecurityGroupDeleteTask) taskFailed(ctx context.Context, secgroup *models.SSecurityGroup, err error) {
secgroup.SetStatus(self.UserCred, api.SECGROUP_STATUS_READY, "")
secgroup.SetStatus(self.UserCred, apis.STATUS_DELETE_FAILED, "")
logclient.AddActionLogWithContext(ctx, secgroup, logclient.ACT_DELOCATE, err, self.UserCred, false)
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *SecurityGroupDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
secgroup := obj.(*models.SSecurityGroup)
caches, err := secgroup.GetSecurityGroupCaches()
region, err := secgroup.GetRegion()
if err != nil {
self.taskFailed(ctx, secgroup, errors.Wrapf(err, "GetSecurityGroupCaches"))
self.taskFailed(ctx, secgroup, errors.Wrapf(err, "GetRegion"))
return
}
isPurge := jsonutils.QueryBoolean(self.Params, "purge", false)
for i := range caches {
if !isPurge {
iSecgroup, err := caches[i].GetISecurityGroup(ctx)
if err != nil {
if errors.Cause(err) == cloudprovider.ErrNotFound {
caches[i].RealDelete(ctx, self.GetUserCred())
continue
}
self.taskFailed(ctx, secgroup, errors.Wrapf(err, "GetISecurityGroup for cache %s(%s)", caches[i].Name, caches[i].Id))
return
}
err = iSecgroup.Delete()
if err != nil {
self.taskFailed(ctx, secgroup, errors.Wrapf(err, "iSecgroup.Delete"))
return
}
}
caches[i].RealDelete(ctx, self.GetUserCred())
driver := region.GetDriver()
self.SetStage("OnSecurityGroupDeleteComplete", nil)
err = driver.RequestDeleteSecurityGroup(ctx, self.GetUserCred(), secgroup, self)
if err != nil {
self.taskFailed(ctx, secgroup, errors.Wrapf(err, "RequestDeleteSecurityGroup"))
return
}
}
func (self *SecurityGroupDeleteTask) OnSecurityGroupDeleteComplete(ctx context.Context, secgroup *models.SSecurityGroup, data jsonutils.JSONObject) {
notifyclient.EventNotify(ctx, self.UserCred, notifyclient.SEventNotifyParam{
Obj: secgroup,
Action: notifyclient.ActionDelete,
@@ -80,3 +69,7 @@ func (self *SecurityGroupDeleteTask) OnInit(ctx context.Context, obj db.IStandal
secgroup.RealDelete(ctx, self.GetUserCred())
self.SetStageComplete(ctx, nil)
}
func (self *SecurityGroupDeleteTask) OnSecurityGroupDeleteCompleteFailed(ctx context.Context, secgroup *models.SSecurityGroup, data jsonutils.JSONObject) {
self.taskFailed(ctx, secgroup, errors.Errorf(data.String()))
}
@@ -0,0 +1,99 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tasks
import (
"context"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/apis"
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 SecurityGroupRemoteUpdateTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(SecurityGroupRemoteUpdateTask{})
}
func (self *SecurityGroupRemoteUpdateTask) taskFailed(ctx context.Context, group *models.SSecurityGroup, err error) {
group.SetStatus(self.UserCred, apis.STATUS_UPDATE_TAGS_FAILED, err.Error())
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *SecurityGroupRemoteUpdateTask) taskComplete(ctx context.Context, group *models.SSecurityGroup) {
group.SetStatus(self.UserCred, api.SECGROUP_STATUS_READY, "")
self.SetStageComplete(ctx, nil)
}
func (self *SecurityGroupRemoteUpdateTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
group := obj.(*models.SSecurityGroup)
provider, err := group.GetCloudprovider()
if err != nil {
self.taskFailed(ctx, group, errors.Wrapf(err, "GetCloudprovider"))
return
}
iGroup, err := group.GetISecurityGroup(ctx)
if err != nil {
self.taskFailed(ctx, group, errors.Wrapf(err, "GetISecurityGroup"))
return
}
oldTags, err := iGroup.GetTags()
if err != nil {
if errors.Cause(err) == cloudprovider.ErrNotSupported || errors.Cause(err) == cloudprovider.ErrNotImplemented {
self.taskComplete(ctx, group)
return
}
self.taskFailed(ctx, group, errors.Wrapf(err, "GetTags"))
return
}
tags, err := group.GetAllUserMetadata()
if err != nil {
self.taskFailed(ctx, group, errors.Wrapf(err, "GetAllUserMetadata"))
return
}
tagsUpdateInfo := cloudprovider.TagsUpdateInfo{OldTags: oldTags, NewTags: tags}
replaceTags := jsonutils.QueryBoolean(self.Params, "replace_tags", false)
err = cloudprovider.SetTags(ctx, iGroup, group.ManagerId, tags, replaceTags)
if err != nil {
if errors.Cause(err) == cloudprovider.ErrNotSupported || errors.Cause(err) == cloudprovider.ErrNotImplemented {
self.taskComplete(ctx, group)
return
}
logclient.AddSimpleActionLog(group, logclient.ACT_UPDATE_TAGS, err, self.UserCred, false)
self.taskFailed(ctx, group, errors.Wrapf(err, "SetTags"))
return
}
logclient.AddSimpleActionLog(group, logclient.ACT_UPDATE_TAGS, tagsUpdateInfo, self.UserCred, true)
// sync back cloud metadata
iGroup.Refresh()
group.SyncWithCloudSecurityGroup(ctx, self.UserCred, iGroup, provider.GetOwnerId(), false)
self.taskComplete(ctx, group)
}
@@ -0,0 +1,115 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tasks
import (
"context"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/secrules"
"yunion.io/x/onecloud/pkg/apis"
"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 SecurityGroupRuleCreateTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(SecurityGroupRuleCreateTask{})
}
func (self *SecurityGroupRuleCreateTask) taskFailed(ctx context.Context, secgroup *models.SSecurityGroup, err error) {
logclient.AddActionLogWithContext(ctx, secgroup, logclient.ACT_CREATE_SECURITY_GROUP_RULE, err, self.UserCred, false)
rule, _ := self.getRule()
if rule != nil {
rule.SetStatus(self.UserCred, apis.STATUS_CREATE_FAILED, "")
logclient.AddActionLogWithContext(ctx, rule, logclient.ACT_ALLOCATE, err, self.UserCred, false)
}
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *SecurityGroupRuleCreateTask) getRule() (*models.SSecurityGroupRule, error) {
ruleId, err := self.GetParams().GetString("rule_id")
if err != nil {
return nil, errors.Wrapf(err, "get rule_id")
}
return models.SecurityGroupRuleManager.FetchRuleById(ruleId)
}
func (self *SecurityGroupRuleCreateTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
secgroup := obj.(*models.SSecurityGroup)
if len(secgroup.ManagerId) == 0 {
self.SetStageComplete(ctx, nil)
return
}
iGroup, err := secgroup.GetISecurityGroup(ctx)
if err != nil {
self.taskFailed(ctx, secgroup, errors.Wrapf(err, "GetISecurityGroup"))
return
}
rule, err := self.getRule()
if err != nil {
self.taskFailed(ctx, secgroup, errors.Wrapf(err, "getRule"))
return
}
opts := &cloudprovider.SecurityGroupRuleCreateOptions{
Desc: rule.Description,
Priority: rule.Priority,
Protocol: rule.Protocol,
Ports: rule.Ports,
Direction: secrules.TSecurityRuleDirection(rule.Direction),
CIDR: rule.CIDR,
Action: secrules.TSecurityRuleAction(rule.Action),
}
iRule, err := iGroup.CreateRule(opts)
if err != nil {
self.taskFailed(ctx, secgroup, errors.Wrapf(err, "CreateRule"))
return
}
_, err = db.Update(rule, func() error {
rule.ExternalId = iRule.GetGlobalId()
rule.Status = apis.STATUS_AVAILABLE
return nil
})
if err != nil {
self.taskFailed(ctx, secgroup, errors.Wrapf(err, "db.Update"))
return
}
iGroup.Refresh()
rules, err := iGroup.GetRules()
if err != nil {
self.taskFailed(ctx, secgroup, errors.Wrapf(err, "db.Update"))
return
}
secgroup.SyncRules(ctx, self.UserCred, rules)
self.SetStageComplete(ctx, nil)
}
@@ -0,0 +1,138 @@
// 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"
"database/sql"
"time"
"yunion.io/x/cloudmux/pkg/apis"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"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 SecurityGroupRuleDeleteTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(SecurityGroupRuleDeleteTask{})
}
func (self *SecurityGroupRuleDeleteTask) taskFailed(ctx context.Context, secgroup *models.SSecurityGroup, err error) {
logclient.AddActionLogWithContext(ctx, secgroup, logclient.ACT_DELETE_SECURITY_GROUP_RULE, err, self.UserCred, false)
rule, _ := self.getRule()
if rule != nil {
rule.SetStatus(self.UserCred, apis.STATUS_CREATE_FAILED, "")
logclient.AddActionLogWithContext(ctx, rule, logclient.ACT_ALLOCATE, err, self.UserCred, false)
}
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *SecurityGroupRuleDeleteTask) getRule() (*models.SSecurityGroupRule, error) {
ruleId, err := self.GetParams().GetString("rule_id")
if err != nil {
return nil, errors.Wrapf(err, "get rule_id")
}
return models.SecurityGroupRuleManager.FetchRuleById(ruleId)
}
func (self *SecurityGroupRuleDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
secgroup := obj.(*models.SSecurityGroup)
if len(secgroup.ManagerId) == 0 {
self.taskComplete(ctx, secgroup, nil)
return
}
rule, err := self.getRule()
if err != nil {
if errors.Cause(err) == sql.ErrNoRows {
self.taskComplete(ctx, secgroup, nil)
return
}
self.taskFailed(ctx, secgroup, errors.Wrapf(err, "getRule"))
return
}
if len(rule.ExternalId) == 0 {
self.taskComplete(ctx, secgroup, nil)
return
}
iGroup, err := secgroup.GetISecurityGroup(ctx)
if err != nil {
self.taskFailed(ctx, secgroup, errors.Wrapf(err, "GetISecurityGroup"))
return
}
rules, err := iGroup.GetRules()
if err != nil {
self.taskFailed(ctx, secgroup, errors.Wrapf(err, "GetRules"))
return
}
for i := range rules {
if rules[i].GetGlobalId() == rule.ExternalId {
err = rules[i].Delete()
if err != nil {
self.taskFailed(ctx, secgroup, errors.Wrapf(err, "Delete"))
return
}
self.taskComplete(ctx, secgroup, iGroup)
return
}
}
self.taskComplete(ctx, secgroup, iGroup)
return
}
func (self *SecurityGroupRuleDeleteTask) taskComplete(ctx context.Context, secgroup *models.SSecurityGroup, iGroup cloudprovider.ICloudSecurityGroup) {
rule, _ := self.getRule()
if rule != nil {
rule.RealDelete(ctx, self.UserCred)
}
// wait rule deleted
if iGroup != nil && rule != nil && len(rule.ExternalId) > 0 {
cloudprovider.Wait(time.Second*5, time.Minute, func() (bool, error) {
iGroup.Refresh()
rules, err := iGroup.GetRules()
if err != nil {
return false, nil
}
for i := range rules {
if rules[i].GetGlobalId() == rule.ExternalId {
return false, nil
}
}
return true, nil
})
rules, err := iGroup.GetRules()
if err == nil {
secgroup.SyncRules(ctx, self.UserCred, rules)
}
}
self.SetStageComplete(ctx, nil)
}
@@ -0,0 +1,119 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tasks
import (
"context"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/secrules"
"yunion.io/x/onecloud/pkg/apis"
"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 SecurityGroupRuleUpdateTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(SecurityGroupRuleUpdateTask{})
}
func (self *SecurityGroupRuleUpdateTask) taskFailed(ctx context.Context, secgroup *models.SSecurityGroup, err error) {
logclient.AddActionLogWithContext(ctx, secgroup, logclient.ACT_UPDATE, err, self.UserCred, false)
rule, _ := self.getRule()
if rule != nil {
rule.SetStatus(self.UserCred, apis.STATUS_UNKNOWN, "")
logclient.AddActionLogWithContext(ctx, rule, logclient.ACT_UPDATE, err, self.UserCred, false)
}
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *SecurityGroupRuleUpdateTask) getRule() (*models.SSecurityGroupRule, error) {
ruleId, err := self.GetParams().GetString("rule_id")
if err != nil {
return nil, errors.Wrapf(err, "get rule_id")
}
return models.SecurityGroupRuleManager.FetchRuleById(ruleId)
}
func (self *SecurityGroupRuleUpdateTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
secgroup := obj.(*models.SSecurityGroup)
if len(secgroup.ManagerId) == 0 {
self.taskComplete(ctx, secgroup, nil)
return
}
rule, err := self.getRule()
if err != nil {
self.taskFailed(ctx, secgroup, errors.Wrapf(err, "getRule"))
return
}
if len(rule.ExternalId) == 0 {
self.taskFailed(ctx, secgroup, errors.Wrapf(err, "empty external id"))
return
}
iGroup, err := secgroup.GetISecurityGroup(ctx)
if err != nil {
self.taskFailed(ctx, secgroup, errors.Wrapf(err, "GetISecurityGroup"))
return
}
rules, err := iGroup.GetRules()
if err != nil {
self.taskFailed(ctx, secgroup, errors.Wrapf(err, "GetRules"))
return
}
for i := range rules {
if rules[i].GetGlobalId() == rule.ExternalId {
opts := &cloudprovider.SecurityGroupRuleUpdateOptions{
CIDR: rule.CIDR,
Action: secrules.TSecurityRuleAction(rule.Action),
Desc: rule.Description,
Ports: rule.Ports,
Protocol: rule.Protocol,
Priority: rule.Priority,
}
err = rules[i].Update(opts)
if err != nil {
self.taskFailed(ctx, secgroup, errors.Wrapf(err, "Update"))
return
}
self.taskComplete(ctx, secgroup, iGroup)
return
}
}
self.taskComplete(ctx, secgroup, iGroup)
return
}
func (self *SecurityGroupRuleUpdateTask) taskComplete(ctx context.Context, secgroup *models.SSecurityGroup, iGroup cloudprovider.ICloudSecurityGroup) {
rule, _ := self.getRule()
if rule != nil {
rule.SetStatus(self.UserCred, apis.STATUS_AVAILABLE, "")
}
self.SetStageComplete(ctx, nil)
}
@@ -0,0 +1,80 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tasks
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/apis"
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 SecurityGroupSyncTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(SecurityGroupSyncTask{})
}
func (self *SecurityGroupSyncTask) taskFailed(ctx context.Context, secgroup *models.SSecurityGroup, err error) {
secgroup.SetStatus(self.UserCred, apis.STATUS_UNKNOWN, "")
logclient.AddActionLogWithContext(ctx, secgroup, logclient.ACT_SYNC_STATUS, err, self.UserCred, false)
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *SecurityGroupSyncTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
secgroup := obj.(*models.SSecurityGroup)
iGroup, err := secgroup.GetISecurityGroup(ctx)
if err != nil {
self.taskFailed(ctx, secgroup, errors.Wrapf(err, "GetISecurityGroup"))
return
}
rules, err := iGroup.GetRules()
if err != nil {
self.taskFailed(ctx, secgroup, errors.Wrapf(err, "GetRules"))
return
}
provider, err := secgroup.GetCloudprovider()
if err != nil {
self.taskFailed(ctx, secgroup, errors.Wrapf(err, "GetCloudprovider"))
return
}
err = secgroup.SyncWithCloudSecurityGroup(ctx, self.GetUserCred(), iGroup, provider.GetOwnerId(), false)
if err != nil {
self.taskFailed(ctx, secgroup, errors.Wrapf(err, "GetRules"))
return
}
result := secgroup.SyncRules(ctx, self.GetUserCred(), rules)
if result.IsError() {
self.taskFailed(ctx, secgroup, errors.Wrapf(result.AllError(), "SyncRules"))
return
}
secgroup.SetStatus(self.GetUserCred(), api.SECGROUP_STATUS_READY, "")
self.SetStageComplete(ctx, nil)
}
+1 -1
View File
@@ -96,7 +96,7 @@ func (self *SCloudpodsClient) auth() error {
client := mcclient.NewClient(self.authURL, 0, self.debug, true, "", "")
client.SetHttpTransportProxyFunc(self.cpcfg.ProxyFunc)
ts, _ := client.GetClient().Transport.(*http.Transport)
client.SetTransport(cloudprovider.GetCheckTransport(ts, func(req *http.Request) (func(resp *http.Response), error) {
client.SetTransport(cloudprovider.GetCheckTransport(ts, func(req *http.Request) (func(resp *http.Response) error, error) {
if self.cpcfg.ReadOnly {
if req.Method == "GET" || req.Method == "HEAD" {
return nil, nil
-7
View File
@@ -194,13 +194,6 @@ func (self *SInstance) GetProjectId() string {
return self.TenantId
}
func (self *SInstance) AssignSecurityGroup(id string) error {
input := api.GuestAssignSecgroupInput{}
input.SecgroupId = id
_, err := self.host.zone.region.perform(&modules.Servers, self.Id, "assign-secgroup", input)
return err
}
func (self *SInstance) SetSecurityGroups(ids []string) error {
if self.Hypervisor == api.HYPERVISOR_ESXI {
return nil
+19 -49
View File
@@ -15,19 +15,15 @@
package cloudpods
import (
"fmt"
"strings"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/cloudmux/pkg/multicloud"
"yunion.io/x/pkg/util/secrules"
api "yunion.io/x/onecloud/pkg/apis/compute"
modules "yunion.io/x/onecloud/pkg/mcclient/modules/compute"
)
type SSecurityGroup struct {
multicloud.SResourceBase
multicloud.SSecurityGroup
CloudpodsTags
region *SRegion
@@ -58,19 +54,16 @@ func (self *SSecurityGroup) GetProjectId() string {
return self.TenantId
}
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 {
rule := cloudprovider.SecurityRule{}
rule.Action = secrules.TSecurityRuleAction(r.Action)
rule.Priority = int(r.Priority)
rule.Protocol = r.Protocol
rule.Description = r.Description
rule.Direction = secrules.TSecurityRuleDirection(r.Direction)
rule.ParseCIDR(r.CIDR)
rule.ParsePorts(r.Ports)
ret = append(ret, rule)
func (self *SSecurityGroup) GetRules() ([]cloudprovider.ISecurityGroupRule, error) {
ret := []cloudprovider.ISecurityGroupRule{}
rules := []SecurityGroupRule{}
err := self.region.list(&modules.SecGroupRules, map[string]interface{}{"scope": "system", "secgroup_id": self.Id}, &rules)
if err != nil {
return nil, err
}
for i := range rules {
rules[i].region = self.region
ret = append(ret, &rules[i])
}
return ret, nil
}
@@ -102,27 +95,17 @@ func (self *SRegion) DeleteSecRule(id string) error {
return self.cli.delete(&modules.SecGroupRules, id)
}
func (self *SRegion) CreateSecRule(secId string, rule cloudprovider.SecurityRule) error {
func (self *SRegion) CreateSecRule(secId string, opts *cloudprovider.SecurityGroupRuleCreateOptions) error {
input := api.SSecgroupRuleCreateInput{}
input.SecgroupId = secId
input.Priority = &rule.Priority
input.Action = string(rule.Action)
input.Protocol = rule.Protocol
input.Direction = string(rule.Direction)
input.Description = rule.Description
if rule.IPNet != nil {
input.CIDR = rule.IPNet.String()
}
input.Priority = &opts.Priority
input.Action = string(opts.Action)
input.Protocol = string(opts.Protocol)
input.Direction = string(opts.Direction)
input.Description = opts.Desc
input.CIDR = opts.CIDR
if len(rule.Ports) > 0 {
ports := []string{}
for _, port := range rule.Ports {
ports = append(ports, fmt.Sprintf("%d", port))
}
input.Ports = strings.Join(ports, ",")
} else if rule.PortStart > 0 && rule.PortEnd > 0 {
input.Ports = fmt.Sprintf("%d-%d", rule.PortStart, rule.PortEnd)
}
input.Ports = opts.Ports
ret := struct{}{}
return self.create(&modules.SecGroupRules, input, &ret)
}
@@ -145,14 +128,9 @@ 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": append(opts.InRules, outRules...),
}
if len(opts.ProjectId) > 0 {
params["project_id"] = opts.ProjectId
@@ -181,11 +159,3 @@ func (self *SRegion) GetISecurityGroupById(secgroupId string) (cloudprovider.ICl
}
return secgroup, nil
}
func (self *SRegion) GetISecurityGroupByName(opts *cloudprovider.SecurityGroupFilterOptions) (cloudprovider.ICloudSecurityGroup, error) {
secgroup, err := self.GetSecurityGroup(opts.Name)
if err != nil {
return nil, err
}
return secgroup, nil
}
+72
View File
@@ -0,0 +1,72 @@
// 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 cloudpods
import (
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/cloudmux/pkg/multicloud"
"yunion.io/x/pkg/util/secrules"
api "yunion.io/x/onecloud/pkg/apis/compute"
modules "yunion.io/x/onecloud/pkg/mcclient/modules/compute"
)
type SecurityGroupRule struct {
multicloud.SResourceBase
CloudpodsTags
region *SRegion
api.SecgroupRuleDetails
}
func (self *SecurityGroupRule) GetGlobalId() string {
return self.Id
}
func (self *SecurityGroupRule) GetAction() secrules.TSecurityRuleAction {
return secrules.TSecurityRuleAction(self.Action)
}
func (self *SecurityGroupRule) GetDescription() string {
return self.Description
}
func (self *SecurityGroupRule) GetDirection() secrules.TSecurityRuleDirection {
return secrules.TSecurityRuleDirection(self.Direction)
}
func (self *SecurityGroupRule) GetCIDRs() []string {
return []string{self.CIDR}
}
func (self *SecurityGroupRule) GetProtocol() string {
return self.Protocol
}
func (self *SecurityGroupRule) GetPorts() string {
return self.Ports
}
func (self *SecurityGroupRule) GetPriority() int {
return int(self.Priority)
}
func (self *SecurityGroupRule) Delete() error {
return self.region.cli.delete(&modules.SecGroupRules, self.Id)
}
func (self *SecurityGroupRule) Update(opts *cloudprovider.SecurityGroupRuleUpdateOptions) error {
return cloudprovider.ErrNotImplemented
}
@@ -1,34 +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 compute
import (
"yunion.io/x/onecloud/pkg/mcclient/modulebase"
"yunion.io/x/onecloud/pkg/mcclient/modules"
)
var (
SecGroupCaches modulebase.ResourceManager
)
func init() {
SecGroupCaches = modules.NewComputeManager("secgroupcache", "secgroupcaches",
[]string{"ID", "Name", "Descritpion", "Status",
"Vpc_Id", "Vpc", "Region", "Account",
"Secgroup_Id"},
[]string{""})
modules.RegisterCompute(&SecGroupCaches)
}
+15
View File
@@ -36,6 +36,7 @@ type SecgroupListOptions struct {
Direction string `help:"Filter secgroup by ports" choices:"all|in|out"`
DBInstance string `help:"Filter secgroups bound to specified rds" json:"dbinstance"`
Cloudregion string `help:"Filter secgroups by region"`
VpcId string
Cloudaccount string `help:"Filter secgroups by account"`
WithCache bool `help:"Whether to bring cache information"`
}
@@ -46,6 +47,8 @@ func (opts *SecgroupListOptions) Params() (jsonutils.JSONObject, error) {
type SecgroupCreateOptions struct {
BaseCreateOptions
VpcId string
Tags []string
Rules []string `help:"security rule to create"`
}
@@ -64,6 +67,18 @@ func (opts *SecgroupCreateOptions) Params() (jsonutils.JSONObject, error) {
if len(rules) > 0 {
params.Add(jsonutils.Marshal(rules), "rules")
}
params.Remove("tags")
tags := map[string]string{}
for _, tag := range opts.Tags {
info := strings.Split(tag, "=")
if len(info) != 2 {
return nil, fmt.Errorf("invalid tag %s, tag should like key=value", tag)
}
tags["user:"+info[0]] = info[1]
}
if len(tags) > 0 {
params.Set("__meta__", jsonutils.Marshal(tags))
}
return params, nil
}
+3
View File
@@ -269,4 +269,7 @@ const (
ACT_REPORT_COLLECT_DATA = "report_collect_data"
ACT_REPORT_SEND = "report_send"
ACT_REPORT_TEMPLATE = "report_template"
ACT_CREATE_SECURITY_GROUP_RULE = "create_security_group_rule"
ACT_DELETE_SECURITY_GROUP_RULE = "delete_security_group_rule"
)
+1 -1
View File
@@ -57,7 +57,7 @@ func (el *SecurityGroup) securityGroupRules(basePriority int64) []*SecurityGroup
rs := make([]*SecurityGroupRule, 0, len(el.SecurityGroupRules))
for _, r := range el.SecurityGroupRules {
r = r.Copy()
r.Priority += basePriority
r.Priority += int(basePriority)
rs = append(rs, r)
}
return rs
+1 -1
View File
@@ -167,7 +167,7 @@ func ruleToAcl(lport string, rule *agentmodels.SecurityGroupRule) (*ovn_nb.ACL,
match = strings.Join(matches, " && ")
acl := &ovn_nb.ACL{
Priority: rule.Priority,
Priority: int64(rule.Priority),
Direction: dir,
Match: match,
Action: action,
+1 -1
View File
@@ -1438,7 +1438,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.20231024052127-016e22c73e9f
# yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20231025082024-ea24588e7245
## explicit; go 1.18
yunion.io/x/cloudmux/pkg/apis
yunion.io/x/cloudmux/pkg/apis/billing
+1
View File
@@ -30,6 +30,7 @@ const (
CLOUD_CAPABILITY_PROJECT = "project"
CLOUD_CAPABILITY_COMPUTE = "compute"
CLOUD_CAPABILITY_NETWORK = "network"
CLOUD_CAPABILITY_SECURITY_GROUP = "security_group"
CLOUD_CAPABILITY_EIP = "eip"
CLOUD_CAPABILITY_LOADBALANCER = "loadbalancer"
CLOUD_CAPABILITY_OBJECTSTORE = "objectstore"
-4
View File
@@ -99,10 +99,6 @@ func (region *SFakeOnPremiseRegion) GetISecurityGroupById(id string) (ICloudSecu
return nil, ErrNotSupported
}
func (region *SFakeOnPremiseRegion) GetISecurityGroupByName(opts *SecurityGroupFilterOptions) (ICloudSecurityGroup, error) {
return nil, ErrNotSupported
}
func (region *SFakeOnPremiseRegion) CreateISecurityGroup(conf *SecurityGroupCreateInput) (ICloudSecurityGroup, error) {
return nil, ErrNotSupported
}
+1 -1
View File
@@ -151,8 +151,8 @@ type SManagedVMCreateConfig struct {
Description string
SysDisk SDiskInfo
DataDisks []SDiskInfo
KeypairName string
PublicKey string
ExternalSecgroupId string
ExternalSecgroupIds []string
Account string
Password string
+24 -6
View File
@@ -24,6 +24,7 @@ import (
"yunion.io/x/pkg/util/billing"
"yunion.io/x/pkg/util/rbacscope"
"yunion.io/x/pkg/util/samlutils"
"yunion.io/x/pkg/util/secrules"
)
type ICloudResource interface {
@@ -83,9 +84,10 @@ type ICloudRegion interface {
GetIVMById(id string) (ICloudVM, error)
GetIDiskById(id string) (ICloudDisk, error)
// 仅返回region级别的安全组, vpc下面的安全组需要在ICloudVpc底下返回
GetISecurityGroups() ([]ICloudSecurityGroup, error)
GetISecurityGroupById(secgroupId string) (ICloudSecurityGroup, error)
GetISecurityGroupByName(opts *SecurityGroupFilterOptions) (ICloudSecurityGroup, error)
CreateISecurityGroup(conf *SecurityGroupCreateInput) (ICloudSecurityGroup, error)
CreateISecurityGroup(opts *SecurityGroupCreateInput) (ICloudSecurityGroup, error)
CreateIVpc(opts *VpcCreateOptions) (ICloudVpc, error)
CreateInternetGateway() (ICloudInternetGateway, error)
@@ -357,13 +359,10 @@ type ICloudVM interface {
GetInstanceType() string
GetSecurityGroupIds() ([]string, error)
AssignSecurityGroup(secgroupId string) error
SetSecurityGroups(secgroupIds []string) error
GetHypervisor() string
// GetSecurityGroup() ICloudSecurityGroup
StartVM(ctx context.Context) error
StopVM(ctx context.Context, opts *ServerStopOptions) error
DeleteVM(ctx context.Context) error
@@ -469,13 +468,29 @@ type ICloudSecurityGroup interface {
GetDescription() string
// 返回的优先级字段(priority)要求数字越大优先级越高, 若有默认不可修改的allow规则依然需要返回
GetRules() ([]SecurityRule, error)
GetRules() ([]ISecurityGroupRule, error)
GetVpcId() string
CreateRule(opts *SecurityGroupRuleCreateOptions) (ISecurityGroupRule, error)
GetReferences() ([]SecurityGroupReference, error)
Delete() error
}
type ISecurityGroupRule interface {
GetGlobalId() string
GetDirection() secrules.TSecurityRuleDirection
GetPriority() int
GetAction() secrules.TSecurityRuleAction
GetProtocol() string
GetPorts() string
GetDescription() string
GetCIDRs() []string
Update(opts *SecurityGroupRuleUpdateOptions) error
Delete() error
}
type ICloudRouteTable interface {
ICloudResource
@@ -563,6 +578,9 @@ type ICloudSnapshotPolicy interface {
type ICloudGlobalVpc interface {
ICloudResource
GetISecurityGroups() ([]ICloudSecurityGroup, error)
CreateISecurityGroup(opts *SecurityGroupCreateInput) (ICloudSecurityGroup, error)
Delete() error
}
+27 -81
View File
@@ -15,9 +15,9 @@
package cloudprovider
import (
"sort"
"fmt"
"strings"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/secrules"
)
@@ -26,97 +26,43 @@ type SecurityGroupReference struct {
Name string
}
type SecurityGroupFilterOptions struct {
VpcId string
Name string
ProjectId string
}
type SecurityGroupCreateInput struct {
Name string
Desc string
VpcId string
ProjectId string
// 安全组刚创建, 但是未设置安全组规则时
OnCreated func(id string)
// 默认优先级从低到高排序, 端口会被分离, 不会出现[10,20]这种规则
InRules SecurityRuleSet
// 同上
OutRules SecurityRuleSet
Tags map[string]string
}
type SecurityRule struct {
secrules.SecurityRule
Name string
Id string
type SecurityGroupRuleCreateOptions struct {
Desc string
Priority int
Protocol string
Ports string
Direction secrules.TSecurityRuleDirection
CIDR string
Action secrules.TSecurityRuleAction
}
type SecurityRuleSet []SecurityRule
func (srs SecurityRuleSet) Len() int {
return len(srs)
type SecurityGroupRuleUpdateOptions struct {
CIDR string
Action secrules.TSecurityRuleAction
Desc string
Ports string
Protocol string
Priority int
}
func (srs SecurityRuleSet) Swap(i, j int) {
srs[i], srs[j] = srs[j], srs[i]
}
func (srs SecurityRuleSet) Less(i, j int) bool {
if srs[i].Priority > srs[j].Priority {
return true
} else if srs[i].Priority == srs[j].Priority {
return srs[i].String() < srs[j].String()
func (self *SecurityGroupRuleCreateOptions) String() string {
ret := fmt.Sprintf("%s_%s_%s", self.Direction, self.Action, self.Protocol)
if len(self.CIDR) > 0 {
ret += "_" + self.CIDR
}
return false
}
func (srs SecurityRuleSet) String() string {
sort.Sort(srs)
rules := secrules.SecurityRuleSet{}
for i := range srs {
rules = append(rules, srs[i].SecurityRule)
if len(self.Ports) > 0 {
ret += "_" + self.Ports
}
return rules.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 GetSecurityGroupRules(sec ICloudSecurityGroup) (SecurityRuleSet, secrules.SecurityRuleSet, secrules.SecurityRuleSet, error) {
rules, err := sec.GetRules()
if err != nil {
return nil, nil, nil, errors.Wrapf(err, "GetRules")
}
for i := range rules {
if err := rules[i].ValidateRule(); err != nil && errors.Cause(err) != secrules.ErrInvalidPriority {
return nil, nil, nil, errors.Wrapf(err, "ValidateRule")
}
}
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
ret = strings.ReplaceAll(ret, ".", "_")
ret = strings.ReplaceAll(ret, ",", "_")
return ret
}
+7 -4
View File
@@ -17,12 +17,12 @@ package cloudprovider
import "net/http"
type transport struct {
check func(*http.Request) (func(resp *http.Response), error)
check func(*http.Request) (func(resp *http.Response) error, error)
ts *http.Transport
}
func (self *transport) RoundTrip(req *http.Request) (*http.Response, error) {
var respCheck func(resp *http.Response) = nil
var respCheck func(resp *http.Response) error = nil
var err error
if self.check != nil {
respCheck, err = self.check(req)
@@ -35,12 +35,15 @@ func (self *transport) RoundTrip(req *http.Request) (*http.Response, error) {
return nil, err
}
if respCheck != nil {
respCheck(resp)
err = respCheck(resp)
if err != nil {
return nil, err
}
}
return resp, nil
}
func GetCheckTransport(ts *http.Transport, check func(*http.Request) (func(resp *http.Response), error)) http.RoundTripper {
func GetCheckTransport(ts *http.Transport, check func(*http.Request) (func(resp *http.Response) error, error)) http.RoundTripper {
ret := &transport{ts: ts, check: check}
return ret
}
+9 -6
View File
@@ -427,23 +427,23 @@ func (self *SAliyunClient) fetchVpcEndpoints() error {
func (self *SAliyunClient) _getSdkClient(regionId string) (*sdk.Client, error) {
transport := httputils.GetAdaptiveTransport(true)
transport.Proxy = self.cpcfg.ProxyFunc
ts := cloudprovider.GetCheckTransport(transport, func(req *http.Request) (func(resp *http.Response), error) {
ts := cloudprovider.GetCheckTransport(transport, func(req *http.Request) (func(resp *http.Response) error, error) {
params, err := url.ParseQuery(req.URL.RawQuery)
if err != nil {
return nil, errors.Wrapf(err, "ParseQuery(%s)", req.URL.RawQuery)
}
service := strings.Split(req.URL.Host, ".")[0]
action := params.Get("Action")
respCheck := func(resp *http.Response) {
respCheck := func(resp *http.Response) error {
if self.cpcfg.UpdatePermission != nil && resp.StatusCode >= 400 && resp.ContentLength > 0 {
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return
return nil
}
resp.Body = ioutil.NopCloser(bytes.NewBuffer(body))
obj, err := jsonutils.Parse(body)
if err != nil {
return
return nil
}
ret := struct{ Code string }{}
obj.Unmarshal(&ret)
@@ -455,6 +455,7 @@ func (self *SAliyunClient) _getSdkClient(regionId string) (*sdk.Client, error) {
self.cpcfg.UpdatePermission(service, action)
}
}
return nil
}
for _, prefix := range []string{"Get", "List", "Describe", "Query"} {
if strings.HasPrefix(action, prefix) {
@@ -652,12 +653,13 @@ func (client *SAliyunClient) getOssClientByEndpoint(endpoint string) (*oss.Clien
// oss use no timeout client so as to send/download large files
httpClient := client.cpcfg.AdaptiveTimeoutHttpClient()
transport, _ := httpClient.Transport.(*http.Transport)
httpClient.Transport = cloudprovider.GetCheckTransport(transport, func(req *http.Request) (func(resp *http.Response), error) {
httpClient.Transport = cloudprovider.GetCheckTransport(transport, func(req *http.Request) (func(resp *http.Response) error, error) {
path, method := req.URL.Path, req.Method
respCheck := func(resp *http.Response) {
respCheck := func(resp *http.Response) error {
if client.cpcfg.UpdatePermission != nil && resp.StatusCode == 403 {
client.cpcfg.UpdatePermission("oss", fmt.Sprintf("%s %s", method, path))
}
return nil
}
if client.cpcfg.ReadOnly {
if req.Method == "GET" || req.Method == "HEAD" {
@@ -959,6 +961,7 @@ func (region *SAliyunClient) GetCapabilities() []string {
cloudprovider.CLOUD_CAPABILITY_PROJECT,
cloudprovider.CLOUD_CAPABILITY_COMPUTE,
cloudprovider.CLOUD_CAPABILITY_NETWORK,
cloudprovider.CLOUD_CAPABILITY_SECURITY_GROUP,
cloudprovider.CLOUD_CAPABILITY_EIP,
cloudprovider.CLOUD_CAPABILITY_LOADBALANCER,
cloudprovider.CLOUD_CAPABILITY_OBJECTSTORE,
+4 -4
View File
@@ -174,7 +174,7 @@ func (self *SHost) GetInstanceById(instanceId string) (*SInstance, error) {
func (self *SHost) CreateVM(desc *cloudprovider.SManagedVMCreateConfig) (cloudprovider.ICloudVM, error) {
vmId, err := self._createVM(desc.Name, desc.Hostname, desc.ExternalImageId, desc.SysDisk, desc.Cpu, desc.MemoryMB,
desc.InstanceType, desc.ExternalNetworkId, desc.IpAddr, desc.Description, desc.Password,
desc.DataDisks, desc.PublicKey, desc.ExternalSecgroupId, desc.UserData, desc.BillingCycle,
desc.DataDisks, desc.PublicKey, desc.ExternalSecgroupIds, desc.UserData, desc.BillingCycle,
desc.ProjectId, desc.OsType, desc.Tags, desc.SPublicIpInfo)
if err != nil {
return nil, err
@@ -189,7 +189,7 @@ func (self *SHost) CreateVM(desc *cloudprovider.SManagedVMCreateConfig) (cloudpr
func (self *SHost) _createVM(name, hostname string, imgId string,
sysDisk cloudprovider.SDiskInfo, cpu int, memMB int, instanceType string,
vswitchId string, ipAddr string, desc string, passwd string,
dataDisks []cloudprovider.SDiskInfo, publicKey string, secgroupId string,
dataDisks []cloudprovider.SDiskInfo, publicKey string, secgroupIds []string,
userData string, bc *billing.SBillingCycle, projectId, osType string,
tags map[string]string, publicIp cloudprovider.SPublicIpInfo,
) (string, error) {
@@ -247,7 +247,7 @@ func (self *SHost) _createVM(name, hostname string, imgId string,
if len(instanceType) > 0 {
log.Debugf("Try instancetype : %s", instanceType)
vmId, err := self.zone.region.CreateInstance(name, hostname, imgId, instanceType, secgroupId, self.zone.ZoneId, desc, passwd, disks, vswitchId, ipAddr, keypair, userData, bc, projectId, osType, tags, publicIp)
vmId, err := self.zone.region.CreateInstance(name, hostname, imgId, instanceType, secgroupIds, self.zone.ZoneId, desc, passwd, disks, vswitchId, ipAddr, keypair, userData, bc, projectId, osType, tags, publicIp)
if err != nil {
log.Errorf("Failed for %s: %s", instanceType, err)
return "", fmt.Errorf("Failed to create specification %s.%s", instanceType, err.Error())
@@ -267,7 +267,7 @@ func (self *SHost) _createVM(name, hostname string, imgId string,
for _, instType := range instanceTypes {
instanceTypeId := instType.InstanceTypeId
log.Debugf("Try instancetype : %s", instanceTypeId)
vmId, err = self.zone.region.CreateInstance(name, hostname, imgId, instanceTypeId, secgroupId, self.zone.ZoneId, desc, passwd, disks, vswitchId, ipAddr, keypair, userData, bc, projectId, osType, tags, publicIp)
vmId, err = self.zone.region.CreateInstance(name, hostname, imgId, instanceTypeId, secgroupIds, self.zone.ZoneId, desc, passwd, disks, vswitchId, ipAddr, keypair, userData, bc, projectId, osType, tags, publicIp)
if err != nil {
log.Errorf("Failed for %s: %s", instanceTypeId, err)
} else {
+4 -6
View File
@@ -561,7 +561,7 @@ func (self *SRegion) GetInstance(instanceId string) (*SInstance, error) {
return &instances[0], nil
}
func (self *SRegion) CreateInstance(name, hostname string, imageId string, instanceType string, securityGroupId string,
func (self *SRegion) CreateInstance(name, hostname string, imageId string, instanceType string, securityGroupIds []string,
zoneId string, desc string, passwd string, disks []SDisk, vSwitchId string, ipAddr string,
keypair string, userData string, bc *billing.SBillingCycle, projectId, osType string,
tags map[string]string, publicIp cloudprovider.SPublicIpInfo,
@@ -570,7 +570,9 @@ func (self *SRegion) CreateInstance(name, hostname string, imageId string, insta
params["RegionId"] = self.RegionId
params["ImageId"] = imageId
params["InstanceType"] = instanceType
params["SecurityGroupId"] = securityGroupId
for _, id := range securityGroupIds {
params["SecurityGroupId"] = id
}
params["ZoneId"] = zoneId
params["InstanceName"] = name
if len(hostname) > 0 {
@@ -983,10 +985,6 @@ func (self *SInstance) GetIEIP() (cloudprovider.ICloudEIP, error) {
return nil, nil
}
func (self *SInstance) AssignSecurityGroup(secgroupId string) error {
return self.host.zone.region.AssignSecurityGroup(secgroupId, self.InstanceId)
}
func (self *SInstance) SetSecurityGroups(secgroupIds []string) error {
return self.host.zone.region.SetSecurityGroups(secgroupIds, self.InstanceId)
}
+3 -33
View File
@@ -863,48 +863,18 @@ func (self *SRegion) GetIEipById(eipId string) (cloudprovider.ICloudEIP, error)
}
func (region *SRegion) GetISecurityGroupById(secgroupId string) (cloudprovider.ICloudSecurityGroup, error) {
secgroup, err := region.GetSecurityGroupDetails(secgroupId)
secgroup, err := region.GetSecurityGroup(secgroupId)
if err != nil {
return nil, err
}
return secgroup, nil
}
func (region *SRegion) GetISecurityGroupByName(opts *cloudprovider.SecurityGroupFilterOptions) (cloudprovider.ICloudSecurityGroup, error) {
secgroups, total, err := region.GetSecurityGroups(opts.VpcId, opts.Name, []string{}, 0, 0)
func (region *SRegion) CreateISecurityGroup(opts *cloudprovider.SecurityGroupCreateInput) (cloudprovider.ICloudSecurityGroup, error) {
externalId, err := region.CreateSecurityGroup(opts)
if err != nil {
return nil, err
}
if total == 0 {
return nil, cloudprovider.ErrNotFound
}
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, 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)
}
+160
View File
@@ -0,0 +1,160 @@
// 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 aliyun
import (
"fmt"
"strings"
"time"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/pkg/util/secrules"
"yunion.io/x/pkg/utils"
)
type SPermission struct {
region *SRegion
CreateTime time.Time
Description string
DestCidrIp string
DestGroupId string
DestGroupName string
DestGroupOwnerAccount string
Direction string
IpProtocol string
NicType SecurityGroupPermissionNicType
Policy string
PortRange string
Priority int
SourceCidrIp string
SourceGroupId string
SourceGroupName string
SourceGroupOwnerAccount string
SecurityGroupRuleId string
SecurityGroupId string
}
func (self *SPermission) GetGlobalId() string {
return self.SecurityGroupRuleId
}
func (self *SPermission) GetAction() secrules.TSecurityRuleAction {
if self.Policy == "Drop" {
return secrules.SecurityRuleDeny
}
return secrules.SecurityRuleAllow
}
func (self *SPermission) GetDescription() string {
return self.Description
}
func (self *SPermission) GetDirection() secrules.TSecurityRuleDirection {
if self.Direction == "ingress" {
return secrules.DIR_IN
}
return secrules.DIR_OUT
}
func (self *SPermission) GetCIDRs() []string {
ret := []string{}
if len(self.SourceCidrIp) > 0 {
ret = append(ret, self.SourceCidrIp)
}
if len(self.SourceGroupId) > 0 {
ret = append(ret, self.SourceGroupId)
}
if len(self.DestGroupId) > 0 {
ret = append(ret, self.SourceGroupId)
}
if len(self.DestCidrIp) > 0 {
ret = append(ret, self.DestCidrIp)
}
return ret
}
func (self *SPermission) GetProtocol() string {
if strings.ToLower(self.IpProtocol) == "all" {
return secrules.PROTO_ANY
}
return strings.ToLower(self.IpProtocol)
}
func (self *SPermission) GetPorts() string {
info := strings.Split(self.PortRange, "/")
if len(info) != 2 {
return ""
}
if info[0] == info[1] {
if info[0] == "-1" {
return ""
}
return info[0]
}
return fmt.Sprintf("%s-%s", info[0], info[1])
}
func (self *SPermission) GetPriority() int {
return self.Priority
}
func (self *SPermission) Delete() error {
return self.region.DeleteSecurityGroupRule(self.SecurityGroupId, self.GetDirection(), self.SecurityGroupRuleId)
}
func (self *SPermission) Update(opts *cloudprovider.SecurityGroupRuleUpdateOptions) error {
return cloudprovider.ErrNotImplemented
}
func (self *SRegion) GetSecurityGroupRules(id string) ([]SPermission, error) {
params := map[string]string{
"SecurityGroupId": id,
"RegionId": self.RegionId,
}
resp, err := self.ecsRequest("DescribeSecurityGroupAttribute", params)
if err != nil {
return nil, err
}
ret := struct {
Permissions struct {
Permission []SPermission
}
SecurityGroupId string
}{}
err = resp.Unmarshal(&ret)
if err != nil {
return nil, err
}
for i := range ret.Permissions.Permission {
ret.Permissions.Permission[i].SecurityGroupId = ret.SecurityGroupId
}
return ret.Permissions.Permission, nil
}
func (self *SRegion) DeleteSecurityGroupRule(groupId string, direction secrules.TSecurityRuleDirection, ruleId string) error {
action := "RevokeSecurityGroup"
if direction == secrules.DIR_OUT {
action = "RevokeSecurityGroupEgress"
}
params := map[string]string{
"RegionId": self.RegionId,
"ClientToken": utils.GenRequestId(20),
"SecurityGroupId": groupId,
"SecurityGroupRuleId.1": ruleId,
}
_, err := self.ecsRequest(action, params)
return err
}
+124 -291
View File
@@ -20,11 +20,11 @@ import (
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/secrules"
"yunion.io/x/pkg/utils"
api "yunion.io/x/cloudmux/pkg/apis/compute"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/cloudmux/pkg/multicloud"
)
@@ -39,25 +39,6 @@ const (
InternetNicType SecurityGroupPermissionNicType = "internet"
)
type SPermission struct {
CreateTime time.Time
Description string
DestCidrIp string
DestGroupId string
DestGroupName string
DestGroupOwnerAccount string
Direction string
IpProtocol string
NicType SecurityGroupPermissionNicType
Policy string
PortRange string
Priority int
SourceCidrIp string
SourceGroupId string
SourceGroupName string
SourceGroupOwnerAccount string
}
type SPermissions struct {
Permission []SPermission
}
@@ -75,6 +56,7 @@ type SSecurityGroup struct {
InnerAccessPolicy string
Permissions SPermissions
RegionId string
ResourceGroupId string
}
func (self *SSecurityGroup) GetVpcId() string {
@@ -93,29 +75,21 @@ func (self *SSecurityGroup) GetDescription() string {
return self.Description
}
func (self *SSecurityGroup) GetRules() ([]cloudprovider.SecurityRule, error) {
rules := make([]cloudprovider.SecurityRule, 0)
secgrp, err := self.region.GetSecurityGroupDetails(self.SecurityGroupId)
func (self *SSecurityGroup) SetTags(tags map[string]string, replace bool) error {
return self.region.SetResourceTags(ALIYUN_SERVICE_ECS, "securitygroup", self.SecurityGroupId, tags, replace)
}
func (self *SSecurityGroup) GetRules() ([]cloudprovider.ISecurityGroupRule, error) {
ret := make([]cloudprovider.ISecurityGroupRule, 0)
rules, err := self.region.GetSecurityGroupRules(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)
continue
}
rules = append(rules, rule)
for i := range rules {
rules[i].region = self.region
ret = append(ret, &rules[i])
}
return rules, nil
return ret, nil
}
func (self *SSecurityGroup) GetName() string {
@@ -126,15 +100,11 @@ func (self *SSecurityGroup) GetName() string {
}
func (self *SSecurityGroup) GetStatus() string {
return ""
}
func (self *SSecurityGroup) IsEmulated() bool {
return false
return api.SECGROUP_STATUS_READY
}
func (self *SSecurityGroup) Refresh() error {
group, err := self.region.GetSecurityGroupDetails(self.SecurityGroupId)
group, err := self.region.GetSecurityGroup(self.SecurityGroupId)
if err != nil {
return err
}
@@ -187,14 +157,10 @@ func (self *SRegion) DescribeSecurityGroupReferences(id string) ([]SecurityGroup
return ret, errors.Wrapf(err, "resp.Unmarshal")
}
func (self *SRegion) GetSecurityGroups(vpcId, name string, securityGroupIds []string, offset int, limit int) ([]SSecurityGroup, int, error) {
if limit > 50 || limit <= 0 {
limit = 50
}
func (self *SRegion) GetSecurityGroups(vpcId, name string, securityGroupIds []string) ([]SSecurityGroup, error) {
params := make(map[string]string)
params["RegionId"] = self.RegionId
params["PageSize"] = fmt.Sprintf("%d", limit)
params["PageNumber"] = fmt.Sprintf("%d", (offset/limit)+1)
params["MaxResults"] = "100"
if len(vpcId) > 0 {
params["VpcId"] = vpcId
}
@@ -202,61 +168,65 @@ func (self *SRegion) GetSecurityGroups(vpcId, name string, securityGroupIds []st
params["SecurityGroupName"] = name
}
if securityGroupIds != nil && len(securityGroupIds) > 0 {
if len(securityGroupIds) > 0 {
params["SecurityGroupIds"] = jsonutils.Marshal(securityGroupIds).String()
}
body, err := self.ecsRequest("DescribeSecurityGroups", params)
if err != nil {
log.Errorf("GetSecurityGroups fail %s", err)
return nil, 0, err
ret := []SSecurityGroup{}
for {
part := struct {
SecurityGroups struct {
SecurityGroup []SSecurityGroup
}
NextToken string
}{}
resp, err := self.ecsRequest("DescribeSecurityGroups", params)
if err != nil {
return nil, err
}
err = resp.Unmarshal(&part)
if err != nil {
return nil, err
}
ret = append(ret, part.SecurityGroups.SecurityGroup...)
if len(part.NextToken) == 0 || len(part.SecurityGroups.SecurityGroup) == 0 {
break
}
params["NextToken"] = part.NextToken
}
secgrps := make([]SSecurityGroup, 0)
err = body.Unmarshal(&secgrps, "SecurityGroups", "SecurityGroup")
if err != nil {
log.Errorf("Unmarshal security groups fail %s", err)
return nil, 0, err
}
total, _ := body.Int("TotalCount")
return secgrps, int(total), nil
return ret, nil
}
func (self *SRegion) GetSecurityGroupDetails(secGroupId string) (*SSecurityGroup, error) {
params := make(map[string]string)
params["RegionId"] = self.RegionId
params["SecurityGroupId"] = secGroupId
body, err := self.ecsRequest("DescribeSecurityGroupAttribute", params)
func (self *SRegion) GetSecurityGroup(id string) (*SSecurityGroup, error) {
groups, err := self.GetSecurityGroups("", "", []string{id})
if err != nil {
return nil, errors.Wrap(err, "DescribeSecurityGroupAttribute")
return nil, err
}
secgrp := SSecurityGroup{region: self}
err = body.Unmarshal(&secgrp)
if err != nil {
return nil, errors.Wrap(err, "body.Unmarshal")
for i := range groups {
if groups[i].SecurityGroupId == id {
groups[i].region = self
return &groups[i], nil
}
}
return &secgrp, nil
return nil, errors.Wrapf(cloudprovider.ErrNotFound, id)
}
func (self *SRegion) CreateSecurityGroup(vpcId string, name string, desc, resourceGroupId string) (string, error) {
func (self *SRegion) CreateSecurityGroup(opts *cloudprovider.SecurityGroupCreateInput) (string, error) {
params := make(map[string]string)
if len(vpcId) > 0 {
params["VpcId"] = vpcId
}
if len(resourceGroupId) > 0 {
params["ResourceGroupId"] = resourceGroupId
}
if len(name) > 0 {
params["SecurityGroupName"] = name
}
if len(desc) > 0 {
params["Description"] = desc
}
params["VpcId"] = opts.VpcId
params["SecurityGroupName"] = opts.Name
params["Description"] = opts.Desc
params["ClientToken"] = utils.GenRequestId(20)
if len(opts.ProjectId) > 0 {
params["ResourceGroupId"] = opts.ProjectId
}
tagIdx := 1
for k, v := range opts.Tags {
params[fmt.Sprintf("Tag.%d.Key", tagIdx)] = k
params[fmt.Sprintf("Tag.%d.Value", tagIdx)] = v
tagIdx += 1
}
body, err := self.ecsRequest("CreateSecurityGroup", params)
if err != nil {
@@ -265,52 +235,6 @@ func (self *SRegion) CreateSecurityGroup(vpcId string, name string, desc, resour
return body.GetString("SecurityGroupId")
}
func (self *SRegion) modifySecurityGroupRule(secGrpId string, rule *secrules.SecurityRule) error {
params := make(map[string]string)
params["RegionId"] = self.RegionId
params["SecurityGroupId"] = secGrpId
params["NicType"] = string(IntranetNicType)
params["Description"] = rule.Description
params["PortRange"] = fmt.Sprintf("%d/%d", rule.PortStart, rule.PortEnd)
protocol := rule.Protocol
if len(rule.Protocol) == 0 || rule.Protocol == secrules.PROTO_ANY {
protocol = "all"
}
params["IpProtocol"] = protocol
if rule.PortStart < 1 && rule.PortEnd < 1 {
if protocol == "udp" || protocol == "tcp" {
params["PortRange"] = "1/65535"
} else {
params["PortRange"] = "-1/-1"
}
}
if rule.Action == secrules.SecurityRuleAllow {
params["Policy"] = "accept"
} else {
params["Policy"] = "drop"
}
params["Priority"] = fmt.Sprintf("%d", rule.Priority)
if rule.Direction == secrules.SecurityRuleIngress {
if rule.IPNet != nil {
params["SourceCidrIp"] = rule.IPNet.String()
} else {
params["SourceCidrIp"] = "0.0.0.0/0"
}
_, err := self.ecsRequest("ModifySecurityGroupRule", params)
return err
} else { // rule.Direction == secrules.SecurityRuleEgress {
//阿里云不支持出方向API接口调用
return nil
// if rule.IPNet != nil {
// params["DestCidrIp"] = rule.IPNet.String()
// } else {
// params["DestCidrIp"] = "0.0.0.0/0"
// }
// _, err := self.ecsRequest("ModifySecurityGroupRule", params)
// return err
}
}
func (self *SRegion) modifySecurityGroup(secGrpId string, name string, desc string) error {
params := make(map[string]string)
params["RegionId"] = self.RegionId
@@ -323,162 +247,48 @@ func (self *SRegion) modifySecurityGroup(secGrpId string, name string, desc stri
return err
}
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 %s", rule.String())
func (self *SRegion) CreateSecurityGroupRule(secGrpId string, opts *cloudprovider.SecurityGroupRuleCreateOptions) error {
params := make(map[string]string)
params["RegionId"] = self.RegionId
params["SecurityGroupId"] = secGrpId
params["Permissions.1.NicType"] = string(IntranetNicType)
params["Permissions.1.Description"] = opts.Desc
params["Permissions.1.PortRange"] = "-1/-1"
params["Permissions.1.IpProtocol"] = opts.Protocol
if opts.Protocol == secrules.PROTO_ANY {
params["Permissions.1.IpProtocol"] = "all"
}
if opts.Protocol == secrules.PROTO_TCP || opts.Protocol == secrules.PROTO_UDP {
if len(opts.Ports) == 0 {
params["Permissions.1.PortRange"] = "1/65535"
} else {
params["Permissions.1.PortRange"] = fmt.Sprintf("%s/%s", opts.Ports, opts.Ports)
if strings.Contains(opts.Ports, "-") {
params["Permissions.1.PortRange"] = strings.ReplaceAll(opts.Ports, "-", "/")
}
}
return nil
}
return self.addSecurityGroupRule(secGrpId, rule)
}
params["Permissions.1.Policy"] = "drop"
if opts.Action == secrules.SecurityRuleAllow {
params["Permissions.1.Policy"] = "accept"
}
func (self *SRegion) addSecurityGroupRule(secGrpId string, rule cloudprovider.SecurityRule) error {
params := make(map[string]string)
params["RegionId"] = self.RegionId
params["SecurityGroupId"] = secGrpId
params["NicType"] = string(IntranetNicType)
params["Description"] = rule.Description
params["PortRange"] = fmt.Sprintf("%d/%d", rule.PortStart, rule.PortEnd)
protocol := rule.Protocol
if len(rule.Protocol) == 0 || rule.Protocol == secrules.PROTO_ANY {
protocol = "all"
}
params["IpProtocol"] = protocol
if rule.PortStart < 1 && rule.PortEnd < 1 {
if protocol == "udp" || protocol == "tcp" {
params["PortRange"] = "1/65535"
} else {
params["PortRange"] = "-1/-1"
action := "AuthorizeSecurityGroup"
params["Permissions.1.Priority"] = fmt.Sprintf("%d", opts.Priority)
if opts.Direction == secrules.SecurityRuleIngress {
params["Permissions.1.SourceCidrIp"] = "0.0.0.0/0"
if len(opts.CIDR) > 0 {
params["Permissions.1.SourceCidrIp"] = opts.CIDR
}
}
if rule.Action == secrules.SecurityRuleAllow {
params["Policy"] = "accept"
} else {
params["Policy"] = "drop"
}
// 忽略地址为0.0.0.0/32这样的阿里云规则
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 rule.IPNet != nil {
params["SourceCidrIp"] = rule.IPNet.String()
} else {
params["SourceCidrIp"] = "0.0.0.0/0"
params["Permissions.1.DestCidrIp"] = "0.0.0.0/0"
if len(opts.CIDR) > 0 {
params["Permissions.1.DestCidrIp"] = opts.CIDR
}
_, err := self.ecsRequest("AuthorizeSecurityGroup", params)
return err
} else { // rule.Direction == secrules.SecurityRuleEgress {
if rule.IPNet != nil {
params["DestCidrIp"] = rule.IPNet.String()
} else {
params["DestCidrIp"] = "0.0.0.0/0"
}
_, err := self.ecsRequest("AuthorizeSecurityGroupEgress", params)
return err
action = "AuthorizeSecurityGroupEgress"
}
}
func (self *SRegion) DelSecurityGroupRule(secGrpId string, rule cloudprovider.SecurityRule) error {
params := make(map[string]string)
params["RegionId"] = self.RegionId
params["SecurityGroupId"] = secGrpId
params["NicType"] = string(IntranetNicType)
params["PortRange"] = fmt.Sprintf("%d/%d", rule.PortStart, rule.PortEnd)
protocol := rule.Protocol
if len(rule.Protocol) == 0 || rule.Protocol == secrules.PROTO_ANY {
protocol = "all"
}
params["IpProtocol"] = protocol
if rule.PortStart < 1 && rule.PortEnd < 1 {
if protocol == "udp" || protocol == "tcp" {
params["PortRange"] = "1/65535"
} else {
params["PortRange"] = "-1/-1"
}
}
if rule.Action == secrules.SecurityRuleAllow {
params["Policy"] = "accept"
} else {
params["Policy"] = "drop"
}
params["Priority"] = fmt.Sprintf("%d", rule.Priority)
if rule.Direction == secrules.SecurityRuleIngress {
if rule.IPNet != nil {
params["SourceCidrIp"] = rule.IPNet.String()
} else {
params["SourceCidrIp"] = "0.0.0.0/0"
}
_, err := self.ecsRequest("RevokeSecurityGroup", params)
return err
} else { // rule.Direction == secrules.SecurityRuleEgress {
if rule.IPNet != nil {
params["DestCidrIp"] = rule.IPNet.String()
} else {
params["DestCidrIp"] = "0.0.0.0/0"
}
_, err := self.ecsRequest("RevokeSecurityGroupEgress", params)
return err
}
}
func (self *SPermission) toRule() (cloudprovider.SecurityRule, error) {
rule := cloudprovider.SecurityRule{
SecurityRule: secrules.SecurityRule{
Action: secrules.SecurityRuleDeny,
Direction: secrules.DIR_IN,
Priority: 101 - self.Priority,
Description: self.Description,
PortStart: -1,
PortEnd: -1,
},
}
if strings.ToLower(self.Policy) == "accept" {
rule.Action = secrules.SecurityRuleAllow
}
cidr := self.SourceCidrIp
if self.Direction == "egress" {
rule.Direction = secrules.DIR_OUT
cidr = self.DestCidrIp
}
rule.ParseCIDR(cidr)
switch strings.ToLower(self.IpProtocol) {
case "tcp", "udp", "icmp":
rule.Protocol = strings.ToLower(self.IpProtocol)
case "all":
rule.Protocol = secrules.PROTO_ANY
default:
return rule, fmt.Errorf("unsupported protocal %s", self.IpProtocol)
}
port, ports := "", strings.Split(self.PortRange, "/")
if ports[0] == ports[1] {
if ports[0] != "-1" {
port = ports[0]
}
} else if ports[0] != "1" && ports[1] != "65535" {
port = fmt.Sprintf("%s-%s", ports[0], ports[1])
}
err := rule.ParsePorts(port)
if err != nil {
return rule, errors.Wrapf(err, "ParsePorts(%s)", port)
}
return rule, nil
}
func (self *SRegion) AssignSecurityGroup(secgroupId, instanceId string) error {
return self.SetSecurityGroups([]string{secgroupId}, instanceId)
_, err := self.ecsRequest(action, params)
return err
}
func (self *SRegion) SetSecurityGroups(secgroupIds []string, instanceId string) error {
@@ -515,8 +325,7 @@ func (self *SRegion) DeleteSecurityGroup(secGrpId string) error {
_, err := self.ecsRequest("DeleteSecurityGroup", params)
if err != nil {
log.Errorf("Delete security group fail %s", err)
return err
return errors.Wrapf(err, "DeleteSecurityGroup")
}
return nil
}
@@ -525,6 +334,30 @@ func (self *SSecurityGroup) Delete() error {
return self.region.DeleteSecurityGroup(self.SecurityGroupId)
}
func (self *SSecurityGroup) GetProjectId() string {
return ""
func (self *SSecurityGroup) CreateRule(opts *cloudprovider.SecurityGroupRuleCreateOptions) (cloudprovider.ISecurityGroupRule, error) {
err := self.region.CreateSecurityGroupRule(self.SecurityGroupId, opts)
if err != nil {
return nil, err
}
rules, err := self.region.GetSecurityGroupRules(self.SecurityGroupId)
if err != nil {
return nil, errors.Wrapf(err, "GetSecurityGroupDetails")
}
for i := range rules {
rule := rules[i]
if rule.Priority == opts.Priority &&
strings.Join(rule.GetCIDRs(), ",") == opts.CIDR &&
rule.GetAction() == opts.Action &&
rule.GetProtocol() == opts.Protocol &&
rule.GetPorts() == opts.Ports &&
rule.GetDirection() == opts.Direction {
rule.region = self.region
return &rule, nil
}
}
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "after created")
}
func (self *SSecurityGroup) GetProjectId() string {
return self.ResourceGroupId
}
+14 -36
View File
@@ -19,7 +19,6 @@ import (
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/cloudmux/pkg/cloudprovider"
@@ -49,7 +48,6 @@ type SVpc struct {
iwires []cloudprovider.ICloudWire
secgroups []cloudprovider.ICloudSecurityGroup
routeTables []cloudprovider.ICloudRouteTable
CidrBlock string
@@ -171,34 +169,17 @@ func (self *SVpc) GetIWireById(wireId string) (cloudprovider.ICloudWire, error)
return nil, cloudprovider.ErrNotFound
}
func (self *SVpc) fetchSecurityGroups() error {
secgroups := make([]SSecurityGroup, 0)
for {
parts, total, err := self.region.GetSecurityGroups(self.VpcId, "", []string{}, len(secgroups), 50)
if err != nil {
return err
}
secgroups = append(secgroups, parts...)
if len(secgroups) >= total {
break
}
}
self.secgroups = make([]cloudprovider.ICloudSecurityGroup, len(secgroups))
for i := 0; i < len(secgroups); i++ {
secgroups[i].region = self.region
self.secgroups[i] = &secgroups[i]
}
return nil
}
func (self *SVpc) GetISecurityGroups() ([]cloudprovider.ICloudSecurityGroup, error) {
if self.secgroups == nil {
err := self.fetchSecurityGroups()
if err != nil {
return nil, err
}
groups, err := self.region.GetSecurityGroups(self.VpcId, "", nil)
if err != nil {
return nil, err
}
return self.secgroups, nil
ret := []cloudprovider.ICloudSecurityGroup{}
for i := range groups {
groups[i].region = self.region
ret = append(ret, &groups[i])
}
return ret, nil
}
func (self *SVpc) fetchRouteTables() error {
@@ -245,17 +226,14 @@ func (self *SVpc) GetIRouteTableById(routeTableId string) (cloudprovider.ICloudR
}
func (self *SVpc) Delete() error {
err := self.fetchSecurityGroups()
secgroups, err := self.region.GetSecurityGroups(self.VpcId, "", nil)
if err != nil {
log.Errorf("fetchSecurityGroup for VPC delete fail %s", err)
return err
return errors.Wrapf(err, "GetSecurityGroups")
}
for i := 0; i < len(self.secgroups); i += 1 {
secgroup := self.secgroups[i].(*SSecurityGroup)
err := self.region.DeleteSecurityGroup(secgroup.SecurityGroupId)
for i := 0; i < len(secgroups); i += 1 {
err := self.region.DeleteSecurityGroup(secgroups[i].SecurityGroupId)
if err != nil {
log.Errorf("deleteSecurityGroup for VPC delete fail %s", err)
return err
return errors.Wrapf(err, "DeleteSecurityGroup %s", secgroups[i].SecurityGroupId)
}
}
return self.region.DeleteVpc(self.VpcId)
+7 -5
View File
@@ -256,23 +256,23 @@ func (self *SApsaraClient) getDefaultClient(regionId string) (*sdk.Client, error
regionId,
&sdk.Config{
HttpTransport: transport,
Transport: cloudprovider.GetCheckTransport(transport, func(req *http.Request) (func(resp *http.Response), error) {
Transport: cloudprovider.GetCheckTransport(transport, func(req *http.Request) (func(resp *http.Response) error, error) {
params, err := url.ParseQuery(req.URL.RawQuery)
if err != nil {
return nil, errors.Wrapf(err, "ParseQuery(%s)", req.URL.RawQuery)
}
action := params.Get("OpenApiAction")
service := strings.ToLower(params.Get("Product"))
respCheck := func(resp *http.Response) {
respCheck := func(resp *http.Response) error {
if self.cpcfg.UpdatePermission != nil {
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return
return nil
}
resp.Body = ioutil.NopCloser(bytes.NewBuffer(body))
obj, err := jsonutils.Parse(body)
if err != nil {
return
return nil
}
ret := struct {
AsapiErrorCode string `json:"asapiErrorCode"`
@@ -286,6 +286,7 @@ func (self *SApsaraClient) getDefaultClient(regionId string) (*sdk.Client, error
self.cpcfg.UpdatePermission(service, action)
}
}
return nil
}
if self.cpcfg.ReadOnly {
for _, prefix := range []string{"Get", "List", "Describe"} {
@@ -405,7 +406,7 @@ func (client *SApsaraClient) getOssClient(endpoint string) (*oss.Client, error)
// oss use no timeout client so as to send/download large files
httpClient := client.cpcfg.AdaptiveTimeoutHttpClient()
transport, _ := httpClient.Transport.(*http.Transport)
httpClient.Transport = cloudprovider.GetCheckTransport(transport, func(req *http.Request) (func(resp *http.Response), error) {
httpClient.Transport = cloudprovider.GetCheckTransport(transport, func(req *http.Request) (func(resp *http.Response) error, error) {
if client.cpcfg.ReadOnly {
if req.Method == "GET" || req.Method == "HEAD" {
return nil, nil
@@ -519,6 +520,7 @@ func (region *SApsaraClient) GetCapabilities() []string {
cloudprovider.CLOUD_CAPABILITY_PROJECT,
cloudprovider.CLOUD_CAPABILITY_COMPUTE,
cloudprovider.CLOUD_CAPABILITY_NETWORK,
cloudprovider.CLOUD_CAPABILITY_SECURITY_GROUP,
cloudprovider.CLOUD_CAPABILITY_EIP,
cloudprovider.CLOUD_CAPABILITY_LOADBALANCER,
cloudprovider.CLOUD_CAPABILITY_OBJECTSTORE,
+4 -4
View File
@@ -174,7 +174,7 @@ func (self *SHost) GetInstanceById(instanceId string) (*SInstance, error) {
func (self *SHost) CreateVM(desc *cloudprovider.SManagedVMCreateConfig) (cloudprovider.ICloudVM, error) {
vmId, err := self._createVM(desc.Name, desc.Hostname, desc.ExternalImageId, desc.SysDisk, desc.Cpu, desc.MemoryMB,
desc.InstanceType, desc.ExternalNetworkId, desc.IpAddr, desc.Description, desc.Password,
desc.DataDisks, desc.PublicKey, desc.ExternalSecgroupId, desc.UserData, desc.BillingCycle,
desc.DataDisks, desc.PublicKey, desc.ExternalSecgroupIds, desc.UserData, desc.BillingCycle,
desc.ProjectId, desc.OsType, desc.Tags)
if err != nil {
return nil, err
@@ -190,7 +190,7 @@ func (self *SHost) CreateVM(desc *cloudprovider.SManagedVMCreateConfig) (cloudpr
func (self *SHost) _createVM(name, hostname string, imgId string,
sysDisk cloudprovider.SDiskInfo, cpu int, memMB int, instanceType string,
vswitchId string, ipAddr string, desc string, passwd string,
dataDisks []cloudprovider.SDiskInfo, publicKey string, secgroupId string,
dataDisks []cloudprovider.SDiskInfo, publicKey string, secgroupIds []string,
userData string, bc *billing.SBillingCycle, projectId, osType string,
tags map[string]string,
) (string, error) {
@@ -248,7 +248,7 @@ func (self *SHost) _createVM(name, hostname string, imgId string,
if len(instanceType) > 0 {
log.Debugf("Try instancetype : %s", instanceType)
vmId, err := self.zone.region.CreateInstance(name, hostname, imgId, instanceType, secgroupId, self.zone.ZoneId, desc, passwd, disks, vswitchId, ipAddr, keypair, userData, bc, projectId, osType, tags)
vmId, err := self.zone.region.CreateInstance(name, hostname, imgId, instanceType, secgroupIds, self.zone.ZoneId, desc, passwd, disks, vswitchId, ipAddr, keypair, userData, bc, projectId, osType, tags)
if err != nil {
log.Errorf("Failed for %s: %s", instanceType, err)
return "", fmt.Errorf("Failed to create specification %s.%s", instanceType, err.Error())
@@ -268,7 +268,7 @@ func (self *SHost) _createVM(name, hostname string, imgId string,
for _, instType := range instanceTypes {
instanceTypeId := instType.InstanceTypeId
log.Debugf("Try instancetype : %s", instanceTypeId)
vmId, err = self.zone.region.CreateInstance(name, hostname, imgId, instanceTypeId, secgroupId, self.zone.ZoneId, desc, passwd, disks, vswitchId, ipAddr, keypair, userData, bc, projectId, osType, tags)
vmId, err = self.zone.region.CreateInstance(name, hostname, imgId, instanceTypeId, secgroupIds, self.zone.ZoneId, desc, passwd, disks, vswitchId, ipAddr, keypair, userData, bc, projectId, osType, tags)
if err != nil {
log.Errorf("Failed for %s: %s", instanceTypeId, err)
} else {
+4 -6
View File
@@ -511,7 +511,7 @@ func (self *SRegion) GetInstance(instanceId string) (*SInstance, error) {
return &instances[0], nil
}
func (self *SRegion) CreateInstance(name, hostname string, imageId string, instanceType string, securityGroupId string,
func (self *SRegion) CreateInstance(name, hostname string, imageId string, instanceType string, securityGroupIds []string,
zoneId string, desc string, passwd string, disks []SDisk, vSwitchId string, ipAddr string,
keypair string, userData string, bc *billing.SBillingCycle, projectId, osType string,
tags map[string]string,
@@ -520,7 +520,9 @@ func (self *SRegion) CreateInstance(name, hostname string, imageId string, insta
params["RegionId"] = self.RegionId
params["ImageId"] = imageId
params["InstanceType"] = instanceType
params["SecurityGroupId"] = securityGroupId
for _, id := range securityGroupIds {
params["SecurityGroupId"] = id
}
params["ZoneId"] = zoneId
params["InstanceName"] = name
if len(hostname) > 0 {
@@ -911,10 +913,6 @@ func (self *SInstance) GetIEIP() (cloudprovider.ICloudEIP, error) {
return nil, nil
}
func (self *SInstance) AssignSecurityGroup(secgroupId string) error {
return self.host.zone.region.AssignSecurityGroup(secgroupId, self.InstanceId)
}
func (self *SInstance) SetSecurityGroups(secgroupIds []string) error {
return self.host.zone.region.SetSecurityGroups(secgroupIds, self.InstanceId)
}
+4 -37
View File
@@ -734,52 +734,19 @@ func (self *SRegion) GetIEipById(eipId string) (cloudprovider.ICloudEIP, error)
}
func (region *SRegion) GetISecurityGroupById(secgroupId string) (cloudprovider.ICloudSecurityGroup, error) {
secgroup, err := region.GetSecurityGroupDetails(secgroupId)
secgroup, err := region.GetSecurityGroup(secgroupId)
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
secgroup.region = region
return secgroup, nil
}
func (region *SRegion) GetISecurityGroupByName(opts *cloudprovider.SecurityGroupFilterOptions) (cloudprovider.ICloudSecurityGroup, error) {
secgroups, total, err := region.GetSecurityGroups(opts.VpcId, opts.Name, []string{}, 0, 0)
func (region *SRegion) CreateISecurityGroup(opts *cloudprovider.SecurityGroupCreateInput) (cloudprovider.ICloudSecurityGroup, error) {
externalId, err := region.CreateSecurityGroup(opts.VpcId, opts.Name, opts.Desc, opts.ProjectId)
if err != nil {
return nil, err
}
if total == 0 {
return nil, cloudprovider.ErrNotFound
}
if total > 1 {
return nil, cloudprovider.ErrDuplicateId
}
return &secgroups[0], nil
}
func (region *SRegion) CreateISecurityGroup(conf *cloudprovider.SecurityGroupCreateInput) (cloudprovider.ICloudSecurityGroup, error) {
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)
}
+136
View File
@@ -0,0 +1,136 @@
// 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 apsara
import (
"fmt"
"strings"
"time"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/pkg/util/secrules"
"yunion.io/x/pkg/utils"
)
type SPermission struct {
region *SRegion
CreateTime time.Time
Description string
DestCidrIp string
DestGroupId string
DestGroupName string
DestGroupOwnerAccount string
Direction string
IpProtocol string
NicType SecurityGroupPermissionNicType
Policy string
PortRange string
Priority int
SourceCidrIp string
SourceGroupId string
SourceGroupName string
SourceGroupOwnerAccount string
SecurityGroupRuleId string
SecurityGroupId string
}
func (self *SPermission) GetGlobalId() string {
return self.SecurityGroupRuleId
}
func (self *SPermission) GetAction() secrules.TSecurityRuleAction {
if self.Policy == "Drop" {
return secrules.SecurityRuleDeny
}
return secrules.SecurityRuleAllow
}
func (self *SPermission) GetDescription() string {
return self.Description
}
func (self *SPermission) GetDirection() secrules.TSecurityRuleDirection {
if self.Direction == "ingress" {
return secrules.DIR_IN
}
return secrules.DIR_OUT
}
func (self *SPermission) GetCIDRs() []string {
ret := []string{}
if len(self.SourceCidrIp) > 0 {
ret = append(ret, self.SourceCidrIp)
}
if len(self.SourceGroupId) > 0 {
ret = append(ret, self.SourceGroupId)
}
if len(self.DestGroupId) > 0 {
ret = append(ret, self.SourceGroupId)
}
if len(self.DestCidrIp) > 0 {
ret = append(ret, self.DestCidrIp)
}
return ret
}
func (self *SPermission) GetProtocol() string {
if strings.ToLower(self.IpProtocol) == "all" {
return secrules.PROTO_ANY
}
return strings.ToLower(self.IpProtocol)
}
func (self *SPermission) GetPorts() string {
info := strings.Split(self.PortRange, "/")
if len(info) != 2 {
return ""
}
if info[0] == info[1] {
if info[0] == "-1" {
return ""
}
return info[0]
}
return fmt.Sprintf("%s-%s", info[0], info[1])
}
func (self *SPermission) GetPriority() int {
return self.Priority
}
func (self *SRegion) DeleteSecurityGroupRule(groupId string, direction secrules.TSecurityRuleDirection, ruleId string) error {
action := "RevokeSecurityGroup"
if direction == secrules.DIR_OUT {
action = "RevokeSecurityGroupEgress"
}
params := map[string]string{
"RegionId": self.RegionId,
"ClientToken": utils.GenRequestId(20),
"SecurityGroupId": groupId,
"SecurityGroupRuleId.1": ruleId,
}
_, err := self.ecsRequest(action, params)
return err
}
func (self *SPermission) Delete() error {
return self.region.DeleteSecurityGroupRule(self.SecurityGroupId, self.GetDirection(), self.SecurityGroupRuleId)
}
func (self *SPermission) Update(opts *cloudprovider.SecurityGroupRuleUpdateOptions) error {
return cloudprovider.ErrNotImplemented
}
+44 -94
View File
@@ -16,7 +16,6 @@ package apsara
import (
"fmt"
"strings"
"time"
"yunion.io/x/jsonutils"
@@ -39,25 +38,6 @@ const (
InternetNicType SecurityGroupPermissionNicType = "internet"
)
type SPermission struct {
CreateTime time.Time
Description string
DestCidrIp string
DestGroupId string
DestGroupName string
DestGroupOwnerAccount string
Direction string
IpProtocol string
NicType SecurityGroupPermissionNicType
Policy string
PortRange string
Priority int
SourceCidrIp string
SourceGroupId string
SourceGroupName string
SourceGroupOwnerAccount string
}
type SPermissions struct {
Permission []SPermission
}
@@ -75,7 +55,7 @@ type SSecurityGroup struct {
multicloud.SSecurityGroup
ApsaraTags
vpc *SVpc
region *SRegion
CreationTime time.Time
Description string
SecurityGroupId string
@@ -117,21 +97,17 @@ func (self *SSecurityGroup) GetCreatedAt() time.Time {
return self.CreationTime
}
func (self *SSecurityGroup) GetRules() ([]cloudprovider.SecurityRule, error) {
rules := make([]cloudprovider.SecurityRule, 0)
secgrp, err := self.vpc.region.GetSecurityGroupDetails(self.SecurityGroupId)
func (self *SSecurityGroup) GetRules() ([]cloudprovider.ISecurityGroupRule, error) {
ret := make([]cloudprovider.ISecurityGroupRule, 0)
rules, err := self.region.GetSecurityGroupRules(self.SecurityGroupId)
if err != nil {
return nil, err
}
for _, permission := range secgrp.Permissions.Permission {
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)
continue
}
rules = append(rules, rule)
for i := range rules {
rules[i].region = self.region
ret = append(ret, &rules[i])
}
return rules, nil
return ret, nil
}
func (self *SSecurityGroup) GetName() string {
@@ -150,13 +126,27 @@ func (self *SSecurityGroup) IsEmulated() bool {
}
func (self *SSecurityGroup) Refresh() error {
group, err := self.vpc.region.GetSecurityGroupDetails(self.SecurityGroupId)
group, err := self.region.GetSecurityGroup(self.SecurityGroupId)
if err != nil {
return err
}
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
}
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 *SRegion) GetSecurityGroups(vpcId, name string, securityGroupIds []string, offset int, limit int) ([]SSecurityGroup, int, error) {
if limit > 50 || limit <= 0 {
limit = 50
@@ -192,22 +182,29 @@ func (self *SRegion) GetSecurityGroups(vpcId, name string, securityGroupIds []st
return secgrps, int(total), nil
}
func (self *SRegion) GetSecurityGroupDetails(secGroupId string) (*SSecurityGroup, error) {
params := make(map[string]string)
params["RegionId"] = self.RegionId
params["SecurityGroupId"] = secGroupId
body, err := self.ecsRequest("DescribeSecurityGroupAttribute", params)
if err != nil {
return nil, errors.Wrap(err, "DescribeSecurityGroupAttribute")
func (self *SRegion) GetSecurityGroupRules(id string) ([]SPermission, error) {
params := map[string]string{
"SecurityGroupId": id,
"RegionId": self.RegionId,
}
secgrp := SSecurityGroup{}
err = body.Unmarshal(&secgrp)
resp, err := self.ecsRequest("DescribeSecurityGroupAttribute", params)
if err != nil {
return nil, errors.Wrap(err, "body.Unmarshal")
return nil, err
}
return &secgrp, nil
ret := struct {
Permissions struct {
Permission []SPermission
}
SecurityGroupId string
}{}
err = resp.Unmarshal(&ret)
if err != nil {
return nil, err
}
for i := range ret.Permissions.Permission {
ret.Permissions.Permission[i].SecurityGroupId = ret.SecurityGroupId
}
return ret.Permissions.Permission, nil
}
func (self *SRegion) CreateSecurityGroup(vpcId string, name string, desc, projectId string) (string, error) {
@@ -400,53 +397,6 @@ func (self *SRegion) DelSecurityGroupRule(secGrpId string, rule secrules.Securit
}
}
func (self *SPermission) toRule() (cloudprovider.SecurityRule, error) {
rule := cloudprovider.SecurityRule{
SecurityRule: secrules.SecurityRule{
Action: secrules.SecurityRuleDeny,
Direction: secrules.DIR_IN,
Priority: self.Priority,
Description: self.Description,
PortStart: -1,
PortEnd: -1,
},
}
if strings.ToLower(self.Policy) == "accept" {
rule.Action = secrules.SecurityRuleAllow
}
cidr := self.SourceCidrIp
if self.Direction == "egress" {
rule.Direction = secrules.DIR_OUT
cidr = self.DestCidrIp
}
rule.ParseCIDR(cidr)
switch strings.ToLower(self.IpProtocol) {
case "tcp", "udp", "icmp":
rule.Protocol = strings.ToLower(self.IpProtocol)
case "all":
rule.Protocol = secrules.PROTO_ANY
default:
return rule, fmt.Errorf("unsupported protocal %s", self.IpProtocol)
}
port, ports := "", strings.Split(self.PortRange, "/")
if ports[0] == ports[1] {
if ports[0] != "-1" {
port = ports[0]
}
} else if ports[0] != "1" && ports[1] != "65535" {
port = fmt.Sprintf("%s-%s", ports[0], ports[1])
}
err := rule.ParsePorts(port)
if err != nil {
return rule, errors.Wrapf(err, "ParsePorts(%s)", port)
}
return rule, nil
}
func (self *SRegion) AssignSecurityGroup(secgroupId, instanceId string) error {
return self.SetSecurityGroups([]string{secgroupId}, instanceId)
}
@@ -492,5 +442,5 @@ 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)
}
+1 -1
View File
@@ -210,7 +210,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
+4 -2
View File
@@ -177,7 +177,7 @@ func (self *SAwsClient) ec2Request(regionId string, apiName string, params map[s
func (client *SAwsClient) getAwsSession(regionId string, assumeRole bool) (*session.Session, error) {
httpClient := client.cpcfg.AdaptiveTimeoutHttpClient()
transport, _ := httpClient.Transport.(*http.Transport)
httpClient.Transport = cloudprovider.GetCheckTransport(transport, func(req *http.Request) (func(resp *http.Response), error) {
httpClient.Transport = cloudprovider.GetCheckTransport(transport, func(req *http.Request) (func(resp *http.Response) error, error) {
var action string
if req.ContentLength > 0 && !strings.Contains(req.URL.Host, ".s3.") {
body, err := ioutil.ReadAll(req.Body)
@@ -194,7 +194,7 @@ func (client *SAwsClient) getAwsSession(regionId string, assumeRole bool) (*sess
service := strings.Split(req.URL.Host, ".")[0]
method, path := req.Method, req.URL.Path
respCheck := func(resp *http.Response) {
respCheck := func(resp *http.Response) error {
if resp.StatusCode == 403 {
if client.cpcfg.UpdatePermission != nil {
if len(action) > 0 {
@@ -204,6 +204,7 @@ func (client *SAwsClient) getAwsSession(regionId string, assumeRole bool) (*sess
}
}
}
return nil
}
if client.cpcfg.ReadOnly {
@@ -489,6 +490,7 @@ func (self *SAwsClient) GetCapabilities() []string {
caps := []string{
cloudprovider.CLOUD_CAPABILITY_COMPUTE,
cloudprovider.CLOUD_CAPABILITY_NETWORK,
cloudprovider.CLOUD_CAPABILITY_SECURITY_GROUP,
cloudprovider.CLOUD_CAPABILITY_EIP,
cloudprovider.CLOUD_CAPABILITY_LOADBALANCER,
cloudprovider.CLOUD_CAPABILITY_OBJECTSTORE,
-4
View File
@@ -452,10 +452,6 @@ func (self *SInstance) GetMachine() string {
return "pc"
}
func (self *SInstance) AssignSecurityGroup(secgroupId string) error {
return self.SetSecurityGroups([]string{secgroupId})
}
func (self *SInstance) SetSecurityGroups(secgroupIds []string) error {
return self.host.zone.region.assignSecurityGroups(secgroupIds, self.InstanceId)
}
+1 -31
View File
@@ -29,7 +29,6 @@ import (
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/gotypes"
"yunion.io/x/pkg/util/secrules"
api "yunion.io/x/cloudmux/pkg/apis/compute"
"yunion.io/x/cloudmux/pkg/cloudprovider"
@@ -774,40 +773,11 @@ func (self *SRegion) GetISecurityGroupById(id string) (cloudprovider.ICloudSecur
return ret, nil
}
func (self *SRegion) GetISecurityGroupByName(opts *cloudprovider.SecurityGroupFilterOptions) (cloudprovider.ICloudSecurityGroup, error) {
secgroups, err := self.GetSecurityGroups(opts.VpcId, opts.Name, "")
if err != nil {
return nil, errors.Wrap(err, "GetSecurityGroups")
}
for i := range secgroups {
if secgroups[i].GetName() == opts.Name {
secgroups[i].region = self
return &secgroups[i], nil
}
}
return nil, errors.Wrapf(cloudprovider.ErrNotFound, opts.Name)
}
func (self *SRegion) CreateISecurityGroup(opts *cloudprovider.SecurityGroupCreateInput) (cloudprovider.ICloudSecurityGroup, error) {
groupId, err := self.CreateSecurityGroup(opts.VpcId, opts.Name, opts.Desc)
groupId, err := self.CreateSecurityGroup(opts)
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)
}
+145
View File
@@ -0,0 +1,145 @@
// 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 aws
import (
"fmt"
"strings"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/pkg/util/secrules"
"yunion.io/x/pkg/utils"
)
type SSecurityGroupRule struct {
group *SSecurityGroup
FromPort int `xml:"fromPort"`
GroupId string `xml:"groupId"`
IpProtocol string `xml:"ipProtocol"`
GroupOwnerId string `xml:"groupOwnerId"`
IsEgress bool `xml:"isEgress"`
SecurityGroupRuleId string `xml:"securityGroupRuleId"`
ReferencedGroupInfo struct {
GroupId string `xml:"groupId"`
UserId string `xml:"userId"`
} `xml:"referencedGroupInfo"`
CidrIpv4 string `xml:"cidrIpv4"`
CidrIpv6 string `xml:"cidrIpv6"`
Description string `xml:"description"`
PrefixListId string `xml:"prefixListId"`
ToPort int `xml:"toPort"`
}
func (self *SSecurityGroupRule) GetGlobalId() string {
return self.SecurityGroupRuleId
}
func (self *SSecurityGroupRule) GetAction() secrules.TSecurityRuleAction {
return secrules.SecurityRuleAllow
}
func (self *SSecurityGroupRule) GetDescription() string {
return self.Description
}
func (self *SSecurityGroupRule) GetDirection() secrules.TSecurityRuleDirection {
if self.IsEgress {
return secrules.DIR_OUT
}
return secrules.DIR_IN
}
func (self *SSecurityGroupRule) GetCIDRs() []string {
ret := []string{self.CidrIpv4 + self.CidrIpv6 + self.PrefixListId}
return ret
}
func (self *SSecurityGroupRule) GetProtocol() string {
if self.IpProtocol == "-1" {
return secrules.PROTO_ANY
}
return strings.ToLower(self.IpProtocol)
}
func (self *SSecurityGroupRule) GetPorts() string {
if self.FromPort > 0 && self.ToPort > 0 {
if self.FromPort == self.ToPort {
return fmt.Sprintf("%d", self.FromPort)
}
return fmt.Sprintf("%d-%d", self.FromPort, self.ToPort)
}
return ""
}
func (self *SSecurityGroupRule) GetPriority() int {
return 0
}
func (self *SSecurityGroupRule) Delete() error {
return self.group.region.DeleteSecurityGroupRule(self.GroupId, string(self.GetDirection()), self.SecurityGroupRuleId)
}
func (self *SRegion) GetSecurityGroupRules(id string) ([]SSecurityGroupRule, error) {
ret := []SSecurityGroupRule{}
params := map[string]string{
"Filter.1.Name": "group-id",
"Filter.1.Value.1": id,
}
for {
part := struct {
NextToken string `xml:"nextToken"`
SecurityGroupRuleSet []SSecurityGroupRule `xml:"securityGroupRuleSet>item"`
}{}
err := self.ec2Request("DescribeSecurityGroupRules", params, &part)
if err != nil {
return nil, err
}
ret = append(ret, part.SecurityGroupRuleSet...)
if len(part.NextToken) == 0 || len(part.SecurityGroupRuleSet) == 0 {
break
}
params["NextToken"] = part.NextToken
}
return ret, nil
}
func (self *SSecurityGroupRule) Update(opts *cloudprovider.SecurityGroupRuleUpdateOptions) error {
return self.group.region.UpdateSecurityGroupRule(self.group.GroupId, self.SecurityGroupRuleId, opts)
}
func (self *SRegion) UpdateSecurityGroupRule(secgroupId, ruleId string, opts *cloudprovider.SecurityGroupRuleUpdateOptions) error {
if opts.Protocol == secrules.PROTO_ANY {
opts.Protocol = "-1"
}
from, to := "-1", "-1"
if len(opts.Ports) > 0 && utils.IsInStringArray(opts.Protocol, []string{secrules.PROTO_TCP, secrules.PROTO_UDP}) {
r := secrules.SecurityRule{}
r.ParsePorts(opts.Ports)
if r.PortStart > 0 && r.PortEnd > 0 {
from, to = fmt.Sprintf("%d", r.PortStart), fmt.Sprintf("%d", r.PortEnd)
}
}
params := map[string]string{
"GroupId": secgroupId,
"SecurityGroupRule.1.SecurityGroupRuleId": ruleId,
"SecurityGroupRule.1.SecurityGroupRule.CidrIpv4": opts.CIDR,
"SecurityGroupRule.1.SecurityGroupRule.Description": opts.Desc,
"SecurityGroupRule.1.SecurityGroupRule.IpProtocol": opts.Protocol,
"SecurityGroupRule.1.SecurityGroupRule.FromPort": from,
"SecurityGroupRule.1.SecurityGroupRule.ToPort": to,
}
return self.ec2Request("ModifySecurityGroupRules", params, nil)
}
+101 -141
View File
@@ -16,47 +16,27 @@ package aws
import (
"fmt"
"net"
"strconv"
"strings"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/secrules"
"yunion.io/x/pkg/utils"
api "yunion.io/x/cloudmux/pkg/apis/compute"
"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
region *SRegion
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"`
GroupId string `xml:"groupId"`
VpcId string `xml:"vpcId"`
GroupName string `xml:"groupName"`
GroupDescription string `xml:"groupDescription"`
}
func (self *SSecurityGroup) GetId() string {
@@ -79,7 +59,7 @@ func (self *SSecurityGroup) GetGlobalId() string {
}
func (self *SSecurityGroup) GetStatus() string {
return ""
return api.SECGROUP_STATUS_READY
}
func (self *SSecurityGroup) Refresh() error {
@@ -87,149 +67,124 @@ func (self *SSecurityGroup) Refresh() error {
if err != nil {
return err
}
self.IpPermissions = group.IpPermissions
self.IpPermissionsEgress = group.IpPermissionsEgress
return jsonutils.Update(self, group)
}
func (self *SSecurityGroup) SetTags(tags map[string]string, replace bool) error {
return self.region.setTags("security-group", self.GroupId, tags, replace)
}
func (self *SSecurityGroup) GetDescription() string {
return self.GroupDescription
}
func (self *SSecurityGroup) GetRules() ([]cloudprovider.SecurityRule, error) {
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,
},
})
}
}
func (self *SSecurityGroup) GetRules() ([]cloudprovider.ISecurityGroupRule, error) {
ret := []cloudprovider.ISecurityGroupRule{}
rules, err := self.region.GetSecurityGroupRules(self.GroupId)
if err != nil {
return nil, err
}
for i := range rules {
rules[i].group = self
ret = append(ret, &rules[i])
}
return ret, nil
}
func (self *SRegion) RemoveSecurityGroupRule(secGrpId string, rule secrules.SecurityRule) error {
func (self *SRegion) CreateSecurityGroupRule(secGrpId string, opts *cloudprovider.SecurityGroupRuleCreateOptions) (*SSecurityGroupRule, error) {
params := map[string]string{
"GroupId": secGrpId,
"GroupId": secGrpId,
"IpPermissions.1.IpProtocol": "-1",
"IpPermissions.1.IpRanges.1.Description": opts.Desc,
"IpPermissions.1.FromPort": "0",
"IpPermissions.1.ToPort": "65535",
}
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 opts.Protocol != secrules.PROTO_ANY {
params["IpPermissions.1.IpProtocol"] = strings.ToLower(opts.Protocol)
}
if rule.IPNet != nil {
params[fmt.Sprintf("IpPermissions.%d.IpRanges.1.CidrIp", idx)] = rule.IPNet.String()
if len(opts.CIDR) > 0 {
params["IpPermissions.1.IpRanges.1.CidrIp"] = opts.CIDR
}
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
}
params := map[string]string{
"GroupId": secGrpId,
}
idx := 1
for i := range rules {
rule := rules[i]
if len(rule.Ports) > 0 {
for _, port := range rule.Ports {
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()
}
params[fmt.Sprintf("IpPermissions.%d.FromPort", idx)] = fmt.Sprintf("%d", port)
params[fmt.Sprintf("IpPermissions.%d.ToPort", idx)] = fmt.Sprintf("%d", port)
idx++
start, end := 0, 0
if len(opts.Ports) > 0 {
if strings.Contains(opts.Ports, "-") {
ports := strings.Split(opts.Ports, "-")
if len(ports) != 2 {
return nil, errors.Errorf("invalid ports %s", opts.Ports)
}
continue
var err error
_start, _end := ports[0], ports[1]
start, err = strconv.Atoi(_start)
if err != nil {
return nil, errors.Errorf("invalid start port %s", _start)
}
end, err = strconv.Atoi(_end)
if err != nil {
return nil, errors.Errorf("invalid end port %s", _end)
}
} else {
port, err := strconv.Atoi(opts.Ports)
if err != nil {
return nil, errors.Errorf("invalid ports %s", opts.Ports)
}
start, end = port, port
}
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()
}
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++
}
if start > 0 && end > 0 {
params["IpPermissions.1.FromPort"] = fmt.Sprintf("%d", start)
params["IpPermissions.1.ToPort"] = fmt.Sprintf("%d", end)
}
if opts.Protocol == secrules.PROTO_ICMP {
params["IpPermissions.1.FromPort"] = "-1"
params["IpPermissions.1.ToPort"] = "-1"
}
action := "AuthorizeSecurityGroupIngress"
if direction == secrules.DIR_OUT {
if opts.Direction == secrules.DIR_OUT {
action = "AuthorizeSecurityGroupEgress"
}
return self.ec2Request(action, params, nil)
ret := struct {
Return bool `xml:"return"`
SecurityGroupRuleSet []SSecurityGroupRule `xml:"securityGroupRuleSet>item"`
}{}
err := self.ec2Request(action, params, &ret)
if err != nil {
return nil, errors.Wrapf(err, action)
}
for i := range ret.SecurityGroupRuleSet {
return &ret.SecurityGroupRuleSet[i], nil
}
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "after create")
}
func (self *SRegion) DelSecurityGroupRule(secGrpId string, ruleId string) error {
func (self *SRegion) DeleteSecurityGroupRule(secGrpId string, direction, ruleId string) error {
params := map[string]string{
"GroupId": secGrpId,
"SecurityGroupRuleId.1": ruleId,
}
return self.ec2Request("RevokeSecurityGroupEgress", params, nil)
action := "RevokeSecurityGroupEgress"
if direction == secrules.DIR_IN {
action = "RevokeSecurityGroupIngress"
}
return self.ec2Request(action, params, nil)
}
func (self *SRegion) CreateSecurityGroup(vpcId string, name string, desc string) (string, error) {
func (self *SRegion) CreateSecurityGroup(opts *cloudprovider.SecurityGroupCreateInput) (string, error) {
params := map[string]string{
"VpcId": vpcId,
"GroupDescription": desc,
"GroupName": name,
"VpcId": opts.VpcId,
"GroupDescription": opts.Desc,
"GroupName": opts.Name,
}
if len(desc) == 0 {
if len(opts.Desc) == 0 {
params["GroupDescription"] = "auto create by cloudpods"
}
tagIdx := 1
for k, v := range opts.Tags {
params[fmt.Sprintf("TagSpecification.1.ResourceType")] = "security-group"
params[fmt.Sprintf("TagSpecification.1.Tag.%d.Key", tagIdx)] = k
params[fmt.Sprintf("TagSpecification.1.Tag.%d.Value", tagIdx)] = v
tagIdx++
}
ret := struct {
GroupId string `xml:"groupId"`
}{}
@@ -289,10 +244,15 @@ func (self *SRegion) GetSecurityGroups(vpcId string, name string, secgroupId str
return result, nil
}
func (self *SSecurityGroup) GetProjectId() string {
return ""
}
func (self *SSecurityGroup) Delete() error {
return self.region.DeleteSecurityGroup(self.GroupId)
}
func (self *SSecurityGroup) CreateRule(opts *cloudprovider.SecurityGroupRuleCreateOptions) (cloudprovider.ISecurityGroupRule, error) {
rule, err := self.region.CreateSecurityGroupRule(self.GroupId, opts)
if err != nil {
return nil, err
}
rule.group = self
return rule, nil
}
+5 -1
View File
@@ -172,7 +172,7 @@ func (self *SAzureClient) getClient(resource TAzureResource) (*azureAuthClient,
httpClient := self.cpcfg.AdaptiveTimeoutHttpClient()
transport, _ := httpClient.Transport.(*http.Transport)
httpClient.Transport = cloudprovider.GetCheckTransport(transport, func(req *http.Request) (func(resp *http.Response), error) {
httpClient.Transport = cloudprovider.GetCheckTransport(transport, func(req *http.Request) (func(resp *http.Response) error, error) {
if self.cpcfg.ReadOnly {
if req.Method == "GET" || (req.Method == "POST" && strings.HasSuffix(req.URL.Path, "oauth2/token")) {
return nil, nil
@@ -516,6 +516,9 @@ func (self *SAzureClient) _apiVersion(resource string, params url.Values) string
if utils.IsInStringArray("applicationgatewayavailablewafrulesets", info) {
return "2018-06-01"
}
if utils.IsInStringArray("securityrules", info) {
return "2023-05-01"
}
return "2018-06-01"
} else if utils.IsInStringArray("microsoft.storage", info) {
if utils.IsInStringArray("storageaccounts", info) {
@@ -1068,6 +1071,7 @@ func (self *SAzureClient) GetCapabilities() []string {
cloudprovider.CLOUD_CAPABILITY_PROJECT,
cloudprovider.CLOUD_CAPABILITY_COMPUTE,
cloudprovider.CLOUD_CAPABILITY_NETWORK,
cloudprovider.CLOUD_CAPABILITY_SECURITY_GROUP,
cloudprovider.CLOUD_CAPABILITY_EIP,
cloudprovider.CLOUD_CAPABILITY_LOADBALANCER + cloudprovider.READ_ONLY_SUFFIX,
cloudprovider.CLOUD_CAPABILITY_OBJECTSTORE,

Some files were not shown because too many files have changed in this diff Show More