diff --git a/Functions/DCIM/DCIM.ps1 b/Functions/DCIM/DCIM.ps1 index 9b53432..159382d 100644 --- a/Functions/DCIM/DCIM.ps1 +++ b/Functions/DCIM/DCIM.ps1 @@ -542,6 +542,60 @@ function Add-NetboxDCIMInterface { InvokeNetboxRequest -URI $URI -Body $URIComponents.Parameters -Method POST } +function Add-NetboxDCIMInterfaceConnection { +<# + .SYNOPSIS + Create a new connection between two interfaces + + .DESCRIPTION + Create a new connection between two interfaces + + .PARAMETER Connection_Status + Is it connected or planned? + + .PARAMETER Interface_A + Database ID of interface A + + .PARAMETER Interface_B + Database ID of interface B + + .EXAMPLE + PS C:\> Add-NetboxDCIMInterfaceConnection -Interface_A $value1 -Interface_B $value2 + + .NOTES + Additional information about the function. +#> + + [CmdletBinding()] + [OutputType([pscustomobject])] + param + ( + [object]$Connection_Status, + + [Parameter(Mandatory = $true)] + [uint16]$Interface_A, + + [Parameter(Mandatory = $true)] + [uint16]$Interface_B + ) + + if ($null -ne $Connection_Status) { + $PSBoundParameters.Connection_Status = ValidateDCIMChoice -ProvidedValue $Connection_Status -InterfaceConnectionStatus + } + + # Verify if both Interfaces exist + $I_A = Get-NetboxDCIMInterface -Id $Interface_A -ErrorAction Stop + $I_B = Get-NetboxDCIMInterface -Id $Interface_B -ErrorAction Stop + + $Segments = [System.Collections.ArrayList]::new(@('dcim', 'interface-connections')) + + $URIComponents = BuildURIComponents -URISegments $Segments.Clone() -ParametersDictionary $PSBoundParameters + + $URI = BuildNewURI -Segments $URIComponents.Segments + + InvokeNetboxRequest -URI $URI -Body $URIComponents.Parameters -Method POST +} + #endregion ADD/NEW commands @@ -714,6 +768,85 @@ function Set-NetboxDCIMInterface { } } +function Set-NetboxDCIMInterfaceConnection { +<# + .SYNOPSIS + Update an interface connection + + .DESCRIPTION + Update an interface connection + + .PARAMETER Id + A description of the Id parameter. + + .PARAMETER Connection_Status + A description of the Connection_Status parameter. + + .PARAMETER Interface_A + A description of the Interface_A parameter. + + .PARAMETER Interface_B + A description of the Interface_B parameter. + + .PARAMETER Force + A description of the Force parameter. + + .EXAMPLE + PS C:\> Set-NetboxDCIMInterfaceConnection -Id $value1 + + .NOTES + Additional information about the function. +#> + + [CmdletBinding(ConfirmImpact = 'Medium', + SupportsShouldProcess = $true)] + param + ( + [Parameter(Mandatory = $true, + ValueFromPipelineByPropertyName = $true)] + [uint16[]]$Id, + + [object]$Connection_Status, + + [uint16]$Interface_A, + + [uint16]$Interface_B, + + [switch]$Force + ) + + begin { + if ($null -ne $Connection_Status) { + $PSBoundParameters.Connection_Status = ValidateDCIMChoice -ProvidedValue $Connection_Status -InterfaceConnectionStatus + } + + if ((@($ID).Count -gt 1) -and ($Interface_A -or $Interface_B)) { + throw "Cannot set multiple connections to the same interface" + } + } + + process { + foreach ($ConnectionID in $Id) { + $CurrentConnection = Get-NetboxDCIMInterfaceConnection -Id $ConnectionID -ErrorAction Stop + + $Segments = [System.Collections.ArrayList]::new(@('dcim', 'interface-connections', $CurrentConnection.Id)) + + if ($Force -or $pscmdlet.ShouldProcess("Connection ID $($CurrentConnection.Id)", "Set")) { + + $URIComponents = BuildURIComponents -URISegments $Segments.Clone() -ParametersDictionary $PSBoundParameters -SkipParameterByName 'Id', 'Force' + + $URI = BuildNewURI -Segments $URIComponents.Segments + + InvokeNetboxRequest -URI $URI -Body $URIComponents.Parameters -Method PATCH + } + } + } + + end { + + } +} + #endregion SET Commands @@ -829,6 +962,45 @@ function Remove-NetboxDCIMInterface { } } +function Remove-NetboxDCIMInterfaceConnection { + [CmdletBinding(ConfirmImpact = 'High', + SupportsShouldProcess = $true)] + [OutputType([void])] + param + ( + [Parameter(Mandatory = $true, + ValueFromPipelineByPropertyName = $true)] + [uint16[]]$Id, + + [switch]$Force + ) + + begin { + + } + + process { + foreach ($ConnectionID in $Id) { + $CurrentConnection = Get-NetboxDCIMInterfaceConnection -Id $ConnectionID -ErrorAction Stop + + if ($Force -or $pscmdlet.ShouldProcess("Connection ID $($ConnectionID.Id)", "REMOVE")) { + $Segments = [System.Collections.ArrayList]::new(@('dcim', 'interface-connections', $CurrentConnection.Id)) + + $URIComponents = BuildURIComponents -URISegments $Segments.Clone() -ParametersDictionary $PSBoundParameters -SkipParameterByName 'Id', 'Force' + + $URI = BuildNewURI -Segments $URIComponents.Segments + + InvokeNetboxRequest -URI $URI -Method DELETE + } + } + } + + end { + + } +} + + #endregion REMOVE commands diff --git a/Tests/DCIM.Interfaces.Tests.ps1 b/Tests/DCIM.Interfaces.Tests.ps1 index d57f7fe..fab96bb 100644 --- a/Tests/DCIM.Interfaces.Tests.ps1 +++ b/Tests/DCIM.Interfaces.Tests.ps1 @@ -337,6 +337,151 @@ Describe -Name "DCIM Interfaces Tests" -Tag 'DCIM', 'Interfaces' -Fixture { } | Should -Throw } } + + Context -Name "Add-NetboxDCIMInterfaceConnection" -Fixture { + It "Should add a new interface connection" { + $Result = Add-NetboxDCIMInterfaceConnection -Interface_A 21 -Interface_B 22 + + Assert-VerifiableMock + Assert-MockCalled -CommandName 'Invoke-RestMethod' -Times 1 -Exactly -Scope 'It' + + $Result.Method | Should -Be 'POST' + $Result.Uri | Should -BeExactly 'https://netbox.domain.com/api/dcim/interface-connections/' + $Result.Headers.Keys.Count | Should -BeExactly 1 + $Result.Body | Should -Be '{"interface_b":22,"interface_a":21}' + } + + It "Should throw because of an invalid connection status" { + { + Add-NetboxDCIMInterfaceConnection -Interface_A 21 -Interface_B 22 -Connection_Status 'fake' + } | Should -Throw + } + } + + + Mock -CommandName "Get-NetboxDCIMInterfaceConnection" -ModuleName 'NetboxPS' -MockWith { + [pscustomobject]@{ + 'Id' = $Id + } + } + + Context -Name "Set-NetboxDCIMInterfaceConnection" -Fixture { + It "Should set an interface connection" { + $Result = Set-NetboxDCIMInterfaceConnection -Id 123 -Interface_B 2 -Force + + Assert-VerifiableMock + Assert-MockCalled -CommandName 'Invoke-RestMethod' -Times 1 -Exactly -Scope 'It' + + $Result.Method | Should -Be 'PATCH' + $Result.Uri | Should -BeExactly 'https://netbox.domain.com/api/dcim/interface-connections/123/' + $Result.Headers.Keys.Count | Should -BeExactly 1 + $Result.Body | Should -Be '{"interface_b":2}' + } + + It "Should set multiple interface connections to a new status" { + $Result = Set-NetboxDCIMInterfaceConnection -Id 456, 789 -Connection_Status 'Planned' -Force + + Assert-VerifiableMock + Assert-MockCalled -CommandName 'Invoke-RestMethod' -Times 2 -Exactly -Scope 'It' + + $Result.Method | Should -Be 'PATCH', 'PATCH' + $Result.Uri | Should -BeExactly 'https://netbox.domain.com/api/dcim/interface-connections/456/', 'https://netbox.domain.com/api/dcim/interface-connections/789/' + $Result.Headers.Keys.Count | Should -BeExactly 2 + $Result.Body | Should -Be '{"connection_status":false}', '{"connection_status":false}' + } + + It "Should set an interface connection from the pipeline" { + $Result = [pscustomobject]@{ + 'id' = 3 + } | Set-NetboxDCIMInterfaceConnection -Connection_Status 'Planned' -Force + + Assert-VerifiableMock + Assert-MockCalled -CommandName 'Invoke-RestMethod' -Times 1 -Exactly -Scope 'It' + + $Result.Method | Should -Be 'PATCH' + $Result.Uri | Should -BeExactly 'https://netbox.domain.com/api/dcim/interface-connections/3/' + $Result.Headers.Keys.Count | Should -BeExactly 1 + $Result.Body | Should -Be '{"connection_status":false}' + } + + It "Should set multiple interface connections from the pipeline" { + $Result = @( + [pscustomobject]@{ + 'id' = 456 + }, + [pscustomobject]@{ + 'id' = 789 + } + ) | Set-NetboxDCIMInterfaceConnection -Connection_Status 'Planned' -Force + + Assert-VerifiableMock + Assert-MockCalled -CommandName 'Invoke-RestMethod' -Times 2 -Exactly -Scope 'It' + + $Result.Method | Should -Be 'PATCH', 'PATCH' + $Result.Uri | Should -BeExactly 'https://netbox.domain.com/api/dcim/interface-connections/456/', 'https://netbox.domain.com/api/dcim/interface-connections/789/' + $Result.Headers.Keys.Count | Should -BeExactly 2 + $Result.Body | Should -Be '{"connection_status":false}', '{"connection_status":false}' + } + + It "Should throw trying to set multiple connections to the same interface" { + { + Set-NetboxDCIMInterfaceConnection -Id 456, 789 -Interface_B 22 -Force + } | Should -Throw -ExpectedMessage "Cannot set multiple connections to the same interface" + } + } + + Context -Name "Remove-NetboxDCIMInterfaceConnection" -Fixture { + It "Should remove an interface connection" { + $Result = Remove-NetboxDCIMInterfaceConnection -Id 10 -Force + + Assert-VerifiableMock + Assert-MockCalled -CommandName 'Get-NetboxDCIMInterfaceConnection' -Times 1 -Exactly -Scope 'It' + + $Result.Method | Should -Be 'DELETE' + $Result.URI | Should -Be 'https://netbox.domain.com/api/dcim/interface-connections/10/' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should remove multiple interface connections" { + $Result = Remove-NetboxDCIMInterfaceConnection -Id 10, 12 -Force + + Assert-VerifiableMock + Assert-MockCalled -CommandName 'Get-NetboxDCIMInterfaceConnection' -Times 2 -Exactly -Scope 'It' + + $Result.Method | Should -Be 'DELETE', 'DELETE' + $Result.URI | Should -Be 'https://netbox.domain.com/api/dcim/interface-connections/10/', 'https://netbox.domain.com/api/dcim/interface-connections/12/' + $Result.Headers.Keys.Count | Should -BeExactly 2 + } + + It "Should remove an interface connection from the pipeline" { + $Result = Get-NetboxDCIMInterfaceConnection -Id 20 | Remove-NetboxDCIMInterfaceConnection -Force + + Assert-VerifiableMock + Assert-MockCalled -CommandName 'Get-NetboxDCIMInterfaceConnection' -Times 2 -Exactly -Scope 'It' + + $Result.Method | Should -Be 'DELETE' + $Result.URI | Should -Be 'https://netbox.domain.com/api/dcim/interface-connections/20/' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should remove mulitple interface connections from the pipeline" { + $Result = @( + [pscustomobject]@{ + 'Id' = 30 + }, + [pscustomobject]@{ + 'Id' = 40 + } + ) | Remove-NetboxDCIMInterfaceConnection -Force + + Assert-VerifiableMock + Assert-MockCalled -CommandName 'Get-NetboxDCIMInterfaceConnection' -Times 2 -Exactly -Scope 'It' + + $Result.Method | Should -Be 'DELETE', 'DELETE' + $Result.URI | Should -Be 'https://netbox.domain.com/api/dcim/interface-connections/30/', 'https://netbox.domain.com/api/dcim/interface-connections/40/' + $Result.Headers.Keys.Count | Should -BeExactly 2 + } + } } }