fix(region): support cloudpods ipset (#25360)

This commit is contained in:
屈轩
2026-08-19 18:56:30 +08:00
committed by GitHub
parent 29f65063b7
commit d2755e8370
61 changed files with 2384 additions and 166 deletions
+2
View File
@@ -23,7 +23,9 @@ import (
func init() {
cmd := shell.NewResourceCmd(&modules.IpSets)
cmd.List(&compute.IpSetListOptions{})
cmd.Show(&compute.IpSetIdOptions{})
cmd.Create(&compute.IpSetCreateOptions{})
cmd.Update(&compute.IpSetUpdateOptions{})
cmd.Delete(&compute.IpSetIdOptions{})
cmd.Perform("syncstatus", &compute.IpSetIdOptions{})
}
+1 -1
View File
@@ -112,7 +112,7 @@ require (
k8s.io/cri-api v0.28.15
k8s.io/klog/v2 v2.90.1
moul.io/http2curl/v2 v2.3.0
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20260812062623-2b79dfea19bd
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20260819093747-311f52c4fa1a
yunion.io/x/executor v0.0.0-20260312022053-f538abd2b005
yunion.io/x/jsonutils v1.0.1-0.20260715075349-615cfb44ff7c
yunion.io/x/log v1.0.1-0.20240305175729-7cf2d6cd5a91
+2 -2
View File
@@ -1754,8 +1754,8 @@ sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20260812062623-2b79dfea19bd h1:rtRzbOZP24DqQ0u0SYfrSdYWLX6Taov0AwkVQyv95p0=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20260812062623-2b79dfea19bd/go.mod h1:QgrcekfkD3fELNYipZnlUfhR8dPI8CCUsuzC2SkP3YE=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20260819093747-311f52c4fa1a h1:o3WfnRmKxVrI8KN9t0Pnlswds2qFRMKyslk6bM3jNoA=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20260819093747-311f52c4fa1a/go.mod h1:IwmeqVkld+4XylS80cyVBXyN8fJ5ynAspd/6tcvqJuc=
yunion.io/x/executor v0.0.0-20260312022053-f538abd2b005 h1:3sWwcjGXGjG9mLBWa7AyLq+QSi0udTAx21pfVQRFMBE=
yunion.io/x/executor v0.0.0-20260312022053-f538abd2b005/go.mod h1:Uxuou9WQIeJXNpy7t2fPLL0BYLvLiMvGQwY7Qc6aSws=
yunion.io/x/jsonutils v0.0.0-20190625054549-a964e1e8a051/go.mod h1:4N0/RVzsYL3kH3WE/H1BjUQdFiWu50JGCFQuuy+Z634=
+11
View File
@@ -42,6 +42,9 @@ func (t TIpSetType) IsValid() bool {
type IpSetCreateInput struct {
apis.SharableVirtualResourceCreateInput
CloudregionResourceInput
CloudproviderResourceInput
// IP集合类型
// enum: ["ipv4_cidr_list", "ipv6_cidr_list"]
// required: true
@@ -63,6 +66,10 @@ type IpSetUpdateInput struct {
type IpSetListInput struct {
apis.SharableVirtualResourceListInput
apis.ExternalizedResourceBaseListInput
ManagedResourceListInput
RegionalFilterListInput
// 按 IP 集合类型过滤
// enum: ["ipv4_cidr_list", "ipv6_cidr_list"]
@@ -74,6 +81,10 @@ type IpSetListInput struct {
type IpSetDetails struct {
apis.SharableVirtualResourceDetails
ManagedResourceInfo
CloudregionResourceInfo
SIpSet
// 关联安全组数量
SecurityGroupCount int `json:"security_group_count"`
+3
View File
@@ -184,6 +184,9 @@ func (input *SSecgroupRuleResource) Check() error {
}
}
if len(input.TargetType) == 0 {
input.TargetType = SecurityGroupRuleTargetTypeCidr
}
switch input.TargetType {
case SecurityGroupRuleTargetTypeCidr:
if len(input.CIDR) > 0 {
+12
View File
@@ -1616,6 +1616,18 @@ type SInterVpcNetworkVpc struct {
VpcId string `json:"vpc_id"`
}
// SIpSet is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SIpSet.
type SIpSet struct {
apis.SSharableVirtualResourceBase
apis.SExternalizedResourceBase
SManagedResourceBase
SCloudregionResourceBase
// IP集合类型
IpSetType TIpSetType `json:"ip_set_type"`
// IP/CIDR 列表,逗号分隔
Data string `json:"data"`
}
// SIsolatedDevice is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SIsolatedDevice.
type SIsolatedDevice struct {
apis.SStandaloneResourceBase
+1
View File
@@ -61,6 +61,7 @@ const (
STATUS_CREATING = "creating"
STATUS_AVAILABLE = "available"
STATUS_CREATE_FAILED = "create_failed"
STATUS_UPDATE_FAILED = "update_failed"
// 更改计费模式
STATUS_CHANGE_BILLING_TYPE = "change_billing_type"
+69
View File
@@ -513,6 +513,42 @@ func syncRegionSecGroup(
}
}
func syncRegionIpSets(
ctx context.Context,
userCred mcclient.TokenCredential,
syncResults SSyncResultSet,
provider *SCloudprovider,
localRegion *SCloudregion,
remoteRegion cloudprovider.ICloudRegion,
syncRange *SSyncRange,
) {
ipSets, err := func() ([]cloudprovider.ICloudIpSet, error) {
defer syncResults.AddRequestCost(IpSetManager)()
return remoteRegion.GetIIpSets()
}()
if err != nil {
if errors.Cause(err) == cloudprovider.ErrNotImplemented || errors.Cause(err) == cloudprovider.ErrNotSupported {
return
}
msg := fmt.Sprintf("GetIIpSets for region %s provider %s failed %s", localRegion.Name, provider.Name, err)
log.Errorf("%s", msg)
return
}
result := func() compare.SyncResult {
defer syncResults.AddSqlCost(IpSetManager)()
return localRegion.SyncIpSets(ctx, userCred, provider, ipSets, syncRange.Xor)
}()
syncResults.Add(IpSetManager, result)
notes := fmt.Sprintf("SyncIpSets for region %s provider %s result: %s", localRegion.Name, provider.Name, result.Result())
log.Infof("%s", notes)
provider.SyncError(result, notes, userCred)
if result.IsError() {
return
}
}
func syncVpcSecGroup(
ctx context.Context,
userCred mcclient.TokenCredential,
@@ -2488,6 +2524,9 @@ func syncPublicCloudProviderInfo(
syncRegionEips(ctx, userCred, syncResults, provider, localRegion, remoteRegion, syncRange)
}
if syncRange.IsNotSkipSyncResource(IpSetManager) {
syncRegionIpSets(ctx, userCred, syncResults, provider, localRegion, remoteRegion, syncRange)
}
if syncRange.IsNotSkipSyncResource(SecurityGroupManager) {
syncRegionSecGroup(ctx, userCred, syncResults, provider, localRegion, remoteRegion, syncRange)
}
@@ -3033,6 +3072,13 @@ func SyncCloudproviderResources(ctx context.Context, userCred mcclient.TokenCred
syncSSLCertificates(ctx, userCred, SSyncResultSet{}, provider, driver, syncRange.Xor)
}
if syncRange.IsNotSkipSyncResource(IpSetManager) {
err = syncProviderIpSets(ctx, userCred, SSyncResultSet{}, provider, driver, syncRange.Xor)
if err != nil {
log.Errorf("syncProviderIpSets error: %v", err)
}
}
return nil
}
@@ -3157,6 +3203,29 @@ func syncSSLCertificates(ctx context.Context, userCred mcclient.TokenCredential,
return nil
}
func syncProviderIpSets(ctx context.Context, userCred mcclient.TokenCredential, syncResults SSyncResultSet, provider *SCloudprovider, driver cloudprovider.ICloudProvider, xor bool) error {
ipSets, err := func() ([]cloudprovider.ICloudIpSet, error) {
defer syncResults.AddRequestCost(IpSetManager)()
return driver.GetIIpSets()
}()
if err != nil {
if errors.Cause(err) == cloudprovider.ErrNotImplemented || errors.Cause(err) == cloudprovider.ErrNotSupported {
return nil
}
return err
}
result := func() compare.SyncResult {
defer syncResults.AddSqlCost(IpSetManager)()
return provider.SyncIpSets(ctx, userCred, ipSets, xor)
}()
syncResults.Add(IpSetManager, result)
notes := fmt.Sprintf("Sync ip sets for provider %s result: %s", provider.Name, result.Result())
log.Infof("%s", notes)
provider.SyncError(result, notes, userCred)
return nil
}
func syncTablestore(
ctx context.Context,
userCred mcclient.TokenCredential,
+1
View File
@@ -45,6 +45,7 @@ func InitDB() error {
WireManager,
StorageManager,
SecurityGroupManager,
IpSetManager,
NetworkManager,
NetworkAddressManager,
NetworkIpMacManager,
+565 -3
View File
@@ -16,16 +16,25 @@ package models
import (
"context"
"fmt"
"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/netutils"
"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/compute/options"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/netutils2"
@@ -36,6 +45,9 @@ import (
// +onecloud:swagger-gen-model-plural=ipsets
type SIpSetManager struct {
db.SSharableVirtualResourceBaseManager
db.SExternalizedResourceBaseManager
SManagedResourceBaseManager
SCloudregionResourceBaseManager
}
var IpSetManager *SIpSetManager
@@ -54,6 +66,9 @@ func init() {
type SIpSet struct {
db.SSharableVirtualResourceBase
db.SExternalizedResourceBase
SManagedResourceBase
SCloudregionResourceBase `width:"36" charset:"ascii" nullable:"true" list:"user" create:"optional"`
// IP集合类型
IpSetType api.TIpSetType `width:"32" charset:"ascii" nullable:"false" list:"user" create:"required" update:"user"`
@@ -61,6 +76,57 @@ type SIpSet struct {
Data string `width:"2048" charset:"ascii" nullable:"false" list:"user" create:"required" update:"user"`
}
func (manager *SIpSetManager) InitializeData() error {
q := manager.Query().IsNullOrEmpty("manager_id").Equals("status", "init")
ipsets := []SIpSet{}
err := db.FetchModelObjects(manager, q, &ipsets)
if err != nil {
return errors.Wrapf(err, "db.FetchModelObjects")
}
for i := range ipsets {
_, err := db.Update(&ipsets[i], func() error {
ipsets[i].Status = apis.STATUS_AVAILABLE
return nil
})
if err != nil {
return errors.Wrapf(err, "Update ipset %s", ipsets[i].Id)
}
}
return nil
}
func ipSetRegionListFilter(ctx context.Context, q *sqlchemy.SQuery, query api.RegionalFilterListInput) (*sqlchemy.SQuery, error) {
regionIds := []string{}
for _, region := range query.CloudregionId {
if len(region) == 0 {
continue
}
regionObj, err := ValidateCloudregionId(ctx, nil, region)
if err != nil {
return nil, errors.Wrap(err, "ValidateCloudregionId")
}
regionIds = append(regionIds, regionObj.GetId())
}
if len(regionIds) > 0 {
providerSubq := CloudproviderRegionManager.Query("cloudprovider_id").In("cloudregion_id", regionIds).Distinct().SubQuery()
q = q.Filter(sqlchemy.OR(
sqlchemy.In(q.Field("cloudregion_id"), regionIds),
sqlchemy.AND(
sqlchemy.IsNullOrEmpty(q.Field("cloudregion_id")),
sqlchemy.In(q.Field("manager_id"), providerSubq),
),
))
}
if len(query.City) > 0 {
subq := CloudregionManager.Query("id").Equals("city", query.City).SubQuery()
q = q.Filter(sqlchemy.OR(
sqlchemy.In(q.Field("cloudregion_id"), subq),
sqlchemy.IsNullOrEmpty(q.Field("cloudregion_id")),
))
}
return q, nil
}
// IP集合列表
func (manager *SIpSetManager) ListItemFilter(
ctx context.Context,
@@ -72,6 +138,18 @@ func (manager *SIpSetManager) ListItemFilter(
if err != nil {
return nil, errors.Wrap(err, "SVirtualResourceBaseManager.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 = ipSetRegionListFilter(ctx, q, query.RegionalFilterListInput)
if err != nil {
return nil, errors.Wrap(err, "ipSetRegionListFilter")
}
if len(query.IpSetType) > 0 {
types := make([]string, 0, len(query.IpSetType))
for _, t := range query.IpSetType {
@@ -95,6 +173,14 @@ func (manager *SIpSetManager) OrderByExtraFields(
if err != nil {
return nil, errors.Wrap(err, "SVirtualResourceBaseManager.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")
}
return q, nil
}
@@ -103,9 +189,54 @@ func (manager *SIpSetManager) QueryDistinctExtraField(q *sqlchemy.SQuery, 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 (manager *SIpSetManager) QueryDistinctExtraFields(q *sqlchemy.SQuery, resource string, fields []string) (*sqlchemy.SQuery, error) {
q, err := manager.SManagedResourceBaseManager.QueryDistinctExtraFields(q, resource, fields)
if err == nil {
return q, nil
}
return q, httperrors.ErrNotFound
}
type sIpSetUsageCount struct {
Cidr string
SecurityGroupCount int
}
func (manager *SIpSetManager) TotalResourceCount(ipSetIds []string) (map[string]int, error) {
ret := map[string]int{}
if len(ipSetIds) == 0 {
return ret, nil
}
sq := SecurityGroupRuleManager.Query("cidr", "secgroup_id").
Equals("target_type", api.SecurityGroupRuleTargetTypeIpSet).
In("cidr", ipSetIds).
Distinct().SubQuery()
q := sq.Query(
sq.Field("cidr"),
sqlchemy.COUNT("security_group_count"),
).GroupBy(sq.Field("cidr"))
counts := []sIpSetUsageCount{}
err := q.All(&counts)
if err != nil {
return nil, errors.Wrapf(err, "q.All")
}
for i := range counts {
ret[counts[i].Cidr] = counts[i].SecurityGroupCount
}
return ret, nil
}
func (manager *SIpSetManager) FetchCustomizeColumns(
ctx context.Context,
userCred mcclient.TokenCredential,
@@ -116,12 +247,25 @@ func (manager *SIpSetManager) FetchCustomizeColumns(
) []api.IpSetDetails {
rows := make([]api.IpSetDetails, len(objs))
virtRows := manager.SSharableVirtualResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
managerRows := manager.SManagedResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
regionRows := manager.SCloudregionResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
ipSetIds := make([]string, len(objs))
for i := range rows {
ipSetIds[i] = objs[i].(*SIpSet).Id
rows[i] = api.IpSetDetails{
SharableVirtualResourceDetails: virtRows[i],
SecurityGroupCount: objs[i].(*SIpSet).GetSecurityGroupCount(),
ManagedResourceInfo: managerRows[i],
CloudregionResourceInfo: regionRows[i],
}
}
counts, err := manager.TotalResourceCount(ipSetIds)
if err != nil {
log.Errorf("TotalResourceCount error: %v", err)
return rows
}
for i := range rows {
rows[i].SecurityGroupCount = counts[ipSetIds[i]]
}
return rows
}
@@ -135,6 +279,18 @@ func (manager *SIpSetManager) ListItemExportKeys(
if err != nil {
return nil, errors.Wrap(err, "SSharableVirtualResourceBaseManager.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")
}
}
return q, nil
}
@@ -158,6 +314,37 @@ func (manager *SIpSetManager) ValidateCreateData(
if err != nil {
return nil, err
}
if len(input.CloudproviderId) > 0 {
providerObj, err := validators.ValidateModel(ctx, userCred, CloudproviderManager, &input.CloudproviderId)
if err != nil {
return nil, err
}
input.ManagerId = input.CloudproviderId
provider := providerObj.(*SCloudprovider)
if len(input.CloudregionId) > 0 {
regionObj, err := validators.ValidateModel(ctx, userCred, CloudregionManager, &input.CloudregionId)
if err != nil {
return nil, err
}
region := regionObj.(*SCloudregion)
if provider.Provider != region.Provider {
return nil, httperrors.NewConflictError("conflict region %s and cloudprovider %s", region.Name, provider.Name)
}
} else if provider.Provider != api.CLOUD_PROVIDER_QCLOUD {
return nil, httperrors.NewMissingParameterError("cloudregion_id")
} else {
input.CloudregionId = ""
}
return input, nil
}
if len(input.CloudregionId) == 0 {
input.CloudregionId = api.DEFAULT_REGION_ID
}
regionObj, err := validators.ValidateModel(ctx, userCred, CloudregionManager, &input.CloudregionId)
if err != nil {
return nil, err
}
_ = regionObj.(*SCloudregion)
return input, nil
}
@@ -183,6 +370,65 @@ func (ipset *SIpSet) ValidateUpdateData(
return input, nil
}
func (ipset *SIpSet) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) {
ipset.SSharableVirtualResourceBase.PostCreate(ctx, userCred, ownerId, query, data)
if ipset.IsManaged() {
regionId, _ := data.GetString("cloudregion_id")
if len(regionId) == 0 {
provider := ipset.GetCloudprovider()
if provider != nil && provider.Provider == api.CLOUD_PROVIDER_QCLOUD && len(ipset.CloudregionId) > 0 {
_, err := db.Update(ipset, func() error {
ipset.CloudregionId = ""
return nil
})
if err != nil {
log.Errorf("clear cloudregion_id for ipset %s: %v", ipset.Id, err)
}
}
}
ipset.StartCreateTask(ctx, userCred, "")
return
}
ipset.SetStatus(ctx, userCred, apis.STATUS_AVAILABLE, "")
ipset.DoSync(ctx, userCred)
}
func (ipset *SIpSet) PostUpdate(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) {
ipset.SSharableVirtualResourceBase.PostUpdate(ctx, userCred, query, data)
if ipset.IsManaged() {
ipset.StartUpdateTask(ctx, userCred, "")
return
}
ipset.DoSync(ctx, userCred)
}
func (ipset *SIpSet) GetSecurityGroups() ([]SSecurityGroup, error) {
sq := SecurityGroupRuleManager.Query("secgroup_id").
Equals("target_type", api.SecurityGroupRuleTargetTypeIpSet).
Equals("cidr", ipset.Id).
Distinct().SubQuery()
q := SecurityGroupManager.Query().In("id", sq)
ret := []SSecurityGroup{}
err := db.FetchModelObjects(SecurityGroupManager, q, &ret)
if err != nil {
return nil, errors.Wrapf(err, "db.FetchModelObjects")
}
return ret, nil
}
func (ipset *SIpSet) DoSync(ctx context.Context, userCred mcclient.TokenCredential) {
secgroups, err := ipset.GetSecurityGroups()
if err != nil {
log.Errorf("GetSecurityGroups error: %s", err.Error())
return
}
for i := range secgroups {
if len(secgroups[i].ManagerId) == 0 {
secgroups[i].DoSync(ctx, userCred)
}
}
}
func normalizeIpSetData(ipSetType api.TIpSetType, data string) string {
parts := strings.Split(data, ",")
normalized := make([]string, 0, len(parts))
@@ -222,10 +468,326 @@ func (ipset *SIpSet) ValidateDeleteCondition(ctx context.Context, info jsonutils
}
func (ipset *SIpSet) GetSecurityGroupCount() int {
q := SecurityGroupRuleManager.Query("secgroup_id").Equals("target_type", api.SecurityGroupRuleTargetTypeIpSet).Equals("cidr", ipset.Id).Distinct()
return q.Count()
counts, err := IpSetManager.TotalResourceCount([]string{ipset.Id})
if err != nil {
return 0
}
return counts[ipset.Id]
}
func (ipset *SIpSet) getIpNets() []*net.IPNet {
return netutils2.Str2IPNets(ipset.Data)
}
func (ipset *SIpSet) GetIRegion(ctx context.Context) (cloudprovider.ICloudRegion, error) {
if ipset.IsManaged() && len(ipset.CloudregionId) == 0 {
return nil, errors.Wrapf(cloudprovider.ErrNotSupported, "account level ipset")
}
region, err := ipset.SCloudregionResourceBase.GetRegion()
if err != nil {
return nil, errors.Wrapf(err, "GetRegion")
}
provider, err := ipset.GetDriver(ctx)
if err != nil {
return nil, errors.Wrapf(err, "GetDriver")
}
return provider.GetIRegionById(region.ExternalId)
}
func (ipset *SIpSet) GetICloudIpSet(ctx context.Context) (cloudprovider.ICloudIpSet, error) {
if len(ipset.ExternalId) == 0 {
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "empty external id")
}
if ipset.IsManaged() && len(ipset.CloudregionId) == 0 {
provider := ipset.GetCloudprovider()
if provider == nil {
return nil, errors.Errorf("empty cloudprovider")
}
driver, err := provider.GetProvider(ctx)
if err != nil {
return nil, errors.Wrapf(err, "GetProvider")
}
return driver.GetIIpSetById(ipset.ExternalId)
}
iRegion, err := ipset.GetIRegion(ctx)
if err != nil {
return nil, errors.Wrapf(err, "GetIRegion")
}
return iRegion.GetIIpSetById(ipset.ExternalId)
}
func (ipset *SIpSet) GetAddresses() []string {
if len(ipset.Data) == 0 {
return []string{}
}
parts := strings.Split(ipset.Data, ",")
ret := make([]string, 0, len(parts))
for i := range parts {
addr := strings.TrimSpace(parts[i])
if len(addr) > 0 {
ret = append(ret, addr)
}
}
return ret
}
func (ipset *SIpSet) StartCreateTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
task, err := taskman.TaskManager.NewTask(ctx, "IpSetCreateTask", ipset, userCred, nil, parentTaskId, "", nil)
if err != nil {
return errors.Wrapf(err, "NewTask")
}
ipset.SetStatus(ctx, userCred, apis.STATUS_CREATING, "")
return task.ScheduleRun(nil)
}
func (ipset *SIpSet) StartUpdateTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
task, err := taskman.TaskManager.NewTask(ctx, "IpSetUpdateTask", ipset, userCred, nil, parentTaskId, "", nil)
if err != nil {
return errors.Wrapf(err, "NewTask")
}
ipset.SetStatus(ctx, userCred, apis.STATUS_SYNC_STATUS, "")
return task.ScheduleRun(nil)
}
func (ipset *SIpSet) StartDeleteTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
task, err := taskman.TaskManager.NewTask(ctx, "IpSetDeleteTask", ipset, userCred, nil, parentTaskId, "", nil)
if err != nil {
return errors.Wrapf(err, "NewTask")
}
ipset.SetStatus(ctx, userCred, apis.STATUS_DELETING, "")
return task.ScheduleRun(nil)
}
func (ipset *SIpSet) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
if ipset.IsManaged() {
return nil
}
return ipset.SSharableVirtualResourceBase.Delete(ctx, userCred)
}
func (ipset *SIpSet) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
return ipset.SSharableVirtualResourceBase.Delete(ctx, userCred)
}
func (ipset *SIpSet) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
if ipset.IsManaged() {
return ipset.StartDeleteTask(ctx, userCred, "")
}
return nil
}
func (ipset *SIpSet) PerformSyncstatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
if !ipset.IsManaged() {
return nil, ipset.SetStatus(ctx, userCred, apis.STATUS_AVAILABLE, "")
}
return nil, StartResourceSyncStatusTask(ctx, userCred, ipset, "IpSetSyncstatusTask", "")
}
func (self *SCloudregion) GetIpSets(managerId string) ([]SIpSet, error) {
q := IpSetManager.Query().Equals("cloudregion_id", self.Id)
if len(managerId) > 0 {
q = q.Equals("manager_id", managerId)
}
ret := []SIpSet{}
err := db.FetchModelObjects(IpSetManager, q, &ret)
if err != nil {
return nil, errors.Wrapf(err, "db.FetchModelObjects")
}
return ret, nil
}
func (self *SCloudregion) SyncIpSets(
ctx context.Context,
userCred mcclient.TokenCredential,
provider *SCloudprovider,
exts []cloudprovider.ICloudIpSet,
xor bool,
) compare.SyncResult {
lockman.LockRawObject(ctx, IpSetManager.Keyword(), fmt.Sprintf("%s-%s", self.Id, provider.Id))
defer lockman.ReleaseRawObject(ctx, IpSetManager.Keyword(), fmt.Sprintf("%s-%s", self.Id, provider.Id))
result := compare.SyncResult{}
dbIpSets, err := self.GetIpSets(provider.Id)
if err != nil {
result.Error(err)
return result
}
removed := make([]SIpSet, 0)
commondb := make([]SIpSet, 0)
commonext := make([]cloudprovider.ICloudIpSet, 0)
added := make([]cloudprovider.ICloudIpSet, 0)
err = compare.CompareSets(dbIpSets, exts, &removed, &commondb, &commonext, &added)
if err != nil {
result.Error(err)
return result
}
for i := 0; i < len(removed); i++ {
err := removed[i].syncRemove(ctx, userCred)
if err != nil {
result.DeleteError(err)
continue
}
result.Delete()
}
if !xor {
for i := 0; i < len(commondb); i++ {
err := commondb[i].SyncWithCloudIpSet(ctx, userCred, commonext[i], provider, self.Id)
if err != nil {
result.UpdateError(err)
continue
}
result.Update()
}
}
for i := 0; i < len(added); i++ {
err = self.newFromCloudIpSet(ctx, userCred, provider, added[i])
if err != nil {
result.AddError(err)
continue
}
result.Add()
}
return result
}
func (provider *SCloudprovider) GetIpSets() ([]SIpSet, error) {
q := IpSetManager.Query().Equals("manager_id", provider.Id)
ret := []SIpSet{}
err := db.FetchModelObjects(IpSetManager, q, &ret)
if err != nil {
return nil, errors.Wrapf(err, "db.FetchModelObjects")
}
return ret, nil
}
func (provider *SCloudprovider) SyncIpSets(
ctx context.Context,
userCred mcclient.TokenCredential,
exts []cloudprovider.ICloudIpSet,
xor bool,
) compare.SyncResult {
lockman.LockRawObject(ctx, IpSetManager.Keyword(), provider.Id)
defer lockman.ReleaseRawObject(ctx, IpSetManager.Keyword(), provider.Id)
result := compare.SyncResult{}
dbIpSets, err := provider.GetIpSets()
if err != nil {
result.Error(err)
return result
}
removed := make([]SIpSet, 0)
commondb := make([]SIpSet, 0)
commonext := make([]cloudprovider.ICloudIpSet, 0)
added := make([]cloudprovider.ICloudIpSet, 0)
err = compare.CompareSets(dbIpSets, exts, &removed, &commondb, &commonext, &added)
if err != nil {
result.Error(err)
return result
}
for i := 0; i < len(removed); i++ {
if len(removed[i].CloudregionId) > 0 {
continue
}
err := removed[i].syncRemove(ctx, userCred)
if err != nil {
result.DeleteError(err)
continue
}
result.Delete()
}
if !xor {
for i := 0; i < len(commondb); i++ {
err := commondb[i].SyncWithCloudIpSet(ctx, userCred, commonext[i], provider, "")
if err != nil {
result.UpdateError(err)
continue
}
result.Update()
}
}
for i := 0; i < len(added); i++ {
err = provider.newFromCloudIpSet(ctx, userCred, added[i])
if err != nil {
result.AddError(err)
continue
}
result.Add()
}
return result
}
func (provider *SCloudprovider) newFromCloudIpSet(ctx context.Context, userCred mcclient.TokenCredential, ext cloudprovider.ICloudIpSet) error {
ret := &SIpSet{}
ret.SetModelManager(IpSetManager, ret)
ret.Name = ext.GetName()
ret.CloudregionId = ""
ret.ManagerId = provider.Id
ret.ExternalId = ext.GetGlobalId()
ret.Status = apis.STATUS_AVAILABLE
ret.IpSetType = api.TIpSetType(ext.GetIpSetType())
ret.Description = ext.GetDescription()
ret.Data = strings.Join(ext.GetAddresses(), ",")
err := IpSetManager.TableSpec().Insert(ctx, ret)
if err != nil {
return errors.Wrapf(err, "Insert")
}
syncVirtualResourceMetadata(ctx, userCred, ret, ext, false)
SyncCloudProject(ctx, userCred, ret, provider.GetOwnerId(), ext, provider)
return nil
}
func (ipset *SIpSet) syncRemove(ctx context.Context, userCred mcclient.TokenCredential) error {
return ipset.RealDelete(ctx, userCred)
}
func (ipset *SIpSet) SyncWithCloudIpSet(ctx context.Context, userCred mcclient.TokenCredential, ext cloudprovider.ICloudIpSet, provider *SCloudprovider, cloudregionId string) error {
_, err := db.Update(ipset, func() error {
ipset.Status = apis.STATUS_AVAILABLE
ipset.CloudregionId = cloudregionId
if options.Options.EnableSyncName {
ipset.Name = ext.GetName()
}
ipset.IpSetType = api.TIpSetType(ext.GetIpSetType())
ipset.Data = strings.Join(ext.GetAddresses(), ",")
if desc := ext.GetDescription(); len(desc) > 0 {
ipset.Description = desc
}
return nil
})
if err != nil {
return err
}
syncVirtualResourceMetadata(ctx, userCred, ipset, ext, false)
SyncCloudProject(ctx, userCred, ipset, provider.GetOwnerId(), ext, provider)
return nil
}
func (self *SCloudregion) newFromCloudIpSet(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, ext cloudprovider.ICloudIpSet) error {
ret := &SIpSet{}
ret.SetModelManager(IpSetManager, ret)
ret.Name = ext.GetName()
ret.CloudregionId = self.Id
ret.ManagerId = provider.Id
ret.ExternalId = ext.GetGlobalId()
ret.Status = apis.STATUS_AVAILABLE
ret.IpSetType = api.TIpSetType(ext.GetIpSetType())
ret.Description = ext.GetDescription()
ret.Data = strings.Join(ext.GetAddresses(), ",")
err := IpSetManager.TableSpec().Insert(ctx, ret)
if err != nil {
return errors.Wrapf(err, "Insert")
}
syncVirtualResourceMetadata(ctx, userCred, ret, ext, false)
SyncCloudProject(ctx, userCred, ret, provider.GetOwnerId(), ext, provider)
return nil
}
+2
View File
@@ -303,6 +303,7 @@ func (self *SCloudregion) purgeResources(ctx context.Context, managerId string)
tables := TablestoreManager.Query("id").Equals("manager_id", managerId).Equals("cloudregion_id", self.Id)
wafs := WafInstanceManager.Query("id").Equals("manager_id", managerId).Equals("cloudregion_id", self.Id)
ipsets := WafIPSetManager.Query("id").Equals("manager_id", managerId).Equals("cloudregion_id", self.Id)
addressIpsets := IpSetManager.Query("id").Equals("manager_id", managerId).Equals("cloudregion_id", self.Id)
regsets := WafRegexSetManager.Query("id").Equals("manager_id", managerId).Equals("cloudregion_id", self.Id)
wafgroups := WafRuleGroupManager.Query("id").Equals("manager_id", managerId).Equals("cloudregion_id", self.Id)
cprs := CloudproviderRegionManager.Query("row_id").Equals("cloudprovider_id", managerId).Equals("cloudregion_id", self.Id)
@@ -312,6 +313,7 @@ func (self *SCloudregion) purgeResources(ctx context.Context, managerId string)
{manager: WafRuleGroupManager, key: "id", q: wafgroups},
{manager: WafRegexSetManager, key: "id", q: regsets},
{manager: WafIPSetManager, key: "id", q: ipsets},
{manager: IpSetManager, key: "id", q: addressIpsets},
{manager: WafInstanceManager, key: "id", q: wafs},
{manager: TablestoreManager, key: "id", q: tables},
{manager: SnapshotManager, key: "id", q: snapshots},
+110 -3
View File
@@ -353,7 +353,9 @@ func (self *SSecurityGroupRule) ValidateUpdateData(ctx context.Context, userCred
return nil, err
}
input.TargetType = self.TargetType
if len(input.TargetType) == 0 {
input.TargetType = self.TargetType
}
input, err = driver.ValidateUpdateSecurityGroupRuleInput(ctx, userCred, input)
if err != nil {
return nil, err
@@ -435,6 +437,43 @@ func (rule *SSecurityGroupRule) fetchIpSet() (*SIpSet, error) {
return ipSetObj.(*SIpSet), nil
}
func GetCloudSecgroupRuleCIDR(targetType api.TSecgroupTargetType, cidr string) (string, error) {
switch targetType {
case api.SecurityGroupRuleTargetTypeIpSet:
if len(cidr) == 0 {
return "", errors.Wrap(errors.ErrEmpty, "empty ip set id")
}
ipSetObj, err := IpSetManager.FetchById(cidr)
if err != nil {
return "", errors.Wrapf(err, "FetchById(%s)", cidr)
}
ipSet := ipSetObj.(*SIpSet)
if len(ipSet.ExternalId) == 0 {
return "", errors.Wrapf(errors.ErrInvalidStatus, "ipset %s has empty external_id", ipSet.Id)
}
return ipSet.ExternalId, nil
case api.SecurityGroupRuleTargetTypeSecurityGroup:
if len(cidr) == 0 {
return "", errors.Wrap(errors.ErrEmpty, "empty security group id")
}
secgroupObj, err := SecurityGroupManager.FetchById(cidr)
if err != nil {
return "", errors.Wrapf(err, "FetchById(%s)", cidr)
}
secgroup := secgroupObj.(*SSecurityGroup)
if len(secgroup.ExternalId) == 0 {
return "", errors.Wrapf(errors.ErrInvalidStatus, "security group %s has empty external_id", secgroup.Id)
}
return secgroup.ExternalId, nil
default:
return cidr, nil
}
}
func (rule *SSecurityGroupRule) GetCloudCIDR() (string, error) {
return GetCloudSecgroupRuleCIDR(rule.TargetType, rule.CIDR)
}
func (self *SSecurityGroupRule) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) {
self.SResourceBase.PostCreate(ctx, userCred, ownerId, query, data)
@@ -583,13 +622,79 @@ func (self *SSecurityGroup) SyncRules(
return result
}
func (self *SSecurityGroup) resolveCloudRuleTarget(ext cloudprovider.ISecurityGroupRule) (api.TSecgroupTargetType, string) {
cidr := strings.Join(ext.GetCIDRs(), ",")
targetType := api.TSecgroupTargetType(ext.GetTargetType())
if len(targetType) == 0 {
targetType = api.SecurityGroupRuleTargetTypeCidr
}
switch targetType {
case api.SecurityGroupRuleTargetTypeIpSet:
if len(cidr) > 0 {
ipSet, err := self.fetchIpSetByExternalId(cidr)
if err == nil && ipSet != nil {
return targetType, ipSet.Id
}
}
case api.SecurityGroupRuleTargetTypeSecurityGroup:
if len(cidr) > 0 {
secgroup, err := self.fetchSecGroupByExternalId(cidr)
if err == nil && secgroup != nil {
return targetType, secgroup.Id
}
}
}
return targetType, cidr
}
func (self *SSecurityGroup) fetchIpSetByExternalId(extId string) (*SIpSet, error) {
obj, err := db.FetchByExternalIdAndManagerId(IpSetManager, extId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
q = q.Equals("manager_id", self.ManagerId)
if len(self.CloudregionId) > 0 {
q = q.Filter(sqlchemy.OR(
sqlchemy.Equals(q.Field("cloudregion_id"), self.CloudregionId),
sqlchemy.IsNullOrEmpty(q.Field("cloudregion_id")),
))
}
return q
})
if err != nil {
return nil, err
}
return obj.(*SIpSet), nil
}
func (self *SSecurityGroup) fetchSecGroupByExternalId(extId string) (*SSecurityGroup, error) {
obj, err := db.FetchByExternalIdAndManagerId(SecurityGroupManager, extId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
q = q.Equals("manager_id", self.ManagerId)
if len(self.CloudregionId) > 0 {
q = q.Equals("cloudregion_id", self.CloudregionId)
}
return q
})
if err != nil {
return nil, err
}
return obj.(*SSecurityGroup), nil
}
func (rule *SSecurityGroupRule) syncWithCloudRule(ctx context.Context, userCred mcclient.TokenCredential, ext cloudprovider.ISecurityGroupRule) error {
secgroup, _ := rule.GetSecGroup()
targetType := api.TSecgroupTargetType(ext.GetTargetType())
if len(targetType) == 0 {
targetType = api.SecurityGroupRuleTargetTypeCidr
}
cidr := strings.Join(ext.GetCIDRs(), ",")
if secgroup != nil {
targetType, cidr = secgroup.resolveCloudRuleTarget(ext)
}
_, 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.CIDR = cidr
rule.TargetType = targetType
rule.Priority = ext.GetPriority()
rule.Ports = ext.GetPorts()
rule.Status = apis.STATUS_AVAILABLE
@@ -599,6 +704,7 @@ func (rule *SSecurityGroupRule) syncWithCloudRule(ctx context.Context, userCred
}
func (self *SSecurityGroup) newFromCloudRule(ctx context.Context, userCred mcclient.TokenCredential, ext cloudprovider.ISecurityGroupRule) error {
targetType, cidr := self.resolveCloudRuleTarget(ext)
rule := &SSecurityGroupRule{}
rule.SetModelManager(SecurityGroupRuleManager, rule)
rule.SecgroupId = self.Id
@@ -606,7 +712,8 @@ func (self *SSecurityGroup) newFromCloudRule(ctx context.Context, userCred mccli
rule.Direction = string(ext.GetDirection())
rule.Protocol = string(ext.GetProtocol())
rule.Description = string(ext.GetDescription())
rule.CIDR = strings.Join(ext.GetCIDRs(), ",")
rule.CIDR = cidr
rule.TargetType = targetType
rule.Priority = ext.GetPriority()
rule.Ports = ext.GetPorts()
rule.ExternalId = ext.GetGlobalId()
+28 -4
View File
@@ -679,8 +679,9 @@ func (self *SAliyunRegionDriver) ValidateCreateWafRuleData(ctx context.Context,
}
func (self *SAliyunRegionDriver) ValidateCreateSecurityGroupInput(ctx context.Context, userCred mcclient.TokenCredential, input *api.SSecgroupCreateInput) (*api.SSecgroupCreateInput, error) {
ipSetCidrs := map[int]string{}
for i := range input.Rules {
rule := input.Rules[i]
rule := &input.Rules[i]
if rule.Priority == nil {
return nil, httperrors.NewMissingParameterError("priority")
}
@@ -692,8 +693,31 @@ func (self *SAliyunRegionDriver) ValidateCreateSecurityGroupInput(ctx context.Co
if len(rule.Ports) > 0 && strings.Contains(input.Rules[i].Ports, ",") {
return nil, httperrors.NewInputParameterError("invalid ports %s", input.Rules[i].Ports)
}
if len(rule.TargetType) == 0 {
rule.TargetType = api.SecurityGroupRuleTargetTypeCidr
}
switch rule.TargetType {
case api.SecurityGroupRuleTargetTypeCidr:
case api.SecurityGroupRuleTargetTypeIpSet:
ipSet, err := validateSecgroupIpSet(ctx, userCred, rule.CIDR, input.CloudproviderId, input.CloudregionId, true)
if err != nil {
return nil, err
}
ipSetCidrs[i] = ipSet.Id
rule.CIDR = ""
default:
return nil, httperrors.NewInputParameterError("unsupported target type %s", rule.TargetType)
}
}
return self.SManagedVirtualizationRegionDriver.ValidateCreateSecurityGroupInput(ctx, userCred, input)
input, err := self.SManagedVirtualizationRegionDriver.ValidateCreateSecurityGroupInput(ctx, userCred, input)
if err != nil {
return nil, err
}
for i, cidr := range ipSetCidrs {
input.Rules[i].CIDR = cidr
}
return input, nil
}
func (self *SAliyunRegionDriver) ValidateCreateSecurityGroupRuleInput(ctx context.Context, userCred mcclient.TokenCredential, input *api.SSecgroupRuleCreateInput) (*api.SSecgroupRuleCreateInput, error) {
@@ -709,7 +733,7 @@ func (self *SAliyunRegionDriver) ValidateCreateSecurityGroupRuleInput(ctx contex
if len(rule.Ports) > 0 && strings.Contains(input.Ports, ",") {
return nil, httperrors.NewInputParameterError("invalid ports %s", input.Ports)
}
return self.SManagedVirtualizationRegionDriver.ValidateCreateSecurityGroupRuleInput(ctx, userCred, input)
return validateManagedSecgroupRuleCreateWithIpSet(ctx, userCred, input, self.SManagedVirtualizationRegionDriver.ValidateCreateSecurityGroupRuleInput)
}
func (self *SAliyunRegionDriver) ValidateUpdateSecurityGroupRuleInput(ctx context.Context, userCred mcclient.TokenCredential, input *api.SSecgroupRuleUpdateInput) (*api.SSecgroupRuleUpdateInput, error) {
@@ -721,5 +745,5 @@ func (self *SAliyunRegionDriver) ValidateUpdateSecurityGroupRuleInput(ctx contex
return nil, httperrors.NewInputParameterError("invalid ports %s", *input.Ports)
}
return self.SManagedVirtualizationRegionDriver.ValidateUpdateSecurityGroupRuleInput(ctx, userCred, input)
return validateManagedSecgroupRuleUpdateWithIpSet(ctx, userCred, input, "", "", self.SManagedVirtualizationRegionDriver.ValidateUpdateSecurityGroupRuleInput)
}
+27 -4
View File
@@ -47,8 +47,9 @@ func (self *SCloudpodsRegionDriver) ValidateCreateVpcData(ctx context.Context, u
}
func (self *SCloudpodsRegionDriver) ValidateCreateSecurityGroupInput(ctx context.Context, userCred mcclient.TokenCredential, input *api.SSecgroupCreateInput) (*api.SSecgroupCreateInput, error) {
ipSetCidrs := map[int]string{}
for i := range input.Rules {
rule := input.Rules[i]
rule := &input.Rules[i]
if rule.Priority == nil {
return nil, httperrors.NewMissingParameterError("priority")
}
@@ -57,8 +58,30 @@ func (self *SCloudpodsRegionDriver) ValidateCreateSecurityGroupInput(ctx context
return nil, httperrors.NewInputParameterError("invalid priority %d, range 1-100", *rule.Priority)
}
if len(rule.TargetType) == 0 {
rule.TargetType = api.SecurityGroupRuleTargetTypeCidr
}
switch rule.TargetType {
case api.SecurityGroupRuleTargetTypeCidr:
case api.SecurityGroupRuleTargetTypeIpSet:
ipSet, err := validateSecgroupIpSet(ctx, userCred, rule.CIDR, input.CloudproviderId, input.CloudregionId, true)
if err != nil {
return nil, err
}
ipSetCidrs[i] = ipSet.Id
rule.CIDR = ""
default:
return nil, httperrors.NewInputParameterError("unsupported target type %s", rule.TargetType)
}
}
return self.SManagedVirtualizationRegionDriver.ValidateCreateSecurityGroupInput(ctx, userCred, input)
input, err := self.SManagedVirtualizationRegionDriver.ValidateCreateSecurityGroupInput(ctx, userCred, input)
if err != nil {
return nil, err
}
for i, cidr := range ipSetCidrs {
input.Rules[i].CIDR = cidr
}
return input, nil
}
func (self *SCloudpodsRegionDriver) ValidateCreateSecurityGroupRuleInput(ctx context.Context, userCred mcclient.TokenCredential, input *api.SSecgroupRuleCreateInput) (*api.SSecgroupRuleCreateInput, error) {
@@ -70,7 +93,7 @@ func (self *SCloudpodsRegionDriver) ValidateCreateSecurityGroupRuleInput(ctx con
if *rule.Priority < 1 || *rule.Priority > 100 {
return nil, httperrors.NewInputParameterError("invalid priority %d, range 1-100", *rule.Priority)
}
return self.SManagedVirtualizationRegionDriver.ValidateCreateSecurityGroupRuleInput(ctx, userCred, input)
return validateManagedSecgroupRuleCreateWithIpSet(ctx, userCred, input, self.SManagedVirtualizationRegionDriver.ValidateCreateSecurityGroupRuleInput)
}
func (self *SCloudpodsRegionDriver) ValidateUpdateSecurityGroupRuleInput(ctx context.Context, userCred mcclient.TokenCredential, input *api.SSecgroupRuleUpdateInput) (*api.SSecgroupRuleUpdateInput, error) {
@@ -78,7 +101,7 @@ func (self *SCloudpodsRegionDriver) ValidateUpdateSecurityGroupRuleInput(ctx con
return nil, httperrors.NewInputParameterError("invalid priority %d, range 1-100", *input.Priority)
}
return self.SManagedVirtualizationRegionDriver.ValidateUpdateSecurityGroupRuleInput(ctx, userCred, input)
return validateManagedSecgroupRuleUpdateWithIpSet(ctx, userCred, input, "", "", self.SManagedVirtualizationRegionDriver.ValidateUpdateSecurityGroupRuleInput)
}
func (self *SCloudpodsRegionDriver) GetSecurityGroupFilter(vpc *models.SVpc) (func(q *sqlchemy.SQuery) *sqlchemy.SQuery, error) {
+7 -6
View File
@@ -301,12 +301,13 @@ func (self *SGoogleRegionDriver) RequestCreateSecurityGroup(
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,
Desc: rules[i].Description,
Direction: secrules.TSecurityRuleDirection(rules[i].Direction),
Action: secrules.TSecurityRuleAction(rules[i].Action),
Protocol: rules[i].Protocol,
CIDR: rules[i].CIDR,
TargetType: string(rules[i].TargetType),
Ports: rules[i].Ports,
}
_, err := iGroup.CreateRule(&opts)
if err != nil {
+100 -2
View File
@@ -91,7 +91,12 @@ func (self *SKVMRegionDriver) ValidateCreateSecurityGroupRuleInput(ctx context.C
switch input.TargetType {
case api.SecurityGroupRuleTargetTypeCidr:
case api.SecurityGroupRuleTargetTypeIpSet:
ipSet, err := validateIpSetId(ctx, userCred, input.CIDR)
secgroupObj, err := models.SecurityGroupManager.FetchById(input.SecgroupId)
if err != nil {
return nil, errors.Wrapf(err, "FetchById(%s)", input.SecgroupId)
}
secgroup := secgroupObj.(*models.SSecurityGroup)
ipSet, err := validateSecgroupIpSet(ctx, userCred, input.CIDR, secgroup.ManagerId, secgroup.CloudregionId, false)
if err != nil {
return nil, err
}
@@ -1636,12 +1641,105 @@ func validateIpSetId(ctx context.Context, userCred mcclient.TokenCredential, ipS
return nil, errors.Wrapf(err, "FetchByIdOrName")
}
ipSet := ipSetObj.(*models.SIpSet)
if !ipSet.IsSharable(userCred) {
if !ipSet.IsSharable(userCred) &&
!ipSet.IsOwner(userCred) &&
!db.IsDomainAllowGet(ctx, userCred, ipSet) &&
!db.IsAdminAllowGet(ctx, userCred, ipSet) {
return nil, errors.Wrapf(httperrors.ErrNotSufficientPrivilege, "ip set %s", ipSetId)
}
return ipSet, nil
}
func validateSecgroupIpSet(ctx context.Context, userCred mcclient.TokenCredential, ipSetId, managerId, cloudregionId string, requireExternal bool) (*models.SIpSet, error) {
ipSet, err := validateIpSetId(ctx, userCred, ipSetId)
if err != nil {
return nil, err
}
if len(managerId) > 0 && ipSet.ManagerId != managerId {
return nil, httperrors.NewInputParameterError("ip set %s and security group belong to different cloudproviders", ipSet.Name)
}
if len(managerId) == 0 && len(ipSet.ManagerId) > 0 {
return nil, httperrors.NewInputParameterError("ip set %s and security group belong to different cloudproviders", ipSet.Name)
}
if len(cloudregionId) > 0 && len(ipSet.CloudregionId) > 0 && ipSet.CloudregionId != cloudregionId {
return nil, httperrors.NewInputParameterError("ip set %s and security group belong to different cloudregions", ipSet.Name)
}
if requireExternal && len(ipSet.ExternalId) == 0 {
return nil, httperrors.NewInputParameterError("ip set %s has not been synchronized to cloud", ipSet.Name)
}
return ipSet, nil
}
func validateManagedSecgroupRuleCreateWithIpSet(
ctx context.Context,
userCred mcclient.TokenCredential,
input *api.SSecgroupRuleCreateInput,
baseValidate func(context.Context, mcclient.TokenCredential, *api.SSecgroupRuleCreateInput) (*api.SSecgroupRuleCreateInput, error),
) (*api.SSecgroupRuleCreateInput, error) {
if len(input.TargetType) == 0 {
input.TargetType = api.SecurityGroupRuleTargetTypeCidr
}
switch input.TargetType {
case api.SecurityGroupRuleTargetTypeCidr:
return baseValidate(ctx, userCred, input)
case api.SecurityGroupRuleTargetTypeIpSet:
secgroupObj, err := models.SecurityGroupManager.FetchById(input.SecgroupId)
if err != nil {
return nil, errors.Wrapf(err, "FetchById(%s)", input.SecgroupId)
}
secgroup := secgroupObj.(*models.SSecurityGroup)
ipSet, err := validateSecgroupIpSet(ctx, userCred, input.CIDR, secgroup.ManagerId, secgroup.CloudregionId, true)
if err != nil {
return nil, err
}
input.CIDR = ""
input, err = baseValidate(ctx, userCred, input)
if err != nil {
return nil, err
}
input.CIDR = ipSet.Id
return input, nil
default:
return nil, httperrors.NewInputParameterError("unsupported target type %s", input.TargetType)
}
}
func validateManagedSecgroupRuleUpdateWithIpSet(
ctx context.Context,
userCred mcclient.TokenCredential,
input *api.SSecgroupRuleUpdateInput,
managerId, cloudregionId string,
baseValidate func(context.Context, mcclient.TokenCredential, *api.SSecgroupRuleUpdateInput) (*api.SSecgroupRuleUpdateInput, error),
) (*api.SSecgroupRuleUpdateInput, error) {
if input.TargetType == api.SecurityGroupRuleTargetTypeIpSet {
if input.CIDR != nil && len(*input.CIDR) > 0 {
var ipSet *models.SIpSet
var err error
if len(managerId) > 0 {
ipSet, err = validateSecgroupIpSet(ctx, userCred, *input.CIDR, managerId, cloudregionId, true)
} else {
ipSet, err = validateIpSetId(ctx, userCred, *input.CIDR)
if err == nil && len(ipSet.ExternalId) == 0 {
err = httperrors.NewInputParameterError("ip set %s has not been synchronized to cloud", ipSet.Name)
}
}
if err != nil {
return nil, err
}
input.CIDR = &ipSet.Id
}
cidr := input.CIDR
input.CIDR = nil
input, err := baseValidate(ctx, userCred, input)
if err != nil {
return nil, err
}
input.CIDR = cidr
return input, nil
}
return baseValidate(ctx, userCred, input)
}
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 {
+13 -8
View File
@@ -3396,15 +3396,20 @@ func (self *SManagedVirtualizationRegionDriver) RequestCreateSecurityGroup(
}
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,
cidr, err := models.GetCloudSecgroupRuleCIDR(rules[i].TargetType, rules[i].CIDR)
if err != nil {
return errors.Wrapf(err, "GetCloudSecgroupRuleCIDR")
}
_, err := iGroup.CreateRule(&opts)
opts := cloudprovider.SecurityGroupRuleCreateOptions{
Desc: rules[i].Description,
Direction: secrules.TSecurityRuleDirection(rules[i].Direction),
Action: secrules.TSecurityRuleAction(rules[i].Action),
Protocol: rules[i].Protocol,
CIDR: cidr,
TargetType: string(rules[i].TargetType),
Ports: rules[i].Ports,
}
_, err = iGroup.CreateRule(&opts)
if err != nil {
return errors.Wrapf(err, "CreateRule")
}
+17 -3
View File
@@ -572,7 +572,7 @@ func (self *SQcloudRegionDriver) ValidateCreateCdnData(ctx context.Context, user
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]
rule := &input.Rules[i]
if rule.Priority == nil {
return nil, httperrors.NewMissingParameterError("priority")
}
@@ -581,6 +581,20 @@ func (self *SQcloudRegionDriver) ValidateCreateSecurityGroupInput(ctx context.Co
return nil, httperrors.NewInputParameterError("invalid priority %d, range 0-99", *rule.Priority)
}
if len(rule.TargetType) == 0 {
rule.TargetType = api.SecurityGroupRuleTargetTypeCidr
}
switch rule.TargetType {
case api.SecurityGroupRuleTargetTypeCidr:
case api.SecurityGroupRuleTargetTypeIpSet:
ipSet, err := validateSecgroupIpSet(ctx, userCred, rule.CIDR, input.CloudproviderId, input.CloudregionId, true)
if err != nil {
return nil, err
}
rule.CIDR = ipSet.Id
default:
return nil, httperrors.NewInputParameterError("unsupported target type %s", rule.TargetType)
}
}
return input, nil
}
@@ -595,7 +609,7 @@ func (self *SQcloudRegionDriver) ValidateCreateSecurityGroupRuleInput(ctx contex
return nil, httperrors.NewInputParameterError("invalid priority %d, range 0-99", *rule.Priority)
}
return input, nil
return validateManagedSecgroupRuleCreateWithIpSet(ctx, userCred, input, self.SManagedVirtualizationRegionDriver.ValidateCreateSecurityGroupRuleInput)
}
func (self *SQcloudRegionDriver) ValidateUpdateSecurityGroupRuleInput(ctx context.Context, userCred mcclient.TokenCredential, input *api.SSecgroupRuleUpdateInput) (*api.SSecgroupRuleUpdateInput, error) {
@@ -603,7 +617,7 @@ func (self *SQcloudRegionDriver) ValidateUpdateSecurityGroupRuleInput(ctx contex
return nil, httperrors.NewInputParameterError("invalid priority %d, range 0-99", *input.Priority)
}
return self.SManagedVirtualizationRegionDriver.ValidateUpdateSecurityGroupRuleInput(ctx, userCred, input)
return validateManagedSecgroupRuleUpdateWithIpSet(ctx, userCred, input, "", "", self.SManagedVirtualizationRegionDriver.ValidateUpdateSecurityGroupRuleInput)
}
func (self *SQcloudRegionDriver) GetSecurityGroupFilter(vpc *models.SVpc) (func(q *sqlchemy.SQuery) *sqlchemy.SQuery, error) {
+15
View File
@@ -0,0 +1,15 @@
// 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 ipset // import "yunion.io/x/onecloud/pkg/compute/tasks/ipset"
@@ -0,0 +1,90 @@
// 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 ipset
import (
"context"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"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 IpSetCreateTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(IpSetCreateTask{})
}
func (self *IpSetCreateTask) taskFailed(ctx context.Context, ipset *models.SIpSet, err error) {
ipset.SetStatus(ctx, self.UserCred, apis.STATUS_CREATE_FAILED, err.Error())
logclient.AddActionLogWithStartable(self, ipset, logclient.ACT_ALLOCATE, err, self.UserCred, false)
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *IpSetCreateTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
ipset := obj.(*models.SIpSet)
opts := &cloudprovider.IpSetCreateOptions{
Name: ipset.Name,
Desc: ipset.Description,
IpSetType: string(ipset.IpSetType),
Addresses: ipset.GetAddresses(),
}
var iIpSet cloudprovider.ICloudIpSet
var err error
if ipset.IsManaged() && len(ipset.CloudregionId) == 0 {
provider := ipset.GetCloudprovider()
if provider == nil {
self.taskFailed(ctx, ipset, errors.Errorf("empty cloudprovider"))
return
}
driver, err := provider.GetProvider(ctx)
if err != nil {
self.taskFailed(ctx, ipset, errors.Wrapf(err, "GetProvider"))
return
}
iIpSet, err = driver.CreateIIpSet(opts)
} else {
iRegion, err := ipset.GetIRegion(ctx)
if err != nil {
self.taskFailed(ctx, ipset, errors.Wrapf(err, "GetIRegion"))
return
}
iIpSet, err = iRegion.CreateIIpSet(opts)
}
if err != nil {
self.taskFailed(ctx, ipset, errors.Wrapf(err, "CreateIIpSet"))
return
}
_, err = db.Update(ipset, func() error {
ipset.ExternalId = iIpSet.GetGlobalId()
ipset.Status = apis.STATUS_AVAILABLE
return nil
})
if err != nil {
self.taskFailed(ctx, ipset, errors.Wrapf(err, "db.Update"))
return
}
logclient.AddActionLogWithStartable(self, ipset, logclient.ACT_ALLOCATE, nil, self.UserCred, true)
self.SetStageComplete(ctx, nil)
}
@@ -0,0 +1,67 @@
// 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 ipset
import (
"context"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"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 IpSetDeleteTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(IpSetDeleteTask{})
}
func (self *IpSetDeleteTask) taskFailed(ctx context.Context, ipset *models.SIpSet, err error) {
ipset.SetStatus(ctx, self.UserCred, apis.STATUS_DELETE_FAILED, err.Error())
logclient.AddActionLogWithStartable(self, ipset, logclient.ACT_DELOCATE, err, self.UserCred, false)
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *IpSetDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
ipset := obj.(*models.SIpSet)
iIpSet, err := ipset.GetICloudIpSet(ctx)
if err != nil {
if errors.Cause(err) == cloudprovider.ErrNotFound {
self.taskComplete(ctx, ipset)
return
}
self.taskFailed(ctx, ipset, errors.Wrapf(err, "GetICloudIpSet"))
return
}
err = iIpSet.Delete()
if err != nil {
self.taskFailed(ctx, ipset, errors.Wrapf(err, "Delete"))
return
}
self.taskComplete(ctx, ipset)
}
func (self *IpSetDeleteTask) taskComplete(ctx context.Context, ipset *models.SIpSet) {
ipset.RealDelete(ctx, self.GetUserCred())
self.SetStageComplete(ctx, nil)
}
@@ -0,0 +1,62 @@
// 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 ipset
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"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 IpSetSyncstatusTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(IpSetSyncstatusTask{})
}
func (self *IpSetSyncstatusTask) taskFailed(ctx context.Context, ipset *models.SIpSet, err error) {
ipset.SetStatus(ctx, self.UserCred, apis.STATUS_UNKNOWN, err.Error())
logclient.AddActionLogWithStartable(self, ipset, logclient.ACT_SYNC_STATUS, err, self.UserCred, false)
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *IpSetSyncstatusTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
ipset := obj.(*models.SIpSet)
iIpSet, err := ipset.GetICloudIpSet(ctx)
if err != nil {
self.taskFailed(ctx, ipset, errors.Wrapf(err, "GetICloudIpSet"))
return
}
provider := ipset.GetCloudprovider()
if provider == nil {
self.taskFailed(ctx, ipset, errors.Errorf("empty cloudprovider"))
return
}
err = ipset.SyncWithCloudIpSet(ctx, self.UserCred, iIpSet, provider, ipset.CloudregionId)
if err != nil {
self.taskFailed(ctx, ipset, errors.Wrapf(err, "SyncWithCloudIpSet"))
return
}
self.SetStageComplete(ctx, nil)
}
@@ -0,0 +1,63 @@
// 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 ipset
import (
"context"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"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 IpSetUpdateTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(IpSetUpdateTask{})
}
func (self *IpSetUpdateTask) taskFailed(ctx context.Context, ipset *models.SIpSet, err error) {
ipset.SetStatus(ctx, self.UserCred, apis.STATUS_UPDATE_FAILED, err.Error())
logclient.AddActionLogWithStartable(self, ipset, logclient.ACT_UPDATE, err, self.UserCred, false)
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *IpSetUpdateTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
ipset := obj.(*models.SIpSet)
iIpSet, err := ipset.GetICloudIpSet(ctx)
if err != nil {
self.taskFailed(ctx, ipset, errors.Wrapf(err, "GetICloudIpSet"))
return
}
err = iIpSet.Update(&cloudprovider.IpSetUpdateOptions{
Name: ipset.Name,
Addresses: ipset.GetAddresses(),
})
if err != nil {
self.taskFailed(ctx, ipset, errors.Wrapf(err, "Update"))
return
}
ipset.SetStatus(ctx, self.UserCred, apis.STATUS_AVAILABLE, "")
logclient.AddActionLogWithStartable(self, ipset, logclient.ACT_UPDATE, nil, self.UserCred, true)
self.SetStageComplete(ctx, nil)
}
+1
View File
@@ -35,6 +35,7 @@ import (
_ "yunion.io/x/onecloud/pkg/compute/tasks/guest"
_ "yunion.io/x/onecloud/pkg/compute/tasks/host"
_ "yunion.io/x/onecloud/pkg/compute/tasks/inter_vpc"
_ "yunion.io/x/onecloud/pkg/compute/tasks/ipset"
_ "yunion.io/x/onecloud/pkg/compute/tasks/kafka"
_ "yunion.io/x/onecloud/pkg/compute/tasks/kube"
_ "yunion.io/x/onecloud/pkg/compute/tasks/loadbalancer"
@@ -74,16 +74,22 @@ func (self *SecurityGroupRuleCreateTask) OnInit(ctx context.Context, obj db.ISta
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),
cidr, err := rule.GetCloudCIDR()
if err != nil {
self.taskFailed(ctx, secgroup, errors.Wrapf(err, "GetCloudCIDR"))
return
}
if len(opts.CIDR) == 0 {
opts := &cloudprovider.SecurityGroupRuleCreateOptions{
Desc: rule.Description,
Priority: rule.Priority,
Protocol: rule.Protocol,
Ports: rule.Ports,
Direction: secrules.TSecurityRuleDirection(rule.Direction),
CIDR: cidr,
TargetType: string(rule.TargetType),
Action: secrules.TSecurityRuleAction(rule.Action),
}
if len(opts.CIDR) == 0 && opts.TargetType != cloudprovider.SecurityGroupRuleTargetTypeIpSet {
opts.CIDR = "0.0.0.0/0"
}
@@ -87,13 +87,19 @@ func (self *SecurityGroupRuleUpdateTask) OnInit(ctx context.Context, obj db.ISta
for i := range rules {
if rules[i].GetGlobalId() == rule.ExternalId {
cidr, err := rule.GetCloudCIDR()
if err != nil {
self.taskFailed(ctx, secgroup, errors.Wrapf(err, "GetCloudCIDR"))
return
}
opts := &cloudprovider.SecurityGroupRuleUpdateOptions{
CIDR: rule.CIDR,
Action: secrules.TSecurityRuleAction(rule.Action),
Desc: rule.Description,
Ports: rule.Ports,
Protocol: rule.Protocol,
Priority: rule.Priority,
CIDR: cidr,
TargetType: string(rule.TargetType),
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 {
+158
View File
@@ -0,0 +1,158 @@
// 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 (
"strings"
"time"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/cloudmux/pkg/multicloud"
"yunion.io/x/jsonutils"
api "yunion.io/x/onecloud/pkg/apis/compute"
modules "yunion.io/x/onecloud/pkg/mcclient/modules/compute"
)
type SIpSet struct {
multicloud.SVirtualResourceBase
CloudpodsTags
region *SRegion
api.IpSetDetails
}
func (self *SIpSet) GetName() string {
return self.Name
}
func (self *SIpSet) GetId() string {
return self.Id
}
func (self *SIpSet) GetGlobalId() string {
return self.Id
}
func (self *SIpSet) GetStatus() string {
return self.Status
}
func (self *SIpSet) GetProjectId() string {
return self.TenantId
}
func (self *SIpSet) GetDescription() string {
return self.Description
}
func (self *SIpSet) GetCreatedAt() time.Time {
return self.CreatedAt
}
func (self *SIpSet) Refresh() error {
ipSet, err := self.region.GetIpSet(self.Id)
if err != nil {
return err
}
return jsonutils.Update(self, ipSet)
}
func (self *SIpSet) GetIpSetType() string {
return string(self.IpSetType)
}
func (self *SIpSet) GetAddresses() []string {
if len(self.Data) == 0 {
return []string{}
}
parts := strings.Split(self.Data, ",")
ret := make([]string, 0, len(parts))
for i := range parts {
addr := strings.TrimSpace(parts[i])
if len(addr) > 0 {
ret = append(ret, addr)
}
}
return ret
}
func (self *SIpSet) Update(opts *cloudprovider.IpSetUpdateOptions) error {
input := api.IpSetUpdateInput{}
if len(opts.Name) > 0 {
input.Name = opts.Name
}
if len(opts.Addresses) > 0 {
data := strings.Join(opts.Addresses, ",")
input.Data = &data
}
return self.region.cli.update(&modules.IpSets, self.Id, input)
}
func (self *SIpSet) Delete() error {
return self.region.cli.delete(&modules.IpSets, self.Id)
}
func (self *SRegion) GetIpSets() ([]SIpSet, error) {
ret := []SIpSet{}
return ret, self.list(&modules.IpSets, map[string]interface{}{"cloud_env": "onpremise"}, &ret)
}
func (self *SRegion) GetIpSet(id string) (*SIpSet, error) {
ipSet := &SIpSet{region: self}
return ipSet, self.cli.get(&modules.IpSets, id, nil, ipSet)
}
func (self *SRegion) GetIIpSets() ([]cloudprovider.ICloudIpSet, error) {
ipSets, err := self.GetIpSets()
if err != nil {
return nil, err
}
ret := []cloudprovider.ICloudIpSet{}
for i := range ipSets {
ipSets[i].region = self
ret = append(ret, &ipSets[i])
}
return ret, nil
}
func (self *SRegion) GetIIpSetById(id string) (cloudprovider.ICloudIpSet, error) {
ipSet, err := self.GetIpSet(id)
if err != nil {
return nil, err
}
return ipSet, nil
}
func (self *SRegion) CreateIIpSet(opts *cloudprovider.IpSetCreateOptions) (cloudprovider.ICloudIpSet, error) {
ipSetType := opts.IpSetType
if len(ipSetType) == 0 {
ipSetType = cloudprovider.IpSetTypeIpv4CidrList
for _, addr := range opts.Addresses {
if strings.Contains(addr, ":") {
ipSetType = cloudprovider.IpSetTypeIpv6CidrList
break
}
}
}
input := api.IpSetCreateInput{}
input.Name = opts.Name
input.Description = opts.Desc
input.IpSetType = api.TIpSetType(ipSetType)
input.Data = strings.Join(opts.Addresses, ",")
input.CloudregionId = self.Id
ipSet := &SIpSet{region: self}
return ipSet, self.create(&modules.IpSets, input, ipSet)
}
+4
View File
@@ -108,6 +108,10 @@ func (self *SRegion) CreateSecRule(secId string, opts *cloudprovider.SecurityGro
input.Direction = string(opts.Direction)
input.Description = opts.Desc
input.CIDR = opts.CIDR
input.TargetType = api.TSecgroupTargetType(opts.TargetType)
if len(input.TargetType) == 0 {
input.TargetType = api.SecurityGroupRuleTargetTypeCidr
}
input.Ports = opts.Ports
ret := &SecurityGroupRule{region: self}
+12
View File
@@ -51,6 +51,13 @@ func (self *SecurityGroupRule) GetCIDRs() []string {
return []string{self.CIDR}
}
func (self *SecurityGroupRule) GetTargetType() string {
if len(self.TargetType) > 0 {
return string(self.TargetType)
}
return cloudprovider.SecurityGroupRuleTargetTypeCidr
}
func (self *SecurityGroupRule) GetProtocol() string {
return self.Protocol
}
@@ -77,5 +84,10 @@ func (self *SecurityGroupRule) Update(opts *cloudprovider.SecurityGroupRuleUpdat
input.Description = opts.Desc
input.CIDR = &opts.CIDR
input.Ports = &opts.Ports
if len(opts.TargetType) > 0 {
input.TargetType = api.TSecgroupTargetType(opts.TargetType)
} else {
input.TargetType = api.SecurityGroupRuleTargetTypeCidr
}
return self.region.cli.update(&modules.SecGroupRules, self.Id, input)
}
+46
View File
@@ -0,0 +1,46 @@
// 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 shell
import (
"yunion.io/x/pkg/util/shellutils"
"yunion.io/x/onecloud/pkg/mcclient/cloudpods"
)
func init() {
type IpSetListOptions struct {
}
shellutils.R(&IpSetListOptions{}, "ipset-list", "List ipsets", func(cli *cloudpods.SRegion, args *IpSetListOptions) error {
ipSets, err := cli.GetIpSets()
if err != nil {
return err
}
printList(ipSets, 0, 0, 0, nil)
return nil
})
type IpSetIdOptions struct {
ID string
}
shellutils.R(&IpSetIdOptions{}, "ipset-show", "Show ipset", func(cli *cloudpods.SRegion, args *IpSetIdOptions) error {
ipSet, err := cli.GetIpSet(args.ID)
if err != nil {
return err
}
printObject(ipSet)
return nil
})
}
+8 -4
View File
@@ -23,8 +23,10 @@ import (
type IpSetListOptions struct {
options.BaseListOptions
IPSetType []string `help:"filter by ip set type" choices:"ipv4_cidr_list|ipv6_cidr_list" json:"ip_set_type"`
Ip string `help:"filter by ip or cidr" json:"ip"`
IPSetType []string `help:"filter by ip set type" choices:"ipv4_cidr_list|ipv6_cidr_list" json:"ip_set_type"`
Ip string `help:"filter by ip or cidr" json:"ip"`
Cloudregion string `help:"filter by cloudregion" json:"cloudregion_id"`
ExternalId string `help:"filter by external id" json:"external_id"`
}
func (opts *IpSetListOptions) Params() (jsonutils.JSONObject, error) {
@@ -34,8 +36,10 @@ func (opts *IpSetListOptions) Params() (jsonutils.JSONObject, error) {
type IpSetCreateOptions struct {
options.BaseCreateOptions
IPSetType string `help:"ip set type" choices:"ipv4_cidr_list|ipv6_cidr_list" json:"ip_set_type" required:"true"`
Data string `help:"comma separated ip/cidr list, e.g. 192.168.1.0/24,10.0.0.1" json:"data" required:"true"`
IPSetType string `help:"ip set type" choices:"ipv4_cidr_list|ipv6_cidr_list" json:"ip_set_type" required:"true"`
Data string `help:"comma separated ip/cidr list, e.g. 192.168.1.0/24,10.0.0.1" json:"data" required:"true"`
CloudregionId string `help:"cloudregion id" json:"cloudregion_id"`
ManagerId string `help:"cloudprovider id" json:"manager_id"`
}
func (opts *IpSetCreateOptions) Params() (jsonutils.JSONObject, error) {
+36 -13
View File
@@ -41,12 +41,14 @@ func (opts *SecGroupRulesListOptions) Params() (jsonutils.JSONObject, error) {
}
type SecGroupRulesCreateOptions struct {
_ struct{} `mcp-desc:"创建安全组规则。SECGROUP 为安全组 id/name,RULE 为规则字符串(如 in:allow tcp 22);可用 climc_secgroup_list 定位安全组"`
_ struct{} `mcp-desc:"创建安全组规则。SECGROUP 为安全组 id/name,RULE 为规则字符串(如 in:allow tcp 22);腾讯云可用 --ip-set 指定地址模板;可用 climc_secgroup_list 定位安全组"`
SECGROUP string `help:"Secgroup ID or Name" metavar:"Secgroup"`
RULE string `json:"-"`
Priority int64 `help:"priority of Rule" default:"50" mcp:"true"`
Desc string `help:"Description" json:"description" mcp:"true"`
SECGROUP string `help:"Secgroup ID or Name" metavar:"Secgroup"`
RULE string `json:"-"`
Priority int64 `help:"priority of Rule" default:"50" mcp:"true"`
Desc string `help:"Description" json:"description" mcp:"true"`
TargetType string `help:"Target type" choices:"cidr|ip_set" json:"target_type"`
IpSet string `help:"Ip set ID or name when target type is ip_set"`
}
// SecGroupRuleShowOptions / SecGroupRuleDeleteOptions 单独包装,避免复用 BaseShow/BaseId 误注册。
@@ -67,27 +69,42 @@ func (opts *SecGroupRulesCreateOptions) Params() (jsonutils.JSONObject, error) {
if err != nil {
return nil, errors.Wrapf(err, "invalid rule %s", opts.RULE)
}
targetType := opts.TargetType
cidr := ""
if rule.IPNet != nil {
cidr = rule.IPNet.String()
}
if len(opts.IpSet) > 0 {
targetType = "ip_set"
cidr = opts.IpSet
}
if len(targetType) == 0 {
targetType = "cidr"
}
return jsonutils.Marshal(map[string]interface{}{
"direction": rule.Direction,
"action": rule.Action,
"protocol": rule.Protocol,
"cidr": rule.IPNet.String(),
"cidr": cidr,
"ports": rule.GetPortsString(),
"priority": opts.Priority,
"description": opts.Desc,
"secgroup_id": opts.SECGROUP,
"target_type": targetType,
}), nil
}
type SecGroupRulesUpdateOptions struct {
options.BaseIdOptions
Name string `help:"New name of rule"`
Priority int64 `help:"priority of Rule"`
Protocol string `help:"Protocol of rule" choices:"any|tcp|udp|icmp"`
Ports string `help:"Ports of rule"`
Cidr string `help:"Cidr of rule"`
Action string `help:"filter Action of rule" choices:"allow|deny"`
Desc string `help:"Description" metavar:"Description"`
Name string `help:"New name of rule"`
Priority int64 `help:"priority of Rule"`
Protocol string `help:"Protocol of rule" choices:"any|tcp|udp|icmp"`
Ports string `help:"Ports of rule"`
Cidr string `help:"Cidr of rule"`
IpSet string `help:"Ip set ID or name when target type is ip_set"`
TargetType string `help:"Target type" choices:"cidr|ip_set"`
Action string `help:"filter Action of rule" choices:"allow|deny"`
Desc string `help:"Description" metavar:"Description"`
}
func (opts *SecGroupRulesUpdateOptions) Params() (jsonutils.JSONObject, error) {
@@ -110,6 +127,12 @@ func (opts *SecGroupRulesUpdateOptions) Params() (jsonutils.JSONObject, error) {
if len(opts.Cidr) > 0 {
params.Add(jsonutils.NewString(opts.Cidr), "cidr")
}
if len(opts.IpSet) > 0 {
params.Add(jsonutils.NewString(opts.IpSet), "cidr")
params.Add(jsonutils.NewString("ip_set"), "target_type")
} else if len(opts.TargetType) > 0 {
params.Add(jsonutils.NewString(opts.TargetType), "target_type")
}
if len(opts.Action) > 0 {
params.Add(jsonutils.NewString(opts.Action), "action")
}
+1 -1
View File
@@ -2545,7 +2545,7 @@ sigs.k8s.io/structured-merge-diff/v4/value
# sigs.k8s.io/yaml v1.3.0
## explicit; go 1.12
sigs.k8s.io/yaml
# yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20260812062623-2b79dfea19bd
# yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20260819093747-311f52c4fa1a
## explicit; go 1.24
yunion.io/x/cloudmux/pkg/apis
yunion.io/x/cloudmux/pkg/apis/billing
+16
View File
@@ -312,6 +312,10 @@ type ICloudProvider interface {
GetISSLCertificates() ([]ICloudSSLCertificate, error)
CreateISSLCertificate(opts *SSLCertificateCreateOptions) (ICloudSSLCertificate, error)
GetIIpSets() ([]ICloudIpSet, error)
GetIIpSetById(id string) (ICloudIpSet, error)
CreateIIpSet(opts *IpSetCreateOptions) (ICloudIpSet, error)
GetIAiGateways() ([]IAiGateway, error)
GetIAiGatewayById(id string) (IAiGateway, error)
CreateIAiGateway(opts *AiGatewayCreateOptions) (IAiGateway, error)
@@ -675,6 +679,18 @@ func (base *SBaseProvider) GetNotices() ([]INotice, error) {
return nil, errors.Wrapf(ErrNotImplemented, "GetNotices")
}
func (base *SBaseProvider) GetIIpSets() ([]ICloudIpSet, error) {
return nil, errors.Wrapf(ErrNotImplemented, "GetIIpSets")
}
func (base *SBaseProvider) GetIIpSetById(id string) (ICloudIpSet, error) {
return nil, errors.Wrapf(ErrNotImplemented, "GetIIpSetById")
}
func (base *SBaseProvider) CreateIIpSet(opts *IpSetCreateOptions) (ICloudIpSet, error) {
return nil, errors.Wrapf(ErrNotImplemented, "CreateIIpSet")
}
func NewBaseProvider(factory ICloudProviderFactory) SBaseProvider {
return SBaseProvider{factory: factory}
}
+42
View File
@@ -0,0 +1,42 @@
// 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 cloudprovider
const (
IpSetTypeIpv4CidrList = "ipv4_cidr_list"
IpSetTypeIpv6CidrList = "ipv6_cidr_list"
)
type IpSetCreateOptions struct {
Name string
Desc string
IpSetType string
Addresses []string
}
type IpSetUpdateOptions struct {
Name string
Addresses []string
}
type ICloudIpSet interface {
IVirtualResource
GetIpSetType() string
GetAddresses() []string
Update(opts *IpSetUpdateOptions) error
Delete() error
}
+5
View File
@@ -94,6 +94,10 @@ type ICloudRegion interface {
GetISecurityGroupById(secgroupId string) (ICloudSecurityGroup, error)
CreateISecurityGroup(opts *SecurityGroupCreateInput) (ICloudSecurityGroup, error)
GetIIpSets() ([]ICloudIpSet, error)
GetIIpSetById(id string) (ICloudIpSet, error)
CreateIIpSet(opts *IpSetCreateOptions) (ICloudIpSet, error)
CreateIVpc(opts *VpcCreateOptions) (ICloudVpc, error)
CreateInternetGateway() (ICloudInternetGateway, error)
CreateEIP(eip *SEip) (ICloudEIP, error)
@@ -539,6 +543,7 @@ type ISecurityGroupRule interface {
GetPorts() string
GetDescription() string
GetCIDRs() []string
GetTargetType() string
Update(opts *SecurityGroupRuleUpdateOptions) error
Delete() error
+22 -13
View File
@@ -26,6 +26,13 @@ type SecurityGroupReference struct {
Name string
}
const (
SecurityGroupRuleTargetTypeCidr = "cidr"
SecurityGroupRuleTargetTypeIpSet = "ip_set"
SecurityGroupRuleTargetTypeIpSetGroup = "ip_set_group"
SecurityGroupRuleTargetTypeSecurityGroup = "security_group"
)
type SecurityGroupCreateInput struct {
Name string
Desc string
@@ -36,22 +43,24 @@ type SecurityGroupCreateInput struct {
}
type SecurityGroupRuleCreateOptions struct {
Desc string
Priority int
Protocol string
Ports string
Direction secrules.TSecurityRuleDirection
CIDR string
Action secrules.TSecurityRuleAction
Desc string
Priority int
Protocol string
Ports string
Direction secrules.TSecurityRuleDirection
CIDR string
TargetType string
Action secrules.TSecurityRuleAction
}
type SecurityGroupRuleUpdateOptions struct {
CIDR string
Action secrules.TSecurityRuleAction
Desc string
Ports string
Protocol string
Priority int
CIDR string
TargetType string
Action secrules.TSecurityRuleAction
Desc string
Ports string
Protocol string
Priority int
}
func (rule *SecurityGroupRuleCreateOptions) String() string {
+282
View File
@@ -0,0 +1,282 @@
// 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/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/utils"
api "yunion.io/x/cloudmux/pkg/apis"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/cloudmux/pkg/multicloud"
)
type SPrefixList struct {
multicloud.SVirtualResourceBase
AliyunTags
region *SRegion
PrefixListId string
PrefixListName string
PrefixListDescription string
IpVersion string
CreationTime time.Time
CidrBlocks []string
MaxEntries int
PrefixListStatus string
Status string
RegionId string
ResourceGroupId string
ShareType string
PrefixListType string
}
func (self *SPrefixList) GetId() string {
return self.PrefixListId
}
func (self *SPrefixList) GetName() string {
if len(self.PrefixListName) > 0 {
return self.PrefixListName
}
return self.PrefixListId
}
func (self *SPrefixList) GetGlobalId() string {
return self.PrefixListId
}
func (self *SPrefixList) GetStatus() string {
status := self.PrefixListStatus
if len(status) == 0 {
status = self.Status
}
switch strings.ToLower(status) {
case "created":
return api.STATUS_AVAILABLE
case "modifying":
return "sync_status"
default:
return strings.ToLower(status)
}
}
func (self *SPrefixList) GetCreatedAt() time.Time {
return self.CreationTime
}
func (self *SPrefixList) GetDescription() string {
return self.PrefixListDescription
}
func (self *SPrefixList) Refresh() error {
pl, err := self.region.GetPrefixList(self.PrefixListId)
if err != nil {
return err
}
return jsonutils.Update(self, pl)
}
func (self *SPrefixList) GetIpSetType() string {
if strings.Contains(strings.ToUpper(self.IpVersion), "IPV6") {
return cloudprovider.IpSetTypeIpv6CidrList
}
return cloudprovider.IpSetTypeIpv4CidrList
}
func (self *SPrefixList) GetAddresses() []string {
return self.CidrBlocks
}
func (self *SPrefixList) Update(opts *cloudprovider.IpSetUpdateOptions) error {
return self.region.ModifyPrefixList(self.PrefixListId, opts)
}
func (self *SPrefixList) Delete() error {
return self.region.DeletePrefixList(self.PrefixListId)
}
func ipSetTypeToAliyunIpVersion(ipSetType string) string {
if ipSetType == cloudprovider.IpSetTypeIpv6CidrList {
return "IPv6"
}
return "IPv4"
}
func (self *SRegion) listPrefixLists(id, nextToken string, maxResults int) ([]SPrefixList, string, error) {
params := map[string]string{
"RegionId": self.RegionId,
}
if len(id) > 0 {
params["PrefixListIds.1"] = id
}
if len(nextToken) > 0 {
params["NextToken"] = nextToken
}
if maxResults <= 0 {
maxResults = 50
}
params["MaxResults"] = fmt.Sprintf("%d", maxResults)
body, err := self.vpcRequest("ListPrefixLists", params)
if err != nil {
return nil, "", errors.Wrapf(err, "ListPrefixLists")
}
ret := struct {
PrefixLists []SPrefixList
NextToken string
}{}
err = body.Unmarshal(&ret)
if err != nil {
return nil, "", errors.Wrapf(err, "Unmarshal")
}
return ret.PrefixLists, ret.NextToken, nil
}
func (self *SRegion) GetPrefixList(id string) (*SPrefixList, error) {
lists, _, err := self.listPrefixLists(id, "", 1)
if err != nil {
return nil, err
}
for i := range lists {
if lists[i].PrefixListId == id {
lists[i].region = self
return &lists[i], nil
}
}
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "%s", id)
}
func (self *SRegion) GetPrefixLists() ([]SPrefixList, error) {
ret := []SPrefixList{}
nextToken := ""
for {
part, token, err := self.listPrefixLists("", nextToken, 100)
if err != nil {
return nil, err
}
for i := range part {
part[i].region = self
ret = append(ret, part[i])
}
if len(token) == 0 || len(part) == 0 {
break
}
nextToken = token
}
return ret, nil
}
func (self *SRegion) GetIIpSets() ([]cloudprovider.ICloudIpSet, error) {
lists, err := self.GetPrefixLists()
if err != nil {
return nil, err
}
ret := make([]cloudprovider.ICloudIpSet, 0, len(lists))
for i := range lists {
ret = append(ret, &lists[i])
}
return ret, nil
}
func (self *SRegion) GetIIpSetById(id string) (cloudprovider.ICloudIpSet, error) {
return self.GetPrefixList(id)
}
func (self *SRegion) CreatePrefixList(opts *cloudprovider.IpSetCreateOptions) (*SPrefixList, error) {
maxEntries := len(opts.Addresses)
if maxEntries < 50 {
maxEntries = 50
}
params := map[string]string{
"RegionId": self.RegionId,
"PrefixListName": opts.Name,
"PrefixListDescription": opts.Desc,
"IpVersion": ipSetTypeToAliyunIpVersion(opts.IpSetType),
"MaxEntries": fmt.Sprintf("%d", maxEntries),
}
for i := range opts.Addresses {
params[fmt.Sprintf("PrefixListEntries.%d.Cidr", i+1)] = opts.Addresses[i]
}
body, err := self.vpcRequest("CreateVpcPrefixList", params)
if err != nil {
return nil, errors.Wrapf(err, "CreateVpcPrefixList")
}
id, _ := body.GetString("PrefixListId")
if len(id) == 0 {
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "empty PrefixListId after create")
}
return self.GetPrefixList(id)
}
func (self *SRegion) CreateIIpSet(opts *cloudprovider.IpSetCreateOptions) (cloudprovider.ICloudIpSet, error) {
return self.CreatePrefixList(opts)
}
func diffPrefixListAddresses(oldAddrs, newAddrs []string) (added, removed []string) {
for _, addr := range newAddrs {
if !utils.IsInStringArray(addr, oldAddrs) {
added = append(added, addr)
}
}
for _, addr := range oldAddrs {
if !utils.IsInStringArray(addr, newAddrs) {
removed = append(removed, addr)
}
}
return added, removed
}
func (self *SRegion) ModifyPrefixList(id string, opts *cloudprovider.IpSetUpdateOptions) error {
params := map[string]string{
"RegionId": self.RegionId,
"PrefixListId": id,
}
if len(opts.Name) > 0 {
params["PrefixListName"] = opts.Name
}
if len(opts.Addresses) > 0 {
cur, err := self.GetPrefixList(id)
if err != nil {
return errors.Wrapf(err, "GetPrefixList")
}
added, removed := diffPrefixListAddresses(cur.GetAddresses(), opts.Addresses)
for i := range added {
params[fmt.Sprintf("AddPrefixListEntry.%d.Cidr", i+1)] = added[i]
}
for i := range removed {
params[fmt.Sprintf("RemovePrefixListEntry.%d.Cidr", i+1)] = removed[i]
}
if len(opts.Addresses) > cur.MaxEntries {
params["MaxEntries"] = fmt.Sprintf("%d", len(opts.Addresses))
}
}
_, err := self.vpcRequest("ModifyVpcPrefixList", params)
return errors.Wrapf(err, "ModifyVpcPrefixList")
}
func (self *SRegion) DeletePrefixList(id string) error {
params := map[string]string{
"RegionId": self.RegionId,
"PrefixListId": id,
}
_, err := self.vpcRequest("DeleteVpcPrefixList", params)
return errors.Wrapf(err, "DeleteVpcPrefixList")
}
+61 -18
View File
@@ -46,6 +46,8 @@ type SPermission struct {
SourceGroupId string
SourceGroupName string
SourceGroupOwnerAccount string
SourcePrefixListId string
DestPrefixListId string
SecurityGroupRuleId string
SecurityGroupId string
}
@@ -74,6 +76,12 @@ func (self *SPermission) GetDirection() secrules.TSecurityRuleDirection {
func (self *SPermission) GetCIDRs() []string {
ret := []string{}
if len(self.SourcePrefixListId) > 0 {
ret = append(ret, self.SourcePrefixListId)
}
if len(self.DestPrefixListId) > 0 {
ret = append(ret, self.DestPrefixListId)
}
if len(self.SourceCidrIp) > 0 {
ret = append(ret, self.SourceCidrIp)
}
@@ -81,7 +89,7 @@ func (self *SPermission) GetCIDRs() []string {
ret = append(ret, self.SourceGroupId)
}
if len(self.DestGroupId) > 0 {
ret = append(ret, self.SourceGroupId)
ret = append(ret, self.DestGroupId)
}
if len(self.DestCidrIp) > 0 {
ret = append(ret, self.DestCidrIp)
@@ -95,6 +103,53 @@ func (self *SPermission) GetCIDRs() []string {
return ret
}
func (self *SPermission) GetTargetType() string {
if len(self.SourcePrefixListId) > 0 || len(self.DestPrefixListId) > 0 {
return cloudprovider.SecurityGroupRuleTargetTypeIpSet
}
if len(self.SourceGroupId) > 0 || len(self.DestGroupId) > 0 {
return cloudprovider.SecurityGroupRuleTargetTypeSecurityGroup
}
return cloudprovider.SecurityGroupRuleTargetTypeCidr
}
func setSecgroupRuleTarget(params map[string]string, prefix string, direction secrules.TSecurityRuleDirection, cidr, targetType string) {
switch targetType {
case cloudprovider.SecurityGroupRuleTargetTypeIpSet:
if direction == secrules.DIR_IN {
params[prefix+"SourcePrefixListId"] = cidr
} else {
params[prefix+"DestPrefixListId"] = cidr
}
case cloudprovider.SecurityGroupRuleTargetTypeSecurityGroup:
if direction == secrules.DIR_IN {
params[prefix+"SourceGroupId"] = cidr
} else {
params[prefix+"DestGroupId"] = cidr
}
default:
if direction == secrules.DIR_IN {
if _, err := netutils.NewIPV6Prefix(cidr); err == nil {
params[prefix+"Ipv6SourceCidrIp"] = cidr
} else {
if len(cidr) == 0 {
cidr = "0.0.0.0/0"
}
params[prefix+"SourceCidrIp"] = cidr
}
} else {
if _, err := netutils.NewIPV6Prefix(cidr); err == nil {
params[prefix+"Ipv6DestCidrIp"] = cidr
} else {
if len(cidr) == 0 {
cidr = "0.0.0.0/0"
}
params[prefix+"DestCidrIp"] = cidr
}
}
}
}
func (self *SPermission) GetProtocol() string {
if strings.ToLower(self.IpProtocol) == "all" {
return secrules.PROTO_ANY
@@ -173,6 +228,7 @@ func (self *SRegion) DeleteSecurityGroupRule(groupId string, direction secrules.
func (self *SRegion) UpdateSecurityGroupRule(groupId, ruleId string, direction secrules.TSecurityRuleDirection, opts *cloudprovider.SecurityGroupRuleUpdateOptions) error {
params := map[string]string{
"RegionId": self.RegionId,
"ClientToken": utils.GenRequestId(20),
"SecurityGroupId": groupId,
"SecurityGroupRuleId": ruleId,
@@ -206,24 +262,11 @@ func (self *SRegion) UpdateSecurityGroupRule(groupId, ruleId string, direction s
params["Policy"] = "drop"
}
action := "ModifySecurityGroupRule"
switch direction {
case secrules.DIR_IN:
if len(opts.CIDR) > 0 {
if _, err := netutils.NewIPV6Prefix(opts.CIDR); err == nil {
params["Ipv6SourceCidrIp"] = opts.CIDR
} else {
params["SourceCidrIp"] = opts.CIDR
}
}
case secrules.DIR_OUT:
if direction == secrules.DIR_OUT {
action = "ModifySecurityGroupEgressRule"
if len(opts.CIDR) > 0 {
if _, err := netutils.NewIPV6Prefix(opts.CIDR); err == nil {
params["Ipv6DestCidrIp"] = opts.CIDR
} else {
params["DestCidrIp"] = opts.CIDR
}
}
}
if len(opts.CIDR) > 0 {
setSecgroupRuleTarget(params, "", direction, opts.CIDR, opts.TargetType)
}
_, err := self.ecsRequest(action, params)
return err
+2 -19
View File
@@ -21,7 +21,6 @@ import (
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/netutils"
"yunion.io/x/pkg/util/secrules"
"yunion.io/x/pkg/utils"
@@ -276,26 +275,10 @@ func (self *SRegion) CreateSecurityGroupRule(secGrpId string, opts *cloudprovide
action := "AuthorizeSecurityGroup"
params["Permissions.1.Priority"] = fmt.Sprintf("%d", opts.Priority)
if opts.Direction == secrules.SecurityRuleIngress {
if _, err := netutils.NewIPV6Prefix(opts.CIDR); err == nil {
params["Permissions.1.Ipv6SourceCidrIp"] = opts.CIDR
} else {
params["Permissions.1.SourceCidrIp"] = "0.0.0.0/0"
if len(opts.CIDR) > 0 {
params["Permissions.1.SourceCidrIp"] = opts.CIDR
}
}
} else {
if _, err := netutils.NewIPV6Prefix(opts.CIDR); err == nil {
params["Permissions.1.Ipv6DestCidrIp"] = opts.CIDR
} else {
params["Permissions.1.DestCidrIp"] = "0.0.0.0/0"
if len(opts.CIDR) > 0 {
params["Permissions.1.DestCidrIp"] = opts.CIDR
}
}
if opts.Direction != secrules.SecurityRuleIngress {
action = "AuthorizeSecurityGroupEgress"
}
setSecgroupRuleTarget(params, "Permissions.1.", opts.Direction, opts.CIDR, opts.TargetType)
_, err := self.ecsRequest(action, params)
return err
}
+7
View File
@@ -87,6 +87,13 @@ func (self *SPermission) GetCIDRs() []string {
return ret
}
func (self *SPermission) GetTargetType() string {
if len(self.SourceGroupId) > 0 || len(self.DestGroupId) > 0 {
return cloudprovider.SecurityGroupRuleTargetTypeSecurityGroup
}
return cloudprovider.SecurityGroupRuleTargetTypeCidr
}
func (self *SPermission) GetProtocol() string {
if strings.ToLower(self.IpProtocol) == "all" {
return secrules.PROTO_ANY
+10
View File
@@ -67,6 +67,16 @@ func (self *SSecurityGroupRule) GetCIDRs() []string {
return ret
}
func (self *SSecurityGroupRule) GetTargetType() string {
if len(self.PrefixListId) > 0 {
return cloudprovider.SecurityGroupRuleTargetTypeIpSet
}
if len(self.ReferencedGroupInfo.GroupId) > 0 {
return cloudprovider.SecurityGroupRuleTargetTypeSecurityGroup
}
return cloudprovider.SecurityGroupRuleTargetTypeCidr
}
func (self *SSecurityGroupRule) GetProtocol() string {
if self.IpProtocol == "-1" {
return secrules.PROTO_ANY
+4
View File
@@ -99,6 +99,10 @@ func (self *SecurityRules) GetCIDRs() []string {
return ret
}
func (self *SecurityRules) GetTargetType() string {
return cloudprovider.SecurityGroupRuleTargetTypeCidr
}
func (self *SecurityRules) GetPorts() string {
ports := []string{}
if len(self.Properties.DestinationPortRange) > 0 && self.Properties.DestinationPortRange != "*" {
+7
View File
@@ -95,6 +95,13 @@ func (self *SSecurityGroupRule) GetCIDRs() []string {
return ret
}
func (self *SSecurityGroupRule) GetTargetType() string {
if len(self.DestGroupId) > 0 || len(self.SourceGroupId) > 0 {
return cloudprovider.SecurityGroupRuleTargetTypeSecurityGroup
}
return cloudprovider.SecurityGroupRuleTargetTypeCidr
}
func (self *SSecurityGroupRule) GetProtocol() string {
if strings.ToLower(self.Protocol) == "all" || len(self.Protocol) == 0 {
return secrules.PROTO_ANY
@@ -83,6 +83,10 @@ func (self *IPPermissions) GetCIDRs() []string {
return nets
}
func (self *IPPermissions) GetTargetType() string {
return cloudprovider.SecurityGroupRuleTargetTypeCidr
}
func (self *IPPermissions) GetDirection() secrules.TSecurityRuleDirection {
return self.direction
}
+4
View File
@@ -83,6 +83,10 @@ func (self *SSecurityGroupRule) GetCIDRs() []string {
return []string{self.DestCidrIP}
}
func (self *SSecurityGroupRule) GetTargetType() string {
return cloudprovider.SecurityGroupRuleTargetTypeCidr
}
func (self *SSecurityGroupRule) Delete() error {
err := self.secgroup.region.DeleteSecgroupRule(self.SecurityGroupId, self.Id, self.GetDirection())
if err != nil {
+7
View File
@@ -80,6 +80,13 @@ func (r *SSecurityGroupRule) GetCIDRs() []string {
return []string{r.RemoteIpPrefix}
}
func (r *SSecurityGroupRule) GetTargetType() string {
if r.AimSgid != nil && len(*r.AimSgid) > 0 {
return cloudprovider.SecurityGroupRuleTargetTypeSecurityGroup
}
return cloudprovider.SecurityGroupRuleTargetTypeCidr
}
func (r *SSecurityGroupRule) Update(opts *cloudprovider.SecurityGroupRuleUpdateOptions) error {
return errors.ErrNotSupported
}
+4
View File
@@ -77,6 +77,10 @@ func (self *SFirewall) GetCIDRs() []string {
return append(self.SourceRanges, self.DestinationRanges...)
}
func (self *SFirewall) GetTargetType() string {
return cloudprovider.SecurityGroupRuleTargetTypeCidr
}
func (self *SFirewall) GetProtocol() string {
ret := func() string {
if len(self.Allowed)+len(self.Denied) == 1 {
+7
View File
@@ -89,6 +89,13 @@ func (self *SecurityGroupRule) GetCIDRs() []string {
return ret
}
func (self *SecurityGroupRule) GetTargetType() string {
if len(self.RemoteGroupId) > 0 {
return cloudprovider.SecurityGroupRuleTargetTypeSecurityGroup
}
return cloudprovider.SecurityGroupRuleTargetTypeCidr
}
func (self *SecurityGroupRule) Delete() error {
return self.secgroup.region.DeleteSecurityGroupRule(self.Id)
}
+7
View File
@@ -90,6 +90,13 @@ func (self *SecurityGroupRule) GetCIDRs() []string {
return ret
}
func (self *SecurityGroupRule) GetTargetType() string {
if len(self.RemoteGroupId) > 0 {
return cloudprovider.SecurityGroupRuleTargetTypeSecurityGroup
}
return cloudprovider.SecurityGroupRuleTargetTypeCidr
}
func (self *SecurityGroupRule) Delete() error {
return self.secgroup.region.DeleteSecurityGroupRule(self.Id)
}
+4
View File
@@ -88,6 +88,10 @@ func (rule *SPermission) GetCIDRs() []string {
return []string{rule.CidrBlock}
}
func (rule *SPermission) GetTargetType() string {
return cloudprovider.SecurityGroupRuleTargetTypeCidr
}
func (rule *SPermission) Update(opts *cloudprovider.SecurityGroupRuleUpdateOptions) error {
return errors.ErrNotSupported
}
@@ -72,6 +72,13 @@ func (self *SSecurityGroupRule) GetCIDRs() []string {
return ret
}
func (self *SSecurityGroupRule) GetTargetType() string {
if len(self.RemoteGroupId) > 0 {
return cloudprovider.SecurityGroupRuleTargetTypeSecurityGroup
}
return cloudprovider.SecurityGroupRuleTargetTypeCidr
}
func (self *SSecurityGroupRule) GetProtocol() string {
if len(self.Protocol) == 0 || self.Protocol == "-1" {
return secrules.PROTO_ANY
+215
View File
@@ -0,0 +1,215 @@
// 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 qcloud
import (
"fmt"
"strings"
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/cloudmux/pkg/apis"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/cloudmux/pkg/multicloud"
)
type AddressTemplate struct {
multicloud.SVirtualResourceBase
QcloudTags
client *SQcloudClient
AddressSet []string
AddressTemplateId string
AddressTemplateName string
CreatedTime time.Time
}
func (self *AddressTemplate) GetId() string {
return self.AddressTemplateId
}
func (self *AddressTemplate) GetName() string {
if len(self.AddressTemplateName) > 0 {
return self.AddressTemplateName
}
return self.AddressTemplateId
}
func (self *AddressTemplate) GetGlobalId() string {
return self.AddressTemplateId
}
func (self *AddressTemplate) GetStatus() string {
return api.STATUS_AVAILABLE
}
func (self *AddressTemplate) GetCreatedAt() time.Time {
return self.CreatedTime
}
func (self *AddressTemplate) Refresh() error {
tpl, err := self.client.GetAddressTemplate(self.AddressTemplateId)
if err != nil {
return err
}
return jsonutils.Update(self, tpl)
}
func (self *AddressTemplate) GetIpSetType() string {
for _, addr := range self.AddressSet {
if strings.Contains(addr, ":") {
return cloudprovider.IpSetTypeIpv6CidrList
}
}
return cloudprovider.IpSetTypeIpv4CidrList
}
func (self *AddressTemplate) GetAddresses() []string {
return self.AddressSet
}
func (self *AddressTemplate) Update(opts *cloudprovider.IpSetUpdateOptions) error {
return self.client.ModifyAddressTemplate(self.AddressTemplateId, opts)
}
func (self *AddressTemplate) Delete() error {
return self.client.DeleteAddressTemplate(self.AddressTemplateId)
}
func (client *SQcloudClient) AddressList(addressId, addressName string, offset, limit int) ([]AddressTemplate, int, error) {
params := map[string]string{}
filter := 0
if len(addressId) > 0 {
params[fmt.Sprintf("Filters.%d.Name", filter)] = "address-template-id"
params[fmt.Sprintf("Filters.%d.Values.0", filter)] = addressId
filter++
}
if len(addressName) > 0 {
params[fmt.Sprintf("Filters.%d.Name", filter)] = "address-template-name"
params[fmt.Sprintf("Filters.%d.Values.0", filter)] = addressName
filter++
}
params["Offset"] = fmt.Sprintf("%d", offset)
if limit == 0 {
limit = 20
}
params["Limit"] = fmt.Sprintf("%d", limit)
body, err := client.vpcRequest("DescribeAddressTemplates", params)
if err != nil {
return nil, 0, err
}
addressTemplates := []AddressTemplate{}
err = body.Unmarshal(&addressTemplates, "AddressTemplateSet")
if err != nil {
return nil, 0, err
}
total, _ := body.Float("TotalCount")
return addressTemplates, int(total), nil
}
func (client *SQcloudClient) GetAddressTemplate(id string) (*AddressTemplate, error) {
templates, _, err := client.AddressList(id, "", 0, 1)
if err != nil {
return nil, err
}
for i := range templates {
if templates[i].AddressTemplateId == id {
templates[i].client = client
return &templates[i], nil
}
}
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "%s", id)
}
func (client *SQcloudClient) GetIIpSets() ([]cloudprovider.ICloudIpSet, error) {
ret := []cloudprovider.ICloudIpSet{}
for {
part, total, err := client.AddressList("", "", len(ret), 100)
if err != nil {
return nil, err
}
for i := range part {
part[i].client = client
ret = append(ret, &part[i])
}
if len(part) == 0 || len(ret) >= total {
break
}
}
return ret, nil
}
func (client *SQcloudClient) GetIIpSetById(id string) (cloudprovider.ICloudIpSet, error) {
return client.GetAddressTemplate(id)
}
func (client *SQcloudClient) CreateAddressTemplate(opts *cloudprovider.IpSetCreateOptions) (*AddressTemplate, error) {
params := map[string]string{
"AddressTemplateName": opts.Name,
}
for i := range opts.Addresses {
params[fmt.Sprintf("Addresses.%d", i)] = opts.Addresses[i]
}
body, err := client.vpcRequest("CreateAddressTemplate", params)
if err != nil {
return nil, errors.Wrapf(err, "CreateAddressTemplate")
}
ret := &AddressTemplate{client: client}
err = body.Unmarshal(ret, "AddressTemplate")
if err != nil {
return nil, errors.Wrapf(err, "Unmarshal")
}
return ret, nil
}
func (client *SQcloudClient) CreateIIpSet(opts *cloudprovider.IpSetCreateOptions) (cloudprovider.ICloudIpSet, error) {
return client.CreateAddressTemplate(opts)
}
func (client *SQcloudClient) ModifyAddressTemplate(id string, opts *cloudprovider.IpSetUpdateOptions) error {
params := map[string]string{
"AddressTemplateId": id,
}
if len(opts.Name) > 0 {
params["AddressTemplateName"] = opts.Name
}
for i := range opts.Addresses {
params[fmt.Sprintf("Addresses.%d", i)] = opts.Addresses[i]
}
_, err := client.vpcRequest("ModifyAddressTemplateAttribute", params)
return errors.Wrapf(err, "ModifyAddressTemplateAttribute")
}
func (client *SQcloudClient) DeleteAddressTemplate(id string) error {
params := map[string]string{
"AddressTemplateId": id,
}
_, err := client.vpcRequest("DeleteAddressTemplate", params)
return errors.Wrapf(err, "DeleteAddressTemplate")
}
func (self *SRegion) GetIIpSets() ([]cloudprovider.ICloudIpSet, error) {
return []cloudprovider.ICloudIpSet{}, nil
}
func (self *SRegion) GetIIpSetById(id string) (cloudprovider.ICloudIpSet, error) {
return nil, cloudprovider.ErrNotFound
}
func (self *SRegion) CreateIIpSet(opts *cloudprovider.IpSetCreateOptions) (cloudprovider.ICloudIpSet, error) {
return nil, cloudprovider.ErrNotSupported
}
+12
View File
@@ -460,6 +460,18 @@ func (self *SQcloudProvider) GetISSLCertificates() ([]cloudprovider.ICloudSSLCer
return self.client.GetISSLCertificates()
}
func (self *SQcloudProvider) GetIIpSets() ([]cloudprovider.ICloudIpSet, error) {
return self.client.GetIIpSets()
}
func (self *SQcloudProvider) GetIIpSetById(id string) (cloudprovider.ICloudIpSet, error) {
return self.client.GetIIpSetById(id)
}
func (self *SQcloudProvider) CreateIIpSet(opts *cloudprovider.IpSetCreateOptions) (cloudprovider.ICloudIpSet, error) {
return self.client.CreateIIpSet(opts)
}
func (self *SQcloudProvider) GetNotices() ([]cloudprovider.INotice, error) {
return self.client.GetNotices()
}
+33 -3
View File
@@ -77,9 +77,37 @@ func (self *SecurityGroupRule) GetDirection() secrules.TSecurityRuleDirection {
return self.Direction
}
func (self *SecurityGroupRule) GetTargetType() string {
if len(self.AddressTemplate.AddressId) > 0 {
return cloudprovider.SecurityGroupRuleTargetTypeIpSet
}
if len(self.AddressTemplate.AddressGroupId) > 0 {
return cloudprovider.SecurityGroupRuleTargetTypeIpSetGroup
}
if len(self.SecurityGroupId) > 0 {
return cloudprovider.SecurityGroupRuleTargetTypeSecurityGroup
}
return cloudprovider.SecurityGroupRuleTargetTypeCidr
}
func (self *SecurityGroupRule) GetCIDRs() []string {
ret := []string{self.CidrBlock + self.SecurityGroupId + self.Ipv6CidrBlock + self.AddressTemplate.GetGlobalId()}
return ret
if len(self.AddressTemplate.AddressId) > 0 {
return []string{self.AddressTemplate.AddressId}
}
if len(self.AddressTemplate.AddressGroupId) > 0 {
return []string{self.AddressTemplate.AddressGroupId}
}
if len(self.SecurityGroupId) > 0 {
return []string{self.SecurityGroupId}
}
ip := self.CidrBlock
if len(ip) == 0 {
ip = self.Ipv6CidrBlock
}
if len(ip) == 0 {
ip = "0.0.0.0/0"
}
return []string{ip}
}
func (self *SecurityGroupRule) GetProtocol() string {
@@ -183,9 +211,11 @@ func (self *SRegion) UpdateSecurityGroupRule(groupId string, idx int, direction
params[prefix+"PolicyIndex"] = fmt.Sprintf("%d", idx)
params[prefix+"Protocol"] = strings.ToUpper(opts.Protocol)
params[prefix+"Port"] = opts.Ports
params[prefix+"CidrBlock"] = opts.CIDR
params[prefix+"Action"] = action
params[prefix+"PolicyDescription"] = opts.Desc
if len(opts.CIDR) > 0 {
setSecurityGroupPolicyAddress(params, prefix, opts.CIDR, opts.TargetType)
}
_, err := self.vpcRequest("ReplaceSecurityGroupPolicy", params)
return err
}
+21 -44
View File
@@ -187,44 +187,6 @@ func (self *SRegion) DeleteSecurityGroup(secGroupId string) error {
return err
}
type AddressTemplate struct {
AddressSet []string
AddressTemplateId string
AddressTemplateName string
CreatedTime time.Time
}
func (self *SRegion) AddressList(addressId, addressName string, offset, limit int) ([]AddressTemplate, int, error) {
params := map[string]string{}
filter := 0
if len(addressId) > 0 {
params[fmt.Sprintf("Filters.%d.Name", filter)] = "address-template-id"
params[fmt.Sprintf("Filters.%d.Values.0", filter)] = addressId
filter++
}
if len(addressName) > 0 {
params[fmt.Sprintf("Filters.%d.Name", filter)] = "address-template-name"
params[fmt.Sprintf("Filters.%d.Values.0", filter)] = addressName
filter++
}
params["Offset"] = fmt.Sprintf("%d", offset)
if limit == 0 {
limit = 20
}
params["Limit"] = fmt.Sprintf("%d", limit)
body, err := self.vpcRequest("DescribeAddressTemplates", params)
if err != nil {
return nil, 0, err
}
addressTemplates := []AddressTemplate{}
err = body.Unmarshal(&addressTemplates, "AddressTemplateSet")
if err != nil {
return nil, 0, err
}
total, _ := body.Float("TotalCount")
return addressTemplates, int(total), nil
}
type AddressTemplateGroup struct {
AddressTemplateIdSet []string
AddressTemplateGroupName string
@@ -338,7 +300,7 @@ func (self *SRegion) CreateSecurityGroupRule(groupId string, opts *cloudprovider
if opts.Action == secrules.SecurityRuleDeny {
action = "drop"
}
if len(opts.CIDR) == 0 {
if len(opts.CIDR) == 0 && (len(opts.TargetType) == 0 || opts.TargetType == cloudprovider.SecurityGroupRuleTargetTypeCidr) {
opts.CIDR = "0.0.0.0/0"
}
params := map[string]string{
@@ -348,12 +310,8 @@ func (self *SRegion) CreateSecurityGroupRule(groupId string, opts *cloudprovider
prefix + "PolicyDescription": opts.Desc,
prefix + "Action": action,
prefix + "Port": opts.Ports,
prefix + "CidrBlock": opts.CIDR,
}
if _, err := netutils.NewIPV6Prefix(opts.CIDR); err == nil {
params[prefix+"Ipv6CidrBlock"] = opts.CIDR
delete(params, prefix+"CidrBlock")
}
setSecurityGroupPolicyAddress(params, prefix, opts.CIDR, opts.TargetType)
_, err := self.vpcRequest("CreateSecurityGroupPolicies", params)
if err != nil {
@@ -362,6 +320,25 @@ func (self *SRegion) CreateSecurityGroupRule(groupId string, opts *cloudprovider
return nil
}
func setSecurityGroupPolicyAddress(params map[string]string, prefix, cidr, targetType string) {
switch targetType {
case cloudprovider.SecurityGroupRuleTargetTypeIpSet:
params[prefix+"AddressTemplate.AddressId"] = cidr
return
case cloudprovider.SecurityGroupRuleTargetTypeIpSetGroup:
params[prefix+"AddressTemplate.AddressGroupId"] = cidr
return
case cloudprovider.SecurityGroupRuleTargetTypeSecurityGroup:
params[prefix+"SecurityGroupId"] = cidr
return
}
if _, err := netutils.NewIPV6Prefix(cidr); err == nil {
params[prefix+"Ipv6CidrBlock"] = cidr
return
}
params[prefix+"CidrBlock"] = cidr
}
func (self *SSecurityGroup) GetProjectId() string {
return self.ProjectId
}
+12
View File
@@ -51,6 +51,18 @@ func (r *SRegion) GetISecurityGroups() ([]cloudprovider.ICloudSecurityGroup, err
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetISecurityGroups")
}
func (r *SRegion) GetIIpSets() ([]cloudprovider.ICloudIpSet, error) {
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetIIpSets")
}
func (r *SRegion) GetIIpSetById(id string) (cloudprovider.ICloudIpSet, error) {
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetIIpSetById")
}
func (r *SRegion) CreateIIpSet(opts *cloudprovider.IpSetCreateOptions) (cloudprovider.ICloudIpSet, error) {
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "CreateIIpSet")
}
func (r *SRegion) GetIStorageById(id string) (cloudprovider.ICloudStorage, error) {
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetIStorageById")
}
+7
View File
@@ -23,6 +23,13 @@ type SSecurityGroup struct {
SVirtualResourceBase
}
type SSecurityGroupRuleBase struct {
}
func (self *SSecurityGroupRuleBase) GetTargetType() string {
return cloudprovider.SecurityGroupRuleTargetTypeCidr
}
func (self *SSecurityGroup) GetReferences() ([]cloudprovider.SecurityGroupReference, error) {
return []cloudprovider.SecurityGroupReference{}, nil
}
+4
View File
@@ -60,6 +60,10 @@ func (self *SecurityGroupRule) GetCIDRs() []string {
return []string{self.SrcIP}
}
func (self *SecurityGroupRule) GetTargetType() string {
return cloudprovider.SecurityGroupRuleTargetTypeCidr
}
func (self *SecurityGroupRule) GetProtocol() string {
return strings.ToLower(self.ProtocolType)
}
+10
View File
@@ -73,6 +73,16 @@ func (self *SSecurityGroupRule) GetCIDRs() []string {
return ret
}
func (self *SSecurityGroupRule) GetTargetType() string {
if len(self.PrefixListId) > 0 {
return cloudprovider.SecurityGroupRuleTargetTypeIpSet
}
if len(self.SourceGroupId) > 0 {
return cloudprovider.SecurityGroupRuleTargetTypeSecurityGroup
}
return cloudprovider.SecurityGroupRuleTargetTypeCidr
}
func (self *SSecurityGroupRule) GetProtocol() string {
if len(self.Protocol) == 0 || self.Protocol == "all" {
return secrules.PROTO_ANY
+7
View File
@@ -66,6 +66,13 @@ func (self *SSecurityGroupRule) GetCIDRs() []string {
return ret
}
func (self *SSecurityGroupRule) GetTargetType() string {
if len(self.RemoteSecurityGroupUUID) > 0 {
return cloudprovider.SecurityGroupRuleTargetTypeSecurityGroup
}
return cloudprovider.SecurityGroupRuleTargetTypeCidr
}
func (self *SSecurityGroupRule) GetProtocol() string {
if self.Protocol == "ALL" {
return secrules.PROTO_ANY