DSCResources/cOctopusServerSpace/cOctopusServerSpace.psm1
# dot-source the helper file (cannot load as a module due to scope considerations) . (Join-Path -Path (Split-Path (Split-Path $PSScriptRoot -Parent) -Parent) -ChildPath 'OctopusDSCHelpers.ps1') function Get-TargetResource { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSDSCUseVerboseMessageInDSCResource", "")] [OutputType([HashTable])] param ( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$Url, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [ValidateSet("Present", "Absent")] [string]$Ensure, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$Name, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$Description, [string[]]$SpaceManagersTeamMembers, [string[]]$SpaceManagersTeams, [PSCredential]$OctopusCredentials = [PSCredential]::Empty, [PSCredential]$OctopusApiKey = [PSCredential]::Empty ) if (($null -eq $SpaceManagersTeamMembers) -and ($null -eq $SpaceManagersTeams)) { throw "Please provide at least one of 'SpaceManagersTeamMembers' or 'SpaceManagersTeams'." } $space = Get-Space -Url $Url ` -Name $Name ` -OctopusCredentials $OctopusCredentials ` -OctopusApiKey $OctopusApiKey $existingEnsure = 'Present' if ($null -eq $space) { $existingEnsure = 'Absent' } $result = @{ Url = $Url Ensure = $existingEnsure Name = $Name Description = $space.Description OctopusCredentials = $OctopusCredentials OctopusApiKey = $OctopusApiKey SpaceManagersTeamMembers = $space.SpaceManagersTeamMembers SpaceManagersTeams = $space.SpaceManagersTeams } return $result } function Set-TargetResource { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSDSCUseVerboseMessageInDSCResource", "")] param ( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$Url, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [ValidateSet("Present", "Absent")] [string]$Ensure, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$Name, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$Description, [string[]]$SpaceManagersTeamMembers, [string[]]$SpaceManagersTeams, [PSCredential]$OctopusCredentials = [PSCredential]::Empty, [PSCredential]$OctopusApiKey = [PSCredential]::Empty ) $currentResource = Get-TargetResource -Url $Url ` -Ensure $Ensure ` -Name $Name ` -Description $Description ` -SpaceManagersTeamMembers $SpaceManagersTeamMembers ` -SpaceManagersTeams $SpaceManagersTeams ` -OctopusCredentials $OctopusCredentials ` -OctopusApiKey $OctopusApiKey if ($Ensure -eq "Absent" -and $currentResource.Ensure -eq "Present") { Remove-Space -Url $Url ` -Name $Name ` -OctopusCredentials $OctopusCredentials ` -OctopusApiKey $OctopusApiKey } elseif ($Ensure -eq "Present" -and $currentResource.Ensure -eq "Absent") { New-Space -Url $Url ` -Name $Name ` -Description $Description ` -SpaceManagersTeamMembers $SpaceManagersTeamMembers ` -SpaceManagersTeams $SpaceManagersTeams ` -OctopusCredentials $OctopusCredentials ` -OctopusApiKey $OctopusApiKey } else { Update-Space -Url $Url ` -Name $Name ` -Description $Description ` -SpaceManagersTeamMembers $SpaceManagersTeamMembers ` -SpaceManagersTeams $SpaceManagersTeams ` -OctopusCredentials $OctopusCredentials ` -OctopusApiKey $OctopusApiKey } } function Test-TargetResource { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSDSCUseVerboseMessageInDSCResource", "")] [OutputType([boolean])] param ( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$Url, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [ValidateSet("Present", "Absent")] [string]$Ensure, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$Name, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$Description, [string[]]$SpaceManagersTeamMembers, [string[]]$SpaceManagersTeams, [PSCredential]$OctopusCredentials = [PSCredential]::Empty, [PSCredential]$OctopusApiKey = [PSCredential]::Empty ) $currentResource = (Get-TargetResource -Url $Url ` -Ensure $Ensure ` -Name $Name ` -Description $Description ` -SpaceManagersTeamMembers $SpaceManagersTeamMembers ` -SpaceManagersTeams $SpaceManagersTeams ` -OctopusCredentials $OctopusCredentials ` -OctopusApiKey $OctopusApiKey) $params = Get-ODSCParameter $MyInvocation.MyCommand.Parameters $currentConfigurationMatchesRequestedConfiguration = $true foreach ($key in $currentResource.Keys) { $currentValue = $currentResource.Item($key) $requestedValue = $params.Item($key) if ($currentValue -ne $requestedValue) { Write-Verbose "(FOUND MISMATCH) Configuration parameter '$key' with value '$currentValue' mismatched the specified value '$requestedValue'" $currentConfigurationMatchesRequestedConfiguration = $false } else { Write-Verbose "Configuration parameter '$key' matches the requested value '$requestedValue'" } } return $currentConfigurationMatchesRequestedConfiguration } function Remove-Space { param ( [Parameter(Mandatory)] [string]$Url, [Parameter(Mandatory)] [string]$Name, [PSCredential]$OctopusCredentials = [PSCredential]::Empty, [PSCredential]$OctopusApiKey = [PSCredential]::Empty ) $repository = Get-OctopusClientRepository -Url $Url ` -OctopusCredentials $OctopusCredentials ` -OctopusApiKey $OctopusApiKey $space = $repository.Spaces.FindByName($Name) $space.TaskQueueStopped = $true $repository.Spaces.Modify($space) # todo: we should probably check to make sure the task queue is empty $repository.Spaces.Delete($space) } function New-Space { param ( [Parameter(Mandatory)] [string]$Url, [Parameter(Mandatory)] [string]$Name, [Parameter(Mandatory)] [string]$Description, [string[]]$SpaceManagersTeamMembers, [string[]]$SpaceManagersTeams, [PSCredential]$OctopusCredentials = [PSCredential]::Empty, [PSCredential]$OctopusApiKey = [PSCredential]::Empty ) $repository = Get-OctopusClientRepository -Url $Url ` -OctopusCredentials $OctopusCredentials ` -OctopusApiKey $OctopusApiKey $space = New-SpaceResource $space.Name = $Name; $space.Description = $Description; $space.SpaceManagersTeamMembers = $SpaceManagersTeamMembers; $space.SpaceManagersTeams = $SpaceManagersTeams; $users = $repository.Users.FindAll() $space.SpaceManagersTeamMembers = ConvertTo-ReferenceCollection @($SpaceManagersTeamMembers | foreach-object { $user = $_ ($users | where-object { $_.Username -eq $user }).Id }) $teams = $repository.Teams.FindAll() | where-object { ($null -eq $_.SpaceId) -or ($_.SpaceId -eq $space.Id) } $space.SpaceManagersTeams = ConvertTo-ReferenceCollection @($SpaceManagersTeams | foreach-object { $team = $_ ($teams | where-object { $_.Name -eq $team }).Id }) $repository.Spaces.Create($space) | Out-Null } function New-SpaceResource { # making this mockable, so we dont have to reference Octopus.Client.dll in the tests return New-Object Octopus.Client.Model.SpaceResource } function ConvertTo-ReferenceCollection ([string[]]$list) { # making this mockable, so we dont have to reference Octopus.Client.dll in the tests return New-Object Octopus.Client.Model.ReferenceCollection ($list) } function Update-Space { param ( [Parameter(Mandatory)] [string]$Url, [Parameter(Mandatory)] [string]$Name, [Parameter(Mandatory)] [string]$Description, [string[]]$SpaceManagersTeamMembers, [string[]]$SpaceManagersTeams, [PSCredential]$OctopusCredentials = [PSCredential]::Empty, [PSCredential]$OctopusApiKey = [PSCredential]::Empty ) $repository = Get-OctopusClientRepository -Url $Url ` -OctopusCredentials $OctopusCredentials ` -OctopusApiKey $OctopusApiKey $space = $repository.Spaces.FindByName($Name) $space.Description = $Description $users = $repository.Users.FindAll() $space.SpaceManagersTeamMembers = @($SpaceManagersTeamMembers | foreach-object { $user = $_ ($users | where-object { $_.Username -eq $user }).Id }) $teams = $repository.Teams.FindAll() | where-object { ($null -eq $_.SpaceId) -or ($_.SpaceId -eq $space.Id) } $space.SpaceManagersTeams = @($SpaceManagersTeams | foreach-object { $team = $_ ($teams | where-object { $_.Name -eq $team }).Id }) if ($null -eq ($SpaceManagersTeams | where-object { $_ -eq 'Space Managers' })) { $space.SpaceManagersTeams += ($teams | where-object { $_.Name -eq 'Space Managers'}).Id } $repository.Spaces.Modify($space) | Out-Null } function Get-Space { param ( [Parameter(Mandatory)] [string]$Url, [Parameter(Mandatory)] [string]$Name, [PSCredential]$OctopusCredentials = [PSCredential]::Empty, [PSCredential]$OctopusApiKey = [PSCredential]::Empty ) $repository = Get-OctopusClientRepository -Url $Url ` -OctopusCredentials $OctopusCredentials ` -OctopusApiKey $OctopusApiKey $space = $repository.Spaces.FindByName($Name) if ($null -ne $space) { # convert to json and back again, so we've got a HashTable rather than a SpaceResource # need a HashTable instead, as we want string[] for SpaceManagersTeamMembers and SpaceManagersTeams $space = ($space | ConvertTo-Json -depth 10 | ConvertFrom-Json) $users = $repository.Users.FindAll() $teams = $repository.Teams.FindAll() | where-object { ($null -eq $_.SpaceId) -or ($_.SpaceId -eq $space.Id) } $space.SpaceManagersTeamMembers = $space.SpaceManagersTeamMembers | foreach-object { $user = $_ ($users | where-object { $_.Id -eq $user }).Username } $space.SpaceManagersTeams = $space.SpaceManagersTeams | foreach-object { $team = $_ ($teams | where-object { $_.Id -eq $team }).Name } } # convert to json and back again, so we've got a HashTable rather than a SpaceResource # need a HashTable instead, as we want string[] for SpaceManagersTeamMembers and SpaceManagersTeams return $space } function Get-OctopusClientRepository { param ( [Parameter(Mandatory)] [string]$Url, [PSCredential]$OctopusCredentials = [PSCredential]::Empty, [PSCredential]$OctopusApiKey = [PSCredential]::Empty ) if ((($null -eq $OctopusCredentials) -or ($OctopusCredentials -eq [PSCredential]::Empty)) -and (($null -eq $OctopusApiKey) -or ($OctopusApiKey -eq [PSCredential]::Empty))) { throw "Please provide either 'OctopusCredentials' or 'OctopusApiKey'." } if ((($null -ne $OctopusCredentials) -and ($OctopusCredentials -ne [PSCredential]::Empty)) -and (($null -ne $OctopusApiKey) -and ($OctopusApiKey -ne [PSCredential]::Empty))) { throw "Please provide either 'OctopusCredentials' or 'OctopusApiKey', not both." } $tempFolder = [System.IO.Path]::GetTempPath() $shadowCopyFolder = Join-Path $tempFolder ([Guid]::NewGuid()) New-Item -type Directory $shadowCopyFolder | Out-Null $filename = "${env:ProgramFiles}\Octopus Deploy\Octopus\Newtonsoft.Json.dll" $version = [System.Diagnostics.FileVersionInfo]::GetVersionInfo($filename) Write-Verbose "Shadow copying '$filename' (version $($version.FileVersion)) to $shadowCopyFolder" Copy-Item $filename $shadowCopyFolder $filename = "${env:ProgramFiles}\Octopus Deploy\Octopus\Octopus.Client.dll" $version = [System.Diagnostics.FileVersionInfo]::GetVersionInfo($filename) Write-Verbose "Shadow copying '$filename' (version $($version.FileVersion)) to $shadowCopyFolder" Copy-Item $filename $shadowCopyFolder $filename = "${env:ProgramFiles}\Octopus Deploy\Octopus\Octopus.Client.Extensibility.dll" if (Test-Path $filename) { $version = [System.Diagnostics.FileVersionInfo]::GetVersionInfo($filename) Write-Verbose "Shadow copying '$filename' (version $($version.FileVersion)) to $shadowCopyFolder" Copy-Item $filename $shadowCopyFolder } #shadow copy these files, so we can uninstall octopus Add-Type -Path (Join-Path $shadowCopyFolder "Newtonsoft.Json.dll") Add-Type -Path (Join-Path $shadowCopyFolder "Octopus.Client.dll") if (($null -ne $OctopusApiKey) -and ($OctopusApiKey -ne [PSCredential]::Empty)) { $apiKey = $OctopusApiKey.GetNetworkCredential().Password $endpoint = New-Object Octopus.Client.OctopusServerEndpoint($Url, $apiKey) $repository = New-Object Octopus.Client.OctopusRepository $endpoint } else { #connect $endpoint = New-Object Octopus.Client.OctopusServerEndpoint $Url $repository = New-Object Octopus.Client.OctopusRepository $endpoint #sign in $credentials = New-Object Octopus.Client.Model.LoginCommand $credentials.Username = $OctopusCredentials.GetNetworkCredential().Username $credentials.Password = $OctopusCredentials.GetNetworkCredential().Password $repository.Users.SignIn($credentials) } return $repository } |