diff --git a/pkg/compute/models/cloudaccounts.go b/pkg/compute/models/cloudaccounts.go index 9c156a8705..b0c63826ea 100644 --- a/pkg/compute/models/cloudaccounts.go +++ b/pkg/compute/models/cloudaccounts.go @@ -2576,6 +2576,7 @@ func (account *SCloudaccount) SubmitSyncAccountTask(ctx context.Context, userCre if err == nil && autoSync && account.GetEnabled() && account.EnableAutoSync { syncRange := SSyncRange{FullSync: true} account.markAutoSync(userCred) + account.SyncAccountResources(ctx, userCred) providers := account.GetEnabledCloudproviders() for i := range providers { provider := &providers[i] @@ -3082,8 +3083,8 @@ func (self *SCloudaccount) GetAvailableExternalProject(local *db.STenant, projec // 若本地项目没有映射云上任何项目,则在云上新建一个同名项目 // 若本地项目a映射云上项目b,但b项目不可用,则看云上是否有a项目,有则直接使用,若没有则在云上创建a-1, a-2类似项目 func (self *SCloudaccount) SyncProject(ctx context.Context, userCred mcclient.TokenCredential, projectId string) (string, error) { - lockman.LockRawObject(ctx, self.Id, projectId) - defer lockman.ReleaseRawObject(ctx, self.Id, projectId) + lockman.LockRawObject(ctx, "projects", self.Id) + defer lockman.ReleaseRawObject(ctx, "projects", self.Id) provider, err := self.GetProvider() if err != nil { @@ -3271,3 +3272,54 @@ func (self *SCloudaccount) SyncDnsZones(ctx context.Context, userCred mcclient.T return localZones, remoteZones, result } + +func (self *SCloudaccount) SyncAccountResources(ctx context.Context, userCred mcclient.TokenCredential) error { + provider, err := self.GetProvider() + if err != nil { + return errors.Wrapf(err, "GetProvider") + } + if cloudprovider.IsSupportProject(provider) { + return func() error { + lockman.LockRawObject(ctx, "projects", self.Id) + defer lockman.ReleaseRawObject(ctx, "projects", self.Id) + + projects, err := provider.GetIProjects() + if err != nil { + return errors.Wrapf(err, "provider.GetIProjects") + } + result := ExternalProjectManager.SyncProjects(ctx, userCred, self, projects) + log.Infof("Sync project for cloudaccount %s result: %s", self.Name, result.Result()) + return nil + }() + } + + if cloudprovider.IsSupportDnsZone(provider) { + return func() error { + lockman.LockRawObject(ctx, "dns_zones", self.Id) + defer lockman.ReleaseRawObject(ctx, "dns_zones", self.Id) + + dnsZones, err := provider.GetICloudDnsZones() + if err != nil { + return errors.Wrapf(err, "GetICloudDnsZones") + } + localZones, remoteZones, result := self.SyncDnsZones(ctx, userCred, dnsZones) + log.Infof("Sync dns zones for cloudaccount %s result: %s", self.Name, result.Result()) + for i := 0; i < len(localZones); i++ { + func() { + lockman.LockObject(ctx, &localZones[i]) + defer lockman.ReleaseObject(ctx, &localZones[i]) + + if localZones[i].Deleted { + return + } + + result := localZones[i].SyncDnsRecordSets(ctx, userCred, self.Provider, remoteZones[i]) + log.Infof("Sync dns records for dns zone %s result: %s", localZones[i].GetName(), result.Result()) + }() + } + return nil + }() + } + + return nil +} diff --git a/pkg/compute/tasks/cloud_account_sync_task.go b/pkg/compute/tasks/cloud_account_sync_task.go index 2ccae73985..dae502f6dc 100644 --- a/pkg/compute/tasks/cloud_account_sync_task.go +++ b/pkg/compute/tasks/cloud_account_sync_task.go @@ -16,19 +16,15 @@ package tasks import ( "context" - "fmt" "yunion.io/x/jsonutils" "yunion.io/x/log" "yunion.io/x/pkg/errors" "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/cloudprovider" "yunion.io/x/onecloud/pkg/compute/models" "yunion.io/x/onecloud/pkg/httperrors" - "yunion.io/x/onecloud/pkg/mcclient" "yunion.io/x/onecloud/pkg/util/logclient" ) @@ -73,26 +69,6 @@ func (self *CloudAccountSyncInfoTask) OnCloudaccountSyncReadyFailed(ctx context. func (self *CloudAccountSyncInfoTask) OnCloudaccountSyncReady(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) { cloudaccount := obj.(*models.SCloudaccount) - driver, err := cloudaccount.GetProvider() - if err != nil { - cloudaccount.MarkEndSyncWithLock(ctx, self.UserCred) - db.OpsLog.LogEvent(cloudaccount, db.ACT_SYNC_HOST_FAILED, err, self.UserCred) - self.SetStageFailed(ctx, jsonutils.NewString(err.Error())) - logclient.AddActionLogWithStartable(self, cloudaccount, logclient.ACT_CLOUD_SYNC, err, self.UserCred, false) - return - } - - if cloudprovider.IsSupportProject(driver) { - projects, err := driver.GetIProjects() - if err != nil { - msg := fmt.Sprintf("GetIProjects for cloudaccount %s failed %s", cloudaccount.GetName(), err) - log.Errorf(msg) - } else { - result := models.ExternalProjectManager.SyncProjects(ctx, self.GetUserCred(), cloudaccount, projects) - log.Infof("Sync project for cloudaccount %s result: %s", cloudaccount.GetName(), result.Result()) - } - } - syncRange := models.SSyncRange{} syncRangeJson, _ := self.Params.Get("sync_range") if syncRangeJson != nil { @@ -107,25 +83,10 @@ func (self *CloudAccountSyncInfoTask) OnCloudaccountSyncReady(ctx context.Contex return } - if syncRange.FullSync && cloudprovider.IsSupportDnsZone(driver) { - dnsZones, err := driver.GetICloudDnsZones() + if syncRange.FullSync { + err := cloudaccount.SyncAccountResources(ctx, self.GetUserCred()) if err != nil { - log.Errorf("failed to get dns zones for account %s error: %v", cloudaccount.Name, err) - } else { - localZones, remoteZones, result := cloudaccount.SyncDnsZones(ctx, self.GetUserCred(), dnsZones) - log.Infof("Sync dns zones for cloudaccount %s result: %s", cloudaccount.GetName(), result.Result()) - for i := 0; i < len(localZones); i++ { - func() { - lockman.LockObject(ctx, &localZones[i]) - defer lockman.ReleaseObject(ctx, &localZones[i]) - - if localZones[i].Deleted { - return - } - - syncDnsRecordSets(ctx, self.GetUserCred(), cloudaccount, &localZones[i], remoteZones[i]) - }() - } + log.Errorf("SyncAccountResources error: %v", err) } } @@ -141,11 +102,6 @@ func (self *CloudAccountSyncInfoTask) OnCloudaccountSyncReady(ctx context.Contex } } -func syncDnsRecordSets(ctx context.Context, userCred mcclient.TokenCredential, account *models.SCloudaccount, localDnsZone *models.SDnsZone, remoteDnsZone cloudprovider.ICloudDnsZone) { - result := localDnsZone.SyncDnsRecordSets(ctx, userCred, account.Provider, remoteDnsZone) - log.Infof("Sync dns records for dns zone %s result: %s", localDnsZone.GetName(), result.Result()) -} - func (self *CloudAccountSyncInfoTask) OnCloudaccountSyncComplete(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) { cloudaccount := obj.(*models.SCloudaccount) cloudaccount.MarkEndSyncWithLock(ctx, self.UserCred)