Providers/Authentik/Public/New-AuthentikOutpost.ps1
|
function New-AuthentikOutpost { <# .EXTERNALHELP TestEnvironment-Help.xml .SYNOPSIS Creates the seeded outposts from Data\AuthentikOutposts.csv, carrying the seeded providers #> [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')] [OutputType([PSCustomObject])] param( [Parameter()] [string[]]$OutpostName, [Parameter()] [switch]$PassThru ) $connection = Get-AuthentikConnection $marker = Get-AuthentikSeedMarker -Connection $connection $csvPath = Join-Path -Path (Get-AuthentikDataPath) -ChildPath 'AuthentikOutposts.csv' $rows = @(Import-Csv -Path $csvPath -Encoding UTF8) if ($OutpostName) { $rows = @($rows | Where-Object { $OutpostName -contains $_.Name }) $unknown = @($OutpostName | Where-Object { $rows.Name -notcontains $_ }) if ($unknown) { throw "No definition in $csvPath for: $($unknown -join ', ')" } } $result = [PSCustomObject]@{ TotalOutposts = $rows.Count CreatedOutposts = 0 UpdatedOutposts = 0 Outposts = @() Errors = @() } $existingByName = @{} foreach ($existing in (Get-AuthentikSeededObject -Type Outposts -Connection $connection)) { $existingByName[[string]$existing.name] = $existing } # Each application's provider, with the type the outpost list reports, so a provider of # the wrong kind is caught before the API refuses it less clearly. $providerBySlug = @{} foreach ($application in (Get-AuthentikSeededObject -Type Applications -Connection $connection)) { if ($application.provider) { $component = if ($application.provider_obj) { [string]$application.provider_obj.component } else { '' } $providerBySlug[[string]$application.slug] = @{ Pk = [int]$application.provider; Component = $component } } } $componentOfType = @{ proxy = 'ak-provider-proxy-form'; ldap = 'ak-provider-ldap-form'; radius = 'ak-provider-radius-form'; rac = 'ak-provider-rac-form' } $outposts = [System.Collections.Generic.List[object]]::new() foreach ($row in $rows) { $name = '{0}{1}' -f $marker.Prefix, $row.Name if (-not $PSCmdlet.ShouldProcess($name, "Create Authentik $($row.Type) outpost")) { continue } try { $providers = @() $carried = @() foreach ($applicationKey in @($row.Applications -split ';' | Where-Object { $_ })) { $slug = '{0}-{1}' -f $marker.SlugPrefix, $applicationKey if (-not $providerBySlug.ContainsKey($slug)) { $message = "Outpost '$name' names application '$slug', which does not exist or has no provider. Skipped." $result.Errors += $message Write-Warning $message continue } $provider = $providerBySlug[$slug] if ($provider.Component -and $componentOfType.ContainsKey($row.Type) -and $provider.Component -ne $componentOfType[$row.Type]) { $message = "Outpost '$name' is a $($row.Type) outpost and cannot carry the provider of '$slug'. Skipped." $result.Errors += $message Write-Warning $message continue } $providers += $provider.Pk $carried += $slug } $body = @{ name = $name type = $row.Type providers = $providers config = @{ authentik_host = $connection.BaseUrl; log_level = 'info' } } $outpost = $null if ($existingByName.ContainsKey($name)) { $outpost = Invoke-AuthentikRequest -Method PATCH -Path "/outposts/instances/$($existingByName[$name].pk)/" -Body $body -Connection $connection $result.UpdatedOutposts++ Write-Verbose "Updated outpost $name" } else { $outpost = Invoke-AuthentikRequest -Method POST -Path '/outposts/instances/' -Body $body -Connection $connection $result.CreatedOutposts++ Write-Verbose "Created outpost $name" } $outposts.Add([PSCustomObject]@{ Id = [string]$outpost.pk Key = $row.Name Name = $name Type = $row.Type Applications = $carried Deployed = $false }) } catch { $message = "Failed to create outpost '$name': $($_.Exception.Message)" $result.Errors += $message Write-Error $message } } $result.Outposts = $outposts.ToArray() Write-Verbose ("Outposts: $($result.CreatedOutposts) created, $($result.UpdatedOutposts) updated, " + "$($result.Errors.Count) problems") if ($PassThru) { return $result } } |