diff --git a/pkg/apis/compute/cloudaccount.go b/pkg/apis/compute/cloudaccount.go index 54c1a660ea..c4eb3e4914 100644 --- a/pkg/apis/compute/cloudaccount.go +++ b/pkg/apis/compute/cloudaccount.go @@ -489,3 +489,17 @@ type CloudaccountProjectMappingInput struct { // 绑定同步策略要求当前云账号此刻未绑定其他同步策略 ProjectMappingId string `json:"project_mapping_id"` } + +type SyncRangeInput struct { + Force bool `json:"force"` + FullSync bool `json:"full_sync"` + DeepSync bool `json:"deep_sync"` + + Region []string `json:"region"` + Zone []string `json:"zone"` + Host []string `json:"host"` + + // 按资源类型同步,可输入多个 + // enmu: compute, loadbalancer, objectstore, rds, cache, nat, nas, waf, mongodb, es, kafka, app, container + Resources []string `json:"resources" choices:"compute|loadbalancer|objectstore|rds|cache|nat|nas|waf|mongodb|es|kafka|app|container"` +} diff --git a/pkg/cloudprovider/cloudprovider.go b/pkg/cloudprovider/cloudprovider.go index 5cf00a4f0b..16a61863d9 100644 --- a/pkg/cloudprovider/cloudprovider.go +++ b/pkg/cloudprovider/cloudprovider.go @@ -330,6 +330,10 @@ func IsSupportRds(prod ICloudProvider) bool { return IsSupportCapability(prod, CLOUD_CAPABILITY_RDS) } +func IsSupportNAS(prod ICloudProvider) bool { + return IsSupportCapability(prod, CLOUD_CAPABILITY_NAS) +} + func IsSupportNAT(prod ICloudProvider) bool { return IsSupportCapability(prod, CLOUD_CAPABILITY_NAT) } diff --git a/pkg/compute/models/cloudaccounts.go b/pkg/compute/models/cloudaccounts.go index 77281ee7ef..e24c9437d8 100644 --- a/pkg/compute/models/cloudaccounts.go +++ b/pkg/compute/models/cloudaccounts.go @@ -643,7 +643,7 @@ func (self *SCloudaccount) AllowPerformSync(ctx context.Context, userCred mcclie return db.IsAdminAllowPerform(userCred, self, "sync") } -func (self *SCloudaccount) PerformSync(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) { +func (self *SCloudaccount) PerformSync(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.SyncRangeInput) (jsonutils.JSONObject, error) { if !self.GetEnabled() { return nil, httperrors.NewInvalidStatusError("Account disabled") } @@ -652,18 +652,14 @@ func (self *SCloudaccount) PerformSync(ctx context.Context, userCred mcclient.To return nil, httperrors.NewInvalidStatusError("Account is not idle") } - syncRange := SSyncRange{} - err := data.Unmarshal(&syncRange) - if err != nil { - return nil, httperrors.NewInputParameterError("invalid input %s", err) - } - if syncRange.FullSync || len(syncRange.Region) > 0 || len(syncRange.Zone) > 0 || len(syncRange.Host) > 0 { + syncRange := SSyncRange{SyncRangeInput: input} + if syncRange.FullSync || len(syncRange.Region) > 0 || len(syncRange.Zone) > 0 || len(syncRange.Host) > 0 || len(syncRange.Resources) > 0 { syncRange.DeepSync = true } if self.CanSync() || syncRange.Force { - err = self.StartSyncCloudProviderInfoTask(ctx, userCred, &syncRange, "") + return nil, self.StartSyncCloudProviderInfoTask(ctx, userCred, &syncRange, "") } - return nil, err + return nil, nil } func (self *SCloudaccount) AllowPerformTestConnectivity(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool { @@ -2188,7 +2184,11 @@ func (account *SCloudaccount) SubmitSyncAccountTask(ctx context.Context, userCre } else { syncCnt := 0 if err == nil && autoSync && account.GetEnabled() && account.EnableAutoSync { - syncRange := SSyncRange{FullSync: true} + syncRange := SSyncRange{ + SyncRangeInput: api.SyncRangeInput{ + FullSync: true, + }, + } account.markAutoSync(userCred) providers := account.GetEnabledCloudproviders() for i := range providers { @@ -2330,7 +2330,11 @@ func (account *SCloudaccount) PerformPublic(ctx context.Context, userCred mcclie return nil, errors.Wrap(err, "account.setShareMode") } - syncRange := &SSyncRange{FullSync: true} + syncRange := &SSyncRange{ + SyncRangeInput: api.SyncRangeInput{ + FullSync: true, + }, + } account.StartSyncCloudProviderInfoTask(ctx, userCred, syncRange, "") return nil, nil @@ -2365,7 +2369,11 @@ func (account *SCloudaccount) PerformPrivate(ctx context.Context, userCred mccli return nil, errors.Wrap(err, "account.setShareMode") } - syncRange := &SSyncRange{FullSync: true} + syncRange := &SSyncRange{ + SyncRangeInput: api.SyncRangeInput{ + FullSync: true, + }, + } account.StartSyncCloudProviderInfoTask(ctx, userCred, syncRange, "") return nil, nil diff --git a/pkg/compute/models/cloudproviders.go b/pkg/compute/models/cloudproviders.go index fb6892c6b1..38f608dc2e 100644 --- a/pkg/compute/models/cloudproviders.go +++ b/pkg/compute/models/cloudproviders.go @@ -470,14 +470,7 @@ func (self *SCloudprovider) saveProject(userCred mcclient.TokenCredential, domai } type SSyncRange struct { - Force bool - FullSync bool - DeepSync bool - // ProjectSync bool - - Region []string - Zone []string - Host []string + api.SyncRangeInput } func (sr *SSyncRange) GetRegionIds() ([]string, error) { @@ -518,17 +511,18 @@ func (sr *SSyncRange) GetRegionIds() ([]string, error) { return regionIds, nil } +func (sr *SSyncRange) NeedSyncResource(res string) bool { + if len(sr.Resources) == 0 { + return true + } + return utils.IsInStringArray(res, sr.Resources) +} + func (sr *SSyncRange) NeedSyncInfo() bool { if sr.FullSync { return true } - if sr.Region != nil && len(sr.Region) > 0 { - return true - } - if sr.Zone != nil && len(sr.Zone) > 0 { - return true - } - if sr.Host != nil && len(sr.Host) > 0 { + if len(sr.Region) > 0 || len(sr.Zone) > 0 || len(sr.Host) > 0 || len(sr.Resources) > 0 { return true } return false @@ -634,7 +628,7 @@ func (self *SCloudprovider) AllowPerformSync(ctx context.Context, userCred mccli return db.IsAdminAllowPerform(userCred, self, "sync") } -func (self *SCloudprovider) PerformSync(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) { +func (self *SCloudprovider) PerformSync(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.SyncRangeInput) (jsonutils.JSONObject, error) { if !self.GetEnabled() { return nil, httperrors.NewInvalidStatusError("Cloudprovider disabled") } @@ -645,18 +639,14 @@ func (self *SCloudprovider) PerformSync(ctx context.Context, userCred mcclient.T if account.EnableAutoSync && self.SyncStatus != api.CLOUD_PROVIDER_SYNC_STATUS_IDLE { return nil, httperrors.NewInvalidStatusError("Cloudprovider is not idle") } - syncRange := SSyncRange{} - err := data.Unmarshal(&syncRange) - if err != nil { - return nil, httperrors.NewInputParameterError("invalid input %s", err) - } - if syncRange.FullSync || len(syncRange.Region) > 0 || len(syncRange.Zone) > 0 || len(syncRange.Host) > 0 { + syncRange := SSyncRange{input} + if syncRange.FullSync || len(syncRange.Region) > 0 || len(syncRange.Zone) > 0 || len(syncRange.Host) > 0 || len(syncRange.Resources) > 0 { syncRange.DeepSync = true } if self.CanSync() || syncRange.Force { - err = self.StartSyncCloudProviderInfoTask(ctx, userCred, &syncRange, "") + return nil, self.StartSyncCloudProviderInfoTask(ctx, userCred, &syncRange, "") } - return nil, err + return nil, nil } func (self *SCloudprovider) StartSyncCloudProviderInfoTask(ctx context.Context, userCred mcclient.TokenCredential, syncRange *SSyncRange, parentTaskId string) error { @@ -741,7 +731,9 @@ func (self *SCloudprovider) PerformChangeProject(ctx context.Context, userCred m return nil, nil } - return nil, self.StartSyncCloudProviderInfoTask(ctx, userCred, &SSyncRange{FullSync: true, DeepSync: true}, "") + return nil, self.StartSyncCloudProviderInfoTask(ctx, userCred, &SSyncRange{SyncRangeInput: api.SyncRangeInput{ + FullSync: true, DeepSync: true, + }}, "") } func (self *SCloudprovider) markStartingSync(userCred mcclient.TokenCredential, syncRange *SSyncRange) error { diff --git a/pkg/compute/models/cloudsync.go b/pkg/compute/models/cloudsync.go index df4167ab52..7a47c3503f 100644 --- a/pkg/compute/models/cloudsync.go +++ b/pkg/compute/models/cloudsync.go @@ -1732,21 +1732,21 @@ func syncPublicCloudProviderInfo( SyncRegionNasSkus(ctx, userCred, localRegion.Id, true) } else { syncSkusFromPrivateCloud(ctx, userCred, syncResults, localRegion, remoteRegion) - if cloudprovider.IsSupportRds(driver) { + if cloudprovider.IsSupportRds(driver) && syncRange.NeedSyncResource(cloudprovider.CLOUD_CAPABILITY_RDS) { syncDBInstanceSkus(ctx, userCred, syncResults, provider, localRegion, remoteRegion, syncRange) } - if cloudprovider.IsSupportNAT(driver) { + if cloudprovider.IsSupportNAT(driver) && syncRange.NeedSyncResource(cloudprovider.CLOUD_CAPABILITY_NAT) { syncNATSkus(ctx, userCred, syncResults, provider, localRegion, remoteRegion, syncRange) } } // no need to lock public cloud region as cloud region for public cloud is readonly - if cloudprovider.IsSupportObjectstore(driver) { + if cloudprovider.IsSupportObjectstore(driver) && syncRange.NeedSyncResource(cloudprovider.CLOUD_CAPABILITY_OBJECTSTORE) { syncRegionBuckets(ctx, userCred, syncResults, provider, localRegion, remoteRegion) } - if cloudprovider.IsSupportCompute(driver) { + if cloudprovider.IsSupportCompute(driver) && syncRange.NeedSyncResource(cloudprovider.CLOUD_CAPABILITY_COMPUTE) { // 需要先同步vpc,避免私有云eip找不到network syncRegionVPCs(ctx, userCred, syncResults, provider, localRegion, remoteRegion, syncRange) @@ -1775,55 +1775,57 @@ func syncPublicCloudProviderInfo( syncRegionSnapshots(ctx, userCred, syncResults, provider, localRegion, remoteRegion, syncRange) } - syncRegionAccessGroups(ctx, userCred, syncResults, provider, localRegion, remoteRegion, syncRange) - syncRegionFileSystems(ctx, userCred, syncResults, provider, localRegion, remoteRegion, syncRange) + if cloudprovider.IsSupportNAS(driver) && syncRange.NeedSyncResource(cloudprovider.CLOUD_CAPABILITY_NAS) { + syncRegionAccessGroups(ctx, userCred, syncResults, provider, localRegion, remoteRegion, syncRange) + syncRegionFileSystems(ctx, userCred, syncResults, provider, localRegion, remoteRegion, syncRange) + } - if cloudprovider.IsSupportLoadbalancer(driver) { + if cloudprovider.IsSupportLoadbalancer(driver) && syncRange.NeedSyncResource(cloudprovider.CLOUD_CAPABILITY_LOADBALANCER) { syncRegionLoadbalancerAcls(ctx, userCred, syncResults, provider, localRegion, remoteRegion, syncRange) syncRegionLoadbalancerCertificates(ctx, userCred, syncResults, provider, localRegion, remoteRegion, syncRange) syncRegionLoadbalancers(ctx, userCred, syncResults, provider, localRegion, remoteRegion, syncRange) } - if cloudprovider.IsSupportCompute(driver) { + if cloudprovider.IsSupportCompute(driver) && syncRange.NeedSyncResource(cloudprovider.CLOUD_CAPABILITY_COMPUTE) { syncRegionNetworkInterfaces(ctx, userCred, syncResults, provider, localRegion, remoteRegion, syncRange) } - if cloudprovider.IsSupportRds(driver) { + if cloudprovider.IsSupportRds(driver) && syncRange.NeedSyncResource(cloudprovider.CLOUD_CAPABILITY_RDS) { syncRegionDBInstances(ctx, userCred, syncResults, provider, localRegion, remoteRegion, syncRange) syncRegionDBInstanceBackups(ctx, userCred, syncResults, provider, localRegion, remoteRegion, syncRange) } - if cloudprovider.IsSupportElasticCache(driver) { + if cloudprovider.IsSupportElasticCache(driver) && syncRange.NeedSyncResource(cloudprovider.CLOUD_CAPABILITY_CACHE) { syncElasticcaches(ctx, userCred, syncResults, provider, localRegion, remoteRegion, syncRange) } - if cloudprovider.IsSupportWaf(driver) { + if cloudprovider.IsSupportWaf(driver) && syncRange.NeedSyncResource(cloudprovider.CLOUD_CAPABILITY_WAF) { syncWafIPSets(ctx, userCred, syncResults, provider, localRegion, remoteRegion) syncWafRegexSets(ctx, userCred, syncResults, provider, localRegion, remoteRegion) syncWafInstances(ctx, userCred, syncResults, provider, localRegion, remoteRegion) } - if cloudprovider.IsSupportMongoDB(driver) { + if cloudprovider.IsSupportMongoDB(driver) && syncRange.NeedSyncResource(cloudprovider.CLOUD_CAPABILITY_MONGO_DB) { syncMongoDBs(ctx, userCred, syncResults, provider, localRegion, remoteRegion) } - if cloudprovider.IsSupportElasticSearch(driver) { + if cloudprovider.IsSupportElasticSearch(driver) && syncRange.NeedSyncResource(cloudprovider.CLOUD_CAPABILITY_ES) { syncElasticSearchs(ctx, userCred, syncResults, provider, localRegion, remoteRegion) } - if cloudprovider.IsSupportKafka(driver) { + if cloudprovider.IsSupportKafka(driver) && syncRange.NeedSyncResource(cloudprovider.CLOUD_CAPABILITY_KAFKA) { syncKafkas(ctx, userCred, syncResults, provider, localRegion, remoteRegion) } - if cloudprovider.IsSupportApp(driver) { + if cloudprovider.IsSupportApp(driver) && syncRange.NeedSyncResource(cloudprovider.CLOUD_CAPABILITY_APP) { syncApps(ctx, userCred, syncResults, provider, localRegion, remoteRegion) } - if cloudprovider.IsSupportContainer(driver) { + if cloudprovider.IsSupportContainer(driver) && syncRange.NeedSyncResource(cloudprovider.CLOUD_CAPABILITY_CONTAINER) { syncKubeClusters(ctx, userCred, syncResults, provider, localRegion, remoteRegion) } - if cloudprovider.IsSupportCompute(driver) { + if cloudprovider.IsSupportCompute(driver) && syncRange.NeedSyncResource(cloudprovider.CLOUD_CAPABILITY_COMPUTE) { log.Debugf("storageCachePairs count %d", len(storageCachePairs)) for i := range storageCachePairs { // always sync private cloud cached images @@ -1934,12 +1936,12 @@ func syncOnPremiseCloudProviderInfo( localRegion := CloudregionManager.FetchDefaultRegion() - if cloudprovider.IsSupportObjectstore(driver) { + if cloudprovider.IsSupportObjectstore(driver) && syncRange.NeedSyncResource(cloudprovider.CLOUD_CAPABILITY_OBJECTSTORE) { syncRegionBuckets(ctx, userCred, syncResults, provider, localRegion, iregion) } var storageCachePairs []sStoragecacheSyncPair - if cloudprovider.IsSupportCompute(driver) { + if cloudprovider.IsSupportCompute(driver) && syncRange.NeedSyncResource(cloudprovider.CLOUD_CAPABILITY_COMPUTE) { storageCachePairs = syncOnPremiseCloudProviderStorage(ctx, userCred, syncResults, provider, iregion, driver, syncRange) ihosts, err := func() ([]cloudprovider.ICloudHost, error) { defer syncResults.AddRequestCost(HostManager)() @@ -1976,7 +1978,7 @@ func syncOnPremiseCloudProviderInfo( } } - if cloudprovider.IsSupportCompute(driver) { + if cloudprovider.IsSupportCompute(driver) && syncRange.NeedSyncResource(cloudprovider.CLOUD_CAPABILITY_COMPUTE) { log.Debugf("storageCachePairs count %d", len(storageCachePairs)) for i := range storageCachePairs { // alway sync on-premise cached images diff --git a/pkg/mcclient/options/cloudaccounts.go b/pkg/mcclient/options/cloudaccounts.go index ebbc93496d..0f5fbf9bfc 100644 --- a/pkg/mcclient/options/cloudaccounts.go +++ b/pkg/mcclient/options/cloudaccounts.go @@ -20,6 +20,7 @@ import ( "yunion.io/x/jsonutils" + api "yunion.io/x/onecloud/pkg/apis/compute" "yunion.io/x/onecloud/pkg/cloudprovider" ) @@ -919,11 +920,8 @@ func (opts *CloudaccountUpdateCredentialOptions) Params() (jsonutils.JSONObject, type CloudaccountSyncOptions struct { SCloudAccountIdOptions - Force bool `help:"Force sync no matter what"` - FullSync bool `help:"Synchronize everything"` - Region []string `help:"region to sync"` - Zone []string `help:"region to sync"` - Host []string `help:"region to sync"` + + api.SyncRangeInput } func (opts *CloudaccountSyncOptions) Params() (jsonutils.JSONObject, error) {