DSCResources/ArcGIS_Portal/ArcGIS_Portal.psm1
|
$modulePath = Join-Path -Path (Split-Path -Path (Split-Path -Path $PSScriptRoot -Parent) -Parent) -ChildPath 'Modules' # Import the ArcGIS Common Modules Import-Module -Name (Join-Path -Path $modulePath ` -ChildPath (Join-Path -Path 'ArcGIS.Common' ` -ChildPath 'ArcGIS.Common.psm1')) Import-Module -Name (Join-Path -Path $modulePath ` -ChildPath (Join-Path -Path 'ArcGIS.Client' ` -ChildPath 'ArcGIS.Client.Portal.psm1')) function Get-TargetResource { [CmdletBinding()] [OutputType([System.Collections.Hashtable])] param ( [parameter(Mandatory = $True)] [System.String] $Version, [parameter(Mandatory = $true)] [System.String] $PortalHostName ) @{} } function Set-TargetResource { [CmdletBinding()] param ( [parameter(Mandatory = $True)] [System.String] $Version, [parameter(Mandatory = $True)] [System.String] $PortalHostName, [ValidateSet("Present", "Absent")] [System.String] $Ensure, [parameter(Mandatory = $false)] [System.String] $LicenseFilePath = $null, [parameter(Mandatory = $false)] [System.String] $UserLicenseTypeId = $null, [System.Management.Automation.PSCredential] $PortalAdministrator, [System.String] $AdminEmail, [System.String] $AdminFullName, [System.String] $AdminDescription, [System.Management.Automation.PSCredential] $AdminSecurityQuestionCredential, [System.Boolean] $Join, [System.Boolean] $EnableDebugLogging = $False, [System.String] $LogLevel = 'WARNING', [System.Boolean] $IsHAPortal, [System.String] $PeerMachineHostName, [System.String] $ContentDirectoryLocation, [parameter(Mandatory = $True)] [System.String] [ValidateSet("None","Azure","AWS")] $CloudProvider = "None", [Parameter(Mandatory=$False)] [System.String] [ValidateSet("AccessKey","IAMRole", "None")] $AWSAuthenticationType = "None", [parameter(Mandatory = $false)] [System.String] $AWSS3ContentBucketName, [Parameter(Mandatory=$False)] [System.String] $AWSRegion, [Parameter(Mandatory=$False)] [System.Management.Automation.PSCredential] $AWSAccessKeyCredential, [Parameter(Mandatory=$False)] [System.String] [ValidateSet("AccessKey","ServicePrincipal","UserAssignedIdentity", "SASToken", "None")] $AzureAuthenticationType = "None", [Parameter(Mandatory=$False)] [System.Management.Automation.PSCredential] $AzureStorageAccountCredential, [parameter(Mandatory = $false)] [System.String] $AzureContentBlobContainerName, [Parameter(Mandatory=$False)] [System.Management.Automation.PSCredential] $AzureServicePrincipalCredential, [Parameter(Mandatory=$False)] [System.String] $AzureServicePrincipalTenantId, [Parameter(Mandatory=$False)] [System.String] $AzureServicePrincipalAuthorityHost, [Parameter(Mandatory=$False)] [System.String] $AzureUserAssignedIdentityClientId, [Parameter(Mandatory=$False)] [System.Boolean] $EnableCreateSiteDebug ) if ($VerbosePreference -ne 'SilentlyContinue') { Write-Verbose ("PortalAdmin UserName:- " + $PortalAdministrator.UserName) } [System.Reflection.Assembly]::LoadWithPartialName("System.Web") | Out-Null $FQDN = if($PortalHostName){ Get-FQDN $PortalHostName }else{ Get-FQDN $env:COMPUTERNAME } $PortalBaseURL = Get-ArcGISComponentBaseUrl -FQDN $FQDN -ComponentName "Portal" if ($EnableDebugLogging) { if (-not(Invoke-TestSetLoggingLevel -EnableDebugLogging $True -Verbose)) { $RestartRequired = $true } } else { if(-not($IsHAPortal)){ Write-Verbose "Setup is Single machine Portal" } if (-not(Invoke-TestSetLoggingLevel -EnableDebugLogging $False -Verbose)) { $RestartRequired = $true } } if ($RestartRequired) { Restart-ArcGISService -ComponentName 'Portal' -Verbose } Test-ArcGISComponentHealth -BaseURL $PortalBaseURL -ComponentName "PortalSharing" -MaxWaitTimeInSeconds 600 -Verbose Write-Verbose "Portal at $($PortalBaseURL)" if ($Ensure -ieq 'Present') { $Referer = 'https://localhost' $RestartRequired = $false $PortalSiteCheck = Test-PortalSiteCreated -URL $PortalBaseURL -Referer $Referer -Verbose if($PortalSiteCheck){ Write-Verbose "Making request to sharing API" $PortalReady = $False try { Test-ArcGISComponentHealth -BaseURL $PortalBaseURL -ComponentName "PortalSharing" -ThrowErrors $True Write-Verbose "Sharing API rest endpoint is available." $PortalReady = $True }catch { Write-Verbose "Sharing API rest endpoint is not available. Error:- $_. Restarting Portal." Restart-ArcGISService -ComponentName 'Portal' -Verbose } if(-not($PortalReady)){ try{ Test-ArcGISComponentHealth -BaseURL $PortalBaseURL -ComponentName "PortalSharing" -MaxWaitTimeInSeconds 600 -Verbose -ThrowErrors $true }catch{ throw "Portal Site is not healthy. Please check your portal site deployment." } } } else { if($Join) { $PrimaryMachineFQDN = Get-FQDN $PeerMachineHostName Write-Verbose "Joining machine '$($FQDN)' to portal site (Primary - $PrimaryMachineFQDN)" Join-PortalSite -URL $PortalBaseURL -Credential $PortalAdministrator -PrimaryMachineHostName $PrimaryMachineFQDN -Verbose Write-Verbose "Machine '$($FQDN)' joined to portal site (Primary - $PrimaryMachineFQDN)" } else { Write-Verbose "Creating Portal site" $PortalArguments = @{ Version = $Version URL = $PortalBaseURL Credential = $PortalAdministrator FullName = $AdminFullName Email = $AdminEmail Description = $AdminDescription AdminSecurityQuestionCredential = $AdminSecurityQuestionCredential LicenseFilePath = $LicenseFilePath UserLicenseTypeId = $UserLicenseTypeId EnableCreateSiteDebug = $EnableCreateSiteDebug } if($CloudProvider -ieq "None"){ $PortalArguments["ContentDirectoryLocation"] = $ContentDirectoryLocation }else{ $PortalArguments["CloudProvider"] = $CloudProvider if($CloudProvider -ieq "Azure"){ $PortalArguments["AzureAuthenticationType"] = $AzureAuthenticationType $PortalArguments["AzureContentBlobContainerName"] = $AzureContentBlobContainerName $PortalArguments["AzureStorageAccountCredential"] = $AzureStorageAccountCredential if($AzureAuthenticationType -ieq "ServicePrincipal"){ $PortalArguments["AzureServicePrincipalCredential"] = $AzureServicePrincipalCredential $PortalArguments["AzureServicePrincipalTenantId"] = $AzureServicePrincipalTenantId $PortalArguments["AzureServicePrincipalAuthorityHost"] = $AzureServicePrincipalAuthorityHost }elseif($AzureAuthenticationType -ieq "UserAssignedIdentity"){ $PortalArguments["AzureUserAssignedIdentityClientId"] = $AzureUserAssignedIdentityClientId } }elseif($CloudProvider -ieq "AWS"){ $PortalArguments["AWSAuthenticationType"] = $AWSAuthenticationType $PortalArguments["AWSS3ContentBucketName"] = $AWSS3ContentBucketName $PortalArguments["AWSRegion"] = $AWSRegion if($AWSAuthenticationType -ieq "AccessKey"){ $PortalArguments["AWSAccessKeyCredential"] = $AWSAccessKeyCredential } } } Invoke-CreatePortalSite @PortalArguments -Verbose Write-Verbose 'Portal site created' } } Test-ArcGISComponentHealth -BaseURL $PortalBaseURL -ComponentName "Portal" -Verbose $token = Get-PortalToken -URL $PortalBaseURL -Credential $PortalAdministrator -Referer $Referer Write-Verbose "Portal site ready. Successfully retrieved token for $($PortalAdministrator.UserName)" #Populating Licenses if(-not($Join) -and $LicenseFilePath){ $token = Get-PortalToken -URL $PortalBaseURL -Credential $PortalAdministrator -Referer $Referer -Verbose $IsLicensePopulated = Test-LicensePopulated -URL $PortalBaseURL -Token $token.token -Referer $Referer -Verbose if(-not($IsLicensePopulated)){ Invoke-PopulateLicense -URL $PortalBaseURL -Token $token.token -Referer $Referer -Verbose } } $token = Get-PortalToken -URL $PortalBaseURL -Credential $PortalAdministrator -Referer $Referer $LogSettings = Get-LogSettings -URL $PortalBaseURL -Token $token.token -Referer $Referer if ($LogSettings -and $LogSettings.logLevel) { $CurrentLogLevel = $LogSettings.logLevel if ($CurrentLogLevel -ne $LogLevel) { Write-Verbose "Portal CurrentLogLevel '$CurrentLogLevel' does not match desired value of '$LogLevel'. Updating it" $LogSettings.logLevel = $LogLevel Update-PortalLogSettings -URL $PortalBaseURL -Token $token.token -Referer $Referer -LogSettings $LogSettings } else { Write-Verbose "Portal CurrentLogLevel '$CurrentLogLevel' matches desired value of '$LogLevel'" } } else { Write-Verbose "[WARNING] Unable to retrieve current log settings from portal admin" } } elseif ($Ensure -ieq 'Absent') { Write-Warning 'Site Delete not implemented' } } function Test-TargetResource { [CmdletBinding()] [OutputType([System.Boolean])] param ( [parameter(Mandatory = $True)] [System.String] $Version, [parameter(Mandatory = $True)] [System.String] $PortalHostName, [ValidateSet("Present", "Absent")] [System.String] $Ensure, [parameter(Mandatory = $false)] [System.String] $LicenseFilePath = $null, [parameter(Mandatory = $false)] [System.String] $UserLicenseTypeId = $null, [System.Management.Automation.PSCredential] $PortalAdministrator, [System.String] $AdminEmail, [System.String] $AdminFullName, [System.String] $AdminDescription, [System.Management.Automation.PSCredential] $AdminSecurityQuestionCredential, [System.Boolean] $Join, [System.Boolean] $EnableDebugLogging = $False, [System.String] $LogLevel = 'WARNING', [System.Boolean] $IsHAPortal, [System.String] $PeerMachineHostName, [System.String] $ContentDirectoryLocation, [parameter(Mandatory = $True)] [System.String] [ValidateSet("None","Azure","AWS")] $CloudProvider = "None", [Parameter(Mandatory=$False)] [System.String] [ValidateSet("AccessKey","IAMRole", "None")] $AWSAuthenticationType = "None", [parameter(Mandatory = $false)] [System.String] $AWSS3ContentBucketName, [Parameter(Mandatory=$False)] [System.String] $AWSRegion, [Parameter(Mandatory=$False)] [System.Management.Automation.PSCredential] $AWSAccessKeyCredential, [Parameter(Mandatory=$False)] [System.String] [ValidateSet("AccessKey","ServicePrincipal","UserAssignedIdentity", "SASToken", "None")] $AzureAuthenticationType = "None", [Parameter(Mandatory=$False)] [System.Management.Automation.PSCredential] $AzureStorageAccountCredential, [parameter(Mandatory = $false)] [System.String] $AzureContentBlobContainerName, [Parameter(Mandatory=$False)] [System.Management.Automation.PSCredential] $AzureServicePrincipalCredential, [Parameter(Mandatory=$False)] [System.String] $AzureServicePrincipalTenantId, [Parameter(Mandatory=$False)] [System.String] $AzureServicePrincipalAuthorityHost, [Parameter(Mandatory=$False)] [System.String] $AzureUserAssignedIdentityClientId, [Parameter(Mandatory=$False)] [System.Boolean] $EnableCreateSiteDebug ) [System.Reflection.Assembly]::LoadWithPartialName("System.Web") | Out-Null $FQDN = if($PortalHostName){ Get-FQDN $PortalHostName }else{ Get-FQDN $env:COMPUTERNAME } $result = $false $PortalBaseURL = Get-ArcGISComponentBaseUrl -FQDN $FQDN -ComponentName "Portal" $result = Invoke-TestSetLoggingLevel -EnableDebugLogging $EnableDebugLogging -TestOnly $true -Verbose if ($result) { $Referer = 'https://localhost' try{ $PortalSiteCheck = Test-PortalSiteCreated -URL $PortalBaseURL -Referer $Referer -Verbose if($PortalSiteCheck){ $token = Get-PortalToken -URL $PortalBaseURL -Credential $PortalAdministrator -Referer $Referer if (-not($token.token)) { Write-Verbose "Unable to retrive token from portal site" $result = $false } else { Write-Verbose "Portal site already created. Successfully retrieved token for $($PortalAdministrator.UserName)" } }else{ $result = $false } }catch{ Write-Verbose "[WARNING] Unable to detect portal site. Error:- $_" $result = $False } } if($result -and -not($Join) -and $LicenseFilePath){ Write-Verbose "Checking if portal licenses are populated" Test-ArcGISComponentHealth -BaseURL $PortalBaseURL -ComponentName "Portal" -Verbose $token = Get-PortalToken -URL $PortalBaseURL -Credential $PortalAdministrator -Referer $Referer $result = Test-LicensePopulated -URL $PortalBaseURL -Token $token.token -Referer $Referer -Verbose if($result){ Write-Verbose "Portal licenses are populated" }else{ Write-Verbose "Portal licenses are not populated. Will be populated." } } if ($result) { Test-ArcGISComponentHealth -BaseURL $PortalBaseURL -ComponentName "Portal" -Verbose $token = Get-PortalToken -URL $PortalBaseURL -Credential $PortalAdministrator -Referer $Referer $LogSettings = Get-LogSettings -URL $PortalBaseURL -Token $token.token -Referer $Referer $CurrentLogLevel = $LogSettings.logLevel if ($CurrentLogLevel -ne $LogLevel) { Write-Verbose "Portal CurrentLogLevel '$CurrentLogLevel' does not match desired value of '$LogLevel'" $result = $false } else { Write-Verbose "Portal CurrentLogLevel '$CurrentLogLevel' matches desired value of '$LogLevel'" } } if ($Ensure -ieq 'Present') { $result } elseif ($Ensure -ieq 'Absent') { (-not($result)) } } function Invoke-TestSetLoggingLevel { [CmdletBinding()] [OutputType([System.Boolean])] param ( [System.Boolean] $EnableDebugLogging, [System.Boolean] $TestOnly = $false ) $ExpectedLogLevelFound = $True $InstallDir = (Get-ArcGISComponentVersionAndInstallDirectory -ComponentName 'Portal').InstallDir $PropertiesFile = Join-Path $InstallDir 'framework\runtime\tomcat\conf\logging.properties' @('org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level', '1catalina.org.apache.juli.FileHandler.level', '2localhost.org.apache.juli.FileHandler.level', '3portal.org.apache.juli.FileHandler.level', 'java.util.logging.ConsoleHandler.level') | ForEach-Object { $PropertyName = $_ $DesiredLoggingLevel = $null if ($EnableDebugLogging) { $DesiredLoggingLevel = 'ALL' } else { # Default values for the levels if ($PropertyName -eq '3portal.org.apache.juli.FileHandler.level') { $DesiredLoggingLevel = 'INFO' } elseif ($PropertyName -eq 'java.util.logging.ConsoleHandler.level') { $DesiredLoggingLevel = 'FINE' } else { $DesiredLoggingLevel = 'SEVERE' } } $CurrentLoggingLevel = Get-PropertyFromPropertiesFile -PropertiesFilePath $PropertiesFile -PropertyName $PropertyName if ($CurrentLoggingLevel -ne $DesiredLoggingLevel) { if($TestOnly){ Write-Verbose "Portal Tomcat CurrentLoggingLevel '$CurrentLoggingLevel' does not match desired value of '$DesiredLoggingLevel' for property '$PropertyName'" $ExpectedLogLevelFound = $false }else{ Write-Verbose "Portal Tomcat CurrentLoggingLevel '$CurrentLoggingLevel' does not match desired value of '$DesiredLoggingLevel'. Updating it" if (Confirm-PropertyInPropertiesFile -PropertiesFilePath $PropertiesFile -PropertyName $PropertyName -PropertyValue $DesiredLoggingLevel) { Write-Verbose "Portal Tomcat logging level '$PropertyName' changed. Restart needed" $ExpectedLogLevelFound = $false } } } else { Write-Verbose "Portal Tomcat CurrentLoggingLevel '$CurrentLoggingLevel' matches desired value of '$DesiredLoggingLevel' for property '$PropertyName'" } } $ExpectedLogLevelFound } Export-ModuleMember -Function *-TargetResource |