diff --git a/pkg/compute/models/cloudsync.go b/pkg/compute/models/cloudsync.go index 9f3c178877..9e2b8851dd 100644 --- a/pkg/compute/models/cloudsync.go +++ b/pkg/compute/models/cloudsync.go @@ -1267,6 +1267,7 @@ func syncOnPremiseCloudProviderInfo( storageCachePairs = append(storageCachePairs, newCachePairs...) } syncHostNics(ctx, userCred, provider, &localHosts[i], remoteHosts[i]) + syncOnPremiseHostWires(ctx, userCred, syncResults, provider, &localHosts[i], remoteHosts[i]) syncHostVMs(ctx, userCred, syncResults, provider, driver, &localHosts[i], remoteHosts[i], syncRange) } } @@ -1287,6 +1288,27 @@ func syncOnPremiseCloudProviderInfo( return nil } +func syncOnPremiseHostWires(ctx context.Context, userCred mcclient.TokenCredential, syncResults SSyncResultSet, provider *SCloudprovider, localHost *SHost, remoteHost cloudprovider.ICloudHost) { + log.Infof("start to sync OnPremeseHostWires") + if provider.Provider != api.CLOUD_PROVIDER_VMWARE { + return + } + result := localHost.SyncEsxiHostWires(ctx, userCred, remoteHost) + if syncResults != nil { + syncResults.Add(HostManager, result) + } + + msg := result.Result() + notes := fmt.Sprintf("SyncEsxiHostWires for host %s result: %s", localHost.Name, msg) + if result.IsError() { + log.Errorf(notes) + return + } else { + log.Infof(notes) + } + db.OpsLog.LogEvent(provider, db.ACT_SYNC_HOST_COMPLETE, msg, userCred) +} + func syncHostNics(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, localHost *SHost, remoteHost cloudprovider.ICloudHost) { result := localHost.SyncHostExternalNics(ctx, userCred, remoteHost) msg := result.Result() diff --git a/pkg/compute/models/hosts.go b/pkg/compute/models/hosts.go index ea901a4fd1..3f365958c6 100644 --- a/pkg/compute/models/hosts.go +++ b/pkg/compute/models/hosts.go @@ -53,6 +53,7 @@ import ( "yunion.io/x/onecloud/pkg/mcclient" "yunion.io/x/onecloud/pkg/mcclient/auth" "yunion.io/x/onecloud/pkg/mcclient/modules" + "yunion.io/x/onecloud/pkg/multicloud/esxi" "yunion.io/x/onecloud/pkg/util/httputils" "yunion.io/x/onecloud/pkg/util/logclient" "yunion.io/x/onecloud/pkg/util/rbacutils" @@ -1398,6 +1399,16 @@ func (self *SHost) GetMasterWire() *SWire { return &wire } +func (self *SHost) getHostwires() ([]SHostwire, error) { + hostwires := make([]SHostwire, 0) + q := self.GetWiresQuery() + err := db.FetchModelObjects(HostwireManager, q, &hostwires) + if err != nil { + return nil, err + } + return hostwires, nil +} + func (self *SHost) getHostwiresOfId(wireId string) []SHostwire { hostwires := make([]SHostwire, 0) @@ -4908,6 +4919,93 @@ func (self *SHost) UpdateDiskConfig(userCred mcclient.TokenCredential, layouts [ return nil } +// TODO: support multithreaded operation +func (host *SHost) SyncEsxiHostWires(ctx context.Context, userCred mcclient.TokenCredential, remoteHost cloudprovider.ICloudHost) compare.SyncResult { + lockman.LockObject(ctx, host) + defer lockman.ReleaseObject(ctx, host) + + result := compare.SyncResult{} + ca := host.GetCloudaccount() + host2wires, err := ca.GetHost2Wire(ctx, userCred) + if err != nil { + result.Error(errors.Wrap(err, "unable to GetHost2Wire")) + return result + } + log.Infof("host2wires: %s", jsonutils.Marshal(host2wires)) + ihost := remoteHost.(*esxi.SHost) + remoteHostId := ihost.GetId() + vsWires := host2wires[remoteHostId] + + log.Infof("vsWires: %s", jsonutils.Marshal(vsWires)) + netIfs := host.GetNetInterfaces() + hostwires, err := host.getHostwires() + if err != nil { + result.Error(errors.Wrapf(err, "unable to getHostwires of host %s", host.GetId())) + return result + } + + for i := range vsWires { + vsWire := vsWires[i] + if vsWire.SyncTimes > 0 { + continue + } + netif := host.findNetIfs(netIfs, vsWire.Mac) + if netif == nil { + // do nothing + continue + } + hostwire := host.findHostwire(hostwires, vsWire.WireId, vsWire.Mac) + if hostwire == nil { + hostwire = &SHostwire{ + Bridge: vsWire.VsId, + MacAddr: vsWire.Mac, + HostId: host.GetId(), + WireId: vsWire.WireId, + } + hostwire.MacAddr = vsWire.Mac + err := HostwireManager.TableSpec().Insert(ctx, hostwire) + if err != nil { + result.Error(errors.Wrapf(err, "unable to create hostwire for host %q", host.GetId())) + continue + } + } + if hostwire.Bridge != vsWire.VsId { + db.Update(hostwire, func() error { + hostwire.Bridge = vsWire.VsId + return nil + }) + } + if len(netif.WireId) == 0 { + db.Update(netif, func() error { + netif.WireId = vsWire.WireId + return nil + }) + } + vsWires[i].SyncTimes += 1 + } + log.Infof("after sync: %s", jsonutils.Marshal(host2wires)) + ca.SetHost2Wire(ctx, userCred, host2wires) + return result +} + +func (host *SHost) findHostwire(hostwires []SHostwire, wireId string, mac string) *SHostwire { + for i := range hostwires { + if hostwires[i].WireId == wireId && hostwires[i].MacAddr == mac { + return &hostwires[i] + } + } + return nil +} + +func (host *SHost) findNetIfs(netIfs []SNetInterface, mac string) *SNetInterface { + for i := range netIfs { + if netIfs[i].Mac == mac { + return &netIfs[i] + } + } + return nil +} + func (host *SHost) SyncHostExternalNics(ctx context.Context, userCred mcclient.TokenCredential, ihost cloudprovider.ICloudHost) compare.SyncResult { result := compare.SyncResult{} @@ -4960,7 +5058,7 @@ func (host *SHost) SyncHostExternalNics(ctx context.Context, userCred mcclient.T if hw != nil && (hw.Bridge != extNics[i].GetBridge() || hw.Interface != extNics[i].GetDevice()) { db.Update(hw, func() error { hw.Interface = extNics[i].GetDevice() - hw.Bridge = extNics[i].GetBridge() + // hw.Bridge = extNics[i].GetBridge() return nil }) } diff --git a/pkg/compute/models/netinterfaces.go b/pkg/compute/models/netinterfaces.go index 9e98e4b5a1..7151f67144 100644 --- a/pkg/compute/models/netinterfaces.go +++ b/pkg/compute/models/netinterfaces.go @@ -273,6 +273,7 @@ func (self *SNetInterface) GetCandidateNetworkForIp(ownerId mcclient.IIdentityPr if wire == nil { return nil, nil } + log.Infof("ipAddr: %s, netiName: %s, wire: %s", ipAddr, self.GetName(), wire.GetName()) return wire.GetCandidateNetworkForIp(ownerId, scope, ipAddr) }