Providers/FreeIPA/Public/New-FreeIPARole.ps1
|
function New-FreeIPARole { <# .EXTERNALHELP TestEnvironment-Help.xml .SYNOPSIS Creates the seeded permissions, privileges and roles from Data\FreeIPAPermissions.csv, Data\FreeIPAPrivileges.csv and Data\FreeIPARoles.csv #> [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')] [OutputType([PSCustomObject])] param( [Parameter()] [string[]]$RoleName, [Parameter()] [switch]$PassThru ) $connection = Get-FreeIPAConnection $marker = Get-FreeIPASeedMarker -Connection $connection $dataPath = Get-FreeIPADataPath $permissionRows = @(Import-Csv -Path (Join-Path -Path $dataPath -ChildPath 'FreeIPAPermissions.csv') -Encoding UTF8) $privilegeRows = @(Import-Csv -Path (Join-Path -Path $dataPath -ChildPath 'FreeIPAPrivileges.csv') -Encoding UTF8) $rolePath = Join-Path -Path $dataPath -ChildPath 'FreeIPARoles.csv' $roleRows = @(Import-Csv -Path $rolePath -Encoding UTF8) if ($RoleName) { $roleRows = @($roleRows | Where-Object { $RoleName -contains $_.Name }) $unknown = @($RoleName | Where-Object { $roleRows.Name -notcontains $_ }) if ($unknown) { throw "No definition in $rolePath for: $($unknown -join ', ')" } } $result = [PSCustomObject]@{ TotalRoles = $roleRows.Count CreatedRoles = 0 UpdatedRoles = 0 PermissionsCreated = 0 PrivilegesCreated = 0 MembershipsApplied = 0 Roles = @() Errors = @() } $split = { param($value) @([string]$value -split ';' | Where-Object { $_ }) } $resolve = { param($keys, $kind) @(& $split $keys | ForEach-Object { Resolve-FreeIPASeedName -Key $_ -Kind $kind -Marker $marker -Connection $connection }) } $describe = { param($text) ('{0} {1}' -f $text, $marker.Marker).Trim() } $record = { param($problem) $result.Errors += $problem; Write-Error $problem } $existingPermissions = @{} foreach ($entry in (Get-FreeIPASeededObject -Type Permissions -Connection $connection)) { $existingPermissions[[string](@($entry.cn)[0])] = $entry } $existingPrivileges = @{} foreach ($entry in (Get-FreeIPASeededObject -Type Privileges -Connection $connection)) { $existingPrivileges[[string](@($entry.cn)[0])] = $entry } $existingRoles = @{} foreach ($entry in (Get-FreeIPASeededObject -Type Roles -Connection $connection)) { $existingRoles[[string](@($entry.cn)[0])] = $entry } # --- Permissions ---------------------------------------------------------------------------- foreach ($row in $permissionRows) { $name = Resolve-FreeIPASeedName -Key $row.Name -Marker $marker -Connection $connection if (-not $PSCmdlet.ShouldProcess($name, 'Create FreeIPA permission')) { continue } try { $options = @{ ipapermright = [object[]]@(& $split $row.Rights) type = $row.Type } if ($row.Attributes) { $options['attrs'] = [object[]]@(& $split $row.Attributes) } if ($row.Filter) { $options['extratargetfilter'] = [object[]]@($row.Filter.Replace('{tag}', $marker.Tag).Replace('{prefix}', $marker.NamePrefix)) } if ($existingPermissions.ContainsKey($name)) { $null = Invoke-FreeIPARequest -Method 'permission_mod' -Arguments $name -Options $options -Connection $connection -IgnoreError 'EmptyModlist' } else { $null = Invoke-FreeIPARequest -Method 'permission_add' -Arguments $name -Options $options -Connection $connection $result.PermissionsCreated++ } } catch { & $record "Failed to create permission '$name': $($_.Exception.Message)" } } # --- Privileges ----------------------------------------------------------------------------- foreach ($row in $privilegeRows) { $name = Resolve-FreeIPASeedName -Key $row.Name -Marker $marker -Connection $connection if (-not $PSCmdlet.ShouldProcess($name, 'Create FreeIPA privilege')) { continue } try { $options = @{ description = & $describe $row.Description } if ($existingPrivileges.ContainsKey($name)) { $null = Invoke-FreeIPARequest -Method 'privilege_mod' -Arguments $name -Options $options -Connection $connection -IgnoreError 'EmptyModlist' } else { $null = Invoke-FreeIPARequest -Method 'privilege_add' -Arguments $name -Options $options -Connection $connection $result.PrivilegesCreated++ } $outcome = Add-FreeIPAMember -Method 'privilege_add_permission' -Name $name -Members @{ permission = @(& $resolve $row.Permissions 'Name') } -Connection $connection $result.MembershipsApplied += $outcome.Completed foreach ($problem in $outcome.Errors) { & $record $problem } } catch { & $record "Failed to create privilege '$name': $($_.Exception.Message)" } } # --- Roles ---------------------------------------------------------------------------------- $roles = [System.Collections.Generic.List[object]]::new() foreach ($row in $roleRows) { $name = Resolve-FreeIPASeedName -Key $row.Name -Marker $marker -Connection $connection if (-not $PSCmdlet.ShouldProcess($name, 'Create FreeIPA role')) { continue } try { $options = @{ description = & $describe $row.Description } if ($existingRoles.ContainsKey($name)) { $null = Invoke-FreeIPARequest -Method 'role_mod' -Arguments $name -Options $options -Connection $connection -IgnoreError 'EmptyModlist' $result.UpdatedRoles++ } else { $null = Invoke-FreeIPARequest -Method 'role_add' -Arguments $name -Options $options -Connection $connection $result.CreatedRoles++ Write-Verbose "Created role $name" } $outcome = Add-FreeIPAMember -Method 'role_add_privilege' -Name $name -Members @{ privilege = @(& $resolve $row.Privileges 'Name') } -Connection $connection $result.MembershipsApplied += $outcome.Completed foreach ($problem in $outcome.Errors) { & $record $problem } $outcome = Add-FreeIPAMember -Method 'role_add_member' -Name $name -Connection $connection -Members @{ user = @(& $split $row.Users) group = @(& $resolve $row.Groups 'Name') host = @(& $resolve $row.Hosts 'Host') } $result.MembershipsApplied += $outcome.Completed foreach ($problem in $outcome.Errors) { & $record $problem } $roles.Add([PSCustomObject]@{ Key = $row.Name; Name = $name; Privileges = @(& $split $row.Privileges) }) } catch { & $record "Failed to create role '$name': $($_.Exception.Message)" } } $result.Roles = $roles.ToArray() Write-Verbose "RBAC: $($result.PermissionsCreated) permissions, $($result.PrivilegesCreated) privileges, $($result.CreatedRoles) roles created, $($result.UpdatedRoles) updated, $($result.Errors.Count) problems" if ($PassThru) { return $result } } |