From 0ebe04234e8fde407f53effb0b5f4d067d6bc53b Mon Sep 17 00:00:00 2001 From: zumun Date: Wed, 21 Oct 2026 19:01:52 +0900 Subject: [PATCH] feat: add preference sorting and multi-ok DC prioritization in replication pipeline --- Modules/NetAppService.ps1 | 32 +++++++++++++++++++++++++++----- Start-App.ps1 | 14 +++++++++++--- 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/Modules/NetAppService.ps1 b/Modules/NetAppService.ps1 index 724a2ea..9342606 100644 --- a/Modules/NetAppService.ps1 +++ b/Modules/NetAppService.ps1 @@ -225,6 +225,7 @@ function Get-NetAppActiveDc { $srvIp = if ($ds.server_ip) { $ds.server_ip } else { "" } $srvType = if ($ds.server_type) { $ds.server_type } elseif ($ds.type) { $ds.type } else { "dc" } + $srvPref = if ($ds.preference) { $ds.preference.ToString().ToLower() } else { "regular" } $srvState = if ($ds.state) { $ds.state } elseif ($ds.status) { $ds.status } else { "unknown" } $srvNode = if ($ds.node -and $ds.node.name) { $ds.node.name } elseif ($ds.node) { $ds.node.ToString() } else { "node-01" } @@ -234,6 +235,7 @@ function Get-NetAppActiveDc { ServerName = $srvName ServerIp = $srvIp ServerType = $srvType + Preference = $srvPref State = $srvState Node = $srvNode Domain = $srvDomain @@ -243,11 +245,25 @@ function Get-NetAppActiveDc { } } - # 1순위: 상태가 "ok", "active", "up" 이면서 type이 DC인 서버 - $bestMatch = $discoveredList | Where-Object { + # OK 상태인 DC 후보군 추출 + $okDcList = @($discoveredList | Where-Object { ($_.State -like "*ok*" -or $_.State -like "*up*" -or $_.State -like "*active*") -and ($_.ServerType -like "*dc*" -or $_.ServerType -like "*primary*") - } | Select-Object -First 1 + }) + + # OK 상태인 고유 DC FQDN 목록 + $allOkDcNames = @($okDcList | Select-Object -ExpandProperty ServerName -Unique) + + # 1순위: OK 상태 중 Preference 가중치 정렬 (preferred: 1, favored: 2, regular: 3) + $sortedOkDcs = @($okDcList | Sort-Object -Property @{ + Expression = { + if ($_.Preference -eq "preferred") { 1 } + elseif ($_.Preference -eq "favored") { 2 } + else { 3 } + } + }) + + $bestMatch = if ($sortedOkDcs.Count -gt 0) { $sortedOkDcs[0] } else { $null } # 2순위: 상태 무관 DC 타입 서버 if (-not $bestMatch) { @@ -265,6 +281,7 @@ function Get-NetAppActiveDc { return [PSCustomObject]@{ ActiveDC = $bestMatch.ServerName ActiveDcIp = $bestMatch.ServerIp + Preference = $bestMatch.Preference Node = $bestMatch.Node SvmName = $bestMatch.SvmName Status = "OK (Active Connected)" @@ -273,6 +290,8 @@ function Get-NetAppActiveDc { IsLive = $true DiscoveryMethod = "ONTAP REST API (/api/protocols/cifs/domains)" DiscoveredServerCount= $discoveredList.Count + OkCount = $allOkDcNames.Count + AllOkDcs = $allOkDcNames AllDiscoveredServers = $discoveredList.ToArray() } } @@ -321,6 +340,7 @@ function Get-NetAppActiveDc { return [PSCustomObject]@{ ActiveDC = "dc04.corp.local" ActiveDcIp = "10.20.1.14" + Preference = "preferred" Node = "ontap-node-02" SvmName = if ($svm) { $svm } else { "svm_cifs_prod01" } Status = "OK (Simulated Active Binding)" @@ -329,10 +349,12 @@ function Get-NetAppActiveDc { IsLive = $false DiscoveryMethod = "ONTAP Domain Discovery (Simulated)" DiscoveredServerCount= 2 + OkCount = 2 + AllOkDcs = @("dc04.corp.local", "dc01.corp.local") FallbackReason = if ($attemptErrors.Count -gt 0) { ($attemptErrors -join "; ") } else { "Live mode not configured" } AllDiscoveredServers = @( - [PSCustomObject]@{ ServerName = "dc04.corp.local"; ServerIp = "10.20.1.14"; ServerType = "ms_dc"; State = "ok"; Node = "ontap-node-02"; SvmName = "svm_cifs_prod01" }, - [PSCustomObject]@{ ServerName = "dc01.corp.local"; ServerIp = "10.10.1.11"; ServerType = "ms_dc"; State = "ok"; Node = "ontap-node-01"; SvmName = "svm_cifs_prod01" } + [PSCustomObject]@{ ServerName = "dc04.corp.local"; ServerIp = "10.20.1.14"; ServerType = "ms_dc"; Preference = "preferred"; State = "ok"; Node = "ontap-node-02"; SvmName = "svm_cifs_prod01" }, + [PSCustomObject]@{ ServerName = "dc01.corp.local"; ServerIp = "10.10.1.11"; ServerType = "ms_dc"; Preference = "favored"; State = "ok"; Node = "ontap-node-01"; SvmName = "svm_cifs_prod01" } ) } } diff --git a/Start-App.ps1 b/Start-App.ps1 index b31f490..223bcd2 100644 --- a/Start-App.ps1 +++ b/Start-App.ps1 @@ -1067,18 +1067,26 @@ function Navigate-ToPage { [System.Threading.Monitor]::Exit($sync.Logs) } - # 3. Background Sync to the other 5 DCs + # 3. Background Sync to the other 5 DCs (NetApp의 다른 OK 상태 DC들을 최우선 복제) if ($pBgSync) { $sync.Status = "3/5단계: 타 도메인 컨트롤러(5대) 백그라운드 복제 큐잉..." Start-Sleep -Milliseconds 150 $allDcs = Get-ADDomainControllers -Config $cfg $otherDcs = @($allDcs | Where-Object { $_.HostName -ne $targetDc }) - foreach ($odc in $otherDcs) { + + # NetApp에서 OK 상태로 감지된 추가 DC가 있다면 최우선 순위로 정렬하여 먼저 동기화 + $priorityDcNames = if ($activeDcInfo.AllOkDcs) { @($activeDcInfo.AllOkDcs | Where-Object { $_ -ne $targetDc }) } else { @() } + $sortedTargetDcs = @($otherDcs | Sort-Object -Property @{ + Expression = { if ($priorityDcNames -contains $_.HostName) { 0 } else { 1 } } + }) + + foreach ($odc in $sortedTargetDcs) { $null = Sync-ADObjectToTargetDc -ObjectDN "CN=$pShare,OU=SecurityGroups,DC=corp,DC=local" -SourceDc $targetDc -DestinationDc $odc.HostName -Config $cfg } [System.Threading.Monitor]::Enter($sync.Logs) try { - $sync.Logs.Add("[$((Get-Date).ToString('yyyy-MM-dd HH:mm:ss'))] [단계 3] 6대 DC 복제 동기화: NetApp 활성 DC($targetDc) -> 5대 DC 비동기 복제 전송 완료") + $pMsg = if ($priorityDcNames.Count -gt 0) { " (NetApp OK 후보 DC [$(($priorityDcNames) -join ', ')] 우선 복제)" } else { "" } + $sync.Logs.Add("[$((Get-Date).ToString('yyyy-MM-dd HH:mm:ss'))] [단계 3] 6대 DC 복제 동기화: NetApp 활성 DC($targetDc) -> 5대 DC 비동기 복제 전송 완료$pMsg") } finally { [System.Threading.Monitor]::Exit($sync.Logs) }