From 8ec7c97890e9ed7b51d701a36c95abbe69423ca8 Mon Sep 17 00:00:00 2001 From: Ben Claussen Date: Tue, 29 May 2018 10:43:23 -0400 Subject: [PATCH] v1.0.2 --- NetboxPS.psd1 | 2 +- dist/NetboxPS.psd1 | 2 +- dist/NetboxPS.psm1 | 1408 ++++++++++++++++++++++++-- dist/Tests/DCIM.Devices.Tests.ps1 | 512 ++++++++++ dist/Tests/DCIM.Interfaces.Tests.ps1 | 505 +++++++++ dist/Tests/DCIM.Platforms.Tests.ps1 | 121 +++ dist/Tests/DCIM.Tests.ps1 | 315 ++++++ dist/Tests/Helpers.Tests.ps1 | 257 ++++- dist/Tests/IPAM.Tests.ps1 | 142 ++- dist/Tests/Virtualization.Tests.ps1 | 124 ++- 10 files changed, 3238 insertions(+), 150 deletions(-) create mode 100644 dist/Tests/DCIM.Devices.Tests.ps1 create mode 100644 dist/Tests/DCIM.Interfaces.Tests.ps1 create mode 100644 dist/Tests/DCIM.Platforms.Tests.ps1 create mode 100644 dist/Tests/DCIM.Tests.ps1 diff --git a/NetboxPS.psd1 b/NetboxPS.psd1 index 6472e5b..0ed2e76 100644 --- a/NetboxPS.psd1 +++ b/NetboxPS.psd1 @@ -19,7 +19,7 @@ ModuleToProcess = 'NetboxPS.psm1' # Version number of this module. - ModuleVersion = '1.0.1' + ModuleVersion = '1.0.2' # ID used to uniquely identify this module GUID = 'bba9b06c-49c8-47cf-8358-aca7c4e78896' diff --git a/dist/NetboxPS.psd1 b/dist/NetboxPS.psd1 index 6472e5b..0ed2e76 100644 --- a/dist/NetboxPS.psd1 +++ b/dist/NetboxPS.psd1 @@ -19,7 +19,7 @@ ModuleToProcess = 'NetboxPS.psm1' # Version number of this module. - ModuleVersion = '1.0.1' + ModuleVersion = '1.0.2' # ID used to uniquely identify this module GUID = 'bba9b06c-49c8-47cf-8358-aca7c4e78896' diff --git a/dist/NetboxPS.psm1 b/dist/NetboxPS.psm1 index e6e5410..5a33364 100644 --- a/dist/NetboxPS.psm1 +++ b/dist/NetboxPS.psm1 @@ -2,7 +2,7 @@ .NOTES -------------------------------------------------------------------------------- Code generated by: SAPIEN Technologies, Inc., PowerShell Studio 2018 v5.5.152 - Generated on: 5/21/2018 3:34 PM + Generated on: 5/29/2018 10:42 AM Generated by: Ben Claussen Organization: NEOnet -------------------------------------------------------------------------------- @@ -42,7 +42,7 @@ Create a new URI for Netbox .DESCRIPTION - A detailed description of the BuildNewURI function. + Internal function used to build a URIBuilder object. .PARAMETER Hostname Hostname of the Netbox API @@ -162,14 +162,14 @@ $URIParameters = @{} foreach ($CmdletParameterName in $ParametersDictionary.Keys) { - if ($CmdletParameterName -in $CommonParameterNames) { + if ($CmdletParameterName -in $script:CommonParameterNames) { # These are common parameters and should not be appended to the URI - Write-Debug "Skipping parameter $CmdletParameterName" + Write-Debug "Skipping common parameter $CmdletParameterName" continue } if ($CmdletParameterName -in $SkipParameterByName) { - Write-Debug "Skipping parameter $CmdletParameterName" + Write-Debug "Skipping parameter $CmdletParameterName by SkipParameterByName" continue } @@ -227,11 +227,11 @@ function ValidateChoice { [CmdletBinding()] - [OutputType([uint16])] + [OutputType([uint16],[string], [bool])] param ( [Parameter(Mandatory = $true)] - [ValidateSet('Circuits', 'Extras', 'IPAM', 'Virtualization', IgnoreCase = $true)] + [ValidateSet('Circuits', 'DCIM', 'Extras', 'IPAM', 'Virtualization', IgnoreCase = $true)] [string]$MajorObject, [Parameter(Mandatory = $true)] @@ -245,22 +245,43 @@ Write-Verbose "Validating $ChoiceName" Write-Verbose "Checking '$ProvidedValue' against [$($ValidValues -join ', ')]" - - if ($ValidValues -inotcontains $ProvidedValue) { + + # Coercing everything to strings for matching... + # some values are integers, some are strings, some are booleans + # Join the valid values with a pipe as a delimeter, because some values have spaces + if (([string]($ValidValues -join '|') -split '\|') -inotcontains [string]$ProvidedValue) { throw "Invalid value '$ProvidedValue' for '$ChoiceName'. Must be one of: $($ValidValues -join ', ')" } - # Convert the ProvidedValue to the integer value - try { - $intVal = [uint16]"$ProvidedValue" - } catch { - # It must not be a number, get the value from the label - $intVal = [uint16]$script:NetboxConfig.Choices.$MajorObject.$ChoiceName.Where({ - $_.Label -eq $ProvidedValue - }).Value + switch -wildcard ("$MajorObject/$ChoiceName") { + "Circuits" { + # This has things that are not integers + } + + "DCIM/*connection_status" { + # This has true/false values instead of integers + try { + $val = [bool]::Parse($ProvidedValue) + } catch { + # It must not be a true/false value + $val = $script:NetboxConfig.Choices.$MajorObject.$ChoiceName.Where({ $_.Label -eq $ProvidedValue }).Value + } + + return $val + } + + default { + # Convert the ProvidedValue to the integer value + try { + $intVal = [uint16]"$ProvidedValue" + } catch { + # It must not be a number, get the value from the label + $intVal = [uint16]$script:NetboxConfig.Choices.$MajorObject.$ChoiceName.Where({ $_.Label -eq $ProvidedValue }).Value + } + + return $intVal + } } - - return $intVal } @@ -416,9 +437,6 @@ public enum $EnumName - - - #endregion #region Invoke-Setup_ps1 @@ -607,7 +625,7 @@ public enum $EnumName Write-Verbose "Caching static choices" $script:NetboxConfig.Choices.Circuits = Get-NetboxCircuitsChoices - #$script:NetboxConfig.Choices.DCIM = Get-NetboxDCIMChoices # Not completed yet + $script:NetboxConfig.Choices.DCIM = Get-NetboxDCIMChoices # Not completed yet $script:NetboxConfig.Choices.Extras = Get-NetboxExtrasChoices $script:NetboxConfig.Choices.IPAM = Get-NetboxIPAMChoices #$script:NetboxConfig.Choices.Secrets = Get-NetboxSecretsChoices # Not completed yet @@ -778,7 +796,7 @@ public enum $EnumName Virtualization object functions #> - function ValidateVirtualizationChoices { + function ValidateVirtualizationChoice { <# .SYNOPSIS Internal function to verify provided values for static choices @@ -986,7 +1004,7 @@ public enum $EnumName ) if ($null -ne $Status) { - $PSBoundParameters.Status = ValidateVirtualizationChoices -ProvidedValue $Status -VirtualMachineStatus + $PSBoundParameters.Status = ValidateVirtualizationChoice -ProvidedValue $Status -VirtualMachineStatus } $Segments = [System.Collections.ArrayList]::new(@('virtualization', 'virtual-machines')) @@ -1258,7 +1276,7 @@ public enum $EnumName [string]$Comments ) - $PSBoundParameters.Status = ValidateVirtualizationChoices -ProvidedValue $Status -VirtualMachineStatus + $PSBoundParameters.Status = ValidateVirtualizationChoice -ProvidedValue $Status -VirtualMachineStatus $Segments = [System.Collections.ArrayList]::new(@('virtualization', 'virtual-machines')) @@ -1269,7 +1287,7 @@ public enum $EnumName InvokeNetboxRequest -URI $URI -Method POST -Body $URIComponents.Parameters } - function Add-NetboxVirtualInterface { + function Add-NetboxVirtualMachineInterface { [CmdletBinding()] param ( @@ -1345,7 +1363,7 @@ public enum $EnumName ) if ($null -ne $Status) { - $PSBoundParameters.Status = ValidateVirtualizationChoices -ProvidedValue $Status -VirtualMachineStatus + $PSBoundParameters.Status = ValidateVirtualizationChoice -ProvidedValue $Status -VirtualMachineStatus } $Segments = [System.Collections.ArrayList]::new(@('virtualization', 'virtual-machines', $Id)) @@ -1419,7 +1437,90 @@ public enum $EnumName - #endregion SET commands#endregion + #endregion SET commands + + + #region REMOVE commands + + function Remove-NetboxVirtualMachine { + <# + .SYNOPSIS + Delete a virtual machine + + .DESCRIPTION + Deletes a virtual machine from Netbox by ID + + .PARAMETER Id + Database ID of the virtual machine + + .PARAMETER Force + Force deletion without any prompts + + .EXAMPLE + PS C:\> Remove-NetboxVirtualMachine -Id $value1 + + .NOTES + Additional information about the function. + #> + + [CmdletBinding(ConfirmImpact = 'High', + SupportsShouldProcess = $true)] + param + ( + [Parameter(Mandatory = $true, + ValueFromPipelineByPropertyName = $true)] + [uint16[]]$Id, + + [switch]$Force + ) + + begin { + + } + + process { + foreach ($VMId in $Id) { + $CurrentVM = Get-NetboxVirtualMachine -Id $VMId -ErrorAction Stop + + if ($Force -or $pscmdlet.ShouldProcess("$($CurrentVM.Name)/$($CurrentVM.Id)", "Remove")) { + $Segments = [System.Collections.ArrayList]::new(@('virtualization', 'virtual-machines', $CurrentVM.Id)) + + $URI = BuildNewURI -Segments $Segments + + InvokeNetboxRequest -URI $URI -Method DELETE + } + } + } + + end { + + } + } + + + #endregion REMOVE commands + + + + + + + + + + + + + + + + + + + + + + #endregion #region Invoke-IPAM_ps1 <# @@ -1447,7 +1548,7 @@ public enum $EnumName InvokeNetboxRequest -URI $uri } - function VerifyIPAMChoices { + function ValidateIPAMChoice { <# .SYNOPSIS Internal function to verify provided values for static choices @@ -1484,10 +1585,10 @@ public enum $EnumName Verify against service protocol values .EXAMPLE - PS C:\> VerifyIPAMChoices -ProvidedValue 'loopback' -IPAddressRole + PS C:\> ValidateIPAMChoice -ProvidedValue 'loopback' -IPAddressRole .EXAMPLE - PS C:\> VerifyIPAMChoices -ProvidedValue 'Loopback' -IPAddressFamily + PS C:\> ValidateIPAMChoice -ProvidedValue 'Loopback' -IPAddressFamily >> Invalid value Loopback for ip-address:family. Must be one of: 4, 6, IPv4, IPv6 .OUTPUTS @@ -1546,7 +1647,6 @@ public enum $EnumName function Get-NetboxIPAMAggregate { [CmdletBinding()] - [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "", Justification = "These are literally 'choices' in Netbox")] param ( [uint16]$Limit, @@ -1569,7 +1669,7 @@ public enum $EnumName ) if ($null -ne $Family) { - $PSBoundParameters.Family = VerifyIPAMChoices -ProvidedValue $Family -AggregateFamily + $PSBoundParameters.Family = ValidateIPAMChoice -ProvidedValue $Family -AggregateFamily } $Segments = [System.Collections.ArrayList]::new(@('ipam', 'aggregates')) @@ -1625,15 +1725,15 @@ public enum $EnumName ) if ($null -ne $Family) { - $PSBoundParameters.Family = VerifyIPAMChoices -ProvidedValue $Family -IPAddressFamily + $PSBoundParameters.Family = ValidateIPAMChoice -ProvidedValue $Family -IPAddressFamily } if ($null -ne $Status) { - $PSBoundParameters.Status = VerifyIPAMChoices -ProvidedValue $Status -IPAddressStatus + $PSBoundParameters.Status = ValidateIPAMChoice -ProvidedValue $Status -IPAddressStatus } if ($null -ne $Role) { - $PSBoundParameters.Role = VerifyIPAMChoices -ProvidedValue $Role -IPAddressRole + $PSBoundParameters.Role = ValidateIPAMChoice -ProvidedValue $Role -IPAddressRole } $Segments = [System.Collections.ArrayList]::new(@('ipam', 'ip-addresses')) @@ -1657,12 +1757,15 @@ public enum $EnumName .PARAMETER Prefix_ID A description of the Prefix_ID parameter. - .PARAMETER NumberOfIPs - A description of the NumberOfIPs parameter. + .PARAMETER Limit + A description of the Limit parameter. .PARAMETER Raw A description of the Raw parameter. + .PARAMETER NumberOfIPs + A description of the NumberOfIPs parameter. + .EXAMPLE PS C:\> Get-NetboxIPAMAvaiableIP -Prefix_ID $value1 @@ -1673,7 +1776,9 @@ public enum $EnumName [CmdletBinding()] param ( - [Parameter(Mandatory = $true)] + [Parameter(Mandatory = $true, + ValueFromPipelineByPropertyName = $true)] + [Alias('Id')] [uint16]$Prefix_ID, [Alias('NumberOfIPs')] @@ -1822,11 +1927,11 @@ public enum $EnumName ) if ($null -ne $Family) { - $PSBoundParameters.Family = VerifyIPAMChoices -ProvidedValue $Family -PrefixFamily + $PSBoundParameters.Family = ValidateIPAMChoice -ProvidedValue $Family -PrefixFamily } if ($null -ne $Status) { - $PSBoundParameters.Status = VerifyIPAMChoices -ProvidedValue $Status -PrefixStatus + $PSBoundParameters.Status = ValidateIPAMChoice -ProvidedValue $Status -PrefixStatus } $Segments = [System.Collections.ArrayList]::new(@('ipam', 'prefixes')) @@ -1909,10 +2014,10 @@ public enum $EnumName [switch]$Raw ) - $PSBoundParameters.Status = VerifyIPAMChoices -ProvidedValue $Status -IPAddressStatus + $PSBoundParameters.Status = ValidateIPAMChoice -ProvidedValue $Status -IPAddressStatus if ($null -ne $Role) { - $PSBoundParameters.Role = VerifyIPAMChoices -ProvidedValue $Role -IPAddressRole + $PSBoundParameters.Role = ValidateIPAMChoice -ProvidedValue $Role -IPAddressRole } $segments = [System.Collections.ArrayList]::new(@('ipam', 'ip-addresses')) @@ -1933,13 +2038,10 @@ public enum $EnumName Removes/deletes an IP address from Netbox by ID and optional other filters .PARAMETER Id - A description of the Id parameter. + Database ID of the IP address object. .PARAMETER Force - A description of the Force parameter. - - .PARAMETER Query - A description of the Query parameter. + Do not confirm. .EXAMPLE PS C:\> Remove-NetboxIPAMAddress -Id $value1 @@ -1952,35 +2054,42 @@ public enum $EnumName SupportsShouldProcess = $true)] param ( - [Parameter(Mandatory = $true)] + [Parameter(Mandatory = $true, + ValueFromPipelineByPropertyName = $true)] [uint16[]]$Id, [switch]$Force ) - $CurrentIPs = @(Get-NetboxIPAMAddress -Id $Id -ErrorAction Stop) + begin { + } - $Segments = [System.Collections.ArrayList]::new(@('ipam', 'ip-addresses')) - - foreach ($IP in $CurrentIPs) { - if ($Force -or $pscmdlet.ShouldProcess($IP.Address, "Delete")) { - $URIComponents = BuildURIComponents -URISegments $Segments.Clone() -ParametersDictionary @{'id' = $IP.Id} + process { + foreach ($IPId in $Id) { + $CurrentIP = Get-NetboxIPAMAddress -Id $IPId -ErrorAction Stop - $URI = BuildNewURI -Segments $URIComponents.Segments + $Segments = [System.Collections.ArrayList]::new(@('ipam', 'ip-addresses', $IPId)) - InvokeNetboxRequest -URI $URI -Method DELETE + if ($Force -or $pscmdlet.ShouldProcess($CurrentIP.Address, "Delete")) { + $URI = BuildNewURI -Segments $Segments + + InvokeNetboxRequest -URI $URI -Method DELETE + } } } + + end { + } } function Set-NetboxIPAMAddress { - [CmdletBinding(ConfirmImpact = 'High', + [CmdletBinding(ConfirmImpact = 'Medium', SupportsShouldProcess = $true)] param ( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] - [uint16]$Id, + [uint16[]]$Id, [string]$Address, @@ -2003,25 +2112,34 @@ public enum $EnumName [switch]$Force ) - if ($Status) { - $PSBoundParameters.Status = VerifyIPAMChoices -ProvidedValue $Status -IPAddressStatus + begin { + if ($Status) { + $PSBoundParameters.Status = ValidateIPAMChoice -ProvidedValue $Status -IPAddressStatus + } + + if ($Role) { + $PSBoundParameters.Role = ValidateIPAMChoice -ProvidedValue $Role -IPAddressRole + } } - if ($Role) { - $PSBoundParameters.Role = VerifyIPAMChoices -ProvidedValue $Role -IPAddressRole + process{ + foreach ($IPId in $Id) { + $Segments = [System.Collections.ArrayList]::new(@('ipam', 'ip-addresses', $IPId)) + + Write-Verbose "Obtaining IPs from ID $IPId" + $CurrentIP = Get-NetboxIPAMAddress -Id $IPId -ErrorAction Stop + + if ($Force -or $PSCmdlet.ShouldProcess($CurrentIP.Address, 'Set')) { + $URIComponents = BuildURIComponents -URISegments $Segments.Clone() -ParametersDictionary $PSBoundParameters -SkipParameterByName 'Id', 'Force' + + $URI = BuildNewURI -Segments $URIComponents.Segments + + InvokeNetboxRequest -URI $URI -Body $URIComponents.Parameters -Method PATCH + } + } } - $Segments = [System.Collections.ArrayList]::new(@('ipam', 'ip-addresses', $Id)) - - Write-Verbose "Obtaining IPs from ID $Id" - $CurrentIP = Get-NetboxIPAMAddress -Id $Id -ErrorAction Stop - - if ($Force -or $PSCmdlet.ShouldProcess($($CurrentIP | Select-Object -ExpandProperty 'Address'), '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{ } } @@ -2034,6 +2152,1146 @@ public enum $EnumName + #endregion + +#region Invoke-DCIM_ps1 + <# + .NOTES + =========================================================================== + Created with: SAPIEN Technologies, Inc., PowerShell Studio 2018 v5.5.152 + Created on: 5/22/2018 4:47 PM + Created by: Ben Claussen + Organization: NEOnet + Filename: DCIM.ps1 + =========================================================================== + .DESCRIPTION + A description of the file. + #> + + function Get-NetboxDCIMChoices { + [CmdletBinding()] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "", Justification = "These are literally 'choices' in Netbox")] + param () + + $uriSegments = [System.Collections.ArrayList]::new(@('dcim', '_choices')) + + $uri = BuildNewURI -Segments $uriSegments -Parameters $Parameters + + InvokeNetboxRequest -URI $uri + } + + function ValidateDCIMChoice { + <# + .SYNOPSIS + Internal function to validate provided values for static choices + + .DESCRIPTION + When users connect to the API, choices for each major object are cached to the config variable. + These values are then utilized to validate if the provided value from a user is valid. + + .PARAMETER ProvidedValue + The value to validate against static choices + + .PARAMETER PowerConnectionStatus + Validate against power connection status values + + .PARAMETER InterfaceTemplateFormFactor + Validate against interface template form factor values + + .PARAMETER InterfaceConnectionStatus + Validate against interface connection status values + + .PARAMETER InterfaceFormFactor + Validate against interface form factor values + + .PARAMETER ConsolePortConnectionStatus + Validate against console port connection status values + + .PARAMETER DeviceStatus + Validate against device status values + + .PARAMETER DeviceFace + Validate against device face values + + .PARAMETER RackType + Validate against rack type values + + .PARAMETER RackWidth + Validate against rack width values. + + .EXAMPLE + PS C:\> ValidateDCIMChoice -ProvidedValue 'rear' -DeviceFace + + .EXAMPLE + PS C:\> ValidateDCIMChoice -ProvidedValue 'middle' -DeviceFace + >> Invalid value middle for device:face. Must be one of: 0, 1, Front, Rear + + .OUTPUTS + This function returns the integer value if valid. Otherwise, it will throw an error. + + .NOTES + Additional information about the function. + + .FUNCTIONALITY + This cmdlet is intended to be used internally and not exposed to the user + #> + + [CmdletBinding()] + [OutputType([uint16])] + param + ( + [Parameter(Mandatory = $true)] + [object]$ProvidedValue, + + [Parameter(ParameterSetName = 'power-port:connection_status', + Mandatory = $true)] + [switch]$PowerConnectionStatus, + + [Parameter(ParameterSetName = 'interface-template:form_factor', + Mandatory = $true)] + [switch]$InterfaceTemplateFormFactor, + + [Parameter(ParameterSetName = 'interface-connection:connection_status', + Mandatory = $true)] + [switch]$InterfaceConnectionStatus, + + [Parameter(ParameterSetName = 'interface:form_factor', + Mandatory = $true)] + [switch]$InterfaceFormFactor, + + [Parameter(ParameterSetName = 'console-port:connection_status', + Mandatory = $true)] + [switch]$ConsolePortConnectionStatus, + + [Parameter(ParameterSetName = 'device:status', + Mandatory = $true)] + [switch]$DeviceStatus, + + [Parameter(ParameterSetName = 'device:face', + Mandatory = $true)] + [switch]$DeviceFace, + + [Parameter(ParameterSetName = 'rack:type', + Mandatory = $true)] + [switch]$RackType, + + [Parameter(ParameterSetName = 'rack:width', + Mandatory = $true)] + [switch]$RackWidth + ) + + ValidateChoice -MajorObject 'DCIM' -ChoiceName $PSCmdlet.ParameterSetName -ProvidedValue $ProvidedValue + } + + + #region GET commands + + function Get-NetboxDCIMPlatform { + [CmdletBinding()] + [OutputType([pscustomobject])] + param + ( + [uint16]$Limit, + + [uint16]$Offset, + + [Parameter(ParameterSetName = 'ById')] + [uint16[]]$Id, + + [string]$Name, + + [string]$Slug, + + [uint16]$Manufacturer_Id, + + [string]$Manufacturer, + + [switch]$Raw + ) + + switch ($PSCmdlet.ParameterSetName) { + 'ById' { + foreach ($PlatformID in $Id) { + $Segments = [System.Collections.ArrayList]::new(@('dcim', 'platforms', $PlatformID)) + + $URIComponents = BuildURIComponents -URISegments $Segments -ParametersDictionary $PSBoundParameters -SkipParameterByName 'Id', 'Raw' + + $URI = BuildNewURI -Segments $URIComponents.Segments -Parameters $URIComponents.Parameters + + InvokeNetboxRequest -URI $URI -Raw:$Raw + } + + break + } + + default { + $Segments = [System.Collections.ArrayList]::new(@('dcim', 'platforms')) + + $URIComponents = BuildURIComponents -URISegments $Segments -ParametersDictionary $PSBoundParameters -SkipParameterByName 'Raw' + + $URI = BuildNewURI -Segments $URIComponents.Segments -Parameters $URIComponents.Parameters + + InvokeNetboxRequest -URI $URI -Raw:$Raw + } + } + } + + #endregion GET commands + + + + #region NEW/ADD commands + + #endregion NEW/ADD commands + + + + #region SET commands + + #endregion SET commands + + + + #region REMOVE commands + + #endregion REMOVE commands + + + + + + + + + + #endregion + +#region Invoke-DCIM_Devices_ps1 + <# + .NOTES + =========================================================================== + Created with: SAPIEN Technologies, Inc., PowerShell Studio 2018 v5.5.152 + Created on: 5/25/2018 2:52 PM + Created by: Ben Claussen + Organization: NEOnet + Filename: DCIM.Devices.ps1 + =========================================================================== + .DESCRIPTION + A description of the file. + #> + + #region GET commands + + function Get-NetboxDCIMDevice { + [CmdletBinding()] + #region Parameters + param + ( + [uint16]$Limit, + + [uint16]$Offset, + + [Parameter(ValueFromPipelineByPropertyName = $true)] + [uint16[]]$Id, + + [string]$Query, + + [string]$Name, + + [uint16]$Manufacturer_Id, + + [string]$Manufacturer, + + [uint16]$Device_Type_Id, + + [uint16]$Role_Id, + + [string]$Role, + + [uint16]$Tenant_Id, + + [string]$Tenant, + + [uint16]$Platform_Id, + + [string]$Platform, + + [string]$Asset_Tag, + + [uint16]$Site_Id, + + [string]$Site, + + [uint16]$Rack_Group_Id, + + [uint16]$Rack_Id, + + [uint16]$Cluster_Id, + + [uint16]$Model, + + [object]$Status, + + [bool]$Is_Full_Depth, + + [bool]$Is_Console_Server, + + [bool]$Is_PDU, + + [bool]$Is_Network_Device, + + [string]$MAC_Address, + + [bool]$Has_Primary_IP, + + [uint16]$Virtual_Chassis_Id, + + [uint16]$Position, + + [string]$Serial, + + [switch]$Raw + ) + + #endregion Parameters + + if ($null -ne $Status) { + $PSBoundParameters.Status = ValidateDCIMChoice -ProvidedValue $Status -DeviceStatus + } + + $Segments = [System.Collections.ArrayList]::new(@('dcim', 'devices')) + + $URIComponents = BuildURIComponents -URISegments $Segments.Clone() -ParametersDictionary $PSBoundParameters -SkipParameterByName 'Raw' + + $URI = BuildNewURI -Segments $URIComponents.Segments -Parameters $URIComponents.Parameters + + InvokeNetboxRequest -URI $URI -Raw:$Raw + } + + function Get-NetboxDCIMDeviceType { + [CmdletBinding()] + #region Parameters + param + ( + [uint16]$Offset, + + [uint16]$Limit, + + [uint16[]]$Id, + + [string]$Query, + + [string]$Slug, + + [string]$Manufacturer, + + [uint16]$Manufacturer_Id, + + [string]$Model, + + [string]$Part_Number, + + [uint16]$U_Height, + + [bool]$Is_Full_Depth, + + [bool]$Is_Console_Server, + + [bool]$Is_PDU, + + [bool]$Is_Network_Device, + + [uint16]$Subdevice_Role, + + [switch]$Raw + ) + #endregion Parameters + + $Segments = [System.Collections.ArrayList]::new(@('dcim', 'device-types')) + + $URIComponents = BuildURIComponents -URISegments $Segments.Clone() -ParametersDictionary $PSBoundParameters -SkipParameterByName 'Raw' + + $URI = BuildNewURI -Segments $URIComponents.Segments -Parameters $URIComponents.Parameters + + InvokeNetboxRequest -URI $URI -Raw:$Raw + } + + function Get-NetboxDCIMDeviceRole { + [CmdletBinding()] + param + ( + [uint16]$Limit, + + [uint16]$Offset, + + [Parameter(ParameterSetName = 'ById')] + [uint16[]]$Id, + + [string]$Name, + + [string]$Slug, + + [string]$Color, + + [bool]$VM_Role, + + [switch]$Raw + ) + + switch ($PSCmdlet.ParameterSetName) { + 'ById' { + foreach ($DRId in $Id) { + $Segments = [System.Collections.ArrayList]::new(@('dcim', 'device-roles', $DRId)) + + $URIComponents = BuildURIComponents -URISegments $Segments -ParametersDictionary $PSBoundParameters -SkipParameterByName 'Id', 'Raw' + + $URI = BuildNewURI -Segments $URIComponents.Segments -Parameters $URIComponents.Parameters + + InvokeNetboxRequest -URI $URI -Raw:$Raw + } + + break + } + + default { + $Segments = [System.Collections.ArrayList]::new(@('dcim', 'device-roles')) + + $URIComponents = BuildURIComponents -URISegments $Segments -ParametersDictionary $PSBoundParameters -SkipParameterByName 'Raw' + + $URI = BuildNewURI -Segments $URIComponents.Segments -Parameters $URIComponents.Parameters + + InvokeNetboxRequest -URI $URI -Raw:$Raw + } + } + } + + #endregion GET commands + + + #region NEW commands + + function New-NetboxDCIMDevice { + [CmdletBinding()] + [OutputType([pscustomobject])] + #region Parameters + param + ( + [Parameter(Mandatory = $true)] + [string]$Name, + + [Parameter(Mandatory = $true)] + [object]$Device_Role, + + [Parameter(Mandatory = $true)] + [object]$Device_Type, + + [Parameter(Mandatory = $true)] + [uint16]$Site, + + [object]$Status = 'Active', + + [uint16]$Platform, + + [uint16]$Tenant, + + [uint16]$Cluster, + + [uint16]$Rack, + + [uint16]$Position, + + [object]$Face, + + [string]$Serial, + + [string]$Asset_Tag, + + [uint16]$Virtual_Chassis, + + [uint16]$VC_Priority, + + [uint16]$VC_Position, + + [uint16]$Primary_IP4, + + [uint16]$Primary_IP6, + + [string]$Comments, + + [hashtable]$Custom_Fields + ) + #endregion Parameters + + if ($null -ne $Device_Role) { + # Validate device role? + } + + if ($null -ne $Device_Type) { + # Validate device type? + } + + if ($null -ne $Status) { + $PSBoundParameters.Status = ValidateDCIMChoice -ProvidedValue $Status -DeviceStatus + } + + if ($null -ne $Face) { + $PSBoundParameters.Face = ValidateDCIMChoice -ProvidedValue $Face -DeviceFace + } + + $Segments = [System.Collections.ArrayList]::new(@('dcim', 'devices')) + + $URIComponents = BuildURIComponents -URISegments $Segments.Clone() -ParametersDictionary $PSBoundParameters + + $URI = BuildNewURI -Segments $URIComponents.Segments + + InvokeNetboxRequest -URI $URI -Body $URIComponents.Parameters -Method POST + } + + #endregion NEW commands + + + #region SET commands + + function Set-NetboxDCIMDevice { + [CmdletBinding(SupportsShouldProcess = $true)] + param + ( + [Parameter(Mandatory = $true, + ValueFromPipelineByPropertyName = $true)] + [uint16[]]$Id, + + [string]$Name, + + [object]$Device_Role, + + [object]$Device_Type, + + [uint16]$Site, + + [object]$Status, + + [uint16]$Platform, + + [uint16]$Tenant, + + [uint16]$Cluster, + + [uint16]$Rack, + + [uint16]$Position, + + [object]$Face, + + [string]$Serial, + + [string]$Asset_Tag, + + [uint16]$Virtual_Chassis, + + [uint16]$VC_Priority, + + [uint16]$VC_Position, + + [uint16]$Primary_IP4, + + [uint16]$Primary_IP6, + + [string]$Comments, + + [hashtable]$Custom_Fields, + + [switch]$Force + ) + + begin { + if ($null -ne $Status) { + $PSBoundParameters.Status = ValidateDCIMChoice -ProvidedValue $Status -DeviceStatus + } + + if ($null -ne $Face) { + $PSBoundParameters.Face = ValidateDCIMChoice -ProvidedValue $Face -DeviceFace + } + } + + process { + foreach ($DeviceID in $Id) { + $CurrentDevice = Get-NetboxDCIMDevice -Id $DeviceID -ErrorAction Stop + + if ($Force -or $pscmdlet.ShouldProcess("$($CurrentDevice.Name)", "Set")) { + $Segments = [System.Collections.ArrayList]::new(@('dcim', 'devices', $CurrentDevice.Id)) + + $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 + + + #region REMOVE commands + + function Remove-NetboxDCIMDevice { + <# + .SYNOPSIS + Delete a device + + .DESCRIPTION + Deletes a device from Netbox by ID + + .PARAMETER Id + Database ID of the device + + .PARAMETER Force + Force deletion without any prompts + + .EXAMPLE + PS C:\> Remove-NetboxDCIMDevice -Id $value1 + + .NOTES + Additional information about the function. + #> + + [CmdletBinding(ConfirmImpact = 'High', + SupportsShouldProcess = $true)] + param + ( + [Parameter(Mandatory = $true, + ValueFromPipelineByPropertyName = $true)] + [uint16[]]$Id, + + [switch]$Force + ) + + begin { + + } + + process { + foreach ($DeviceID in $Id) { + $CurrentDevice = Get-NetboxDCIMDevice -Id $DeviceID -ErrorAction Stop + + if ($Force -or $pscmdlet.ShouldProcess("Name: $($CurrentDevice.Name) | ID: $($CurrentDevice.Id)", "Remove")) { + $Segments = [System.Collections.ArrayList]::new(@('dcim', 'devices', $CurrentDevice.Id)) + + $URI = BuildNewURI -Segments $Segments + + InvokeNetboxRequest -URI $URI -Method DELETE + } + } + } + + end { + + } + } + + #endregion REMOVE commands#endregion + +#region Invoke-DCIM_Interfaces_ps1 + <# + .NOTES + =========================================================================== + Created with: SAPIEN Technologies, Inc., PowerShell Studio 2018 v5.5.152 + Created on: 5/25/2018 2:57 PM + Created by: Ben Claussen + Organization: NEOnet + Filename: DCIM.Interfaces.ps1 + =========================================================================== + .DESCRIPTION + A description of the file. + #> + + #region GET Commands + + function Get-NetboxDCIMInterface { + [CmdletBinding()] + [OutputType([pscustomobject])] + param + ( + [uint16]$Limit, + + [uint16]$Offset, + + [Parameter(ValueFromPipelineByPropertyName = $true)] + [uint16]$Id, + + [uint16]$Name, + + [object]$Form_Factor, + + [bool]$Enabled, + + [uint16]$MTU, + + [bool]$MGMT_Only, + + [string]$Device, + + [uint16]$Device_Id, + + [uint16]$Type, + + [uint16]$LAG_Id, + + [string]$MAC_Address, + + [switch]$Raw + ) + + if ($null -ne $Form_Factor) { + $PSBoundParameters.Form_Factor = ValidateDCIMChoice -ProvidedValue $Form_Factor -InterfaceFormFactor + } + + $Segments = [System.Collections.ArrayList]::new(@('dcim', 'interfaces')) + + $URIComponents = BuildURIComponents -URISegments $Segments.Clone() -ParametersDictionary $PSBoundParameters + + $URI = BuildNewURI -Segments $URIComponents.Segments -Parameters $URIComponents.Parameters + + InvokeNetboxRequest -URI $URI -Raw:$Raw + } + + function Get-NetboxDCIMInterfaceConnection { + [CmdletBinding()] + [OutputType([pscustomobject])] + param + ( + [uint16]$Limit, + + [uint16]$Offset, + + [uint16]$Id, + + [object]$Connection_Status, + + [uint16]$Site, + + [uint16]$Device, + + [switch]$Raw + ) + + if ($null -ne $Connection_Status) { + $PSBoundParameters.Connection_Status = ValidateDCIMChoice -ProvidedValue $Connection_Status -InterfaceConnectionStatus + } + + $Segments = [System.Collections.ArrayList]::new(@('dcim', 'interface-connections')) + + $URIComponents = BuildURIComponents -URISegments $Segments.Clone() -ParametersDictionary $PSBoundParameters -SkipParameterByName 'Raw' + + $URI = BuildNewURI -Segments $URIComponents.Segments -Parameters $URIComponents.Parameters + + InvokeNetboxRequest -URI $URI -Raw:$Raw + } + + #endregion GET Commands + + + #region ADD/NEW commands + + function Add-NetboxDCIMInterface { + [CmdletBinding()] + [OutputType([pscustomobject])] + param + ( + [Parameter(Mandatory = $true)] + [uint16]$Device, + + [Parameter(Mandatory = $true)] + [string]$Name, + + [bool]$Enabled, + + [object]$Form_Factor, + + [uint16]$MTU, + + [string]$MAC_Address, + + [bool]$MGMT_Only, + + [uint16]$LAG, + + [string]$Description, + + [ValidateSet('Access', 'Tagged', 'Tagged All', '100', '200', '300', IgnoreCase = $true)] + [string]$Mode, + + [ValidateRange(1, 4094)] + [uint16]$Untagged_VLAN, + + [ValidateRange(1, 4094)] + [uint16[]]$Tagged_VLANs + ) + + if ($null -ne $Form_Factor) { + $PSBoundParameters.Form_Factor = ValidateDCIMChoice -ProvidedValue $Form_Factor -InterfaceFormFactor + } + + if (-not [System.String]::IsNullOrWhiteSpace($Mode)) { + $PSBoundParameters.Mode = switch ($Mode) { + 'Access' { + 100 + break + } + + 'Tagged' { + 200 + break + } + + 'Tagged All' { + 300 + break + } + + default { + $_ + } + } + } + + $Segments = [System.Collections.ArrayList]::new(@('dcim', 'interfaces')) + + $URIComponents = BuildURIComponents -URISegments $Segments.Clone() -ParametersDictionary $PSBoundParameters + + $URI = BuildNewURI -Segments $URIComponents.Segments + + 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 + + + #region SET Commands + + function Set-NetboxDCIMInterface { + [CmdletBinding()] + [OutputType([pscustomobject])] + param + ( + [Parameter(Mandatory = $true, + ValueFromPipelineByPropertyName = $true)] + [uint16[]]$Id, + + [uint16]$Device, + + [string]$Name, + + [bool]$Enabled, + + [object]$Form_Factor, + + [uint16]$MTU, + + [string]$MAC_Address, + + [bool]$MGMT_Only, + + [uint16]$LAG, + + [string]$Description, + + [ValidateSet('Access', 'Tagged', 'Tagged All', '100', '200', '300', IgnoreCase = $true)] + [string]$Mode, + + [ValidateRange(1, 4094)] + [uint16]$Untagged_VLAN, + + [ValidateRange(1, 4094)] + [uint16[]]$Tagged_VLANs + ) + + begin { + if ($null -ne $Form_Factor) { + $PSBoundParameters.Form_Factor = ValidateDCIMChoice -ProvidedValue $Form_Factor -InterfaceFormFactor + } + + if (-not [System.String]::IsNullOrWhiteSpace($Mode)) { + $PSBoundParameters.Mode = switch ($Mode) { + 'Access' { + 100 + break + } + + 'Tagged' { + 200 + break + } + + 'Tagged All' { + 300 + break + } + + default { + $_ + } + } + } + } + + process { + foreach ($InterfaceId in $Id) { + $CurrentInterface = Get-NetboxDCIMInterface -Id $InterfaceId -ErrorAction Stop + + $Segments = [System.Collections.ArrayList]::new(@('dcim', 'interfaces', $CurrentInterface.Id)) + + $URIComponents = BuildURIComponents -URISegments $Segments.Clone() -ParametersDictionary $PSBoundParameters -SkipParameterByName 'Id' + + $URI = BuildNewURI -Segments $Segments + + InvokeNetboxRequest -URI $URI -Body $URIComponents.Parameters -Method PATCH + } + } + + end { + + } + } + + 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 + + + #region REMOVE commands + + function Remove-NetboxDCIMInterface { + <# + .SYNOPSIS + Removes an interface + + .DESCRIPTION + Removes an interface by ID from a device + + .PARAMETER Id + A description of the Id parameter. + + .PARAMETER Force + A description of the Force parameter. + + .EXAMPLE + PS C:\> Remove-NetboxDCIMInterface -Id $value1 + + .NOTES + Additional information about the function. + #> + + [CmdletBinding(ConfirmImpact = 'High', + SupportsShouldProcess = $true)] + param + ( + [Parameter(Mandatory = $true, + ValueFromPipelineByPropertyName = $true)] + [uint16[]]$Id, + + [switch]$Force + ) + + begin { + + } + + process { + foreach ($InterfaceId in $Id) { + $CurrentInterface = Get-NetboxDCIMInterface -Id $InterfaceId -ErrorAction Stop + + if ($Force -or $pscmdlet.ShouldProcess("Name: $($CurrentInterface.Name) | ID: $($CurrentInterface.Id)", "Remove")) { + $Segments = [System.Collections.ArrayList]::new(@('dcim', 'interfaces', $CurrentInterface.Id)) + + $URI = BuildNewURI -Segments $Segments + + InvokeNetboxRequest -URI $URI -Method DELETE + } + } + } + + end { + + } + } + + 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 + #endregion # Build a list of common paramters so we can omit them to build URI parameters diff --git a/dist/Tests/DCIM.Devices.Tests.ps1 b/dist/Tests/DCIM.Devices.Tests.ps1 new file mode 100644 index 0000000..8a9e22f --- /dev/null +++ b/dist/Tests/DCIM.Devices.Tests.ps1 @@ -0,0 +1,512 @@ +<# + .NOTES + =========================================================================== + Created with: SAPIEN Technologies, Inc., PowerShell Studio 2018 v5.5.152 + Created on: 5/22/2018 4:48 PM + Created by: Ben Claussen + Organization: NEOnet + Filename: DCIM.Tests.ps1 + =========================================================================== + .DESCRIPTION + DCIM tests. +#> + +Import-Module Pester +Remove-Module NetboxPS -Force -ErrorAction SilentlyContinue + +$ModulePath = "$PSScriptRoot\..\dist\NetboxPS.psd1" + +if (Test-Path $ModulePath) { + Import-Module $ModulePath -ErrorAction Stop +} + +Describe -Name "DCIM Devices Tests" -Tag 'DCIM', 'Devices' -Fixture { + Mock -CommandName 'CheckNetboxIsConnected' -Verifiable -ModuleName 'NetboxPS' -MockWith { + return $true + } + + Mock -CommandName 'Invoke-RestMethod' -Verifiable -ModuleName 'NetboxPS' -MockWith { + # Return a hashtable of the items we would normally pass to Invoke-RestMethod + return [ordered]@{ + 'Method' = $Method + 'Uri' = $Uri + 'Headers' = $Headers + 'Timeout' = $Timeout + 'ContentType' = $ContentType + 'Body' = $Body + } + } + + Mock -CommandName 'Get-NetboxCredential' -Verifiable -ModuleName 'NetboxPS' -MockWith { + return [PSCredential]::new('notapplicable', (ConvertTo-SecureString -String "faketoken" -AsPlainText -Force)) + } + + Mock -CommandName 'Get-NetboxHostname' -Verifiable -ModuleName 'NetboxPS' -MockWith { + return 'netbox.domain.com' + } + + InModuleScope -ModuleName 'NetboxPS' -ScriptBlock { + $script:NetboxConfig.Choices.DCIM = (Get-Content "$PSScriptRoot\DCIMChoices.json" -ErrorAction Stop | ConvertFrom-Json) + + Context -Name "Get-NetboxDCIMDevice" -Fixture { + It "Should request the default number of devices" { + $Result = Get-NetboxDCIMDevice + + Assert-VerifiableMock + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/devices/' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request with a limit and offset" { + $Result = Get-NetboxDCIMDevice -Limit 10 -Offset 100 + + Assert-VerifiableMock + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/devices/?offset=100&limit=10' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request with a query" { + $Result = Get-NetboxDCIMDevice -Query 'testdevice' + + Assert-VerifiableMock + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/devices/?q=testdevice' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request with an escaped query" { + $Result = Get-NetboxDCIMDevice -Query 'test device' + + Assert-VerifiableMock + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/devices/?q=test+device' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request with a name" { + $Result = Get-NetboxDCIMDevice -Name 'testdevice' + + Assert-VerifiableMock + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/devices/?name=testdevice' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request with a single ID" { + $Result = Get-NetboxDCIMDevice -Id 10 + + Assert-VerifiableMock + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/devices/10/' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request a device by ID from the pipeline" { + $Result = [pscustomobject]@{ + 'id' = 10 + } | Get-NetboxDCIMDevice + + Assert-VerifiableMock + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/devices/10/' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request with multiple IDs" { + $Result = Get-NetboxDCIMDevice -Id 10, 12, 15 + + Assert-VerifiableMock + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/devices/?id__in=10,12,15' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request a status" { + $Result = Get-NetboxDCIMDevice -Status 'Active' + + Assert-VerifiableMock + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/devices/?status=1' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should throw for an invalid status" { + { + Get-NetboxDCIMDevice -Status 'Fake' + } | Should -Throw + } + + It "Should request devices that are a PDU" { + $Result = Get-NetboxDCIMDevice -Is_PDU $True + + Assert-VerifiableMock + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -BeExactly 'https://netbox.domain.com/api/dcim/devices/?is_pdu=True' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + } + + Context -Name "Get-NetboxDCIMDeviceType" -Fixture { + It "Should request the default number of devices types" { + $Result = Get-NetboxDCIMDeviceType + + Assert-VerifiableMock + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/device-types/' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request with a limit and offset" { + $Result = Get-NetboxDCIMDeviceType -Limit 10 -Offset 100 + + Assert-VerifiableMock + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/device-types/?offset=100&limit=10' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request with a query" { + $Result = Get-NetboxDCIMDeviceType -Query 'testdevice' + + Assert-VerifiableMock + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/device-types/?q=testdevice' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request with an escaped query" { + $Result = Get-NetboxDCIMDeviceType -Query 'test device' + + Assert-VerifiableMock + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/device-types/?q=test+device' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request with a slug" { + $Result = Get-NetboxDCIMDeviceType -Slug 'testdevice' + + Assert-VerifiableMock + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/device-types/?slug=testdevice' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request with a single ID" { + $Result = Get-NetboxDCIMDeviceType -Id 10 + + Assert-VerifiableMock + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/device-types/10/' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request with multiple IDs" { + $Result = Get-NetboxDCIMDeviceType -Id 10, 12, 15 + + Assert-VerifiableMock + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/device-types/?id__in=10,12,15' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request a device type that is PDU" { + $Result = Get-NetboxDCIMDeviceType -Is_PDU $true + + Assert-VerifiableMock + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/device-types/?is_pdu=True' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + } + + Context -Name "Get-NetboxDCIMDeviceRole" -Fixture { + It "Should request the default number of devices types" { + $Result = Get-NetboxDCIMDeviceRole + + Assert-VerifiableMock + Assert-MockCalled -CommandName "Invoke-RestMethod" -Times 1 -Scope 'It' -Exactly + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/device-roles/' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request a device role by Id" { + $Result = Get-NetboxDCIMDeviceRole -Id 10 + + Assert-VerifiableMock + Assert-MockCalled -CommandName "Invoke-RestMethod" -Times 1 -Scope 'It' -Exactly + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/device-roles/10/' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request multiple roles by Id" { + $Result = Get-NetboxDCIMDeviceRole -Id 10, 12 + + Assert-VerifiableMock + Assert-MockCalled -CommandName "Invoke-RestMethod" -Times 2 -Scope 'It' -Exactly + + $Result.Method | Should -Be 'GET', 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/device-roles/10/', 'https://netbox.domain.com/api/dcim/device-roles/12/' + $Result.Headers.Keys.Count | Should -BeExactly 2 + } + + It "Should request single role by Id and color" { + $Result = Get-NetboxDCIMDeviceRole -Id 10 -Color '0fab12' + + Assert-VerifiableMock + Assert-MockCalled -CommandName "Invoke-RestMethod" -Times 1 -Scope 'It' -Exactly + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/device-roles/10/?color=0fab12' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request multiple roles by Id and color" { + $Result = Get-NetboxDCIMDeviceRole -Id 10, 12 -Color '0fab12' + + Assert-VerifiableMock + Assert-MockCalled -CommandName "Invoke-RestMethod" -Times 2 -Scope 'It' -Exactly + + $Result.Method | Should -Be 'GET', 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/device-roles/10/?color=0fab12', 'https://netbox.domain.com/api/dcim/device-roles/12/?color=0fab12' + $Result.Headers.Keys.Count | Should -BeExactly 2 + } + + It "Should request with a limit and offset" { + $Result = Get-NetboxDCIMDeviceRole -Limit 10 -Offset 100 + + Assert-VerifiableMock + Assert-MockCalled -CommandName "Invoke-RestMethod" -Times 1 -Scope 'It' -Exactly + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/device-roles/?offset=100&limit=10' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request with a slug" { + $Result = Get-NetboxDCIMDeviceRole -Slug 'testdevice' + + Assert-VerifiableMock + Assert-MockCalled -CommandName "Invoke-RestMethod" -Times 1 -Scope 'It' -Exactly + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/device-roles/?slug=testdevice' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request with a name" { + $Result = Get-NetboxDCIMDeviceRole -Name 'TestRole' + + Assert-VerifiableMock + Assert-MockCalled -CommandName "Invoke-RestMethod" -Times 1 -Scope 'It' -Exactly + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/device-roles/?name=TestRole' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request those that are VM role" { + $Result = Get-NetboxDCIMDeviceRole -VM_Role $true + + Assert-VerifiableMock + Assert-MockCalled -CommandName "Invoke-RestMethod" -Times 1 -Scope 'It' -Exactly + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/device-roles/?vm_role=True' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + } + + Context -Name "New-NetboxDCIMDevice" -Fixture { + It "Should create a new device" { + $Result = New-NetboxDCIMDevice -Name "newdevice" -Device_Role 4 -Device_Type 10 -Site 1 -Face 0 + + Assert-MockCalled -CommandName 'Invoke-RestMethod' -Times 1 -Exactly -Scope 'It' + + $Result.Method | Should -Be 'POST' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/devices/' + $Result.Headers.Keys.Count | Should -BeExactly 1 + $Result.Body | Should -Be '{"site":1,"face":0,"name":"newdevice","status":1,"device_type":10,"device_role":4}' + } + + It "Should throw because of an invalid status" { + { + New-NetboxDCIMDevice -Name "newdevice" -Device_Role 4 -Device_Type 10 -Site 1 -Status 5555 + } | Should -Throw + } + } + + + Mock -CommandName "Get-NetboxDCIMDevice" -ModuleName NetboxPS -MockWith { + return [pscustomobject]@{ + 'Id' = $Id + 'Name' = $Name + } + } + + Context -Name "Set-NetboxDCIMDevice" -Fixture { + It "Should set a device to a new name" { + $Result = Set-NetboxDCIMDevice -Id 1234 -Name 'newtestname' -Force + + Assert-VerifiableMock + Assert-MockCalled -CommandName 'Get-NetboxDCIMDevice' -Times 1 -Exactly -Scope 'It' + + $Result.Method | Should -Be 'PATCH' + $Result.URI | Should -Be 'https://netbox.domain.com/api/dcim/devices/1234/' + $Result.Headers.Keys.Count | Should -BeExactly 1 + $Result.Body | Should -Be '{"name":"newtestname"}' + } + + It "Should set a device with new properties" { + $Result = Set-NetboxDCIMDevice -Id 1234 -Name 'newtestname' -Cluster 10 -Platform 20 -Site 15 -Force + + Assert-VerifiableMock + Assert-MockCalled -CommandName 'Get-NetboxDCIMDevice' -Times 1 -Exactly -Scope 'It' + + $Result.Method | Should -Be 'PATCH' + $Result.URI | Should -Be 'https://netbox.domain.com/api/dcim/devices/1234/' + $Result.Headers.Keys.Count | Should -BeExactly 1 + $Result.Body | Should -Be '{"cluster":10,"platform":20,"name":"newtestname","site":15}' + } + + It "Should set multiple devices with new properties" { + $Result = Set-NetboxDCIMDevice -Id 1234, 3214 -Cluster 10 -Platform 20 -Site 15 -Force + + Assert-VerifiableMock + Assert-MockCalled -CommandName 'Get-NetboxDCIMDevice' -Times 2 -Exactly -Scope 'It' + + $Result.Method | Should -Be 'PATCH', 'PATCH' + $Result.URI | Should -Be 'https://netbox.domain.com/api/dcim/devices/1234/', 'https://netbox.domain.com/api/dcim/devices/3214/' + $Result.Headers.Keys.Count | Should -BeExactly 2 + $Result.Body | Should -Be '{"cluster":10,"platform":20,"site":15}', '{"cluster":10,"platform":20,"site":15}' + } + + It "Should set multiple devices with new properties from the pipeline" { + $Result = @( + [pscustomobject]@{ + 'id' = 4432 + }, + [pscustomobject]@{ + 'id' = 3241 + } + ) | Set-NetboxDCIMDevice -Cluster 10 -Platform 20 -Site 15 -Force + + Assert-VerifiableMock + Assert-MockCalled -CommandName 'Get-NetboxDCIMDevice' -Times 2 -Exactly -Scope 'It' + + $Result.Method | Should -Be 'PATCH', 'PATCH' + $Result.URI | Should -Be 'https://netbox.domain.com/api/dcim/devices/4432/', 'https://netbox.domain.com/api/dcim/devices/3241/' + $Result.Headers.Keys.Count | Should -BeExactly 2 + $Result.Body | Should -Be '{"cluster":10,"platform":20,"site":15}', '{"cluster":10,"platform":20,"site":15}' + } + } + + Context -Name "Remove-NetboxDCIMDevice" -Fixture { + It "Should remove a device" { + $Result = Remove-NetboxDCIMDevice -Id 10 -Force + + Assert-VerifiableMock + Assert-MockCalled -CommandName 'Get-NetboxDCIMDevice' -Times 1 -Exactly -Scope 'It' + + $Result.Method | Should -Be 'DELETE' + $Result.URI | Should -Be 'https://netbox.domain.com/api/dcim/devices/10/' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should remove multiple devices" { + $Result = Remove-NetboxDCIMDevice -Id 10, 12 -Force + + Assert-VerifiableMock + Assert-MockCalled -CommandName 'Get-NetboxDCIMDevice' -Times 2 -Exactly -Scope 'It' + + $Result.Method | Should -Be 'DELETE', 'DELETE' + $Result.URI | Should -Be 'https://netbox.domain.com/api/dcim/devices/10/', 'https://netbox.domain.com/api/dcim/devices/12/' + $Result.Headers.Keys.Count | Should -BeExactly 2 + } + + It "Should remove a device from the pipeline" { + $Result = Get-NetboxDCIMDevice -Id 20 | Remove-NetboxDCIMDevice -Force + + Assert-VerifiableMock + Assert-MockCalled -CommandName 'Get-NetboxDCIMDevice' -Times 2 -Exactly -Scope 'It' + + $Result.Method | Should -Be 'DELETE' + $Result.URI | Should -Be 'https://netbox.domain.com/api/dcim/devices/20/' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should remove mulitple devices from the pipeline" { + $Result = @( + [pscustomobject]@{ + 'Id' = 30 + }, + [pscustomobject]@{ + 'Id' = 40 + } + ) | Remove-NetboxDCIMDevice -Force + + Assert-VerifiableMock + Assert-MockCalled -CommandName 'Get-NetboxDCIMDevice' -Times 2 -Exactly -Scope 'It' + + $Result.Method | Should -Be 'DELETE', 'DELETE' + $Result.URI | Should -Be 'https://netbox.domain.com/api/dcim/devices/30/', 'https://netbox.domain.com/api/dcim/devices/40/' + $Result.Headers.Keys.Count | Should -BeExactly 2 + } + } + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dist/Tests/DCIM.Interfaces.Tests.ps1 b/dist/Tests/DCIM.Interfaces.Tests.ps1 new file mode 100644 index 0000000..b903e08 --- /dev/null +++ b/dist/Tests/DCIM.Interfaces.Tests.ps1 @@ -0,0 +1,505 @@ +<# + .NOTES + =========================================================================== + Created with: SAPIEN Technologies, Inc., PowerShell Studio 2018 v5.5.152 + Created on: 5/24/2018 10:50 AM + Created by: Ben Claussen + Organization: NEOnet + Filename: DCIM.Interfaces.Tests.ps1 + =========================================================================== + .DESCRIPTION + A description of the file. +#> + +Import-Module Pester +Remove-Module NetboxPS -Force -ErrorAction SilentlyContinue + +$ModulePath = "$PSScriptRoot\..\dist\NetboxPS.psd1" + +if (Test-Path $ModulePath) { + Import-Module $ModulePath -ErrorAction Stop +} + +Describe -Name "DCIM Interfaces Tests" -Tag 'DCIM', 'Interfaces' -Fixture { + Mock -CommandName 'CheckNetboxIsConnected' -Verifiable -ModuleName 'NetboxPS' -MockWith { + return $true + } + + Mock -CommandName 'Invoke-RestMethod' -Verifiable -ModuleName 'NetboxPS' -MockWith { + # Return a hashtable of the items we would normally pass to Invoke-RestMethod + return [ordered]@{ + 'Method' = $Method + 'Uri' = $Uri + 'Headers' = $Headers + 'Timeout' = $Timeout + 'ContentType' = $ContentType + 'Body' = $Body + } + } + + Mock -CommandName 'Get-NetboxCredential' -Verifiable -ModuleName 'NetboxPS' -MockWith { + return [PSCredential]::new('notapplicable', (ConvertTo-SecureString -String "faketoken" -AsPlainText -Force)) + } + + Mock -CommandName 'Get-NetboxHostname' -Verifiable -ModuleName 'NetboxPS' -MockWith { + return 'netbox.domain.com' + } + + InModuleScope -ModuleName 'NetboxPS' -ScriptBlock { + $script:NetboxConfig.Choices.DCIM = (Get-Content "$PSScriptRoot\DCIMChoices.json" -ErrorAction Stop | ConvertFrom-Json) + + Context -Name "Get-NetboxDCIMInterface" -Fixture { + It "Should request the default number of interfaces" { + $Result = Get-NetboxDCIMInterface + + Assert-VerifiableMock + Assert-MockCalled -CommandName 'Invoke-RestMethod' -Times 1 -Scope 'It' -Exactly + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/interfaces/' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request with a limit and offset" { + $Result = Get-NetboxDCIMInterface -Limit 10 -Offset 100 + + Assert-VerifiableMock + Assert-MockCalled -CommandName 'Invoke-RestMethod' -Times 1 -Scope 'It' -Exactly + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/interfaces/?offset=100&limit=10' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request with enabled" { + $Result = Get-NetboxDCIMInterface -Enabled $true + + Assert-VerifiableMock + Assert-MockCalled -CommandName 'Invoke-RestMethod' -Times 1 -Scope 'It' -Exactly + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -BeExactly 'https://netbox.domain.com/api/dcim/interfaces/?enabled=True' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request with a form factor name" { + $Result = Get-NetboxDCIMInterface -Form_Factor '10GBASE-T (10GE)' + + Assert-VerifiableMock + Assert-MockCalled -CommandName 'Invoke-RestMethod' -Times 1 -Scope 'It' -Exactly + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/interfaces/?form_factor=1150' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should throw for an invalid form factor" { + { + Get-NetboxDCIMInterface -Form_Factor 'Fake' + } | Should -Throw + } + + It "Should request devices that are mgmt only" { + $Result = Get-NetboxDCIMInterface -MGMT_Only $True + + Assert-VerifiableMock + Assert-MockCalled -CommandName 'Invoke-RestMethod' -Times 1 -Scope 'It' -Exactly + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -BeExactly 'https://netbox.domain.com/api/dcim/interfaces/?mgmt_only=True' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request an interface from the pipeline" { + $Result = [pscustomobject]@{ + 'Id' = 1234 + } | Get-NetboxDCIMInterface + + Assert-VerifiableMock + Assert-MockCalled -CommandName 'Invoke-RestMethod' -Times 1 -Scope 'It' -Exactly + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/interfaces/1234/' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + } + + Context -Name "Add-NetboxDCIMInterface" -Fixture { + It "Should add a basic interface to a device" { + $Result = Add-NetboxDCIMInterface -Device 111 -Name "TestInterface" + + 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/interfaces/' + $Result.Headers.Keys.Count | Should -BeExactly 1 + $Result.Body | Should -Be '{"name":"TestInterface","device":111}' + } + + It "Should add an interface to a device with lots of properties" { + $paramAddNetboxDCIMInterface = @{ + Device = 123 + Name = "TestInterface" + Form_Factor = '10GBASE-T (10GE)' + MTU = 9000 + MGMT_Only = $true + Description = 'Test Description' + Mode = 'Access' + } + + $Result = Add-NetboxDCIMInterface @paramAddNetboxDCIMInterface + + 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/interfaces/' + $Result.Headers.Keys.Count | Should -BeExactly 1 + $Result.Body | Should -Be '{"mtu":9000,"mgmt_only":true,"description":"Test Description","mode":100,"name":"TestInterface","device":123,"form_factor":1150}' + } + + It "Should add an interface with multiple tagged VLANs" { + $Result = Add-NetboxDCIMInterface -Device 444 -Name "TestInterface" -Mode 'Tagged' -Tagged_VLANs 1, 2, 3, 4 + + 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/interfaces/' + $Result.Headers.Keys.Count | Should -BeExactly 1 + $Result.Body | Should -Be '{"mode":200,"name":"TestInterface","device":444,"tagged_vlans":[1,2,3,4]}' + } + + It "Should throw for invalid mode" { + { + Add-NetboxDCIMInterface -Device 321 -Name "Test123" -Mode 'Fake' + } | Should -Throw + } + + It "Should throw for out of range VLAN" { + { + Add-NetboxDCIMInterface -Device 321 -Name "Test123" -Untagged_VLAN 4100 + } | Should -Throw + } + } + + + Mock -CommandName "Get-NetboxDCIMInterface" -ModuleName "NetboxPS" -MockWith { + return [pscustomobject]@{ + 'Id' = $Id + } + } + + Context -Name "Set-NetboxDCIMInterface" -Fixture { + It "Should set an interface to a new name" { + $Result = Set-NetboxDCIMInterface -Id 123 -Name "TestInterface" + + Assert-VerifiableMock + Assert-MockCalled -CommandName 'Get-NetboxDCIMInterface' -Times 1 -Exactly -Scope 'It' + 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/interfaces/123/' + $Result.Headers.Keys.Count | Should -BeExactly 1 + $Result.Body | Should -Be '{"name":"TestInterface"}' + } + + It "Should set multiple interfaces to a new name" { + $Result = Set-NetboxDCIMInterface -Id 456, 789 -Name "TestInterface" + + Assert-VerifiableMock + Assert-MockCalled -CommandName 'Get-NetboxDCIMInterface' -Times 2 -Exactly -Scope 'It' + 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/interfaces/456/', 'https://netbox.domain.com/api/dcim/interfaces/789/' + $Result.Headers.Keys.Count | Should -BeExactly 2 + $Result.Body | Should -Be '{"name":"TestInterface"}', '{"name":"TestInterface"}' + } + + It "Should set multiple interfaces to a new name from the pipeline" { + $Result = @( + [pscustomobject]@{ + 'Id' = 1234 + }, + [pscustomobject]@{ + 'Id' = 4231 + } + ) | Set-NetboxDCIMInterface -Name "TestInterface" + + Assert-VerifiableMock + Assert-MockCalled -CommandName 'Get-NetboxDCIMInterface' -Times 2 -Exactly -Scope 'It' + 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/interfaces/1234/', 'https://netbox.domain.com/api/dcim/interfaces/4231/' + $Result.Headers.Keys.Count | Should -BeExactly 2 + $Result.Body | Should -Be '{"name":"TestInterface"}', '{"name":"TestInterface"}' + } + + It "Should throw for invalid form factor" { + { + Set-NetboxDCIMInterface -Id 1234 -Form_Factor 'fake' + } | Should -Throw + } + } + + Context -Name "Remove-NetboxDCIMInterface" -Fixture { + It "Should remove an interface" { + $Result = Remove-NetboxDCIMInterface -Id 10 -Force + + Assert-VerifiableMock + Assert-MockCalled -CommandName 'Get-NetboxDCIMInterface' -Times 1 -Exactly -Scope 'It' + + $Result.Method | Should -Be 'DELETE' + $Result.URI | Should -Be 'https://netbox.domain.com/api/dcim/interfaces/10/' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should remove multiple interfaces" { + $Result = Remove-NetboxDCIMInterface -Id 10, 12 -Force + + Assert-VerifiableMock + Assert-MockCalled -CommandName 'Get-NetboxDCIMInterface' -Times 2 -Exactly -Scope 'It' + + $Result.Method | Should -Be 'DELETE', 'DELETE' + $Result.URI | Should -Be 'https://netbox.domain.com/api/dcim/interfaces/10/', 'https://netbox.domain.com/api/dcim/interfaces/12/' + $Result.Headers.Keys.Count | Should -BeExactly 2 + } + + It "Should remove an interface from the pipeline" { + $Result = Get-NetboxDCIMInterface -Id 20 | Remove-NetboxDCIMInterface -Force + + Assert-VerifiableMock + Assert-MockCalled -CommandName 'Get-NetboxDCIMInterface' -Times 2 -Exactly -Scope 'It' + + $Result.Method | Should -Be 'DELETE' + $Result.URI | Should -Be 'https://netbox.domain.com/api/dcim/interfaces/20/' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should remove mulitple interfaces from the pipeline" { + $Result = @( + [pscustomobject]@{ + 'Id' = 30 + }, + [pscustomobject]@{ + 'Id' = 40 + } + ) | Remove-NetboxDCIMInterface -Force + + Assert-VerifiableMock + Assert-MockCalled -CommandName 'Get-NetboxDCIMInterface' -Times 2 -Exactly -Scope 'It' + + $Result.Method | Should -Be 'DELETE', 'DELETE' + $Result.URI | Should -Be 'https://netbox.domain.com/api/dcim/interfaces/30/', 'https://netbox.domain.com/api/dcim/interfaces/40/' + $Result.Headers.Keys.Count | Should -BeExactly 2 + } + } + + + Context -Name "Get-NetboxDCIMInterfaceConnection" -Fixture { + It "Should request the default number of interface connections" { + $Result = Get-NetboxDCIMInterfaceConnection + + Assert-VerifiableMock + Assert-MockCalled -CommandName 'Invoke-RestMethod' -Times 1 -Scope 'It' -Exactly + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/interface-connections/' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request with a limit and offset" { + $Result = Get-NetboxDCIMInterfaceConnection -Limit 10 -Offset 100 + + Assert-VerifiableMock + Assert-MockCalled -CommandName 'Invoke-RestMethod' -Times 1 -Scope 'It' -Exactly + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/interface-connections/?offset=100&limit=10' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request connected interfaces" { + $Result = Get-NetboxDCIMInterfaceConnection -Connection_Status 'Connected' + + Assert-VerifiableMock + Assert-MockCalled -CommandName 'Invoke-RestMethod' -Times 1 -Scope 'It' -Exactly + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -BeExactly 'https://netbox.domain.com/api/dcim/interface-connections/?connection_status=True' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should throw for an invalid connection status" { + { + Get-NetboxDCIMInterfaceConnection -Connection_Status 'Fake' + } | 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 + } + } + } +} + + + + + + + + + + + + + + + + + diff --git a/dist/Tests/DCIM.Platforms.Tests.ps1 b/dist/Tests/DCIM.Platforms.Tests.ps1 new file mode 100644 index 0000000..a909bc6 --- /dev/null +++ b/dist/Tests/DCIM.Platforms.Tests.ps1 @@ -0,0 +1,121 @@ +<# + .NOTES + =========================================================================== + Created with: SAPIEN Technologies, Inc., PowerShell Studio 2018 v5.5.152 + Created on: 5/25/2018 1:03 PM + Created by: Ben Claussen + Organization: NEOnet + Filename: DCIM.Platforms.Tests.ps1 + =========================================================================== + .DESCRIPTION + A description of the file. +#> + +Import-Module Pester +Remove-Module NetboxPS -Force -ErrorAction SilentlyContinue + +$ModulePath = "$PSScriptRoot\..\dist\NetboxPS.psd1" + +if (Test-Path $ModulePath) { + Import-Module $ModulePath -ErrorAction Stop +} + +Describe -Name "DCIM Platforms Tests" -Tag 'DCIM', 'platforms' -Fixture { + Mock -CommandName 'CheckNetboxIsConnected' -Verifiable -ModuleName 'NetboxPS' -MockWith { + return $true + } + + Mock -CommandName 'Invoke-RestMethod' -Verifiable -ModuleName 'NetboxPS' -MockWith { + # Return a hashtable of the items we would normally pass to Invoke-RestMethod + return [ordered]@{ + 'Method' = $Method + 'Uri' = $Uri + 'Headers' = $Headers + 'Timeout' = $Timeout + 'ContentType' = $ContentType + 'Body' = $Body + } + } + + Mock -CommandName 'Get-NetboxCredential' -Verifiable -ModuleName 'NetboxPS' -MockWith { + return [PSCredential]::new('notapplicable', (ConvertTo-SecureString -String "faketoken" -AsPlainText -Force)) + } + + Mock -CommandName 'Get-NetboxHostname' -Verifiable -ModuleName 'NetboxPS' -MockWith { + return 'netbox.domain.com' + } + + InModuleScope -ModuleName 'NetboxPS' -ScriptBlock { + Context -Name "Get-NetboxDCIMPlatform" -Fixture { + It "Should request the default number of platforms" { + $Result = Get-NetboxDCIMPlatform + + Assert-VerifiableMock + Assert-MockCalled -CommandName 'Invoke-RestMethod' -Times 1 -Scope 'It' -Exactly + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/platforms/' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request with a limit and offset" { + $Result = Get-NetboxDCIMPlatform -Limit 10 -Offset 100 + + Assert-VerifiableMock + Assert-MockCalled -CommandName 'Invoke-RestMethod' -Times 1 -Scope 'It' -Exactly + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/platforms/?offset=100&limit=10' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request with a platform name" { + $Result = Get-NetboxDCIMPlatform -Name "Windows Server 2016" + + Assert-VerifiableMock + Assert-MockCalled -CommandName 'Invoke-RestMethod' -Times 1 -Scope 'It' -Exactly + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/platforms/?name=Windows+Server+2016' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request a platform by manufacturer" { + $Result = Get-NetboxDCIMPlatform -Manufacturer 'Cisco' + + Assert-VerifiableMock + Assert-MockCalled -CommandName 'Invoke-RestMethod' -Times 1 -Scope 'It' -Exactly + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -BeExactly 'https://netbox.domain.com/api/dcim/platforms/?manufacturer=Cisco' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request a platform by ID" { + $Result = Get-NetboxDCIMPlatform -Id 10 + + Assert-VerifiableMock + Assert-MockCalled -CommandName 'Invoke-RestMethod' -Times 1 -Scope 'It' -Exactly + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -BeExactly 'https://netbox.domain.com/api/dcim/platforms/10/' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request multiple platforms by ID" { + $Result = Get-NetboxDCIMPlatform -Id 10, 20 + + Assert-VerifiableMock + Assert-MockCalled -CommandName 'Invoke-RestMethod' -Times 2 -Scope 'It' -Exactly + + $Result.Method | Should -Be 'GET', 'GET' + $Result.Uri | Should -BeExactly 'https://netbox.domain.com/api/dcim/platforms/10/', 'https://netbox.domain.com/api/dcim/platforms/20/' + $Result.Headers.Keys.Count | Should -BeExactly 2 + } + } + } +} + + + + diff --git a/dist/Tests/DCIM.Tests.ps1 b/dist/Tests/DCIM.Tests.ps1 new file mode 100644 index 0000000..a5eb14a --- /dev/null +++ b/dist/Tests/DCIM.Tests.ps1 @@ -0,0 +1,315 @@ +<# + .NOTES + =========================================================================== + Created with: SAPIEN Technologies, Inc., PowerShell Studio 2018 v5.5.152 + Created on: 5/22/2018 4:48 PM + Created by: Ben Claussen + Organization: NEOnet + Filename: DCIM.Tests.ps1 + =========================================================================== + .DESCRIPTION + DCIM tests. +#> + +Import-Module Pester +Remove-Module NetboxPS -Force -ErrorAction SilentlyContinue + +$ModulePath = "$PSScriptRoot\..\dist\NetboxPS.psd1" + +if (Test-Path $ModulePath) { + Import-Module $ModulePath -ErrorAction Stop +} + +Describe -Name "DCIM Tests" -Tag 'DCIM' -Fixture { + Mock -CommandName 'CheckNetboxIsConnected' -Verifiable -ModuleName 'NetboxPS' -MockWith { + return $true + } + + Mock -CommandName 'Invoke-RestMethod' -Verifiable -ModuleName 'NetboxPS' -MockWith { + # Return a hashtable of the items we would normally pass to Invoke-RestMethod + return [ordered]@{ + 'Method' = $Method + 'Uri' = $Uri + 'Headers' = $Headers + 'Timeout' = $Timeout + 'ContentType' = $ContentType + 'Body' = $Body + } + } + + Mock -CommandName 'Get-NetboxCredential' -Verifiable -ModuleName 'NetboxPS' -MockWith { + return [PSCredential]::new('notapplicable', (ConvertTo-SecureString -String "faketoken" -AsPlainText -Force)) + } + + Mock -CommandName 'Get-NetboxHostname' -Verifiable -ModuleName 'NetboxPS' -MockWith { + return 'netbox.domain.com' + } + + InModuleScope -ModuleName 'NetboxPS' -ScriptBlock { + $script:NetboxConfig.Choices.DCIM = (Get-Content "$PSScriptRoot\DCIMChoices.json" -ErrorAction Stop | ConvertFrom-Json) + + Context -Name "Get-NetboxDCIMDevice" -Fixture { + It "Should request the default number of devices" { + $Result = Get-NetboxDCIMDevice + + Assert-VerifiableMock + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/devices/' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request with a limit and offset" { + $Result = Get-NetboxDCIMDevice -Limit 10 -Offset 100 + + Assert-VerifiableMock + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/devices/?offset=100&limit=10' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request with a query" { + $Result = Get-NetboxDCIMDevice -Query 'testdevice' + + Assert-VerifiableMock + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/devices/?q=testdevice' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request with an escaped query" { + $Result = Get-NetboxDCIMDevice -Query 'test device' + + Assert-VerifiableMock + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/devices/?q=test+device' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request with a name" { + $Result = Get-NetboxDCIMDevice -Name 'testdevice' + + Assert-VerifiableMock + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/devices/?name=testdevice' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request with a single ID" { + $Result = Get-NetboxDCIMDevice -Id 10 + + Assert-VerifiableMock + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/devices/10/' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request with multiple IDs" { + $Result = Get-NetboxDCIMDevice -Id 10, 12, 15 + + Assert-VerifiableMock + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/devices/?id__in=10,12,15' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request a status" { + $Result = Get-NetboxDCIMDevice -Status 'Active' + + Assert-VerifiableMock + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/devices/?status=1' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should throw for an invalid status" { + { + Get-NetboxDCIMDevice -Status 'Fake' + } | Should -Throw + } + + It "Should request devices that are a PDU" { + $Result = Get-NetboxDCIMDevice -Is_PDU $True + + Assert-VerifiableMock + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -BeExactly 'https://netbox.domain.com/api/dcim/devices/?is_pdu=True' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + } + + Context -Name "Get-NetboxDCIMDeviceType" -Fixture { + It "Should request the default number of devices types" { + $Result = Get-NetboxDCIMDeviceType + + Assert-VerifiableMock + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/device-types/' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request with a limit and offset" { + $Result = Get-NetboxDCIMDeviceType -Limit 10 -Offset 100 + + Assert-VerifiableMock + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/device-types/?offset=100&limit=10' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request with a query" { + $Result = Get-NetboxDCIMDeviceType -Query 'testdevice' + + Assert-VerifiableMock + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/device-types/?q=testdevice' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request with an escaped query" { + $Result = Get-NetboxDCIMDeviceType -Query 'test device' + + Assert-VerifiableMock + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/device-types/?q=test+device' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request with a slug" { + $Result = Get-NetboxDCIMDeviceType -Slug 'testdevice' + + Assert-VerifiableMock + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/device-types/?slug=testdevice' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request with a single ID" { + $Result = Get-NetboxDCIMDeviceType -Id 10 + + Assert-VerifiableMock + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/device-types/10/' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request with multiple IDs" { + $Result = Get-NetboxDCIMDeviceType -Id 10, 12, 15 + + Assert-VerifiableMock + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/device-types/?id__in=10,12,15' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request a device type that is PDU" { + $Result = Get-NetboxDCIMDeviceType -Is_PDU $true + + Assert-VerifiableMock + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/device-types/?is_pdu=True' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + } + + Context -Name "Get-NetboxDCIMDeviceRole" -Fixture { + It "Should request the default number of devices types" { + $Result = Get-NetboxDCIMDeviceRole + + Assert-VerifiableMock + Assert-MockCalled -CommandName "Invoke-RestMethod" -Times 1 -Scope 'It' -Exactly + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/device-roles/' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request with a limit and offset" { + $Result = Get-NetboxDCIMDeviceRole -Limit 10 -Offset 100 + + Assert-VerifiableMock + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/device-roles/?offset=100&limit=10' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request with a slug" { + $Result = Get-NetboxDCIMDeviceRole -Slug 'testdevice' + + Assert-VerifiableMock + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/device-roles/?slug=testdevice' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request with a name" { + $Result = Get-NetboxDCIMDeviceRole -Name 'TestRole' + + Assert-VerifiableMock + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/device-roles/?name=TestRole' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should request those that are VM role" { + $Result = Get-NetboxDCIMDeviceRole -VM_Role $true + + Assert-VerifiableMock + + $Result.Method | Should -Be 'GET' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/dcim/device-roles/?vm_role=True' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + } + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dist/Tests/Helpers.Tests.ps1 b/dist/Tests/Helpers.Tests.ps1 index 7195980..63587eb 100644 --- a/dist/Tests/Helpers.Tests.ps1 +++ b/dist/Tests/Helpers.Tests.ps1 @@ -244,11 +244,9 @@ Describe "Helpers tests" -Tag 'Core', 'Helpers' -Fixture { } Context -Name "Validating choices" -Fixture { - $script:NetboxConfig.Choices.Virtualization = (Get-Content "$PSScriptRoot\VirtualizationChoices.json" -ErrorAction Stop | ConvertFrom-Json) - $script:NetboxConfig.Choices.IPAM = (Get-Content "$PSScriptRoot\IPAMChoices.json" -ErrorAction Stop | ConvertFrom-Json) - Context -Name "Virtualization choices" -Fixture { $MajorObject = 'Virtualization' + $script:NetboxConfig.Choices.Virtualization = (Get-Content "$PSScriptRoot\VirtualizationChoices.json" -ErrorAction Stop | ConvertFrom-Json) It "Should return a valid integer for status when provided a name" { $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName 'virtual-machine:status' -ProvidedValue 'Active' @@ -273,6 +271,7 @@ Describe "Helpers tests" -Tag 'Core', 'Helpers' -Fixture { Context -Name "IPAM choices" -Fixture { $MajorObject = 'IPAM' + $script:NetboxConfig.Choices.IPAM = (Get-Content "$PSScriptRoot\IPAMChoices.json" -ErrorAction Stop | ConvertFrom-Json) Context -Name "aggregate:family" -Fixture { $ChoiceName = 'aggregate:family' @@ -467,10 +466,248 @@ Describe "Helpers tests" -Tag 'Core', 'Helpers' -Fixture { } } - + Context -Name "DCIM choices" -Fixture { + $MajorObject = 'DCIM' + $script:NetboxConfig.Choices.DCIM = (Get-Content "$PSScriptRoot\DCIMChoices.json" -ErrorAction Stop | ConvertFrom-Json) + + Context -Name "device:face" -Fixture { + $ChoiceName = 'device:face' + + It "Should return a valid integer when provided a name" { + $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 'Front' + + $Result | Should -BeOfType [uint16] + $Result | Should -BeExactly 0 + } + + It "Should return a valid integer when provided an integer" { + $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 1 + + $Result | Should -BeOfType [uint16] + $Result | Should -BeExactly 1 + } + + It "Should throw because of an invalid choice" { + { + ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 'fake' + } | Should -Throw + } + } + + Context -Name "device:status" -Fixture { + $ChoiceName = 'device:status' + + It "Should return a valid integer when provided a name" { + $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 'Active' + + $Result | Should -BeOfType [uint16] + $Result | Should -BeExactly 1 + } + + It "Should return a valid integer when provided an integer" { + $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 0 + + $Result | Should -BeOfType [uint16] + $Result | Should -BeExactly 0 + } + + It "Should throw because of an invalid choice" { + { + ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 'fake' + } | Should -Throw + } + } + + Context -Name "console-port:connection_status" -Fixture { + $ChoiceName = 'console-port:connection_status' + + It "Should return a valid string when provided a name" { + $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 'Planned' + + $Result | Should -BeOfType [bool] + $Result | Should -Be $false + } + + It "Should return a valid string when provided a string" { + $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 'false' + + $Result | Should -BeOfType [bool] + $Result | Should -Be $false + } + + It "Should return a valid string when provided a boolean" { + $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue $true + + $Result | Should -BeOfType [bool] + $Result | Should -Be $true + } + + It "Should throw because of an invalid choice" { + { + ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 'fake' + } | Should -Throw + } + } + + Context -Name "interface:form_factor" -Fixture { + $ChoiceName = 'interface:form_factor' + + It "Should return a valid integer when provided a name" { + $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue '10GBASE-CX4 (10GE)' + + $Result | Should -BeOfType [uint16] + $Result | Should -BeExactly 1170 + } + + It "Should return a valid integer when provided an integer" { + $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 1500 + + $Result | Should -BeOfType [uint16] + $Result | Should -BeExactly 1500 + } + + It "Should throw because of an invalid choice" { + { + ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 'fake' + } | Should -Throw + } + } + + Context -Name "interface-connection:connection_status" -Fixture { + $ChoiceName = 'interface-connection:connection_status' + + It "Should return a valid string when provided a name" { + $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 'Planned' + + $Result | Should -BeOfType [bool] + $Result | Should -Be $false + } + + It "Should return a valid string when provided a string" { + $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 'false' + + $Result | Should -BeOfType [bool] + $Result | Should -Be $false + } + + It "Should return a valid string when provided a boolean" { + $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue $true + + $Result | Should -BeOfType [bool] + $Result | Should -Be $true + } + + It "Should throw because of an invalid choice" { + { + ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 'fake' + } | Should -Throw + } + } + + Context -Name "interface-template:form_factor" -Fixture { + $ChoiceName = 'interface-template:form_factor' + + It "Should return a valid integer when provided a name" { + $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue '10GBASE-CX4 (10GE)' + + $Result | Should -BeOfType [uint16] + $Result | Should -BeExactly 1170 + } + + It "Should return a valid integer when provided an integer" { + $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 1500 + + $Result | Should -BeOfType [uint16] + $Result | Should -BeExactly 1500 + } + + It "Should throw because of an invalid choice" { + { + ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 'fake' + } | Should -Throw + } + } + + Context -Name "power-port:connection_status" -Fixture { + $ChoiceName = 'power-port:connection_status' + + It "Should return a valid string when provided a name" { + $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 'Planned' + + $Result | Should -BeOfType [bool] + $Result | Should -Be $false + } + + It "Should return a valid string when provided a string" { + $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 'false' + + $Result | Should -BeOfType [bool] + $Result | Should -Be $false + } + + It "Should return a valid string when provided a boolean" { + $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue $true + + $Result | Should -BeOfType [bool] + $Result | Should -Be $true + } + + It "Should throw because of an invalid choice" { + { + ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 'fake' + } | Should -Throw + } + } + + Context -Name "rack:type" -Fixture { + $ChoiceName = 'rack:type' + + It "Should return a valid integer when provided a name" { + $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue '2-post frame' + + $Result | Should -BeOfType [uint16] + $Result | Should -BeExactly 100 + } + + It "Should return a valid integer when provided an integer" { + $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 300 + + $Result | Should -BeOfType [uint16] + $Result | Should -BeExactly 300 + } + + It "Should throw because of an invalid choice" { + { + ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 'fake' + } | Should -Throw + } + } + + Context -Name "rack:width" -Fixture { + $ChoiceName = 'rack:width' + + It "Should return a valid integer when provided a name" { + $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue '19 inches' + + $Result | Should -BeOfType [uint16] + $Result | Should -BeExactly 19 + } + + It "Should return a valid integer when provided an integer" { + $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 23 + + $Result | Should -BeOfType [uint16] + $Result | Should -BeExactly 23 + } + + It "Should throw because of an invalid choice" { + { + ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 'fake' + } | Should -Throw + } + } + } } - - } } @@ -479,3 +716,11 @@ Describe "Helpers tests" -Tag 'Core', 'Helpers' -Fixture { + + + + + + + + diff --git a/dist/Tests/IPAM.Tests.ps1 b/dist/Tests/IPAM.Tests.ps1 index 438f342..e637f75 100644 --- a/dist/Tests/IPAM.Tests.ps1 +++ b/dist/Tests/IPAM.Tests.ps1 @@ -48,11 +48,7 @@ Describe -Name "IPAM tests" -Tag 'Ipam' -Fixture { InModuleScope -ModuleName 'NetboxPS' -ScriptBlock { $script:NetboxConfig.Choices.IPAM = (Get-Content "$PSScriptRoot\IPAMChoices.json" -ErrorAction Stop | ConvertFrom-Json) - - Context -Name "VerifyIPAMChoices" -Fixture { - #It "Should return a valid integer" - } - + Context -Name "Get-NetboxIPAMAggregate" -Fixture { It "Should request the default number of aggregates" { $Result = Get-NetboxIPAMAggregate @@ -388,18 +384,18 @@ Describe -Name "IPAM tests" -Tag 'Ipam' -Fixture { } Context -Name "Remove-NetboxIPAMAddress" -Fixture { - It "Should remove a single IP" { - Mock -CommandName "Get-NetboxIPAMAddress" -ModuleName NetboxPS -MockWith { - return @{ - 'address' = '10.1.1.1/24' - 'id' = 4109 - } + Mock -CommandName "Get-NetboxIPAMAddress" -ModuleName NetboxPS -MockWith { + return @{ + 'address' = "10.1.1.1/$Id" + 'id' = $id } - - $Result = Remove-NetboxIPAMAddress -Id '4109' -Force + } + + It "Should remove a single IP" { + $Result = Remove-NetboxIPAMAddress -Id 4109 -Force Assert-VerifiableMock - Assert-MockCalled -CommandName "Get-NetboxIPAMAddress" -Times 1 + Assert-MockCalled -CommandName "Get-NetboxIPAMAddress" -Times 1 -Scope 'It' -Exactly $Result.Method | Should -Be 'DELETE' $Result.Uri | Should -Be 'https://netbox.domain.com/api/ipam/ip-addresses/4109/' @@ -407,24 +403,43 @@ Describe -Name "IPAM tests" -Tag 'Ipam' -Fixture { $Result.Body | Should -Be $null } - It "Should remove multiple IPs" { - Mock -CommandName "Get-NetboxIPAMAddress" -ModuleName NetboxPS -MockWith { - return @( - @{ - 'address' = '10.1.1.1/24' - 'id' = 4109 - }, - @{ - 'address' = '10.1.1.2/24' - 'id' = 4110 - } - ) - } + It "Should remove a single IP from the pipeline" { + $Result = [pscustomobject]@{ + 'id' = 4110 + } | Remove-NetboxIPAMAddress -Force + Assert-VerifiableMock + Assert-MockCalled -CommandName "Get-NetboxIPAMAddress" -Times 1 -Scope 'It' -Exactly + + $Result.Method | Should -Be 'DELETE' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/ipam/ip-addresses/4110/' + $Result.Headers.Keys.Count | Should -BeExactly 1 + $Result.Body | Should -Be $null + } + + It "Should remove multiple IPs" { $Result = Remove-NetboxIPAMAddress -Id 4109, 4110 -Force Assert-VerifiableMock - Assert-MockCalled -CommandName "Get-NetboxIPAMAddress" -Times 2 + Assert-MockCalled -CommandName "Get-NetboxIPAMAddress" -Times 2 -Scope 'It' -Exactly + + $Result.Method | Should -Be 'DELETE', 'DELETE' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/ipam/ip-addresses/4109/', 'https://netbox.domain.com/api/ipam/ip-addresses/4110/' + $Result.Headers.Keys.Count | Should -BeExactly 2 + } + + It "Should remove multiple IPs from the pipeline" { + $Result = @( + [pscustomobject]@{ + 'id' = 4109 + }, + [pscustomobject]@{ + 'id' = 4110 + } + ) | Remove-NetboxIPAMAddress -Force + + Assert-VerifiableMock + Assert-MockCalled -CommandName "Get-NetboxIPAMAddress" -Times 2 -Scope 'It' -Exactly $Result.Method | Should -Be 'DELETE', 'DELETE' $Result.Uri | Should -Be 'https://netbox.domain.com/api/ipam/ip-addresses/4109/', 'https://netbox.domain.com/api/ipam/ip-addresses/4110/' @@ -433,18 +448,18 @@ Describe -Name "IPAM tests" -Tag 'Ipam' -Fixture { } Context -Name "Set-NetboxIPAMAddress" -Fixture { - It "Should set an IP with a new status" { - Mock -CommandName "Get-NetboxIPAMAddress" -ModuleName NetboxPS -MockWith { - return @{ - 'address' = '10.1.1.1/24' - 'id' = 4109 - } + Mock -CommandName "Get-NetboxIPAMAddress" -ModuleName NetboxPS -MockWith { + return @{ + 'address' = '10.1.1.1/24' + 'id' = $id } - - $Result = Set-NetboxIPAMAddress -Id '4109' -Status 2 -Force + } + + It "Should set an IP with a new status" { + $Result = Set-NetboxIPAMAddress -Id 4109 -Status 2 -Force Assert-VerifiableMock - Assert-MockCalled -CommandName "Get-NetboxIPAMAddress" -Times 1 + Assert-MockCalled -CommandName "Get-NetboxIPAMAddress" -Times 1 -Scope "It" -Exactly $Result.Method | Should -Be 'PATCH' $Result.Uri | Should -Be 'https://netbox.domain.com/api/ipam/ip-addresses/4109/' @@ -452,17 +467,62 @@ Describe -Name "IPAM tests" -Tag 'Ipam' -Fixture { $Result.Body | Should -Be '{"status":2}' } - It "Should set an IP with VRF, Tenant, and Description" { - $Result = Set-NetboxIPAMAddress -Id 4109 -VRF 10 -Tenant 14 -Description 'Test description' -Force + It "Should set an IP from the pipeline" { + $Result = [pscustomobject]@{ + 'Id' = 4501 + } | Set-NetboxIPAMAddress -VRF 10 -Tenant 14 -Description 'Test description' -Force Assert-VerifiableMock - Assert-MockCalled -CommandName "Get-NetboxIPAMAddress" -Times 1 + Assert-MockCalled -CommandName "Get-NetboxIPAMAddress" -Times 1 -Scope "It" -Exactly $Result.Method | Should -Be 'PATCH' - $Result.Uri | Should -Be 'https://netbox.domain.com/api/ipam/ip-addresses/4109/' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/ipam/ip-addresses/4501/' $Result.Headers.Keys.Count | Should -BeExactly 1 $Result.Body | Should -Be '{"vrf":10,"description":"Test description","tenant":14}' } + + It "Should set mulitple IPs to a new status" { + $Result = Set-NetboxIPAMAddress -Id 4109, 4555 -Status 2 -Force + + Assert-VerifiableMock + Assert-MockCalled -CommandName "Get-NetboxIPAMAddress" -Times 2 -Scope "It" -Exactly + + $Result.Method | Should -Be 'PATCH', 'PATCH' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/ipam/ip-addresses/4109/', 'https://netbox.domain.com/api/ipam/ip-addresses/4555/' + $Result.Headers.Keys.Count | Should -BeExactly 2 + $Result.Body | Should -Be '{"status":2}', '{"status":2}' + } + + It "Should set an IP with VRF, Tenant, and Description" { + $Result = Set-NetboxIPAMAddress -Id 4110 -VRF 10 -Tenant 14 -Description 'Test description' -Force + + Assert-VerifiableMock + Assert-MockCalled -CommandName "Get-NetboxIPAMAddress" -Times 1 -Scope "It" -Exactly + + $Result.Method | Should -Be 'PATCH' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/ipam/ip-addresses/4110/' + $Result.Headers.Keys.Count | Should -BeExactly 1 + $Result.Body | Should -Be '{"vrf":10,"description":"Test description","tenant":14}' + } + + It "Should set multiple IPs from the pipeline" { + $Result = @( + [pscustomobject]@{ + 'Id' = 4501 + }, + [pscustomobject]@{ + 'Id' = 4611 + } + ) | Set-NetboxIPAMAddress -Status 2 -Force + + Assert-VerifiableMock + Assert-MockCalled -CommandName "Get-NetboxIPAMAddress" -Times 2 -Scope "It" -Exactly + + $Result.Method | Should -Be 'PATCH', 'PATCH' + $Result.Uri | Should -Be 'https://netbox.domain.com/api/ipam/ip-addresses/4501/', 'https://netbox.domain.com/api/ipam/ip-addresses/4611/' + $Result.Headers.Keys.Count | Should -BeExactly 2 + $Result.Body | Should -Be '{"status":2}', '{"status":2}' + } } } } diff --git a/dist/Tests/Virtualization.Tests.ps1 b/dist/Tests/Virtualization.Tests.ps1 index 2dcb9cd..327060a 100644 --- a/dist/Tests/Virtualization.Tests.ps1 +++ b/dist/Tests/Virtualization.Tests.ps1 @@ -128,6 +128,10 @@ Describe -Name "Virtualization tests" -Tag 'Virtualization' -Fixture { $Result.Uri | Should -Be 'https://netbox.domain.com/api/virtualization/virtual-machines/?status=1' $Result.Headers.Keys.Count | Should -BeExactly 1 } + + It "Should throw for an invalid status" { + { Get-NetboxVirtualMachine -Status 'Fake' } | Should -Throw + } } Context -Name "Get-NetboxVirtualMachineInterface" -Fixture { @@ -334,9 +338,9 @@ Describe -Name "Virtualization tests" -Tag 'Virtualization' -Fixture { } } - Context -Name "Add-NetboxVirtualInterface" -Fixture { + Context -Name "Add-NetboxVirtualMachineInterface" -Fixture { It "Should add a basic interface" { - $Result = Add-NetboxVirtualInterface -Name 'Ethernet0' -Virtual_Machine 10 + $Result = Add-NetboxVirtualMachineInterface -Name 'Ethernet0' -Virtual_Machine 10 Assert-VerifiableMock @@ -347,7 +351,7 @@ Describe -Name "Virtualization tests" -Tag 'Virtualization' -Fixture { } It "Should add an interface with a MAC, MTU, and Description" { - $Result = Add-NetboxVirtualInterface -Name 'Ethernet0' -Virtual_Machine 10 -Mac_Address '11:22:33:44:55:66' -MTU 1500 -Description "Test description" + $Result = Add-NetboxVirtualMachineInterface -Name 'Ethernet0' -Virtual_Machine 10 -Mac_Address '11:22:33:44:55:66' -MTU 1500 -Description "Test description" Assert-VerifiableMock @@ -358,18 +362,20 @@ Describe -Name "Virtualization tests" -Tag 'Virtualization' -Fixture { } } - Context -Name "Set-NetboxVirtualMachine" -Fixture { - Mock -CommandName "Get-NetboxVirtualMachine" -ModuleName NetboxPS -MockWith { - return @{ - 'Id' = 1234 - 'Name' = 'TestVM' - } + + Mock -CommandName "Get-NetboxVirtualMachine" -ModuleName NetboxPS -MockWith { + return [pscustomobject]@{ + 'Id' = $Id + 'Name' = $Name } - + } + + Context -Name "Set-NetboxVirtualMachine" -Fixture { It "Should set a VM to a new name" { $Result = Set-NetboxVirtualMachine -Id 1234 -Name 'newtestname' -Force Assert-VerifiableMock + Assert-MockCalled -CommandName 'Get-NetboxVirtualMachine' -Times 1 -Exactly -Scope 'It' $Result.Method | Should -Be 'PATCH' $Result.URI | Should -Be 'https://netbox.domain.com/api/virtualization/virtual-machines/1234/' @@ -381,6 +387,7 @@ Describe -Name "Virtualization tests" -Tag 'Virtualization' -Fixture { $Result = Set-NetboxVirtualMachine -Id 1234 -Name 'newtestname' -Cluster 10 -Platform 15 -Status 'Offline' -Force Assert-VerifiableMock + Assert-MockCalled -CommandName 'Get-NetboxVirtualMachine' -Times 1 -Exactly -Scope 'It' $Result.Method | Should -Be 'PATCH' $Result.URI | Should -Be 'https://netbox.domain.com/api/virtualization/virtual-machines/1234/' @@ -392,17 +399,19 @@ Describe -Name "Virtualization tests" -Tag 'Virtualization' -Fixture { { Set-NetboxVirtualMachine -Id 1234 -Status 'Fake' -Force } | Should -Throw Assert-VerifiableMock + Assert-MockCalled -CommandName 'Get-NetboxVirtualMachine' -Times 0 -Exactly -Scope 'It' + } + } + + + Mock -CommandName "Get-NetboxVirtualMachineInterface" -ModuleName NetboxPS -MockWith { + return [pscustomobject]@{ + 'Id' = $Id + 'Name' = $Name } } Context -Name "Set-NetboxVirtualMachineInterface" -Fixture { - Mock -CommandName "Get-NetboxVirtualMachineInterface" -ModuleName NetboxPS -MockWith { - return @{ - 'Id' = 1234 - 'Name' = 'TestVM' - } - } - It "Should set an interface to a new name" { $Result = Set-NetboxVirtualMachineInterface -Id 1234 -Name 'newtestname' -Force @@ -437,15 +446,6 @@ Describe -Name "Virtualization tests" -Tag 'Virtualization' -Fixture { } It "Should set multiple interfaces to a new name" { - Mock -CommandName "Get-NetboxVirtualMachineInterface" -ModuleName NetboxPS -MockWith { - return @( - @{ - 'Id' = $Id - 'Name' = 'TestVM' - } - ) - } - $Result = Set-NetboxVirtualMachineInterface -Id 1234, 4321 -Name 'newtestname' -Force Assert-VerifiableMock @@ -456,6 +456,78 @@ Describe -Name "Virtualization tests" -Tag 'Virtualization' -Fixture { $Result.Headers.Keys.Count | Should -BeExactly 2 $Result.Body | Should -Be '{"name":"newtestname"}', '{"name":"newtestname"}' } + + It "Should set multiple interfaces to a new name from the pipeline" { + $Result = @( + [pscustomobject]@{ + 'Id' = 4123 + }, + [pscustomobject]@{ + 'Id' = 4321 + } + ) | Set-NetboxVirtualMachineInterface -Name 'newtestname' -Force + + Assert-VerifiableMock + Assert-MockCalled -CommandName Get-NetboxVirtualMachineInterface -Times 2 -Scope 'It' -Exactly + + $Result.Method | Should -Be 'PATCH', 'PATCH' + $Result.URI | Should -Be 'https://netbox.domain.com/api/virtualization/interfaces/4123/', 'https://netbox.domain.com/api/virtualization/interfaces/4321/' + $Result.Headers.Keys.Count | Should -BeExactly 2 + $Result.Body | Should -Be '{"name":"newtestname"}', '{"name":"newtestname"}' + } + } + + Context -Name "Remove-NetboxVirtualMachine" -Fixture { + It "Should remove a single VM" { + $Result = Remove-NetboxVirtualMachine -Id 4125 -Force + + Assert-VerifiableMock + Assert-MockCalled -CommandName 'Get-NetboxVirtualMachine' -Times 1 -Exactly -Scope 'It' + + $Result.Method | Should -Be 'DELETE' + $Result.URI | Should -Be 'https://netbox.domain.com/api/virtualization/virtual-machines/4125/' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should remove mulitple VMs" { + $Result = Remove-NetboxVirtualMachine -Id 4125, 4132 -Force + + Assert-VerifiableMock + Assert-MockCalled -CommandName 'Get-NetboxVirtualMachine' -Times 2 -Exactly -Scope 'It' + + $Result.Method | Should -Be 'DELETE', 'DELETE' + $Result.URI | Should -Be 'https://netbox.domain.com/api/virtualization/virtual-machines/4125/', 'https://netbox.domain.com/api/virtualization/virtual-machines/4132/' + $Result.Headers.Keys.Count | Should -BeExactly 2 + } + + It "Should remove a VM from the pipeline" { + $Result = Get-NetboxVirtualMachine -Id 4125 | Remove-NetboxVirtualMachine -Force + + Assert-VerifiableMock + Assert-MockCalled -CommandName 'Get-NetboxVirtualMachine' -Times 2 -Exactly -Scope 'It' + + $Result.Method | Should -Be 'DELETE' + $Result.URI | Should -Be 'https://netbox.domain.com/api/virtualization/virtual-machines/4125/' + $Result.Headers.Keys.Count | Should -BeExactly 1 + } + + It "Should remove multiple VMs from the pipeline" { + $Result = @( + [pscustomobject]@{ + 'Id' = 4125 + }, + [pscustomobject]@{ + 'Id' = 4132 + } + ) | Remove-NetboxVirtualMachine -Force + + Assert-VerifiableMock + Assert-MockCalled -CommandName 'Get-NetboxVirtualMachine' -Times 2 -Exactly -Scope 'It' + + $Result.Method | Should -Be 'DELETE', 'DELETE' + $Result.URI | Should -Be 'https://netbox.domain.com/api/virtualization/virtual-machines/4125/', 'https://netbox.domain.com/api/virtualization/virtual-machines/4132/' + $Result.Headers.Keys.Count | Should -BeExactly 2 + } } } }