mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-10-29 17:58:36 +08:00
fix(region): support cloudpods ipset (#25360)
This commit is contained in:
@@ -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{})
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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=
|
||||
|
||||
@@ -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"`
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -45,6 +45,7 @@ func InitDB() error {
|
||||
WireManager,
|
||||
StorageManager,
|
||||
SecurityGroupManager,
|
||||
IpSetManager,
|
||||
NetworkManager,
|
||||
NetworkAddressManager,
|
||||
NetworkIpMacManager,
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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},
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
})
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
+4
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
}
|
||||
|
||||
+7
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user