Skip to content

Commit

Permalink
Take ownership of a pipeline schedule
Browse files Browse the repository at this point in the history
This pulled a thread that required creating impersonation cmdlets
  • Loading branch information
chris-peterson committed Aug 29, 2024
1 parent cf2c57f commit 78a1507
Show file tree
Hide file tree
Showing 6 changed files with 600 additions and 503 deletions.
23 changes: 14 additions & 9 deletions src/GitlabCli/GitlabCli.psd1
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
@{
ModuleVersion = '1.117.2'
ModuleVersion = '1.118.0'

RequiredModules = @('powershell-yaml')

Expand Down Expand Up @@ -27,8 +27,8 @@
ExternalModuleDependencies = @('powershell-yaml')
ReleaseNotes =
@'
* https://github.com/chris-peterson/pwsh-gitlab/issues/94
* https://github.com/chris-peterson/pwsh-gitlab/issues/97
* Wrap pipeline schedule ownership transfer
* Support impersonation session
'@
}
}
Expand Down Expand Up @@ -66,6 +66,7 @@
'Notes.psm1'
'PersonalAccessTokens.psm1'
'Pipelines.psm1'
'PipelineSchedules.psm1'
'Projects.psm1'
'ProjectHooks.psm1'
'RepositoryFiles.psm1'
Expand Down Expand Up @@ -202,19 +203,21 @@
'Get-GitlabPipelineVariable'
'New-GitlabPipeline'
'Remove-GitlabPipeline'
'Get-GitlabPipelineSchedule'
'New-GitlabPipelineSchedule'
'Update-GitlabPipelineSchedule'
'Enable-GitlabPipelineSchedule'
'Disable-GitlabPipelineSchedule'
'Remove-GitlabPipelineSchedule'
'Get-GitlabPipelineScheduleVariable'
'New-GitlabPipelineScheduleVariable'
'Remove-GitlabPipelineScheduleVariable'
'Update-GitlabPipelineScheduleVariable'
'New-GitlabScheduledPipeline'
'Get-GitlabPipelineBridge'

# Pipeline Schedules
'Get-GitlabPipelineSchedule'
'New-GitlabPipelineSchedule'
'Update-GitlabPipelineSchedule'
'Enable-GitlabPipelineSchedule'
'Disable-GitlabPipelineSchedule'
'Remove-GitlabPipelineSchedule'

# Jobs
'Get-GitlabJob'
'Get-GitlabJobTrace'
Expand Down Expand Up @@ -250,6 +253,8 @@
'Get-GitlabUser'
'Get-GitlabCurrentUser'
'Block-GitlabUser'
'Start-GitlabUserImpersonation'
'Stop-GitlabUserImpersonation'
'Unblock-GitlabUser'

# Events
Expand Down
507 changes: 507 additions & 0 deletions src/GitlabCli/PipelineSchedules.psm1

Large diffs are not rendered by default.

491 changes: 0 additions & 491 deletions src/GitlabCli/Pipelines.psm1

Large diffs are not rendered by default.

71 changes: 71 additions & 0 deletions src/GitlabCli/Users.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -265,3 +265,74 @@ function Get-GitlabCurrentUser {

Get-GitlabUser -Me -SiteUrl $SiteUrl
}

function Start-GitlabUserImpersonation {
[CmdletBinding(SupportsShouldProcess)]
param (
[Parameter(Position=0, Mandatory, ValueFromPipelineByPropertyName)]
[Alias('Id')]
[Alias('Username')]
[Alias('EmailAddress')]
[string]
$UserId,

[Parameter()]
[string]
$SiteUrl
)
$User = Get-GitlabUser $UserId

# https://docs.gitlab.com/ee/api/users.html#create-an-impersonation-token
$Parameters = @{
Method = 'POST'
Path = "users/$($User.Id)/impersonation_tokens"
Body = @{
name = "pwsh-gitlab temporary impersonation token $($User.Username)"
expires_at = (Get-Date).AddDays(1).ToString('yyyy-MM-dd')
scopes = @('api', 'read_user')
}
SiteUrl = $SiteUrl
}
if ($PSCmdlet.ShouldProcess("$($User.Username)", "start impersonation")) {

if ($global:GitlabUserImpersonationSession) {
Write-Error "Impersonation session already started by $($global:GitlabUserImpersonationSession.StartedBy). Call 'Stop-GitlabUserImpersonation' before attempting a new session."
}

$Result = Invoke-GitlabApi @Parameters
$global:GitlabUserImpersonationSession = @{
Id = $Result.id
UserId = $Result.user_id
Username = $User.Username
Token = $Result.token
}
}
}

function Stop-GitlabUserImpersonation {
[CmdletBinding(SupportsShouldProcess)]
param (
[Parameter()]
[string]
$SiteUrl
)

if ($PSCmdlet.ShouldProcess("Impersonation session for $($global:GitlabUserImpersonationSession.Username)", "stop")) {
if ($global:GitlabUserImpersonationSession) {
# https://docs.gitlab.com/ee/api/users.html#revoke-an-impersonation-token
$Parameters = @{
Method = 'DELETE'
Path = "users/$($global:GitlabUserImpersonationSession.UserId)/impersonation_tokens/$($global:GitlabUserImpersonationSession.Id)"
SiteUrl = $SiteUrl
}
# NOTE: important that we clear first as the revoke API requires admin
$global:GitlabUserImpersonationSession = $null
if (Invoke-GitlabApi @Parameters) {
Write-Host "Impersonation session ($($global:GitlabUserImpersonationSession.Username)) stopped"
}
}
else {
Write-Warning "No impersonation session started. Call 'Start-GitlabUserImpersonation' to start one."
}
}
}
10 changes: 7 additions & 3 deletions src/GitlabCli/Utilities.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,10 @@ function Invoke-GitlabApi {
$Headers = @{
Accept = 'application/json'
}
if (-not $AccessToken) {
if ($global:GitlabUserImpersonationSession) {
Write-Verbose "Impersonating API call as '$($global:GitlabUserImpersonationSession.Username)'..."
$AccessToken = $global:GitlabUserImpersonationSession.Token
} elseif (-not $AccessToken) {
$AccessToken = $Site.AccessToken
}
if ($AccessToken) {
Expand Down Expand Up @@ -142,7 +145,7 @@ function Invoke-GitlabApi {
}
$Proxy = $ProxyUrl ?? $Site.ProxyUrl
if (-not [string]::IsNullOrWhiteSpace($Proxy)) {
Write-Verbose "Using proxy $Proxy"
Write-Verbose "Using proxy $Proxy..."
}
if($MaxPages -gt 1) {
$RestMethodParams.FollowRelLink = $true
Expand All @@ -159,8 +162,9 @@ function Invoke-GitlabApi {
Write-Host "WhatIf: $HostOutput"
}
else {
Write-Verbose "$HostOutput"
Write-Verbose "Request: $HostOutput"
$Result = Invoke-RestMethod @RestMethodParams
Write-Verbose "Response: $($Result | ConvertTo-Json)"
if($MaxPages -gt 1) {
# Unwrap pagination container
$Result | ForEach-Object {
Expand Down
1 change: 1 addition & 0 deletions src/GitlabCli/_Init.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,4 @@ $global:GitlabIdentityPropertyNameExemptions=@{
'Gitlab.Variable' = ''
}
$global:GitlabJobLogSections = New-Object 'Collections.Generic.Stack[string]'
$global:GitlabUserImpersonationSession = $null

0 comments on commit 78a1507

Please sign in to comment.