DSCResources/ArcGIS_DataStoreItemServer/ArcGIS_DataStoreItemServer.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')) function Get-TargetResource { [CmdletBinding()] [OutputType([System.Collections.Hashtable])] param( [parameter(Mandatory = $true)] [System.String] $Name, [parameter(Mandatory = $false)] [System.String] $ServerHostName, [parameter(Mandatory = $false)] [System.String] $ServerHostPort = 6443, [parameter(Mandatory = $false)] [System.String] $ServerSiteName = 'arcgis', [parameter(Mandatory = $true)] [System.Management.Automation.PSCredential] $SiteAdministrator, [parameter(Mandatory = $true)] [System.String] [ValidateSet("Folder", "CloudStore", "RasterStore", "BigDataFileShare")] $DataStoreType, [System.String] $ConnectionString, [System.Management.Automation.PSCredential] $ConnectionSecret, [System.Boolean] $ForceUpdate = $false ) $null } function Set-TargetResource { [CmdletBinding()] param( [parameter(Mandatory = $true)] [System.String] $Name, [parameter(Mandatory = $false)] [System.String] $ServerHostName, [parameter(Mandatory = $false)] [System.String] $ServerHostPort = 6443, [parameter(Mandatory = $false)] [System.String] $ServerSiteName = 'arcgis', [parameter(Mandatory = $true)] [System.Management.Automation.PSCredential] $SiteAdministrator, [parameter(Mandatory = $true)] [System.String] [ValidateSet("Folder", "CloudStore", "RasterStore", "BigDataFileShare")] $DataStoreType, [parameter(Mandatory = $true)] [System.String] $ConnectionString, [parameter(Mandatory = $false)] [System.Management.Automation.PSCredential] $ConnectionSecret, [parameter(Mandatory = $false)] [System.Boolean] $ForceUpdate = $false ) [System.Reflection.Assembly]::LoadWithPartialName("System.Web") | Out-Null $FQDN = if ($ServerHostName) { Get-FQDN $ServerHostName }else { Get-FQDN $env:COMPUTERNAME } $Scheme = if ($ServerHostPort -eq 6080 -or $ServerHostPort -eq 80) { 'http' } else { 'https' } $ServerUrl = "$($Scheme)://$($FQDN):$($ServerHostPort)" Write-Verbose "ServerURL:- $ServerUrl" $Referer = 'http://locahost' $token = Get-ServerToken -ServerEndPoint $ServerUrl -ServerSiteName $ServerSiteName -Credential $SiteAdministrator -Referer $Referer $DataStoreItemUrl = $ServerURL.TrimEnd('/') + '/' + $ServerSiteName + '/admin/data' $DataStoreItemConnectionObject = Get-DataStoreItemConnectionObject -ItemName $Name -DataStoreType $DataStoreType -ConnectionString $ConnectionString -ConnectionSecret $ConnectionSecret Write-Verbose ($DataStoreItemConnectionObject | ConvertTo-Json -Depth 5) # Validate Data Store Item Connection if(Invoke-ValidateDataStoreItemConnection -DataStoreItemUrl $DataStoreItemUrl -Token $token.token -Referer $Referer -DataStoreItemConnectionObject $DataStoreItemConnectionObject){ if(Test-DataStoreItemExists -ItemName $Name -DataStoreItemUrl $DataStoreItemUrl -Token $token.token -Referer $Referer -DataStoreType $DataStoreType){ # Edit Data Store Item Connection Edit-DataStoreItemConnection -DataStoreItemUrl $DataStoreItemUrl -Token $token.token -Referer $Referer -DataStoreItemConnectionObject $DataStoreItemConnectionObject }else{ # Register Data Store Item Register-DataStoreItem -DataStoreItemUrl $DataStoreItemUrl -Token $token.token -Referer $Referer -DataStoreItemConnectionObject $DataStoreItemConnectionObject } }else{ throw "Validation of Data Store Item Connection failed." } } function Test-TargetResource { [CmdletBinding()] [OutputType([System.Boolean])] param( [parameter(Mandatory = $true)] [System.String] $Name, [parameter(Mandatory = $false)] [System.String] $ServerHostName, [parameter(Mandatory = $false)] [System.String] $ServerHostPort = 6443, [parameter(Mandatory = $false)] [System.String] $ServerSiteName = 'arcgis', [parameter(Mandatory = $true)] [System.Management.Automation.PSCredential] $SiteAdministrator, [parameter(Mandatory = $true)] [System.String] [ValidateSet("Folder", "CloudStore", "RasterStore", "BigDataFileShare")] $DataStoreType, [System.String] $ConnectionString, [System.Management.Automation.PSCredential] $ConnectionSecret, [System.Boolean] $ForceUpdate = $false ) [System.Reflection.Assembly]::LoadWithPartialName("System.Web") | Out-Null $result = $false $FQDN = if ($ServerHostName) { Get-FQDN $ServerHostName }else { Get-FQDN $env:COMPUTERNAME } $Scheme = if ($ServerHostPort -eq 6080 -or $ServerHostPort -eq 80) { 'http' } else { 'https' } $ServerUrl = "$($Scheme)://$($FQDN):$($ServerHostPort)" Write-Verbose "ServerURL:- $ServerUrl" $Referer = 'http://locahost' $token = Get-ServerToken -ServerEndPoint $ServerUrl -ServerSiteName $ServerSiteName -Credential $SiteAdministrator -Referer $Referer $DataStoreItemUrl = $ServerURL.TrimEnd('/') + '/' + $ServerSiteName + '/admin/data' if(Test-DataStoreItemExists -ItemName $Name -DataStoreItemUrl $DataStoreItemUrl -Token $token.token -Referer $Referer -DataStoreType $DataStoreType){ if($ForceUpdate){ Write-Verbose "$DataStoreType DataStore Item with name '$Name' already exists. Force Update specified." }else{ Write-Verbose "$DataStoreType DataStore Item with name '$Name' already exists." $result = $true } } else { Write-Verbose "$DataStoreType DataStore Item with name '$Name' does not exist" } $result } function Test-DataStoreItemExists { [CmdletBinding()] param( [System.String] $ItemName, [System.String] $DataStoreItemUrl, [System.String] $Token, [System.String] $Referer = 'http://localhost', [System.String] $DataStoreType ) $TypeString = "" $AncestorPath = "" if ($DataStoreType -ieq 'Folder') { $TypeString = "folder" $AncestorPath = "/fileShares" } elseif ($DataStoreType -ieq 'CloudStore') { $TypeString = "cloudStore" $AncestorPath = "/cloudStores" } elseif ($DataStoreType -ieq 'BigDataFileShare') { $TypeString = "bigDataFileShare" $AncestorPath = "/bigDataFileShares" } elseif ($DataStoreType -ieq 'RasterStore') { $TypeString = "rasterStores" $AncestorPath = "/rasterStores" } $DataItemsUrl = $DataStoreItemUrl + '/findItems' $DataStoreItems = Invoke-ArcGISWebRequest -Url $DataItemsUrl -HttpFormParameters @{ f = 'json'; token = $Token; types = $TypeString; ancestorPath = $AncestorPath } -Referer $Referer return (($DataStoreItems.items | Where-Object { $_.path -ieq "$($AncestorPath)/$($ItemName)" } | Measure-Object).Count -gt 0) } function Invoke-ValidateDataStoreItemConnection { [CmdletBinding()] [OutputType([System.Boolean])] param ( [System.String] $DataStoreItemUrl, [System.String] $Token, [System.String] $Referer = 'http://localhost', [System.Object] $DataStoreItemConnectionObject ) $FormParameters = @{ f = 'json'; token = $Token; item = (ConvertTo-Json -InputObject $DataStoreItemConnectionObject -Depth 5 -Compress) } $ValidateDataStoreItemUrl = $DataStoreItemUrl+ "/validateDataItem" $response = Invoke-ArcGISWebRequest -Url $ValidateDataStoreItemUrl -HttpFormParameters $FormParameters -Referer $Referer if ($response.status -ieq 'success') { Write-Verbose "Validation of Data Store Item successful" return $true } else { if (($response.status -ieq 'error') -and $response.messages) { throw "[ERROR]:- Validation of Data Store Item failed. $($response.messages -join ',')" } } } function Edit-DataStoreItemConnection { [CmdletBinding()] [OutputType([System.Boolean])] param ( [System.String] $DataStoreItemUrl, [System.String] $Token, [System.String] $Referer = 'http://localhost', [System.Object] $DataStoreItemConnectionObject ) $FormParameters = @{ f = 'json'; token = $Token; item = (ConvertTo-Json -InputObject $DataStoreItemConnectionObject -Depth 5 -Compress) } $EditDataStoreItemUrl = $DataStoreItemUrl + '/items'+$($DataStoreItemConnectionObject.path)+'/edit' $response = Invoke-ArcGISWebRequest -Url $EditDataStoreItemUrl -HttpFormParameters $FormParameters -Referer $Referer if ($response.status -ieq 'success') { Write-Verbose "Edit of Data Store item connection successful." return $true } else { if (($response.status -ieq 'error') -and $response.messages) { throw "[ERROR]:- Edit of Data Store item connection failed. $($response.messages -join ',')" } } } function Register-DataStoreItem { [CmdletBinding()] [OutputType([System.Boolean])] param ( [System.String] $DataStoreItemUrl, [System.String] $Token, [System.String] $Referer = 'http://localhost', [System.Object] $DataStoreItemConnectionObject, [System.String] $OperationType = 'register' ) $FormParameters = @{ f = 'json'; token = $Token; item = (ConvertTo-Json -InputObject $DataStoreItemConnectionObject -Depth 5 -Compress) } $RegisterDataStoreItemUrl = $DataStoreItemUrl + '/registerItem' $response = Invoke-ArcGISWebRequest -Url $RegisterDataStoreItemUrl -HttpFormParameters $FormParameters -Referer $Referer if ($response.status -ieq 'success') { Write-Verbose "Registration of Data Store Item successful" return $true } else { if (($response.status -ieq 'error') -and $response.messages) { throw "[ERROR]:- Registration of Data Store Item failed. $($response.messages -join ',')" } } } function Get-DataStoreItemConnectionObject { [CmdletBinding()] param ( [parameter(Mandatory = $true)] [System.String] $ItemName, [System.String] $DataStoreType, [System.String] $ConnectionString, [System.Management.Automation.PSCredential] $ConnectionSecret ) <# - Deconstructed Connection String Object @{ DataStorePath = "" CloudStoreType = "" AzureStorage = @{ AccountName = "" AccountEndpoint = "" DefaultEndpointsProtocol = "" OverrideEndpoint = "" ContainerName = "" FolderPath = "" AuthenticationType = "" UserAssignedIdentityClientId = "" ServicePrincipalTenantId = "" ServicePrincipalClientId = "" } AmazonS3 = @{ BucketName = "" FolderPath = "" Region = "" RegionEndpointUrl = "" AuthenticationType = "" } } #> $ConnStringObj = ConvertFrom-Json $ConnectionString if ($DataStoreType -ieq 'Folder') { $item = @{ type = 'folder'; info = @{ dataStoreConnectionType = "shared"; hostName = $null path = $ConnStringObj.DataStorePath }; path = "/fileShares/$($ItemName)" } } elseif ($DataStoreType -ieq 'RasterStore') { $item = @{ type = 'rasterStore'; info = @{ connectionString = @{ path = $ConnStringObj.DataStorePath }; connectionType = if ($ConnStringObj.DataStorePath.StartsWith('/cloudStores')) { 'dataStore' } else { 'fileShare' } }; path = "/rasterStores/$($ItemName)" } } elseif ($DataStoreType -ieq 'BigDataFileShare') { $item = @{ type = 'bigDataFileShare'; info = @{ connectionString = @{ path = $ConnStringObj.DataStorePath }; connectionType = if ($ConnStringObj.DataStorePath.StartsWith('/cloudStores')) { 'cloudstore' } else { 'fileShare' } }; path = "/bigDataFileShares/$($ItemName)" } } elseif ($DataStoreType -ieq 'CloudStore') { $CloudStoreType = $ConnStringObj.CloudStoreType $item = @{ type = 'cloudStore'; path = "/cloudStores/$($ItemName)"; info = @{ isManaged = $false; connectionString = @{}; }; provider = $CloudStoreType } if ($CloudStoreType -ieq "Azure") { $ObjectStorePath = "$($ConnStringObj.AzureStorage.ContainerName)" if ($ConnStringObj.AzureStorage.FolderPath) { $ObjectStorePath = "$($ConnStringObj.AzureStorage.ContainerName)/$($ConnStringObj.AzureStorage.FolderPath)" } $item.info["objectStore"] = $ObjectStorePath $item.info.connectionString = @{ accountName = $ConnStringObj.AzureStorage.AccountName; defaultEndpointsProtocol = $ConnStringObj.AzureStorage.DefaultEndpointsProtocol; #https accountEndpoint = $ConnStringObj.AzureStorage.AccountEndpoint; #core.windows.net } $AzureCloudStoreAuthenticationType = $ConnStringObj.AzureStorage.AuthenticationType if ($ConnStringObj.AzureStorage.OverrideEndpoint) { $item.info.connectionString["regionEndpointUrl"] = $ConnStringObj.AzureStorage.OverrideEndpoint # GDAL } if ($AzureCloudStoreAuthenticationType -ieq "AccessKey") { $item.info.connectionString["credentialType"] = 'accessKey' $item.info.connectionString["accountKey"] = $ConnectionSecret.GetNetworkCredential().Password } elseif ($AzureCloudStoreAuthenticationType -ieq "SASToken") { $item.info.connectionString["credentialType"] = 'sasToken' $item.info.connectionString["sasToken"] = $ConnectionSecret.GetNetworkCredential().Password } elseif ($AzureCloudStoreAuthenticationType -ieq "ServicePrincipal") { $item.info.connectionString["credentialType"] = 'servicePrincipal' $item.info.connectionString["tenantId"] = $ConnStringObj.AzureStorage.ServicePrincipalTenantId $item.info.connectionString["clientId"] = $ConnStringObj.AzureStorage.ServicePrincipalClientId $item.info.connectionString["clientSecret"] = $ConnectionSecret.GetNetworkCredential().Password } elseif ($AzureCloudStoreAuthenticationType -ieq "UserAssignedIdentity") { $item.info.connectionString["credentialType"] = 'userAssignedIdentity' $item.info.connectionString["managedIdentityClientId"] = $ConnStringObj.AzureStorage.UserAssignedIdentityClientId } # if(-not([string]::IsNullOrEmpty($AzureTableName))){ # $item.info.Add('tableStore', $AzureTableName); # } } elseif ($CloudStoreType -ieq "Amazon") { $ObjectStorePath = "$($ConnStringObj.AmazonS3.BucketName)" if ($ConnStringObj.AmazonS3.FolderPath) { $ObjectStorePath = "$($ConnStringObj.AmazonS3.BucketName)/$($ConnStringObj.AmazonS3.FolderPath)" # GDAL } $item.info["objectStore"] = $ObjectStorePath $item.info.connectionString["region"] = $ConnStringObj.AmazonS3.Region if ($ConnStringObj.OverrideEndpoint) { $item.info.connectionString["regionEndpointUrl"] = $ConnStringObj.AmazonS3.RegionEndpointUrl } if($ConnStringObj.AmazonS3.AuthenticationType -eq "IAMRole"){ $item.info.connectionString["credentialType"] = 'IAMRole' }else{ $item.info.connectionString["credentialType"] = 'accessKey' $item.info.connectionString["accessKeyId"] = $ConnectionSecret.UserName $item.info.connectionString["secretAccessKey"] = $ConnectionSecret.GetNetworkCredential().Password } } } return $item } Export-ModuleMember -Function *-TargetResource |