ΠΡΠΈΠ²Π΅Ρ, Π₯Π°Π±Ρ! ΠΡΠ΅Π΄ΡΡΠ°Π²Π»ΡΡ Π²Π°ΡΠ΅ΠΌΡ Π²Π½ΠΈΠΌΠ°Π½ΠΈΡ ΠΏΠ΅ΡΠ΅Π²ΠΎΠ΄ ΡΡΠ°ΡΡΠΈ
I promise itβs not an oxymoron"
ΠΠ±ΡΠ΅ΠΊΡΠ½ΠΎ-ΠΎΡΠΈΠ΅Π½ΡΠΈΡΠΎΠ²Π°Π½Π½Π°Ρ ΠΈ ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»ΡΠ½Π°Ρ ΠΏΠ°ΡΠ°Π΄ΠΈΠ³ΠΌΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΌΠΎΠ³ΡΡ ΠΊΠ°Π·Π°ΡΡΡΡ Π½Π΅ Π² Π»Π°Π΄Π°Ρ Π΄ΡΡΠ³ Ρ Π΄ΡΡΠ³ΠΎΠΌ, Π½ΠΎ ΠΎΠ±Π΅ Π² ΡΠ°Π²Π½ΠΎΠΉ ΠΌΠ΅ΡΠ΅ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°ΡΡΡΡ Π² Powershell. ΠΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΈ Π²ΡΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ½ΡΠ΅ ΡΠ·ΡΠΊΠΈ, ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»ΡΠ½ΡΠ΅ ΠΈ Π½Π΅Ρ, ΠΈΠΌΠ΅ΡΡ ΡΡΠ΅Π΄ΡΡΠ²Π° ΡΠ°ΡΡΠΈΡΠ΅Π½Π½ΠΎΠ³ΠΎ ΡΠ²ΡΠ·ΡΠ²Π°Π½ΠΈΡ ΠΈΠΌΡΠ½ ΠΈ Π·Π½Π°ΡΠ΅Π½ΠΈΠΉ; ΠΠ»Π°ΡΡΡ, ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎ struct-Π°ΠΌ ΠΈ record-Π°ΠΌ, ΡΡΠΎ Π²ΡΠ΅Π³ΠΎ Π»ΠΈΡΡ ΠΎΠ΄ΠΈΠ½ ΠΏΠΎΠ΄Ρ ΠΎΠ΄. ΠΡΠ»ΠΈ ΠΌΡ ΠΎΠ³ΡΠ°Π½ΠΈΡΠΈΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΠ»Π°ΡΡΠΎΠ² ΡΠ²ΡΠ·ΡΠ²Π°Π½ΠΈΠ΅ΠΌ ΠΈΠΌΡΠ½ ΠΈ Π·Π½Π°ΡΠ΅Π½ΠΈΠΉ ΠΈ ΡΡΠ°Π½Π΅ΠΌ ΠΈΠ·Π±Π΅Π³Π°ΡΡ ΡΠ°ΠΊΠΈΡ "ΡΡΠΆΡΠ»ΡΡ " ΠΎΠ±ΡΠ΅ΠΊΡΠ½ΠΎ-ΠΎΡΠΈΠ΅Π½ΡΠΈΡΠΎΠ²Π°Π½Π½ΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ½ΡΡ ΠΊΠΎΠ½ΡΠ΅ΠΏΡΠΈΠΉ, ΠΊΠ°ΠΊ Π½Π°ΡΠ»Π΅Π΄ΠΎΠ²Π°Π½ΠΈΠ΅, ΠΏΠΎΠ»ΠΈΠΌΠΎΡΡΠΈΠ·ΠΌ, ΠΈΠ»ΠΈ ΠΈΠ·ΠΌΠ΅Π½ΡΠ΅ΠΌΠΎΡΡΡ (mutability), ΠΌΡ ΡΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΈΡ ΠΏΡΠ΅ΠΈΠΌΡΡΠ΅ΡΡΠ²Π°, Π½Π΅ ΡΡΠ»ΠΎΠΆΠ½ΡΡ Π½Π°Ρ ΠΊΠΎΠ΄. ΠΠ°Π»Π΅Π΅, Π΄ΠΎΠ±Π°Π²Π»ΡΡ Π½Π΅ΠΈΠ·ΠΌΠ΅Π½ΡΠ΅ΠΌΡΠ΅ (immutable) ΠΌΠ΅ΡΠΎΠ΄Ρ ΠΏΡΠ΅ΠΎΠ±ΡΠ°Π·ΠΎΠ²Π°Π½ΠΈΡ ΡΠΈΠΏΠΎΠ², ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΎΠ±ΠΎΠ³Π°ΡΠΈΡΡ ΠΠ»Π°ΡΡΠ°ΠΌΠΈ Π½Π°Ρ ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»ΡΠ½ΡΠΉ ΠΊΠΎΠ΄.
ΠΠ°Π³ΠΈΡ ΠΊΠ°ΡΡΠΎΠ²
ΠΠ°ΡΡΡ ΠΎΠ΄Π½Π° ΠΈΠ· ΡΠ°ΠΌΡΡ ΠΌΠΎΡΠ½ΡΡ ΡΠΈΡ Π² Powershell. ΠΠΎΠ³Π΄Π° Π²Ρ ΠΏΠΎΠ΄Π²Π΅ΡΠ³Π°Π΅ΡΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΠΊΠ°ΡΡΡ, Π²Ρ ΠΏΠΎΠ»Π°Π³Π°Π΅ΡΠ΅ΡΡ Π½Π° Π΄ΠΎΠ±Π°Π²Π»ΡΠ΅ΠΌΡΡ ΡΡΠ΅Π΄ΠΎΠΉ Π² Π²Π°ΡΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ Π½Π΅ΡΠ²Π½ΡΡ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΠΈ ΠΈ Π²Π°Π»ΠΈΠ΄Π°ΡΠΈΠΈ. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, ΠΏΡΠΎΡΡΠΎΠΉ ΠΊΠ°ΡΡ ΡΡΡΠΎΠΊΠΈ Π² [xml] ΠΏΡΠΎΠ³ΠΎΠ½ΠΈΡ Π΅Ρ ΡΠ΅ΡΠ΅Π· ΠΊΠΎΠ΄ ΠΏΠ°ΡΡΠ΅ΡΠ° ΠΈ ΡΠ³Π΅Π½Π΅ΡΠΈΡΡΠ΅Ρ ΠΏΠΎΠ»Π½ΠΎΠ΅ Π΄Π΅ΡΠ΅Π²ΠΎ xml. ΠΡ ΠΌΠΎΠΆΠ΅ΠΌ Π² ΡΠ²ΠΎΡΠΌ ΠΊΠΎΠ΄Π΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΠ»Π°ΡΡΡ Ρ ΡΠΎΠΉ ΠΆΠ΅ ΡΠ΅Π»ΡΡ.
ΠΠ°ΡΡ Ρ ΡΡΡΠ°Π±Π»ΠΈΡ
ΠΡΠ»ΠΈ Ρ Π²Π°Ρ Π½Π΅Ρ ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΎΡΠ°, Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΏΡΠΎΠ΄ΠΎΠ»ΠΆΠ°ΡΡ ΠΈ Π΄Π°Π»ΡΡΠ΅ Π±Π΅Π· Π½Π΅Π³ΠΎ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ ΠΊΠ°ΡΡ Ρ ΡΡΡΠ°Π±Π»ΠΈΡΡ Π² ΡΠΈΠΏ Π²Π°ΡΠ΅Π³ΠΎ ΠΊΠ»Π°ΡΡΠ°. ΠΠ΅ Π·Π°Π±ΡΠ΄ΡΡΠ΅ Π²ΠΎΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ Π°ΡΡΠΈΠ±ΡΡΠ°ΠΌΠΈ Π²Π°Π»ΠΈΠ΄Π°ΡΠΈΠΈ, ΡΡΠΎΠ±Ρ Π² ΠΏΠΎΠ»Π½ΠΎΠΉ ΠΌΠ΅ΡΠ΅ Π²ΠΎΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ ΡΡΠΈΠΌ ΠΏΠ°ΡΡΠ΅ΡΠ½ΠΎΠΌ. ΠΠ°ΠΎΠ΄Π½ΠΎ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΠΈΠΏΠΈΠ·ΠΈΡΠΎΠ²Π°Π½Π½ΡΠ΅ ΡΠ²ΠΎΠΉΡΡΠ²Π° ΠΊΠ»Π°ΡΡΠ°, ΡΡΠΎΠ±Ρ Π·Π°ΠΏΡΡΡΠΈΡΡ Π΅ΡΡ Π±ΠΎΠ»Π΅Π΅ Π³Π»ΡΠ±ΠΎΠΊΡΡ Π»ΠΎΠ³ΠΈΠΊΡ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΠΈ ΠΈ Π²Π°Π»ΠΈΠ΄Π°ΡΠΈΠΈΠΈ.
class Cluster {
[ValidatePattern("^[A-z]+$")]
[string] $Service
[ValidateSet("TEST", "STAGE", "CANARY", "PROD")]
[string] $FlightingRing
[ValidateSet("EastUS", "WestUS", "NorthEurope")]
[string] $Region
[ValidateRange(0, 255)]
[int] $Index
}
[Cluster]@{
Service = "MyService"
FlightingRing = "PROD"
Region = "EastUS"
Index = 2
}
ΠΡΠΎΠΌΠ΅ ΡΠΎΠ³ΠΎ, ΠΊΠ°ΡΡ ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ ΠΏΠΎΠ»ΡΡΠΈΡΡ ΡΠΈΡΡΡΠΉ Π²ΡΠ²ΠΎΠ΄. Π‘ΡΠ°Π²Π½ΠΈΡΠ΅ Π²ΡΠ²ΠΎΠ΄ ΠΌΠ°ΡΡΠΈΠ²Π° Ρ ΡΡΡΠ°Π±Π»ΠΈΡ Cluster ΠΏΠ΅ΡΠ΅Π΄Π°Π½Π½ΡΠΉ Π² Format-Table c ΡΠ΅ΠΌ, ΡΡΠΎ ΠΏΠΎΠ»ΡΡΠΈΡΡΡ, Π΅ΡΠ»ΠΈ ΠΏΡΠ΅ΠΆΠ΄Π΅ ΠΊΠ°ΡΡΠΎΠ²Π°ΡΡ ΡΡΠΈ Ρ ΡΡΡΠ°Π±Π»ΠΈΡΡ Π² ΠΊΠ»Π°ΡΡ. Π‘Π²ΠΎΠΉΡΡΠ²Π° ΠΊΠ»Π°ΡΡΠ° Π²ΡΠ΅Π³Π΄Π° ΠΏΠ΅ΡΠ΅ΡΠΈΡΠ»ΡΡΡΡΡ Π² ΡΠΎΠΌ ΠΏΠΎΡΡΠ΄ΠΊΠ΅, Π² ΠΊΠΎΡΠΎΡΠΎΠΌ ΠΎΠ½ΠΈ ΡΠ°ΠΌ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Ρ. ΠΠ΅ Π·Π°Π±ΡΠ΄ΡΡΠ΅ Π΄ΠΎΠ±Π°Π²ΠΈΡΡ ΠΊΠ»ΡΡΠ΅Π²ΠΎΠ΅ ΡΠ»ΠΎΠ²ΠΎ hidden ΠΏΠ΅ΡΠ΅Π΄ Π²ΡΠ΅ΠΌΠΈ ΡΠ΅ΠΌΠΈ ΡΠ²ΠΎΠΉΡΡΠ²Π°ΠΌΠΈ, ΠΊΠΎΡΠΎΡΡΠ΅ Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½Ρ Π±ΡΡΡ Π²ΠΈΠ΄Π½Ρ Π² Π²ΡΠ΄Π°ΡΠ΅.
ΠΠ°ΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠΉ
ΠΡΠ»ΠΈ Ρ Π²Π°Ρ Π΅ΡΡΡ ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΎΡ Ρ ΠΎΠ΄Π½ΠΈΠΌ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠΎΠΌ, ΠΊΠ°ΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΡ ΠΊ Π²Π°ΡΠ΅ΠΌΡ ΡΠΈΠΏΡ ΠΊΠ»Π°ΡΡΠ° ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΡΡΠΎΠΌΡ Π²Π°ΡΠ΅ΠΌΡ ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΎΡΡ, Π² ΠΊΠΎΡΠΎΡΠΎΠΌ Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΠΎΠ²Π°ΡΡ ΠΈΠ½ΡΡΠ°Π½Ρ Π²Π°ΡΠ΅Π³ΠΎ ΠΊΠ»Π°ΡΡΠ°
class Cluster {
[ValidatePattern("^[A-z]+$")]
[string] $Service
[ValidateSet("TEST", "STAGE", "CANARY", "PROD")]
[string] $FlightingRing
[ValidateSet("EastUS", "WestUS", "NorthEurope")]
[string] $Region
[ValidateRange(0, 255)]
[int] $Index
Cluster([string] $id) {
$this.Service, $this.FlightingRing, $this.Region, $this.Index = $id -split "-"
}
}
[Cluster]"MyService-PROD-EastUS-2"
ΠΠ°ΡΡ ΠΊ ΡΡΡΠΎΠΊΠ΅
Π’Π°ΠΊΠΆΠ΅ Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΏΠ΅ΡΠ΅ΠΎΠΏΡΠ΅Π΄Π΅Π»ΠΈΡΡ ΠΌΠ΅ΡΠΎΠ΄ ΠΊΠ»Π°ΡΡΠ° [string] ToString(), ΡΡΠΎΠ±Ρ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΠΈΡΡ Π»ΠΎΠ³ΠΈΠΊΡ ΡΡΡΠΎΠΊΠΎΠ²ΠΎΠ³ΠΎ ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»Π΅Π½ΠΈΡ ΠΎΠ±ΡΠ΅ΠΊΡΠ°, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΈΠ½ΡΠ΅ΡΠΏΠΎΠ»ΡΡΠΈΡ ΡΡΡΠΎΠΊ.
class Cluster {
[ValidatePattern("^[A-z]+$")]
[string] $Service
[ValidateSet("TEST", "STAGE", "CANARY", "PROD")]
[string] $FlightingRing
[ValidateSet("EastUS", "WestUS", "NorthEurope")]
[string] $Region
[ValidateRange(0, 255)]
[int] $Index
[string] ToString() {
return $this.Service, $this.FlightingRing, $this.Region, $this.Index -join "-"
}
}
$cluster = [Cluster]@{
Service = "MyService"
FlightingRing = "PROD"
Region = "EastUS"
Index = 2
}
Write-Host "We just created a model for '$cluster'"
ΠΠ°ΡΡ ΡΠ΅ΡΠΈΠ°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½ΡΡ ΠΈΠ½ΡΡΠ°Π½ΡΠΎΠ²
ΠΠ°ΡΡ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΡΡ Π΄Π΅ΡΠ΅ΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΡ. ΠΡΠΈΠΌΠ΅ΡΡ Π½ΠΈΠΆΠ΅ Π·Π°Π²Π΅ΡΡΠ°ΡΡΡ ΠΎΡΠΈΠ±ΠΊΠΎΠΉ, Π΅ΡΠ»ΠΈ Π΄Π°Π½Π½ΡΠ΅ Π½Π΅ ΠΎΡΠ²Π΅ΡΠ°ΡΡ Π½Π°ΡΠ΅ΠΉ ΡΠΏΠ΅ΡΠΈΡΠΈΠΊΠ°ΡΠΈΠΈ Π² Cluster
# ΠΠ°Π»ΠΈΠ΄Π°ΡΠΈΡ ΡΠ΅ΡΠΈΠ°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½ΡΡ
Π΄Π°Π½Π½ΡΡ
[Cluster]$cluster = Get-Content "./my-cluster.json" | ConvertFrom-Json
[Cluster[]]$clusters = Import-Csv "./my-clusters.csv"
ΠΠ°ΡΡΡ Π² Π²Π°ΡΠ΅ΠΌ ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»ΡΠ½ΠΎΠΌ ΠΊΠΎΠ΄Π΅
Π€ΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»ΡΠ½ΡΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ ΡΠ½Π°ΡΠ°Π»Π° ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΡΡ ΡΡΡΡΠΊΡΡΡΡ Π΄Π°Π½Π½ΡΡ , Π·Π°ΡΠ΅ΠΌ ΠΈΠΌΠΏΠ»Π΅ΠΌΠ΅Π½ΡΠΈΡΡΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ ΠΊΠ°ΠΊ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΠΎΡΡΡ ΡΡΠ°Π½ΡΡΠΎΡΠΌΠ°ΡΠΈΠΉ Π½Π°Π΄ Π½Π΅ΠΈΠ·ΠΌΠ΅Π½ΡΠ΅ΠΌΡΠΌΠΈ ΡΡΡΡΠΊΡΡΡΠ°ΠΌΠΈ Π΄Π°Π½Π½ΡΡ . ΠΠ΅ΡΠΌΠΎΡΡΡ Π½Π° ΠΏΡΠΎΡΠΈΠ²ΠΎΡΠ΅ΡΠΈΠ²ΠΎΠ΅ Π²ΠΏΠ΅ΡΠ°ΡΠ»Π΅Π½ΠΈΠ΅, ΠΊΠ»Π°ΡΡΡ ΡΠ΅Π°Π»ΡΠ½ΠΎ ΠΏΠΎΠΌΠΎΠ³Π°ΡΡ ΠΏΠΈΡΠ°ΡΡ ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»ΡΠ½ΡΠΉ ΠΊΠΎΠ΄, Π±Π»Π°Π³ΠΎΠ΄Π°ΡΡ ΠΌΠ΅ΡΠΎΠ΄Π°ΠΌ ΠΊΠΎΠ½Π²Π΅ΡΡΠ°ΡΠΈΠΈ ΡΠΈΠΏΠΎΠ².
Π€ΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»ΡΠ½ΡΠΉ Π»ΠΈ Powershell Ρ ΠΏΠΈΡΡ?
ΠΠ½ΠΎΠ³ΠΎ Π»ΡΠ΄Π΅ΠΉ ΠΏΡΠΈΡΠ΅Π΄ΡΠΈΡ ΠΈΠ· C# ΠΈΠ»ΠΈ Ρ ΠΏΠΎΠ΄ΠΎΠ±Π½ΡΠΌ ΠΏΡΠΎΡΠ»ΡΠΌ ΠΏΠΈΡΡΡ Powershell, ΠΊΠΎΡΠΎΡΡΠΉ ΠΏΠΎΡ ΠΎΠΆ Π½Π° Π‘#. ΠΠΎΡΡΡΠΏΠ°Ρ ΡΠ°ΠΊ, Π²Ρ ΠΎΡΠΊΠ°Π·ΡΠ²Π°Π΅ΡΠ΅ΡΡ ΠΎΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ ΠΊΠΎΠ½ΡΠ΅ΠΏΡΠΈΠΉ ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»ΡΠ½ΠΎΠ³ΠΎ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΈ, Π²Π΅ΡΠΎΡΡΠ½ΠΎ, ΠΏΠΎΠ»ΡΡΠΈΡΠ΅ ΠΏΠΎΠ»ΡΠ·Ρ ΡΡΠΈΠ»Π΅Π½Π½ΠΎ ΠΏΠΎΠ³ΡΡΠ·ΠΈΠ²ΡΠΈΡΡ Π² ΠΎΠ±ΡΠ΅ΠΊΡΠ½ΠΎ-ΠΎΡΠΈΠ΅Π½ΡΠΈΡΠΎΠ²Π°Π½Π½ΠΎΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ Π² Powershell ΠΈΠ»ΠΈ Π»ΡΡΡΠ΅ ΠΈΠ·ΡΡΠΈΠ² ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»ΡΠ½ΠΎΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅.
ΠΡΠ»ΠΈ Π²Ρ Π³Π»ΡΠ±ΠΎΠΊΠΎ ΠΏΠΎΠ»Π°Π³Π°Π΅ΡΠ΅ΡΡ Π½Π° ΡΡΠ°Π½ΡΡΠΎΡΠΌΠ°ΡΠΈΡ ΠΈΠΌΠΌΡΡΠ°Π±Π΅Π»ΡΠ½ΡΡ Π΄Π°Π½Π½ΡΡ , ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅ΡΡ (|), Where-Object, ForEach-Object, Select-Object, Group-Object, Sort-Object ΠΈ Ρ. Π΄. β Ρ Π²Π°Ρ Π±ΠΎΠ»Π΅Π΅ ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»ΡΠ½ΡΠΉ ΡΡΠΈΠ»Ρ, ΠΈ Π²Π°ΠΌ ΠΏΠΎΠΌΠΎΠΆΠ΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΊΠ»Π°ΡΡΠΎΠ² Powershell Π² ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»ΡΠ½ΠΎΠΌ ΡΡΠΈΠ»Π΅.
Π€ΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»ΡΠ½ΠΎΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΊΠ»Π°ΡΡΠΎΠ²
ΠΠ°ΡΡΡ, Ρ ΠΎΡΡ ΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡ Π°Π»ΡΡΠ΅ΡΠ½Π°ΡΠΈΠ²Π½ΡΠΉ ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡ, Π²ΡΠ΅Π³ΠΎ Π»ΠΈΡΡ ΠΌΠ°ΠΏΠΏΠΈΠ½Π³ ΠΌΠ΅ΠΆΠ΄Ρ Π΄Π²ΡΠΌΡ Π΄ΠΎΠΌΠ΅Π½Π°ΠΌΠΈ. Π ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅ΡΠ΅ ΠΌΠΎΠΆΠ½ΠΎ ΡΠΌΠ°ΠΏΠΈΡΡ ΠΌΠ°ΡΡΠΈΠ² Π·Π½Π°ΡΠ΅Π½ΠΈΠΉ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ ForEach-Object.
Π ΠΏΡΠΈΠΌΠ΅ΡΠ΅ Π½ΠΈΠΆΠ΅ ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΎΡ Node ΠΈΡΠΏΠΎΠ»Π½ΡΠ΅ΡΡΡ ΠΊΠ°ΠΆΠ΄ΡΠΉ ΡΠ°Π· ΠΊΠΎΠ³Π΄Π° ΠΏΡΠΎΠΈΡΡ ΠΎΠ΄ΠΈΡ ΠΊΠ°ΡΡ ΠΊ Datum, ΠΈ ΡΡΠΎ Π΄Π°ΡΡ Π½Π°ΠΌ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ Π½Π΅ ΠΏΠΈΡΠ°ΡΡ ΠΈΠ·ΡΡΠ΄Π½ΠΎΠ΅ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΠΊΠΎΠ΄Π°. Π ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ΅ Π½Π°Ρ ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ ΡΠΎΠΊΡΡΠΈΡΡΠ΅ΡΡΡ Π½Π° Π΄Π΅ΠΊΠ»Π°ΡΠ°ΡΠΈΠ²Π½ΠΎΠΌ Π·Π°ΠΏΡΠΎΡΠ΅ Π΄Π°Π½Π½ΡΡ ΠΈ Π°Π³ΡΠ΅Π³Π°ΡΠΈΠΈ, Π² ΡΠΎ Π²ΡΠ΅ΠΌΡ ΠΊΠ°ΠΊ Π½Π°ΡΠΈ ΠΊΠ»Π°ΡΡΡ Π±Π΅ΡΡΡ Π½Π° ΡΠ΅Π±Ρ ΠΏΠ°ΡΡΠΈΠ½Π³ Π΄Π°Π½Π½ΡΡ ΠΈ Π²Π°Π»ΠΈΠ΄Π°ΡΠΈΡ.
# ΠΡΠΈΠΌΠ΅Ρ ΠΊΠΎΠΌΠ±ΠΈΠ½ΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΊΠ»Π°ΡΡΠΎΠ² Ρ ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅ΡΠ°ΠΌΠΈ Π΄Π»Ρ separation of concerns Π² ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅ΡΠ°Ρ
class Node {
[ValidateLength(3, 7)]
[string] $Name
[ValidateSet("INT", "PPE", "PROD")]
[string] $FlightingRing
[ValidateSet("EastUS", "WestUS", "NorthEurope", "WestEurope")]
[string] $Region
Node([string] $Name) {
$Name -match "([a-z]+)(INT|PPE|PROD)([a-z]+)"
$_, $this.Service, $this.FlightingRing, $this.Region = $Matches
$this.Name = $Name
}
}
class Datum {
[string] $Name
[int] $Value
[Node] $Computer
[int] Severity() {
$this.Name -match "[0-9]+$"
return $Matches[0]
}
}
Write-Host "Urgent Security Audit Issues:"
Import-Csv "./audit-results.csv" `
| ForEach-Object {[Datum]$_} `
| Where-Object Value -gt 0 `
| Group-Object {$_.Severity()} `
| Where-Object Name -lt 2 `
| ForEach-Object Group `
| ForEach-Object Computer `
| Where-Object FlightingRing -eq "PROD" `
| Sort-Object Name, Region -Unique
Π£ΠΏΠ°ΠΊΠΎΠ²ΠΊΠ° ΠΊΠ»Π°ΡΡΠ° Π΄Π»Ρ ΠΏΠ΅ΡΠ΅ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ
ΠΠΈΡΡΠΎ Π½Π΅ ΡΡΠΎΠ»Ρ ΡΠΆ Ρ ΠΎΡΠΎΡΠΎ, ΠΊΠ°ΠΊ ΠΊΠ°ΠΆΠ΅ΡΡΡ
Π ΡΠΎΠΆΠ°Π»Π΅Π½ΠΈΡ, ΠΊΠ»Π°ΡΡΡ Π½Π΅ ΠΌΠΎΠ³ΡΡ Π±ΡΡΡ ΡΠΊΡΠΏΠΎΡΡΠΈΡΠΎΠ²Π°Π½Ρ ΠΌΠΎΠ΄ΡΠ»ΡΠΌΠΈ ΡΠ΅ΠΌ ΠΆΠ΅ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ, ΠΊΠ°ΠΊ ΡΡΠ½ΠΊΡΠΈΠΈ ΠΈΠ»ΠΈ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅; Π½ΠΎ Ρ ΠΈΡΡΠΎΡΡΠΈ ΠΊΠΎΠ΅-ΠΊΠ°ΠΊΠΈΠ΅ Π΅ΡΡΡ. ΠΠΎΠΏΡΡΡΠΈΠΌ, Π²Π°ΡΠΈ ΠΊΠ»Π°ΡΡΡ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Ρ Π² ΡΠ°ΠΉΠ»Π΅ ./my-classes.ps1
-
ΠΡ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΡΠ΄Π΅Π»Π°ΡΡ Π΄ΠΎΡΡΠΎΡΡΠΈΠ½Π³ ΡΠ°ΠΉΠ»Π° Ρ ΠΊΠ»Π°ΡΡΠ°ΠΌΠΈ:. ./my-classes.ps1. ΠΡΠΎ Π²ΡΠΏΠΎΠ»Π½ΠΈΡ my-classes.ps1 Π² Π²Π°ΡΠ΅ΠΉ ΡΠ΅ΠΊΡΡΠ΅ΠΉ ΠΎΠ±Π»Π°ΡΡΠΈ Π²ΠΈΠ΄ΠΈΠΌΠΎΡΡΠΈ ΠΈ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΠΈΡ ΡΠ°ΠΌ Π²ΡΠ΅ ΠΊΠ»Π°ΡΡΡ ΠΈΠ· ΡΠ°ΠΉΠ»Π°.
-
ΠΡ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΡΠΎΠ·Π΄Π°ΡΡ ΠΌΠΎΠ΄ΡΠ»Ρ Powershell, ΠΊΠΎΡΠΎΡΡΠΉ ΡΠΊΡΠΏΠΎΡΡΠΈΡΡΠ΅Ρ Π²ΡΠ΅ Π²Π°ΡΠΈ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΡΡΠΊΠΈΠ΅ API (ΠΊΠΎΠΌΠ°Π½Π΄Π»Π΅ΡΡ) ΠΈ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ ScriptsToProcess = "./my-classes.ps1" Π² ΠΌΠ°Π½ΠΈΡΠ΅ΡΡΠ΅ Π²Π°ΡΠ΅Π³ΠΎ ΠΌΠΎΠ΄ΡΠ»Ρ, Ρ ΡΠ΅ΠΌ ΠΆΠ΅ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠΎΠΌ: ./my-classes.ps1 Π²ΡΠΏΠΎΠ»Π½ΠΈΡΡΡ Π² Π²Π°ΡΠ΅ΠΌ ΠΎΠΊΡΡΠΆΠ΅Π½ΠΈΠΈ.
ΠΠ°ΠΊΠΎΠΉ Π±Ρ Π²Π°ΡΠΈΠ°Π½Ρ Π²Ρ Π½ΠΈ Π²ΡΠ±ΡΠ°Π»ΠΈ, Π½Π΅ Π·Π°Π±ΡΠ²Π°ΠΉΡΠ΅, ΡΡΠΎ ΡΠΈΡΡΠ΅ΠΌΠ° ΡΠΈΠΏΠΎΠ² Powershell Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ ΡΠ°Π·ΡΡΠ»ΠΈΡΡ ΠΎΠ΄Π½ΠΎΠΈΠΌΡΠ½Π½ΡΠ΅ ΡΠΈΠΏΡ, Π·Π°Π³ΡΡΠΆΠ΅Π½Π½ΡΠ΅ ΠΈΠ· ΡΠ°Π·Π½ΡΡ
ΠΌΠ΅ΡΡ.
ΠΠ°ΠΆΠ΅ Π΅ΡΠ»ΠΈ Π²Ρ Π·Π°Π³ΡΡΠ·ΠΈΠ»ΠΈ ΠΈΠ· ΡΠ°Π·Π½ΡΡ
ΠΌΠ΅ΡΡ Π΄Π²Π° ΠΈΠ΄Π΅Π½ΡΠΈΡΠ½ΡΡ
ΠΊΠ»Π°ΡΡΠ° Ρ ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²ΡΠΌΠΈ ΡΠ²ΠΎΠΉΡΡΠ²Π°ΠΌΠΈ, Π²Ρ ΡΠΈΡΠΊΡΠ΅ΡΠ΅ Π½Π°ΡΠ²Π°ΡΡΡΡ Π½Π° ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ.
ΠΡΡΡ Π²ΠΏΠ΅ΡΠ΅Π΄
ΠΡΡΡΠΈΠΉ ΡΠΏΠΎΡΠΎΠ± ΠΈΠ·Π±Π΅ΠΆΠ°ΡΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌ Ρ ΡΠ°Π·ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ΠΌ ΡΠΈΠΏΠΎΠ² β Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ Π²ΡΡΡΠ°Π²Π»ΡΡΡ Π΄Π»Ρ ΡΠ·Π΅ΡΠΎΠ² Π²Π°ΡΠΈ ΠΊΠ»Π°ΡΡΡ. ΠΠΌΠ΅ΡΡΠΎ ΡΠΎΠ³ΠΎ, ΡΡΠΎΠ±Ρ ΠΎΠΆΠΈΠ΄Π°ΡΡ, ΡΡΠΎ ΡΠ·Π΅Ρ ΠΈΠΌΠΏΠΎΡΡΠΈΡΡΠ΅Ρ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ½Π½ΡΠΉ Π² ΠΊΠ»Π°ΡΡΠ΅ ΡΠΈΠΏ, ΡΠΊΡΠΏΠΎΡΡΠΈΡΡΠΉΡΠ΅ ΠΈΠ· Π²Π°ΡΠ΅Π³ΠΎ ΠΌΠΎΠ΄ΡΠ»Ρ ΡΡΠ½ΠΊΡΠΈΡ, ΠΊΠΎΡΠΎΡΠ°Ρ ΠΎΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π°Π΅Ρ ΠΎΡ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎΡΡΠΈ Π½Π°ΠΏΡΡΠΌΡΡ ΠΎΠ±ΡΠ°ΡΠ°ΡΡΡΡ ΠΊ ΠΊΠ»Π°ΡΡΡ. ΠΡΠΈΠΌΠ΅Π½ΠΈΡΠ΅Π»ΡΠ½ΠΎ ΠΊ Cluster, ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠΊΡΠΏΠΎΡΡΠΈΡΠΎΠ²Π°ΡΡ ΡΡΠ½ΠΊΡΠΈΡ New-Cluster, ΠΊΠΎΡΠΎΡΠ°Ρ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΡ Π΄ΡΡΠΆΠ΅ΡΡΠ²Π΅Π½Π½ΡΠ΅ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ Π½Π°Π±ΠΎΡΡ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠ² ΠΈ Π²Π΅ΡΠ½ΡΡ Cluster.
class Cluster {
[ValidatePattern("^[A-z]+$")]
[string] $Service
[ValidateSet("TEST", "STAGE", "CANARY", "PROD")]
[string] $FlightingRing
[ValidateSet("EastUS", "WestUS", "NorthEurope")]
[string] $Region
[ValidateRange(0, 255)]
[int] $Index
}
function New-Cluster {
[OutputType([Cluster])]
Param(
[Parameter(Mandatory, ParameterSetName = "Id", Position = 0)]
[ValidateNotNullOrEmpty()]
[string] $Id,
[Parameter(Mandatory, ParameterSetName = "Components")]
[string] $Service,
[Parameter(Mandatory, ParameterSetName = "Components")]
[string] $FlightingRing,
[Parameter(Mandatory, ParameterSetName = "Components")]
[string] $Region,
[Parameter(Mandatory, ParameterSetName = "Components")]
[int] $Index
)
if ($Id) {
$Service, $FlightingRing, $Region, $Index = $Id -split "-"
}
[Cluster]@{
Service = $Service
FlightingRing = $FlightingRing
Region = $Region
Index = $Index
}
}
Export-ModuleMember New-Cluster
Π§ΡΠΎ Π΅ΡΡ ΠΏΠΎΡΠΈΡΠ°ΡΡ
ΠΡΡΠΎΡΠ½ΠΈΠΊ: habr.com