Classes/VMWare.VCenterManager.psm1
|
using module .\VMWare.AuthType.psm1 using module .\VMWare.VCenter.psm1 using module .\VMWare.Settings.psm1 class VCenterManager { # Singleton Storage static [VCenterManager] $Instance # Saved vCenter profiles and the currently active one [System.Collections.Generic.List[VMWareVCenter]]$Profiles [String]$ActiveVSphere VCenterManager() { $this.Profiles = [System.Collections.Generic.List[VMWareVCenter]]::new() } static [Void] ClearInstance() { [VCenterManager]::Instance = $null } # Get the in-memory instance, loading from disk or creating an empty one. Does not connect. static [VCenterManager] GetOrCreate() { if ($null -eq [VCenterManager]::Instance) { if ($null -eq [VCenterManager]::Load()) { [VCenterManager]::Instance = [VCenterManager]::new() } } return [VCenterManager]::Instance } # Get the instance and ensure the active vCenter is connected. Throws if nothing is saved. static [VCenterManager] GetInstance() { $auth = [VCenterManager]::GetOrCreate() if ($auth.Profiles.Count -eq 0) { throw 'You are not logged in. Please login with Login-VSphere.' } $auth.ConnectActive() return $auth } [VMWareVCenter] GetActiveProfile() { $active = $this.ActiveVSphere return ($this.Profiles | Where-Object { $_.VSphere -eq $active } | Select-Object -First 1) } [VMWareVCenter] GetProfile([String]$VSphere) { return ($this.Profiles | Where-Object { $_.VSphere -eq $VSphere } | Select-Object -First 1) } # Add a new profile or replace an existing one with the same FQDN. [Void] AddOrUpdate([VMWareVCenter]$VCenter) { $existing = $this.GetProfile($VCenter.VSphere) if ($null -ne $existing) { [void]$this.Profiles.Remove($existing) } $this.Profiles.Add($VCenter) } [Void] Remove([String]$VSphere) { $existing = $this.GetProfile($VSphere) if ($null -eq $existing) { throw "No saved vCenter found for '$VSphere'." } [void]$this.Profiles.Remove($existing) if ($this.ActiveVSphere -eq $VSphere) { $this.ActiveVSphere = '' } } [Bool] IsConnected([String]$VSphere) { $servers = Get-Variable -Name 'DefaultVIServers' -Scope 'Global' -ValueOnly -ErrorAction SilentlyContinue $connection = $servers | Where-Object { $_.Name -eq $VSphere -and $_.IsConnected } return ($null -ne $connection) } [Void] Disconnect([String]$VSphere) { $servers = Get-Variable -Name 'DefaultVIServers' -Scope 'Global' -ValueOnly -ErrorAction SilentlyContinue $connections = $servers | Where-Object { $_.Name -eq $VSphere } foreach ($server in $connections) { Disconnect-VIServer -Server $server -Force -Confirm:$false -ErrorAction SilentlyContinue } } [Void] DisconnectAllExcept([String]$VSphere) { $servers = Get-Variable -Name 'DefaultVIServers' -Scope 'Global' -ValueOnly -ErrorAction SilentlyContinue $connections = $servers | Where-Object { $_.Name -ne $VSphere } foreach ($server in $connections) { Disconnect-VIServer -Server $server -Force -Confirm:$false -ErrorAction SilentlyContinue } } # Connect the active vCenter if it is not already connected. [Void] ConnectActive() { $active = $this.GetActiveProfile() if ($null -eq $active) { throw 'No active vCenter is selected. Use Switch-VSphereLogin to select one.' } if (-not $this.IsConnected($active.VSphere)) { $active.Connect() } } # Make a saved vCenter the active one: disconnect any others and connect the target. [Void] SetActive([String]$VSphere) { $target = $this.GetProfile($VSphere) if ($null -eq $target) { throw "No saved vCenter found for '$VSphere'." } $this.DisconnectAllExcept($VSphere) $target.Connect() $this.ActiveVSphere = $VSphere } # Persist the settings to the local system. [Void] Save() { if (!(Test-Path([VMWareSettings]::SAVE_DIR))) { New-Item -Type Directory -Path ([VMWareSettings]::SAVE_DIR) | Out-Null } $savedProfiles = @() foreach ($vcenter in $this.Profiles) { $savedProfiles += [PSCustomObject]@{ VSphere = $vcenter.VSphere AuthType = $vcenter.AuthType.ToString() Credential = $(if ($vcenter.AuthType -eq [VMWareAuthType]::Credential) { $vcenter.Credential } else { $null }) ClientId = $vcenter.ClientId ClientSecret = $(if ($vcenter.AuthType -eq [VMWareAuthType]::SSO) { $vcenter.ClientSecret } else { $null }) AuthorizationEndpointUrl = $(if ($vcenter.AuthorizationEndpointUrl) { $vcenter.AuthorizationEndpointUrl.ToString() } else { $null }) TokenEndpointUrl = $(if ($vcenter.TokenEndpointUrl) { $vcenter.TokenEndpointUrl.ToString() } else { $null }) RedirectUrl = $(if ($vcenter.RedirectUrl) { $vcenter.RedirectUrl.ToString() } else { $null }) Scope = $vcenter.Scope IgnoreCertificateErrors = $vcenter.IgnoreCertificateErrors } } $save = [PSCustomObject]@{ Version = [VMWareSettings]::SCHEMA_VERSION ActiveVSphere = $this.ActiveVSphere Profiles = @($savedProfiles) } $save | Export-Clixml -Path ([VMWareSettings]::SAVE_PATH) -Encoding 'utf8' -Force } # Persist only if a save file already exists (respects the opt-in save model). [Void] SaveIfPersisted() { if (Test-Path([VMWareSettings]::SAVE_PATH)) { $this.Save() } } # Remove the saved settings file from the local system. static [Void] Delete() { if (Test-Path([VMWareSettings]::SAVE_PATH)) { $file = Get-Item -Path ([VMWareSettings]::SAVE_PATH) if ($file.Name -eq [VMWareSettings]::SAVE_FILE) { Remove-Item -Path ([VMWareSettings]::SAVE_PATH) -Force } } } # Load saved settings, migrating older schema versions as needed. hidden static [VCenterManager] Load() { if (-not (Test-Path([VMWareSettings]::SAVE_PATH))) { return $null } try { $import = Import-Clixml -Path ([VMWareSettings]::SAVE_PATH) } catch { Write-Warning 'Failed to load settings' return $null } # Version 1 files predate the Version property. $version = if ($null -ne $import.Version) { [Int]$import.Version } else { 1 } if ($version -gt [VMWareSettings]::SCHEMA_VERSION) { throw "The saved vCenter profile file was written by a newer version of this module (schema version $version). This module supports up to schema version $([VMWareSettings]::SCHEMA_VERSION). To use this older module version you must delete the profile file at: $([VMWareSettings]::SAVE_PATH)" } $auth = [VCenterManager]::new() if ($version -eq 1) { $auth.ImportV1($import) } else { $auth.ImportCurrent($import) } [VCenterManager]::Instance = $auth # Rewrite older files in the current schema. if ($version -lt [VMWareSettings]::SCHEMA_VERSION) { $auth.Save() } return $auth } # Migrate a version 1 (single-profile) file into the current format. hidden [Void] ImportV1([Object]$import) { $vcenter = [VMWareVCenter]::new() $vcenter.VSphere = $import.VSphere if ($null -ne $import.Credential) { $vcenter.Credential = $import.Credential $vcenter.AuthType = [VMWareAuthType]::Credential } else { $vcenter.AuthType = [VMWareAuthType]::Integrated } $this.Profiles.Add($vcenter) $this.ActiveVSphere = $import.VSphere } hidden [Void] ImportCurrent([Object]$import) { foreach ($saved in $import.Profiles) { $vcenter = [VMWareVCenter]::new() $vcenter.VSphere = $saved.VSphere $vcenter.AuthType = [VMWareAuthType]$saved.AuthType $vcenter.Credential = $saved.Credential $vcenter.ClientId = $saved.ClientId $vcenter.ClientSecret = $saved.ClientSecret if ($saved.AuthorizationEndpointUrl) { $vcenter.AuthorizationEndpointUrl = [Uri]$saved.AuthorizationEndpointUrl } if ($saved.TokenEndpointUrl) { $vcenter.TokenEndpointUrl = [Uri]$saved.TokenEndpointUrl } if ($saved.RedirectUrl) { $vcenter.RedirectUrl = [Uri]$saved.RedirectUrl } $vcenter.Scope = $saved.Scope $vcenter.IgnoreCertificateErrors = [Bool]$saved.IgnoreCertificateErrors $this.Profiles.Add($vcenter) } $this.ActiveVSphere = $import.ActiveVSphere } } |