diff --git a/Functions/Circuits/Circuits.ps1 b/Functions/Circuits/Circuits.ps1
index 2235cc3..913b99b 100644
--- a/Functions/Circuits/Circuits.ps1
+++ b/Functions/Circuits/Circuits.ps1
@@ -25,8 +25,9 @@ function Get-NetboxCircuitsChoices {
.NOTES
Additional information about the function.
#>
-
- [CmdletBinding()]
+
+ [CmdletBinding()]
+ [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "", Justification = "These are literally 'choices' in Netbox")]
param ()
$uriSegments = [System.Collections.ArrayList]::new(@('circuits', '_choices'))
diff --git a/Functions/Extras/Extras.ps1 b/Functions/Extras/Extras.ps1
index ecf8b30..63e7435 100644
--- a/Functions/Extras/Extras.ps1
+++ b/Functions/Extras/Extras.ps1
@@ -12,7 +12,8 @@
#>
function Get-NetboxExtrasChoices {
- [CmdletBinding()]
+ [CmdletBinding()]
+ [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "", Justification = "These are literally 'choices' in Netbox")]
param ()
$uriSegments = [System.Collections.ArrayList]::new(@('extras', '_choices'))
diff --git a/Functions/Helpers.ps1 b/Functions/Helpers.ps1
index 685fac7..5a259d7 100644
--- a/Functions/Helpers.ps1
+++ b/Functions/Helpers.ps1
@@ -145,7 +145,7 @@ function BuildURIComponents {
Write-Verbose "Building URI components"
- $URIParameters = [System.Collections.Hashtable]::new()
+ $URIParameters = @{}
foreach ($CmdletParameterName in $ParametersDictionary.Keys) {
if ($CmdletParameterName -in $CommonParameterNames) {
@@ -163,7 +163,7 @@ function BuildURIComponents {
# Check if there is one or more values for Id and build a URI or query as appropriate
if (@($ParametersDictionary[$CmdletParameterName]).Count -gt 1) {
Write-Verbose " Joining IDs for parameter"
- $URIParameters['id__in'] = $Id -join ','
+ $URIParameters['id__in'] = $ParametersDictionary[$CmdletParameterName] -join ','
} else {
Write-Verbose " Adding ID to segments"
[void]$uriSegments.Add($ParametersDictionary[$CmdletParameterName])
@@ -185,6 +185,7 @@ function BuildURIComponents {
function GetChoiceValidValues {
[CmdletBinding()]
+ [OutputType([System.Collections.ArrayList])]
param
(
[Parameter(Mandatory = $true)]
@@ -220,13 +221,16 @@ function ValidateChoice {
[string]$MajorObject,
[Parameter(Mandatory = $true)]
- [string]$ChoiceName
+ [string]$ChoiceName,
+
+ [Parameter(Mandatory = $true)]
+ [object]$ProvidedValue
)
$ValidValues = GetChoiceValidValues -MajorObject $MajorObject -Choice $ChoiceName
Write-Verbose "Validating $ChoiceName"
- Write-Verbose "Checking '$ProvidedValue' against $($ValidValues -join ', ')"
+ Write-Verbose "Checking '$ProvidedValue' against [$($ValidValues -join ', ')]"
if ($ValidValues -inotcontains $ProvidedValue) {
throw "Invalid value '$ProvidedValue' for '$ChoiceName'. Must be one of: $($ValidValues -join ', ')"
@@ -263,7 +267,7 @@ function GetNetboxAPIErrorBody {
}
function InvokeNetboxRequest {
- [CmdletBinding(SupportsShouldProcess = $true)]
+ [CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
diff --git a/Functions/IPAM/IPAM.ps1 b/Functions/IPAM/IPAM.ps1
index 0e42c2c..29ed607 100644
--- a/Functions/IPAM/IPAM.ps1
+++ b/Functions/IPAM/IPAM.ps1
@@ -13,6 +13,7 @@
function Get-NetboxIPAMChoices {
[CmdletBinding()]
+ [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "", Justification = "These are literally 'choices' in Netbox")]
param ()
$uriSegments = [System.Collections.ArrayList]::new(@('ipam', '_choices'))
@@ -115,12 +116,13 @@ function VerifyIPAMChoices {
[switch]$ServiceProtocol
)
- ValidateChoice -MajorObject 'IPAM' -ChoiceName $PSCmdlet.ParameterSetName
+ ValidateChoice -MajorObject 'IPAM' -ChoiceName $PSCmdlet.ParameterSetName -ProvidedValue $ProvidedValue
}
function Get-NetboxIPAMAggregate {
[CmdletBinding()]
+ [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "", Justification = "These are literally 'choices' in Netbox")]
param
(
[uint16]$Limit,
@@ -142,7 +144,7 @@ function Get-NetboxIPAMAggregate {
[switch]$Raw
)
- if ($Family -ne $null) {
+ if ($null -ne $Family) {
$PSBoundParameters.Family = VerifyIPAMChoices -ProvidedValue $Family -AggregateFamily
}
@@ -198,15 +200,15 @@ function Get-NetboxIPAMAddress {
[switch]$Raw
)
- if ($Family -ne $null) {
+ if ($null -ne $Family) {
$PSBoundParameters.Family = VerifyIPAMChoices -ProvidedValue $Family -IPAddressFamily
}
- if ($Status -ne $null) {
+ if ($null -ne $Status) {
$PSBoundParameters.Status = VerifyIPAMChoices -ProvidedValue $Status -IPAddressStatus
}
- if ($Role -ne $null) {
+ if ($null -ne $Role) {
$PSBoundParameters.Role = VerifyIPAMChoices -ProvidedValue $Role -IPAddressRole
}
@@ -395,11 +397,11 @@ function Get-NetboxIPAMPrefix {
[switch]$Raw
)
- if ($Family -ne $null) {
+ if ($null -ne $Family) {
$PSBoundParameters.Family = VerifyIPAMChoices -ProvidedValue $Family -PrefixFamily
}
- if ($Status -ne $null) {
+ if ($null -ne $Status) {
$PSBoundParameters.Status = VerifyIPAMChoices -ProvidedValue $Status -PrefixStatus
}
@@ -485,7 +487,7 @@ function Add-NetboxIPAMAddress {
$PSBoundParameters.Status = VerifyIPAMChoices -ProvidedValue $Status -IPAddressStatus
- if ($Role -ne $null) {
+ if ($null -ne $Role) {
$PSBoundParameters.Role = VerifyIPAMChoices -ProvidedValue $Role -IPAddressRole
}
@@ -558,7 +560,7 @@ function Set-NetboxIPAMAddress {
[string]$Address,
- [object]$Status = 'Active',
+ [object]$Status,
[uint16]$Tenant,
@@ -577,7 +579,9 @@ function Set-NetboxIPAMAddress {
[switch]$Force
)
- $PSBoundParameters.Status = VerifyIPAMChoices -ProvidedValue $Status -IPAddressStatus
+ if ($Status) {
+ $PSBoundParameters.Status = VerifyIPAMChoices -ProvidedValue $Status -IPAddressStatus
+ }
if ($Role) {
$PSBoundParameters.Role = VerifyIPAMChoices -ProvidedValue $Role -IPAddressRole
diff --git a/Functions/Setup.ps1 b/Functions/Setup.ps1
index b98177a..38de303 100644
--- a/Functions/Setup.ps1
+++ b/Functions/Setup.ps1
@@ -36,15 +36,17 @@ function GetNetboxConfigVariable {
}
function Set-NetboxHostName {
- [CmdletBinding()]
- param
- (
- [Parameter(Mandatory = $true)]
- [string]$Hostname
- )
-
- $script:NetboxConfig.Hostname = $Hostname.Trim()
- $script:NetboxConfig.Hostname
+ [CmdletBinding(ConfirmImpact = 'Medium',
+ SupportsShouldProcess = $true)]
+ [OutputType([string])]
+ param
+ (
+ [Parameter(Mandatory = $true)]
+ [string]$Hostname
+ )
+
+ $script:NetboxConfig.Hostname = $Hostname.Trim()
+ $script:NetboxConfig.Hostname
}
function Get-NetboxHostname {
@@ -52,7 +54,7 @@ function Get-NetboxHostname {
param ()
Write-Verbose "Getting Netbox hostname"
- if ($script:NetboxConfig.Hostname -eq $null) {
+ if ($null -eq $script:NetboxConfig.Hostname) {
throw "Netbox Hostname is not set! You may set it with Set-NetboxHostname -Hostname 'hostname.domain.tld'"
}
@@ -60,34 +62,37 @@ function Get-NetboxHostname {
}
function Set-NetboxCredentials {
- [CmdletBinding(DefaultParameterSetName = 'CredsObject')]
- [OutputType([pscredential], ParameterSetName = 'CredsObject')]
- [OutputType([pscredential], ParameterSetName = 'UserPass')]
- param
- (
- [Parameter(ParameterSetName = 'CredsObject',
- Mandatory = $true)]
- [pscredential]$Credentials,
-
- [Parameter(ParameterSetName = 'UserPass',
- Mandatory = $true)]
- [string]$Token
- )
-
- switch ($PsCmdlet.ParameterSetName) {
- 'CredsObject' {
- $script:NetboxConfig.Credentials = $Credentials
- break
- }
-
- 'UserPass' {
- $securePW = ConvertTo-SecureString $Token -AsPlainText -Force
- $script:NetboxConfig.Credentials = [System.Management.Automation.PSCredential]::new('notapplicable', $securePW)
- break
- }
- }
-
- $script:NetboxConfig.Credentials
+ [CmdletBinding(DefaultParameterSetName = 'CredsObject',
+ ConfirmImpact = 'Medium',
+ SupportsShouldProcess = $true)]
+ [OutputType([pscredential], ParameterSetName = 'CredsObject')]
+ [OutputType([pscredential], ParameterSetName = 'UserPass')]
+ [OutputType([pscredential])]
+ param
+ (
+ [Parameter(ParameterSetName = 'CredsObject',
+ Mandatory = $true)]
+ [pscredential]$Credentials,
+
+ [Parameter(ParameterSetName = 'UserPass',
+ Mandatory = $true)]
+ [string]$Token
+ )
+
+ switch ($PsCmdlet.ParameterSetName) {
+ 'CredsObject' {
+ $script:NetboxConfig.Credentials = $Credentials
+ break
+ }
+
+ 'UserPass' {
+ $securePW = ConvertTo-SecureString $Token -AsPlainText -Force
+ $script:NetboxConfig.Credentials = [System.Management.Automation.PSCredential]::new('notapplicable', $securePW)
+ break
+ }
+ }
+
+ $script:NetboxConfig.Credentials
}
function Get-NetboxCredentials {
@@ -162,7 +167,7 @@ function Connect-NetboxAPI {
try {
Write-Verbose "Verifying API connectivity..."
- $APIInfo = VerifyAPIConnectivity
+ $null = VerifyAPIConnectivity
$script:NetboxConfig.Connected = $true
Write-Verbose "Successfully connected!"
} catch {
diff --git a/Functions/Virtualization/Virtualization.ps1 b/Functions/Virtualization/Virtualization.ps1
index c4f27bd..e0fe5a3 100644
--- a/Functions/Virtualization/Virtualization.ps1
+++ b/Functions/Virtualization/Virtualization.ps1
@@ -72,13 +72,14 @@ function VerifyVirtualizationChoices {
[switch]$VirtualMachineStatus
)
- ValidateChoice -MajorObject 'Virtualization' -ChoiceName $PSCmdlet.ParameterSetName
+ ValidateChoice -MajorObject 'Virtualization' -ChoiceName $PSCmdlet.ParameterSetName -ProvidedValue $ProvidedValue
}
#region GET commands
function Get-NetboxVirtualizationChoices {
[CmdletBinding()]
+ [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "", Justification = "These are literally 'choices' in Netbox")]
param ()
$uriSegments = [System.Collections.ArrayList]::new(@('virtualization', '_choices'))
@@ -217,7 +218,7 @@ function Get-NetboxVirtualMachine {
[switch]$Raw
)
- if ($Status -ne $null) {
+ if ($null -ne $Status) {
$PSBoundParameters.Status = VerifyVirtualizationChoices -ProvidedValue $Status -VirtualMachineStatus
}
@@ -533,8 +534,69 @@ function Add-NetboxVirtualInterface {
InvokeNetboxRequest -URI $uri -Method POST -Body $URIComponents.Parameters
}
-
-
#endregion ADD commands
+#region SET commands
+
+function Set-NetboxVirtualMachine {
+ [CmdletBinding(ConfirmImpact = 'High',
+ SupportsShouldProcess = $true)]
+ param
+ (
+ [Parameter(Mandatory = $true,
+ ValueFromPipelineByPropertyName = $true)]
+ [uint16]$Id,
+
+ [string]$Name,
+
+ [uint16]$Role,
+
+ [uint16]$Cluster,
+
+ [object]$Status,
+
+ [uint16]$Platform,
+
+ [uint16]$Primary_IPv4,
+
+ [uint16]$Primary_IPv6,
+
+ [byte]$VCPUs,
+
+ [uint16]$Memory,
+
+ [uint16]$Disk,
+
+ [uint16]$Tenant,
+
+ [string]$Comments,
+
+ [hashtable]$Custom_Fields,
+
+ [switch]$Force
+ )
+
+ if ($Status) {
+ $PSBoundParameters.Status = VerifyVirtualizationChoices -ProvidedValue $Status -VirtualMachineStatus
+ }
+
+ $Segments = [System.Collections.ArrayList]::new(@('virtualization', 'virtual-machines', $Id))
+
+ Write-Verbose "Obtaining VM from ID $Id"
+
+ $CurrentVM = Get-NetboxVirtualMachine -Id $Id -ErrorAction Stop
+
+ Write-Verbose "Finished obtaining VM"
+
+ if ($Force -or $pscmdlet.ShouldProcess($CurrentVM.Name, "Set")) {
+ $URIComponents = BuildURIComponents -URISegments $Segments -ParametersDictionary $PSBoundParameters -SkipParameterByName 'Id', 'Force'
+
+ $URI = BuildNewURI -Segments $URIComponents.Segments
+
+ InvokeNetboxRequest -URI $URI -Body $URIComponents.Parameters -Method PATCH
+ }
+}
+
+
+#endregion SET commands
\ No newline at end of file
diff --git a/NetboxPS.psproj b/NetboxPS.psproj
index 6bafb75..50531cb 100644
--- a/NetboxPS.psproj
+++ b/NetboxPS.psproj
@@ -26,7 +26,8 @@
Tests\Virtualization.Tests.ps1
Tests\IPAM.Tests.ps1
Functions\IPAM\IPAM.ps1
- Tests\IPAMChoices.json.txt
+ Tests\IPAMChoices.json
+ Tests\VirtualizationChoices.json
R:\Netbox\NetboxPS\Test-Module.ps1
\ No newline at end of file
diff --git a/Staging/NetboxPS.psm1 b/Staging/NetboxPS.psm1
index 4e5c1d3..8968ea0 100644
--- a/Staging/NetboxPS.psm1
+++ b/Staging/NetboxPS.psm1
@@ -1,8 +1,8 @@
<#
.NOTES
--------------------------------------------------------------------------------
- Code generated by: SAPIEN Technologies, Inc., PowerShell Studio 2018 v5.5.150
- Generated on: 5/11/2018 4:30 PM
+ Code generated by: SAPIEN Technologies, Inc., PowerShell Studio 2018 v5.5.152
+ Generated on: 5/18/2018 11:21 AM
Generated by: Ben Claussen
Organization: NEOnet
--------------------------------------------------------------------------------
@@ -103,17 +103,17 @@
}
if ($HTTPS) {
- Write-Verbose "Setting scheme to HTTPS"
+ Write-Verbose " Setting scheme to HTTPS"
$Scheme = 'https'
} else {
- Write-Warning "Connecting via non-secure HTTP is not-recommended"
+ Write-Warning " Connecting via non-secure HTTP is not-recommended"
- Write-Verbose "Setting scheme to HTTP"
+ Write-Verbose " Setting scheme to HTTP"
$Scheme = 'http'
if (-not $PSBoundParameters.ContainsKey('Port')) {
# Set the port to 80 if the user did not supply it
- Write-Verbose "Setting port to 80 as default because it was not supplied by the user"
+ Write-Verbose " Setting port to 80 as default because it was not supplied by the user"
$Port = 80
}
}
@@ -124,25 +124,146 @@
# Generate the path by trimming excess slashes and whitespace from the $segments[] and joining together
$uriBuilder.Path = "api/{0}/" -f ($Segments.ForEach({$_.trim('/').trim()}) -join '/')
- Write-Verbose "URIPath: $($uriBuilder.Path)"
+ Write-Verbose " URIPath: $($uriBuilder.Path)"
if ($parameters) {
# Loop through the parameters and use the HttpUtility to create a Query string
[System.Collections.Specialized.NameValueCollection]$URIParams = [System.Web.HttpUtility]::ParseQueryString([String]::Empty)
foreach ($param in $Parameters.GetEnumerator()) {
- Write-Verbose "Adding URI parameter $($param.Key):$($param.Value)"
+ Write-Verbose " Adding URI parameter $($param.Key):$($param.Value)"
$URIParams[$param.Key] = $param.Value
}
$uriBuilder.Query = $URIParams.ToString()
}
- Write-Verbose "Completed building URIBuilder"
+ Write-Verbose " Completed building URIBuilder"
# Return the entire UriBuilder object
$uriBuilder
}
+ function BuildURIComponents {
+ [CmdletBinding()]
+ [OutputType([hashtable])]
+ param
+ (
+ [Parameter(Mandatory = $true)]
+ [System.Collections.ArrayList]$URISegments,
+
+ [Parameter(Mandatory = $true)]
+ [object]$ParametersDictionary,
+
+ [string[]]$SkipParameterByName
+ )
+
+ Write-Verbose "Building URI components"
+
+ $URIParameters = @{}
+
+ foreach ($CmdletParameterName in $ParametersDictionary.Keys) {
+ if ($CmdletParameterName -in $CommonParameterNames) {
+ # These are common parameters and should not be appended to the URI
+ Write-Debug "Skipping parameter $CmdletParameterName"
+ continue
+ }
+
+ if ($CmdletParameterName -in $SkipParameterByName) {
+ Write-Debug "Skipping parameter $CmdletParameterName"
+ continue
+ }
+
+ if ($CmdletParameterName -eq 'Id') {
+ # Check if there is one or more values for Id and build a URI or query as appropriate
+ if (@($ParametersDictionary[$CmdletParameterName]).Count -gt 1) {
+ Write-Verbose " Joining IDs for parameter"
+ $URIParameters['id__in'] = $ParametersDictionary[$CmdletParameterName] -join ','
+ } else {
+ Write-Verbose " Adding ID to segments"
+ [void]$uriSegments.Add($ParametersDictionary[$CmdletParameterName])
+ }
+ } elseif ($CmdletParameterName -eq 'Query') {
+ Write-Verbose " Adding query parameter"
+ $URIParameters['q'] = $ParametersDictionary[$CmdletParameterName]
+ } else {
+ Write-Verbose " Adding $($CmdletParameterName.ToLower()) parameter"
+ $URIParameters[$CmdletParameterName.ToLower()] = $ParametersDictionary[$CmdletParameterName]
+ }
+ }
+
+ return @{
+ 'Segments' = [System.Collections.ArrayList]$URISegments
+ 'Parameters' = $URIParameters
+ }
+ }
+
+ function GetChoiceValidValues {
+ [CmdletBinding()]
+ [OutputType([System.Collections.ArrayList])]
+ param
+ (
+ [Parameter(Mandatory = $true)]
+ [string]$MajorObject,
+
+ [Parameter(Mandatory = $true)]
+ [object]$Choice
+ )
+
+ $ValidValues = New-Object System.Collections.ArrayList
+
+ if (-not $script:NetboxConfig.Choices.$MajorObject.$Choice) {
+ throw "Missing choices for $Choice"
+ }
+
+ [void]$ValidValues.AddRange($script:NetboxConfig.Choices.$MajorObject.$Choice.value)
+ [void]$ValidValues.AddRange($script:NetboxConfig.Choices.$MajorObject.$Choice.label)
+
+ if ($ValidValues.Count -eq 0) {
+ throw "Missing valid values for $MajorObject.$Choice"
+ }
+
+ return [System.Collections.ArrayList]$ValidValues
+ }
+
+ function ValidateChoice {
+ [CmdletBinding()]
+ [OutputType([uint16])]
+ param
+ (
+ [Parameter(Mandatory = $true)]
+ [ValidateSet('Circuits', 'Extras', 'IPAM', 'Virtualization', IgnoreCase = $true)]
+ [string]$MajorObject,
+
+ [Parameter(Mandatory = $true)]
+ [string]$ChoiceName,
+
+ [Parameter(Mandatory = $true)]
+ [object]$ProvidedValue
+ )
+
+ $ValidValues = GetChoiceValidValues -MajorObject $MajorObject -Choice $ChoiceName
+
+ Write-Verbose "Validating $ChoiceName"
+ Write-Verbose "Checking '$ProvidedValue' against [$($ValidValues -join ', ')]"
+
+ if ($ValidValues -inotcontains $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
+ }
+
+ return $intVal
+ }
+
+
function GetNetboxAPIErrorBody {
param
(
@@ -160,7 +281,7 @@
}
function InvokeNetboxRequest {
- [CmdletBinding(SupportsShouldProcess = $true)]
+ [CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
@@ -237,7 +358,7 @@
# If the user wants the raw value from the API... otherwise return only the actual result
if ($Raw) {
- Write-Verbose "Returning raw result"
+ Write-Verbose "Returning raw result by choice"
return $result
} else {
if ($result.psobject.Properties.Name.Contains('results')) {
@@ -247,9 +368,14 @@
Write-Verbose "Did NOT find results property on data, returning raw result"
return $result
}
- }
+ }
}
+
+
+
+ #region Troubleshooting commands
+
function ThrowNetboxRESTError {
$uriSegments = [System.Collections.ArrayList]::new(@('fake', 'url'))
@@ -260,8 +386,33 @@
InvokeNetboxRequest -URI $uri -Raw
}
+ function CreateEnum {
+ [CmdletBinding()]
+ param
+ (
+ [Parameter(Mandatory = $true)]
+ [string]$EnumName,
+
+ [Parameter(Mandatory = $true)]
+ [pscustomobject]$Values,
+
+ [switch]$PassThru
+ )
+
+ $definition = @"
+public enum $EnumName
+{`n$(foreach ($value in $values) {"`t$($value.label) = $($value.value),`n"})
+}
+"@
+ if (-not ([System.Management.Automation.PSTypeName]"$EnumName").Type) {
+ #Write-Host $definition -ForegroundColor Green
+ Add-Type -TypeDefinition $definition -PassThru:$PassThru
+ } else {
+ Write-Warning "EnumType $EnumName already exists."
+ }
+ }
-
+ #endregion Troubleshooting commands
@@ -297,15 +448,7 @@
Write-Verbose "Creating NetboxConfig hashtable"
$script:NetboxConfig = @{
'Connected' = $false
- 'Choices' = @{
- 'Circuits' = $null
- 'DCIM' = $null
- 'Extras' = $null
- 'IPAM' = $null
- 'Secrets' = $null
- 'Tenancy' = $null
- 'Virtualization' = $null
- }
+ 'Choices' = @{}
}
}
@@ -317,15 +460,17 @@
}
function Set-NetboxHostName {
- [CmdletBinding()]
- param
- (
- [Parameter(Mandatory = $true)]
- [string]$Hostname
- )
-
- $script:NetboxConfig.Hostname = $Hostname.Trim()
- $script:NetboxConfig.Hostname
+ [CmdletBinding(ConfirmImpact = 'Medium',
+ SupportsShouldProcess = $true)]
+ [OutputType([string])]
+ param
+ (
+ [Parameter(Mandatory = $true)]
+ [string]$Hostname
+ )
+
+ $script:NetboxConfig.Hostname = $Hostname.Trim()
+ $script:NetboxConfig.Hostname
}
function Get-NetboxHostname {
@@ -333,7 +478,7 @@
param ()
Write-Verbose "Getting Netbox hostname"
- if ($script:NetboxConfig.Hostname -eq $null) {
+ if ($null -eq $script:NetboxConfig.Hostname) {
throw "Netbox Hostname is not set! You may set it with Set-NetboxHostname -Hostname 'hostname.domain.tld'"
}
@@ -341,34 +486,37 @@
}
function Set-NetboxCredentials {
- [CmdletBinding(DefaultParameterSetName = 'CredsObject')]
- [OutputType([pscredential], ParameterSetName = 'CredsObject')]
- [OutputType([pscredential], ParameterSetName = 'UserPass')]
- param
- (
- [Parameter(ParameterSetName = 'CredsObject',
- Mandatory = $true)]
- [pscredential]$Credentials,
-
- [Parameter(ParameterSetName = 'UserPass',
- Mandatory = $true)]
- [string]$Token
- )
-
- switch ($PsCmdlet.ParameterSetName) {
- 'CredsObject' {
- $script:NetboxConfig.Credentials = $Credentials
- break
- }
-
- 'UserPass' {
- $securePW = ConvertTo-SecureString $Token -AsPlainText -Force
- $script:NetboxConfig.Credentials = [System.Management.Automation.PSCredential]::new('notapplicable', $securePW)
- break
- }
- }
-
- $script:NetboxConfig.Credentials
+ [CmdletBinding(DefaultParameterSetName = 'CredsObject',
+ ConfirmImpact = 'Medium',
+ SupportsShouldProcess = $true)]
+ [OutputType([pscredential], ParameterSetName = 'CredsObject')]
+ [OutputType([pscredential], ParameterSetName = 'UserPass')]
+ [OutputType([pscredential])]
+ param
+ (
+ [Parameter(ParameterSetName = 'CredsObject',
+ Mandatory = $true)]
+ [pscredential]$Credentials,
+
+ [Parameter(ParameterSetName = 'UserPass',
+ Mandatory = $true)]
+ [string]$Token
+ )
+
+ switch ($PsCmdlet.ParameterSetName) {
+ 'CredsObject' {
+ $script:NetboxConfig.Credentials = $Credentials
+ break
+ }
+
+ 'UserPass' {
+ $securePW = ConvertTo-SecureString $Token -AsPlainText -Force
+ $script:NetboxConfig.Credentials = [System.Management.Automation.PSCredential]::new('notapplicable', $securePW)
+ break
+ }
+ }
+
+ $script:NetboxConfig.Credentials
}
function Get-NetboxCredentials {
@@ -443,7 +591,7 @@
try {
Write-Verbose "Verifying API connectivity..."
- $APIInfo = VerifyAPIConnectivity
+ $null = VerifyAPIConnectivity
$script:NetboxConfig.Connected = $true
Write-Verbose "Successfully connected!"
} catch {
@@ -456,14 +604,16 @@
}
}
+ Write-Verbose "Caching static choices"
$script:NetboxConfig.Choices.Circuits = Get-NetboxCircuitsChoices
- #$script:NetboxConfig.Choices.DCIM = Get-NetboxDCIMChoices
+ #$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
- #$script:NetboxConfig.Choices.Tenancy = Get-NetboxTenancyChoices
+ #$script:NetboxConfig.Choices.Secrets = Get-NetboxSecretsChoices # Not completed yet
+ #$script:NetboxConfig.Choices.Tenancy = Get-NetboxTenancyChoices # Not completed yet
$script:NetboxConfig.Choices.Virtualization = Get-NetboxVirtualizationChoices
+ Write-Verbose "Connection process completed"
}
@@ -474,7 +624,6 @@
-
#endregion
#region Invoke-Extras_ps1
@@ -492,7 +641,8 @@
#>
function Get-NetboxExtrasChoices {
- [CmdletBinding()]
+ [CmdletBinding()]
+ [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "", Justification = "These are literally 'choices' in Netbox")]
param ()
$uriSegments = [System.Collections.ArrayList]::new(@('extras', '_choices'))
@@ -531,8 +681,9 @@
.NOTES
Additional information about the function.
#>
-
- [CmdletBinding()]
+
+ [CmdletBinding()]
+ [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "", Justification = "These are literally 'choices' in Netbox")]
param ()
$uriSegments = [System.Collections.ArrayList]::new(@('circuits', '_choices'))
@@ -626,15 +777,80 @@
Virtualization object functions
#>
+ function VerifyVirtualizationChoices {
+ <#
+ .SYNOPSIS
+ Internal function to verify 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 verify if the provided value from a user is valid.
+
+ .PARAMETER ProvidedValue
+ The value to validate against static choices
+
+ .PARAMETER AggregateFamily
+ Verify against aggregate family values
+
+ .PARAMETER PrefixFamily
+ Verify against prefix family values
+
+ .PARAMETER PrefixStatus
+ Verify against prefix status values
+
+ .PARAMETER IPAddressFamily
+ Verify against ip-address family values
+
+ .PARAMETER IPAddressStatus
+ Verify against ip-address status values
+
+ .PARAMETER IPAddressRole
+ Verify against ip-address role values
+
+ .PARAMETER VLANStatus
+ Verify against VLAN status values
+
+ .PARAMETER ServiceProtocol
+ Verify against service protocol values
+
+ .EXAMPLE
+ PS C:\> VerifyIPAMChoices -ProvidedValue 'loopback' -IPAddressRole
+
+ .EXAMPLE
+ PS C:\> VerifyIPAMChoices -ProvidedValue 'Loopback' -IPAddressFamily
+ >> Invalid value Loopback for ip-address:family. Must be one of: 4, 6, IPv4, IPv6
+
+ .FUNCTIONALITY
+ This cmdlet is intended to be used internally and not exposed to the user
+
+ .OUTPUT
+ This function returns nothing if the value is valid. Otherwise, it will throw an error.
+ #>
+
+ [CmdletBinding()]
+ param
+ (
+ [Parameter(Mandatory = $true)]
+ [object]$ProvidedValue,
+
+ [Parameter(ParameterSetName = 'virtual-machine:status',
+ Mandatory = $true)]
+ [switch]$VirtualMachineStatus
+ )
+
+ ValidateChoice -MajorObject 'Virtualization' -ChoiceName $PSCmdlet.ParameterSetName -ProvidedValue $ProvidedValue
+ }
+
#region GET commands
function Get-NetboxVirtualizationChoices {
[CmdletBinding()]
+ [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "", Justification = "These are literally 'choices' in Netbox")]
param ()
$uriSegments = [System.Collections.ArrayList]::new(@('virtualization', '_choices'))
- $uri = BuildNewURI -Segments $uriSegments -Parameters $Parameters
+ $uri = BuildNewURI -Segments $uriSegments
InvokeNetboxRequest -URI $uri
}
@@ -735,10 +951,9 @@
[string]$Name,
- [Alias('id__in')]
[uint16[]]$Id,
- [NetboxVirtualMachineStatus]$Status,
+ [object]$Status,
[string]$Tenant,
@@ -769,34 +984,15 @@
[switch]$Raw
)
- $uriSegments = [System.Collections.ArrayList]::new(@('virtualization', 'virtual-machines'))
-
- $URIParameters = @{}
-
- foreach ($CmdletParameterName in $PSBoundParameters.Keys) {
- if ($CmdletParameterName -in $CommonParameterNames) {
- # These are common parameters and should not be appended to the URI
- Write-Debug "Skipping parameter $CmdletParameterName"
- continue
- }
-
- if ($CmdletParameterName -eq 'Id') {
- # Check if there is one or more values for Id and build a URI or query as appropriate
- if (@($PSBoundParameters[$CmdletParameterName]).Count -gt 1) {
- $URIParameters['id__in'] = $Id -join ','
- } else {
- [void]$uriSegments.Add($PSBoundParameters[$CmdletParameterName])
- }
- } elseif ($CmdletParameterName -eq 'Query') {
- $URIParameters['q'] = $PSBoundParameters[$CmdletParameterName]
- } elseif ($CmdletParameterName -eq 'Status') {
- $URIParameters[$CmdletParameterName.ToLower()] = $PSBoundParameters[$CmdletParameterName].value__
- } else {
- $URIParameters[$CmdletParameterName.ToLower()] = $PSBoundParameters[$CmdletParameterName]
- }
+ if ($null -ne $Status) {
+ $PSBoundParameters.Status = VerifyVirtualizationChoices -ProvidedValue $Status -VirtualMachineStatus
}
- $uri = BuildNewURI -Segments $uriSegments -Parameters $URIParameters
+ $Segments = [System.Collections.ArrayList]::new(@('virtualization', 'virtual-machines'))
+
+ $URIComponents = BuildURIComponents -URISegments $Segments -ParametersDictionary $PSBoundParameters
+
+ $uri = BuildNewURI -Segments $URIComponents.Segments -Parameters $URIComponents.Parameters
InvokeNetboxRequest -URI $uri -Raw:$Raw
}
@@ -849,61 +1045,33 @@
[CmdletBinding()]
param
(
- [Parameter(ValueFromPipeline = $true,
- ValueFromPipelineByPropertyName = $true)]
[uint16]$Limit,
- [Parameter(ValueFromPipeline = $true,
- ValueFromPipelineByPropertyName = $true)]
[uint16]$Offset,
[Parameter(ValueFromPipeline = $true)]
[uint16]$Id,
- [Parameter(ValueFromPipeline = $true)]
[string]$Name,
- [Parameter(ValueFromPipeline = $true)]
[boolean]$Enabled,
- [Parameter(ValueFromPipeline = $true)]
[uint16]$MTU,
- [Parameter(ValueFromPipeline = $true)]
[uint16]$Virtual_Machine_Id,
- [Parameter(ValueFromPipeline = $true)]
[string]$Virtual_Machine,
- [Parameter(ValueFromPipeline = $true)]
[string]$MAC_Address,
- [Parameter(ValueFromPipeline = $true,
- ValueFromPipelineByPropertyName = $true)]
[switch]$Raw
)
- $uriSegments = [System.Collections.ArrayList]::new(@('virtualization', 'interfaces'))
+ $Segments = [System.Collections.ArrayList]::new(@('virtualization', 'interfaces'))
- $URIParameters = @{}
+ $URIComponents = BuildURIComponents -URISegments $Segments -ParametersDictionary $PSBoundParameters
- foreach ($CmdletParameterName in $PSBoundParameters.Keys) {
- if ($CmdletParameterName -in $CommonParameterNames) {
- # These are common parameters and should not be appended to the URI
- Write-Debug "Skipping parameter $CmdletParameterName"
- continue
- }
-
- if ($CmdletParameterName -eq 'Id') {
- [void]$uriSegments.Add($PSBoundParameters[$CmdletParameterName])
- } elseif ($CmdletParameterName -eq 'Enabled') {
- $URIParameters[$CmdletParameterName.ToLower()] = $PSBoundParameters[$CmdletParameterName].ToString().ToLower()
- } else {
- $URIParameters[$CmdletParameterName.ToLower()] = $PSBoundParameters[$CmdletParameterName]
- }
- }
-
- $uri = BuildNewURI -Segments $uriSegments -Parameters $URIParameters
+ $uri = BuildNewURI -Segments $URIComponents.Segments -Parameters $URIComponents.Parameters
InvokeNetboxRequest -URI $uri -Raw:$Raw
}
@@ -1072,7 +1240,7 @@
[uint16]$Tenant,
- [NetboxVirtualMachineStatus]$Status = 'Active',
+ [object]$Status = 'Active',
[uint16]$Role,
@@ -1089,31 +1257,15 @@
[string]$Comments
)
- $uriSegments = [System.Collections.ArrayList]::new(@('virtualization', 'virtual-machines'))
+ $PSBoundParameters.Status = VerifyVirtualizationChoices -ProvidedValue $Status -VirtualMachineStatus
- $Body = @{}
+ $Segments = [System.Collections.ArrayList]::new(@('virtualization', 'virtual-machines'))
- if (-not $PSBoundParameters.ContainsKey('Status')) {
- [void]$PSBoundParameters.Add('Status', $Status)
- }
+ $URIComponents = BuildURIComponents -URISegments $Segments -ParametersDictionary $PSBoundParameters
- foreach ($CmdletParameterName in $PSBoundParameters.Keys) {
- if ($CmdletParameterName -in $CommonParameterNames) {
- # These are common parameters and should not be appended to the URI
- Write-Debug "Skipping parameter $CmdletParameterName"
- continue
- }
-
- if ($CmdletParameterName -eq 'Status') {
- $Body[$CmdletParameterName.ToLower()] = $PSBoundParameters[$CmdletParameterName].value__
- } else {
- $Body[$CmdletParameterName.ToLower()] = $PSBoundParameters[$CmdletParameterName]
- }
- }
+ $URI = BuildNewURI -Segments $URIComponents.Segments
- $uri = BuildNewURI -Segments $uriSegments
-
- InvokeNetboxRequest -URI $uri -Method POST -Body $Body
+ InvokeNetboxRequest -URI $URI -Method POST -Body $URIComponents.Parameters
}
function Add-NetboxVirtualInterface {
@@ -1137,35 +1289,83 @@
[switch]$Raw
)
- $uriSegments = [System.Collections.ArrayList]::new(@('virtualization', 'interfaces'))
+ $Segments = [System.Collections.ArrayList]::new(@('virtualization', 'interfaces'))
- $Body = @{}
+ $PSBoundParameters.Enabled = $Enabled
- if (-not $PSBoundParameters.ContainsKey('Enabled')) {
- [void]$PSBoundParameters.Add('enabled', $Enabled)
- }
+ $URIComponents = BuildURIComponents -URISegments $Segments -ParametersDictionary $PSBoundParameters
- foreach ($CmdletParameterName in $PSBoundParameters.Keys) {
- if ($CmdletParameterName -in $CommonParameterNames) {
- # These are common parameters and should not be appended to the URI
- Write-Debug "Skipping parameter $CmdletParameterName"
- continue
- }
-
- $Body[$CmdletParameterName.ToLower()] = $PSBoundParameters[$CmdletParameterName]
- }
+ $uri = BuildNewURI -Segments $URIComponents.Segments
- $uri = BuildNewURI -Segments $uriSegments
-
- InvokeNetboxRequest -URI $uri -Method POST -Body $Body
+ InvokeNetboxRequest -URI $uri -Method POST -Body $URIComponents.Parameters
}
-
-
#endregion ADD commands
- #endregion
+ #region SET commands
+
+ function Set-NetboxVirtualMachine {
+ [CmdletBinding(ConfirmImpact = 'High',
+ SupportsShouldProcess = $true)]
+ param
+ (
+ [Parameter(Mandatory = $true,
+ ValueFromPipelineByPropertyName = $true)]
+ [uint16]$Id,
+
+ [string]$Name,
+
+ [uint16]$Role,
+
+ [uint16]$Cluster,
+
+ [object]$Status,
+
+ [uint16]$Platform,
+
+ [uint16]$Primary_IPv4,
+
+ [uint16]$Primary_IPv6,
+
+ [byte]$VCPUs,
+
+ [uint16]$Memory,
+
+ [uint16]$Disk,
+
+ [uint16]$Tenant,
+
+ [string]$Comments,
+
+ [hashtable]$Custom_Fields,
+
+ [switch]$Force
+ )
+
+ if ($Status) {
+ $PSBoundParameters.Status = VerifyVirtualizationChoices -ProvidedValue $Status -VirtualMachineStatus
+ }
+
+ $Segments = [System.Collections.ArrayList]::new(@('virtualization', 'virtual-machines', $Id))
+
+ Write-Verbose "Obtaining VM from ID $Id"
+
+ $CurrentVM = Get-NetboxVirtualMachine -Id $Id -ErrorAction Stop
+
+ Write-Verbose "Finished obtaining VM"
+
+ if ($Force -or $pscmdlet.ShouldProcess($CurrentVM.Name, "Set")) {
+ $URIComponents = BuildURIComponents -URISegments $Segments -ParametersDictionary $PSBoundParameters -SkipParameterByName 'Id', 'Force'
+
+ $URI = BuildNewURI -Segments $URIComponents.Segments
+
+ InvokeNetboxRequest -URI $URI -Body $URIComponents.Parameters -Method PATCH
+ }
+ }
+
+
+ #endregion SET commands#endregion
#region Invoke-IPAM_ps1
<#
@@ -1198,7 +1398,7 @@
Internal function to verify provided values for static choices
.DESCRIPTION
- When users connect to the API, choices for each major object are cached to the config variable.
+ When users connect to the API, choices for each major object are cached to the config variable.
These values are then utilized to verify if the provided value from a user is valid.
.PARAMETER ProvidedValue
@@ -1233,16 +1433,20 @@
.EXAMPLE
PS C:\> VerifyIPAMChoices -ProvidedValue 'Loopback' -IPAddressFamily
- >> Invalid value Loopback for ip-address:family. Must be one of: 4, 6, IPv4, IPv6
+ >> Invalid value Loopback for ip-address:family. Must be one of: 4, 6, IPv4, IPv6
+
+ .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
-
- .OUTPUT
- This function returns nothing if the value is valid. Otherwise, it will throw an error.
#>
- [CmdletBinding()]
+ [CmdletBinding(DefaultParameterSetName = 'service:protocol')]
+ [OutputType([uint16])]
param
(
[Parameter(Mandatory = $true)]
@@ -1281,44 +1485,20 @@
[switch]$ServiceProtocol
)
- $ValidValues = New-Object System.Collections.ArrayList
-
- if (-not $script:NetboxConfig.Choices.IPAM.$($PSCmdlet.ParameterSetName)) {
- throw "Missing choices for $($PSCmdlet.ParameterSetName)"
- }
-
- [void]$ValidValues.AddRange($script:NetboxConfig.Choices.IPAM.$($PSCmdlet.ParameterSetName).value)
- [void]$ValidValues.AddRange($script:NetboxConfig.Choices.IPAM.$($PSCmdlet.ParameterSetName).label)
-
- if ($ValidValues.Count -eq 0) {
- throw "Missing valid values for $($PSCmdlet.ParameterSetName)"
- }
-
- if ($ValidValues -inotcontains $ProvidedValue) {
- throw "Invalid value '$ProvidedValue' for '$($PSCmdlet.ParameterSetName)'. 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.IPAM.$($PSCmdlet.ParameterSetName).Where({$_.Label -eq $ProvidedValue}).Value
- }
-
- return $intVal
+ ValidateChoice -MajorObject 'IPAM' -ChoiceName $PSCmdlet.ParameterSetName -ProvidedValue $ProvidedValue
}
function Get-NetboxIPAMAggregate {
[CmdletBinding()]
+ [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "", Justification = "These are literally 'choices' in Netbox")]
param
(
[uint16]$Limit,
[uint16]$Offset,
- [string]$Family,
+ [object]$Family,
[datetime]$Date_Added,
@@ -1333,32 +1513,15 @@
[switch]$Raw
)
- $uriSegments = [System.Collections.ArrayList]::new(@('ipam', 'aggregates'))
-
- $URIParameters = @{}
-
- foreach ($CmdletParameterName in $PSBoundParameters.Keys) {
- if ($CmdletParameterName -in $CommonParameterNames) {
- # These are common parameters and should not be appended to the URI
- Write-Debug "Skipping parameter $CmdletParameterName"
- continue
- }
-
- if ($CmdletParameterName -eq 'Id') {
- # Check if there is one or more values for Id and build a URI or query as appropriate
- if (@($PSBoundParameters[$CmdletParameterName]).Count -gt 1) {
- $URIParameters['id__in'] = $Id -join ','
- } else {
- [void]$uriSegments.Add($PSBoundParameters[$CmdletParameterName])
- }
- } elseif ($CmdletParameterName -eq 'Query') {
- $URIParameters['q'] = $PSBoundParameters[$CmdletParameterName]
- } else {
- $URIParameters[$CmdletParameterName.ToLower()] = $PSBoundParameters[$CmdletParameterName]
- }
+ if ($null -ne $Family) {
+ $PSBoundParameters.Family = VerifyIPAMChoices -ProvidedValue $Family -AggregateFamily
}
- $uri = BuildNewURI -Segments $uriSegments -Parameters $URIParameters
+ $Segments = [System.Collections.ArrayList]::new(@('ipam', 'aggregates'))
+
+ $URIComponents = BuildURIComponents -URISegments $Segments.Clone() -ParametersDictionary $PSBoundParameters
+
+ $uri = BuildNewURI -Segments $URIComponents.Segments -Parameters $URIComponents.Parameters
InvokeNetboxRequest -URI $uri -Raw:$Raw
}
@@ -1406,44 +1569,23 @@
[switch]$Raw
)
- if ($Family) {
- $PSBoundParameters.Family = VerifyIPAMChoices -ProvidedValue $Family -IPAddressFamily
+ if ($null -ne $Family) {
+ $PSBoundParameters.Family = VerifyIPAMChoices -ProvidedValue $Family -IPAddressFamily
}
- if ($Status) {
+ if ($null -ne $Status) {
$PSBoundParameters.Status = VerifyIPAMChoices -ProvidedValue $Status -IPAddressStatus
}
- if ($Role) {
+ if ($null -ne $Role) {
$PSBoundParameters.Role = VerifyIPAMChoices -ProvidedValue $Role -IPAddressRole
}
- $uriSegments = [System.Collections.ArrayList]::new(@('ipam', 'ip-addresses'))
+ $Segments = [System.Collections.ArrayList]::new(@('ipam', 'ip-addresses'))
- $URIParameters = @{}
+ $URIComponents = BuildURIComponents -URISegments $Segments -ParametersDictionary $PSBoundParameters
- foreach ($CmdletParameterName in $PSBoundParameters.Keys) {
- if ($CmdletParameterName -in $CommonParameterNames) {
- # These are common parameters and should not be appended to the URI
- Write-Debug "Skipping parameter $CmdletParameterName"
- continue
- }
-
- if ($CmdletParameterName -eq 'Id') {
- # Check if there is one or more values for Id and build a URI or query as appropriate
- if (@($PSBoundParameters[$CmdletParameterName]).Count -gt 1) {
- $URIParameters['id__in'] = $Id -join ','
- } else {
- [void]$uriSegments.Add($PSBoundParameters[$CmdletParameterName])
- }
- } elseif ($CmdletParameterName -eq 'Query') {
- $URIParameters['q'] = $PSBoundParameters[$CmdletParameterName]
- } else {
- $URIParameters[$CmdletParameterName.ToLower()] = $PSBoundParameters[$CmdletParameterName]
- }
- }
-
- $uri = BuildNewURI -Segments $uriSegments -Parameters $URIParameters
+ $uri = BuildNewURI -Segments $URIComponents.Segments -Parameters $URIComponents.Parameters
InvokeNetboxRequest -URI $uri -Raw:$Raw
}
@@ -1479,21 +1621,17 @@
[Parameter(Mandatory = $true)]
[uint16]$Prefix_ID,
- [Alias('Limit')]
- [uint16]$NumberOfIPs,
+ [Alias('NumberOfIPs')]
+ [uint16]$Limit,
[switch]$Raw
)
- $uriSegments = [System.Collections.ArrayList]::new(@('ipam', 'prefixes', $Prefix_ID, 'available-ips'))
+ $Segments = [System.Collections.ArrayList]::new(@('ipam', 'prefixes', $Prefix_ID, 'available-ips'))
- $uriParameters = @{}
+ $URIComponents = BuildURIComponents -URISegments $Segments -ParametersDictionary $PSBoundParameters -SkipParameterByName 'prefix_id'
- if ($NumberOfIPs) {
- [void]$uriParameters.Add('limit', $NumberOfIPs)
- }
-
- $uri = BuildNewURI -Segments $uriSegments -Parameters $uriParameters
+ $uri = BuildNewURI -Segments $URIComponents.Segments -Parameters $URIComponents.Parameters
InvokeNetboxRequest -URI $uri -Raw:$Raw
}
@@ -1628,51 +1766,209 @@
[switch]$Raw
)
- if ($Family) {
+ if ($null -ne $Family) {
$PSBoundParameters.Family = VerifyIPAMChoices -ProvidedValue $Family -PrefixFamily
}
- if ($Status) {
+ if ($null -ne $Status) {
$PSBoundParameters.Status = VerifyIPAMChoices -ProvidedValue $Status -PrefixStatus
}
- $uriSegments = [System.Collections.ArrayList]::new(@('ipam', 'prefixes'))
+ $Segments = [System.Collections.ArrayList]::new(@('ipam', 'prefixes'))
- $URIParameters = @{
- }
+ $URIComponents = BuildURIComponents -URISegments $Segments -ParametersDictionary $PSBoundParameters
- foreach ($CmdletParameterName in $PSBoundParameters.Keys) {
- if ($CmdletParameterName -in $CommonParameterNames) {
- # These are common parameters and should not be appended to the URI
- Write-Debug "Skipping parameter $CmdletParameterName"
- continue
- }
-
- if ($CmdletParameterName -eq 'Id') {
- # Check if there is one or more values for Id and build a URI or query as appropriate
- if (@($PSBoundParameters[$CmdletParameterName]).Count -gt 1) {
- $URIParameters['id__in'] = $Id -join ','
- } else {
- [void]$uriSegments.Add($PSBoundParameters[$CmdletParameterName])
- }
- } elseif ($CmdletParameterName -eq 'Query') {
- $URIParameters['q'] = $PSBoundParameters[$CmdletParameterName]
- } else {
- $URIParameters[$CmdletParameterName.ToLower()] = $PSBoundParameters[$CmdletParameterName]
- }
- }
-
- $uri = BuildNewURI -Segments $uriSegments -Parameters $URIParameters
+ $uri = BuildNewURI -Segments $URIComponents.Segments -Parameters $URIComponents.Parameters
InvokeNetboxRequest -URI $uri -Raw:$Raw
}
+ function Add-NetboxIPAMAddress {
+ <#
+ .SYNOPSIS
+ Add a new IP address to Netbox
+
+ .DESCRIPTION
+ Adds a new IP address to Netbox with a status of Active by default.
+
+ .PARAMETER Address
+ IP address in CIDR notation: 192.168.1.1/24
+
+ .PARAMETER Status
+ Status of the IP. Defaults to Active
+
+ .PARAMETER Tenant
+ Tenant ID
+
+ .PARAMETER VRF
+ VRF ID
+
+ .PARAMETER Role
+ Role such as anycast, loopback, etc... Defaults to nothing
+
+ .PARAMETER NAT_Inside
+ ID of IP for NAT
+
+ .PARAMETER Custom_Fields
+ Custom field hash table. Will be validated by the API service
+
+ .PARAMETER Interface
+ ID of interface to apply IP
+
+ .PARAMETER Description
+ Description of IP address
+
+ .PARAMETER Raw
+ Return raw results from API service
+
+ .EXAMPLE
+ PS C:\> Add-NetboxIPAMAddress
+
+ .NOTES
+ Additional information about the function.
+ #>
+
+ [CmdletBinding()]
+ [OutputType([pscustomobject])]
+ param
+ (
+ [Parameter(Mandatory = $true)]
+ [string]$Address,
+
+ [object]$Status = 'Active',
+
+ [uint16]$Tenant,
+
+ [uint16]$VRF,
+
+ [object]$Role,
+
+ [uint16]$NAT_Inside,
+
+ [hashtable]$Custom_Fields,
+
+ [uint16]$Interface,
+
+ [string]$Description,
+
+ [switch]$Raw
+ )
+
+ $PSBoundParameters.Status = VerifyIPAMChoices -ProvidedValue $Status -IPAddressStatus
+
+ if ($null -ne $Role) {
+ $PSBoundParameters.Role = VerifyIPAMChoices -ProvidedValue $Role -IPAddressRole
+ }
+
+ $segments = [System.Collections.ArrayList]::new(@('ipam', 'ip-addresses'))
+
+ $URIComponents = BuildURIComponents -URISegments $segments -ParametersDictionary $PSBoundParameters
+
+ $URI = BuildNewURI -Segments $URIComponents.Segments
+
+ InvokeNetboxRequest -URI $URI -Method POST -Body $URIComponents.Parameters -Raw:$Raw
+ }
+ function Remove-NetboxIPAMAddress {
+ <#
+ .SYNOPSIS
+ Remove an IP address from Netbox
+
+ .DESCRIPTION
+ Removes/deletes an IP address from Netbox by ID and optional other filters
+
+ .PARAMETER Id
+ A description of the Id parameter.
+
+ .PARAMETER Force
+ A description of the Force parameter.
+
+ .PARAMETER Query
+ A description of the Query parameter.
+
+ .EXAMPLE
+ PS C:\> Remove-NetboxIPAMAddress -Id $value1
+
+ .NOTES
+ Additional information about the function.
+ #>
+
+ [CmdletBinding(ConfirmImpact = 'High',
+ SupportsShouldProcess = $true)]
+ param
+ (
+ [Parameter(Mandatory = $true)]
+ [uint16[]]$Id,
+
+ [switch]$Force
+ )
+
+ $CurrentIPs = @(Get-NetboxIPAMAddress -Id $Id -ErrorAction Stop)
+
+ $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}
+
+ $URI = BuildNewURI -Segments $URIComponents.Segments
+
+ InvokeNetboxRequest -URI $URI -Method DELETE
+ }
+ }
+ }
-
-
-
-
+ function Set-NetboxIPAMAddress {
+ [CmdletBinding(ConfirmImpact = 'High',
+ SupportsShouldProcess = $true)]
+ param
+ (
+ [Parameter(Mandatory = $true,
+ ValueFromPipelineByPropertyName = $true)]
+ [uint16]$Id,
+
+ [string]$Address,
+
+ [object]$Status,
+
+ [uint16]$Tenant,
+
+ [uint16]$VRF,
+
+ [object]$Role,
+
+ [uint16]$NAT_Inside,
+
+ [hashtable]$Custom_Fields,
+
+ [uint16]$Interface,
+
+ [string]$Description,
+
+ [switch]$Force
+ )
+
+ if ($Status) {
+ $PSBoundParameters.Status = VerifyIPAMChoices -ProvidedValue $Status -IPAddressStatus
+ }
+
+ if ($Role) {
+ $PSBoundParameters.Role = VerifyIPAMChoices -ProvidedValue $Role -IPAddressRole
+ }
+
+ $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
+ }
+ }
@@ -1693,16 +1989,16 @@ $script:CommonParameterNames = New-Object System.Collections.ArrayList
SetupNetboxConfigVariable
-if (-not ([System.Management.Automation.PSTypeName]'NetboxVirtualMachineStatus').Type) {
- Add-Type -TypeDefinition @"
-public enum NetboxVirtualMachineStatus
-{
- Offline = 0,
- Active = 1,
- Staged = 3
-}
-"@
-}
+#if (-not ([System.Management.Automation.PSTypeName]'NetboxVirtualMachineStatus').Type) {
+# Add-Type -TypeDefinition @"
+#public enum NetboxVirtualMachineStatus
+#{
+# Offline = 0,
+# Active = 1,
+# Staged = 3
+#}
+#"@
+#}
Export-ModuleMember -Function *
diff --git a/Staging/Tests/Helpers.Tests.ps1 b/Staging/Tests/Helpers.Tests.ps1
index 395c666..331da0f 100644
--- a/Staging/Tests/Helpers.Tests.ps1
+++ b/Staging/Tests/Helpers.Tests.ps1
@@ -31,8 +31,8 @@ Describe "Helpers tests" -Tag 'Core', 'Helpers' -Fixture {
return $true
} -ModuleName 'NetboxPS'
- Context "Building URI tests" {
- InModuleScope -ModuleName 'NetboxPS' -ScriptBlock {
+ InModuleScope -ModuleName 'NetboxPS' -ScriptBlock {
+ Context -Name "Building URIBuilder" -Fixture {
It "Should give a basic URI object" {
BuildNewURI -HostName 'netbox.domain.com' | Should -BeOfType [System.UriBuilder]
}
@@ -85,10 +85,70 @@ Describe "Helpers tests" -Tag 'Core', 'Helpers' -Fixture {
$URIBuilder.URI.AbsoluteURI | Should -BeExactly 'https://netbox.domain.com/api/seg1/seg2/?param1=paramval1¶m2=paramval2'
}
}
- }
-
- Context "Invoking request tests" {
- InModuleScope -ModuleName 'NetboxPS' -ScriptBlock {
+
+ Context -Name "Building URI components" -Fixture {
+ It "Should give a basic hashtable" {
+ $URIComponents = BuildURIComponents -URISegments @('segment1', 'segment2') -ParametersDictionary @{'param1' = 1}
+
+ $URIComponents | Should -BeOfType [hashtable]
+ $URIComponents.Keys.Count | Should -BeExactly 2
+ $URIComponents.Keys | Should -Be @("Segments", "Parameters")
+ $URIComponents.Segments | Should -Be @("segment1", "segment2")
+ $URIComponents.Parameters.Count | Should -BeExactly 1
+ $URIComponents.Parameters | Should -BeOfType [hashtable]
+ $URIComponents.Parameters['param1'] | Should -Be 1
+ }
+
+ It "Should add a single ID parameter to the segments" {
+ $URIComponents = BuildURIComponents -URISegments @('segment1', 'segment2') -ParametersDictionary @{'id' = 123}
+
+ $URIComponents | Should -BeOfType [hashtable]
+ $URIComponents.Keys.Count | Should -BeExactly 2
+ $URIComponents.Keys | Should -Be @("Segments", "Parameters")
+ $URIComponents.Segments | Should -Be @("segment1", "segment2", '123')
+ $URIComponents.Parameters.Count | Should -BeExactly 0
+ $URIComponents.Parameters | Should -BeOfType [hashtable]
+ }
+
+ It "Should add multiple IDs to the parameters id__in" {
+ $URIComponents = BuildURIComponents -URISegments @('segment1', 'segment2') -ParametersDictionary @{'id' = "123", "456"}
+
+ $URIComponents | Should -BeOfType [hashtable]
+ $URIComponents.Keys.Count | Should -BeExactly 2
+ $URIComponents.Keys | Should -Be @("Segments", "Parameters")
+ $URIComponents.Segments | Should -Be @("segment1", "segment2")
+ $URIComponents.Parameters.Count | Should -BeExactly 1
+ $URIComponents.Parameters | Should -BeOfType [hashtable]
+ $URIComponents.Parameters['id__in'] | Should -Be '123,456'
+ }
+
+ It "Should skip a particular parameter name" {
+ $URIComponents = BuildURIComponents -URISegments @('segment1', 'segment2') -ParametersDictionary @{'param1' = 1; 'param2' = 2} -SkipParameterByName 'param2'
+
+ $URIComponents | Should -BeOfType [hashtable]
+ $URIComponents.Keys.Count | Should -BeExactly 2
+ $URIComponents.Keys | Should -Be @("Segments", "Parameters")
+ $URIComponents.Segments | Should -Be @("segment1", "segment2")
+ $URIComponents.Parameters.Count | Should -BeExactly 1
+ $URIComponents.Parameters | Should -BeOfType [hashtable]
+ $URIComponents.Parameters['param1'] | Should -Be 1
+ $URIComponents.Parameters['param2'] | Should -BeNullOrEmpty
+ }
+
+ It "Should add a query (q) parameter" {
+ $URIComponents = BuildURIComponents -URISegments @('segment1', 'segment2') -ParametersDictionary @{'query' = 'mytestquery'}
+
+ $URIComponents | Should -BeOfType [hashtable]
+ $URIComponents.Keys.Count | Should -BeExactly 2
+ $URIComponents.Keys | Should -Be @("Segments", "Parameters")
+ $URIComponents.Segments | Should -Be @("segment1", "segment2")
+ $URIComponents.Parameters.Count | Should -BeExactly 1
+ $URIComponents.Parameters | Should -BeOfType [hashtable]
+ $URIComponents.Parameters['q'] | Should -Be 'mytestquery'
+ }
+ }
+
+ Context -Name "Invoking request tests" -Fixture {
Mock -CommandName 'Invoke-RestMethod' -Verifiable -MockWith {
# Return an object of the items we would normally pass to Invoke-RestMethod
return [pscustomobject]@{
@@ -123,7 +183,7 @@ Describe "Helpers tests" -Tag 'Core', 'Helpers' -Fixture {
$Result = InvokeNetboxRequest -URI $URIBuilder -Raw
Assert-VerifiableMock
-
+
$Result.Method | Should -Be 'GET'
$Result.Uri | Should -Be $URIBuilder.Uri.AbsoluteUri
$Result.Headers | Should -BeOfType [System.Collections.HashTable]
@@ -136,7 +196,9 @@ Describe "Helpers tests" -Tag 'Core', 'Helpers' -Fixture {
It "Should generate a POST request with body" {
$URIBuilder = BuildNewURI -Hostname "netbox.domain.com" -Segments 'seg1', 'seg2'
- $Result = InvokeNetboxRequest -URI $URIBuilder -Method POST -Body @{'bodyparam1' = 'val1'} -Raw
+ $Result = InvokeNetboxRequest -URI $URIBuilder -Method POST -Body @{
+ 'bodyparam1' = 'val1'
+ } -Raw
Assert-VerifiableMock
@@ -161,6 +223,7 @@ Describe "Helpers tests" -Tag 'Core', 'Helpers' -Fixture {
$Result.Method | Should -Be 'POST'
$Result.Body | Should -Be '{"bodyparam1":"val1"}'
+ $Result.Headers.Count | Should -BeExactly 2
$Result.Headers.Authorization | Should -Be "Token faketoken"
$Result.Headers.Connection | Should -Be "keep-alive"
}
@@ -179,6 +242,235 @@ Describe "Helpers tests" -Tag 'Core', 'Helpers' -Fixture {
} | Should -Throw
}
}
+
+ 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'
+
+ It "Should return a valid integer for status when provided a name" {
+ $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName 'virtual-machine:status' -ProvidedValue 'Active'
+
+ $Result | Should -BeOfType [uint16]
+ $Result | Should -BeExactly 1
+ }
+
+ It "Should return a valid integer for status when provided an integer" {
+ $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName 'virtual-machine:status' -ProvidedValue 0
+
+ $Result | Should -BeOfType [uint16]
+ $Result | Should -BeExactly 0
+ }
+
+ It "Should throw because of an invalid choice" {
+ {
+ ValidateChoice -MajorObject $MajorObject -ChoiceName 'virtual-machine:status' -ProvidedValue 'Fake'
+ } | Should -Throw
+ }
+ }
+
+ Context -Name "IPAM choices" -Fixture {
+ $MajorObject = 'IPAM'
+
+ Context -Name "aggregate:family" -Fixture {
+ $ChoiceName = 'aggregate:family'
+
+ It "Should return a valid integer when provided a name" {
+ $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 'IPv4'
+
+ $Result | Should -BeOfType [uint16]
+ $Result | Should -BeExactly 4
+ }
+
+ It "Should return a valid integer when provided an integer" {
+ $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 4
+
+ $Result | Should -BeOfType [uint16]
+ $Result | Should -BeExactly 4
+ }
+
+ It "Should throw because of an invalid choice" {
+ {
+ ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 0
+ } | Should -Throw
+ }
+ }
+
+ Context -Name "prefix:family" {
+ $ChoiceName = 'prefix:family'
+
+ It "Should return a valid integer when provided a name" {
+ $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 'IPv4'
+
+ $Result | Should -BeOfType [uint16]
+ $Result | Should -BeExactly 4
+ }
+
+ It "Should return a valid integer when provided an integer" {
+ $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 4
+
+ $Result | Should -BeOfType [uint16]
+ $Result | Should -BeExactly 4
+ }
+
+ It "Should throw because of an invalid choice" {
+ {
+ ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 0
+ } | Should -Throw
+ }
+ }
+
+ Context -Name "prefix:status" {
+ $ChoiceName = 'prefix: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 1
+
+ $Result | Should -BeOfType [uint16]
+ $Result | Should -BeExactly 1
+ }
+
+ It "Should throw because of an invalid choice" {
+ {
+ ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 10
+ } | Should -Throw
+ }
+ }
+
+ Context -Name "ip-address:family" {
+ $ChoiceName = 'ip-address:family'
+
+ It "Should return a valid integer when provided a name" {
+ $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 'IPv4'
+
+ $Result | Should -BeOfType [uint16]
+ $Result | Should -BeExactly 4
+ }
+
+ It "Should return a valid integer when provided an integer" {
+ $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 4
+
+ $Result | Should -BeOfType [uint16]
+ $Result | Should -BeExactly 4
+ }
+
+ It "Should throw because of an invalid choice" {
+ {
+ ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 10
+ } | Should -Throw
+ }
+ }
+
+ Context -Name "ip-address:status" {
+ $ChoiceName = 'ip-address: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 1
+
+ $Result | Should -BeOfType [uint16]
+ $Result | Should -BeExactly 1
+ }
+
+ It "Should throw because of an invalid choice" {
+ {
+ ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 10
+ } | Should -Throw
+ }
+ }
+
+ Context -Name "ip-address:role" {
+ $ChoiceName = 'ip-address:role'
+
+ It "Should return a valid integer when provided a name" {
+ $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 'Anycast'
+
+ $Result | Should -BeOfType [uint16]
+ $Result | Should -BeExactly 30
+ }
+
+ It "Should return a valid integer when provided an integer" {
+ $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 30
+
+ $Result | Should -BeOfType [uint16]
+ $Result | Should -BeExactly 30
+ }
+
+ It "Should throw because of an invalid choice" {
+ {
+ ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 1
+ } | Should -Throw
+ }
+ }
+
+ Context -Name "vlan:status" {
+ $ChoiceName = 'vlan: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 1
+
+ $Result | Should -BeOfType [uint16]
+ $Result | Should -BeExactly 1
+ }
+
+ It "Should throw because of an invalid choice" {
+ {
+ ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 0
+ } | Should -Throw
+ }
+ }
+
+ Context -Name "service:protocol" {
+ $ChoiceName = 'service:protocol'
+
+ It "Should return a valid integer when provided a name" {
+ $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 'TCP'
+
+ $Result | Should -BeOfType [uint16]
+ $Result | Should -BeExactly 6
+ }
+
+ It "Should return a valid integer when provided an integer" {
+ $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 6
+
+ $Result | Should -BeOfType [uint16]
+ $Result | Should -BeExactly 6
+ }
+
+ It "Should throw because of an invalid choice" {
+ {
+ ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 0
+ } | Should -Throw
+ }
+ }
+ }
+
+
+ }
+
+
}
}
diff --git a/Staging/Tests/IPAM.Tests.ps1 b/Staging/Tests/IPAM.Tests.ps1
index ef9b994..fd21b2d 100644
--- a/Staging/Tests/IPAM.Tests.ps1
+++ b/Staging/Tests/IPAM.Tests.ps1
@@ -47,6 +47,12 @@ 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
@@ -182,31 +188,25 @@ Describe -Name "IPAM tests" -Tag 'Ipam' -Fixture {
$Result.Headers.Authorization | Should -Be "Token faketoken"
}
- #region TODO: Figure out how to mock/test Verification appropriately...
- <#
It "Should request with a family number" {
- Mock -CommandName 'Get-NetboxIPAMChoices' -ModuleName 'NetboxPS' -MockWith {
- return @"
-{"aggregate:family":[{"label":"IPv4","value":4},{"label":"IPv6","value":6}],"prefix:family":[{"label":"IPv4","value":4},{"label":"IPv6","value":6}],"prefix:status":[{"label":"Container","value":0},{"label":"Active","value":1},{"label":"Reserved","value":2},{"label":"Deprecated","value":3}],"ip-address:family":[{"label":"IPv4","value":4},{"label":"IPv6","value":6}],"ip-address:status":[{"label":"Active","value":1},{"label":"Reserved","value":2},{"label":"Deprecated","value":3},{"label":"DHCP","value":5}],"ip-address:role":[{"label":"Loopback","value":10},{"label":"Secondary","value":20},{"label":"Anycast","value":30},{"label":"VIP","value":40},{"label":"VRRP","value":41},{"label":"HSRP","value":42},{"label":"GLBP","value":43},{"label":"CARP","value":44}],"vlan:status":[{"label":"Active","value":1},{"label":"Reserved","value":2},{"label":"Deprecated","value":3}],"service:protocol":[{"label":"TCP","value":6},{"label":"UDP","value":17}]}
-"@ | ConvertFrom-Json
- }
-
- Mock -CommandName 'Connect-NetboxAPI' -ModuleName 'NetboxPS' -MockWith {
- $script:NetboxConfig.Connected = $true
- $script:NetboxConfig.Choices.IPAM = Get-NetboxIPAMChoices
- }
- Connect-NetboxAPI
- $Result = Get-NetboxIPAMAddress -Role 4
+ $Result = Get-NetboxIPAMAddress -Family 4
Assert-VerifiableMock
- Assert-MockCalled -CommandName "Get-NetboxIPAMChoices"
$Result.Method | Should -Be 'GET'
- $Result.Uri | Should -Be 'https://netbox.domain.com/api/ipam/ip-addresses/?role=4'
+ $Result.Uri | Should -Be 'https://netbox.domain.com/api/ipam/ip-addresses/?family=4'
+ $Result.Headers.Keys.Count | Should -BeExactly 1
+ }
+
+ It "Should request with a family name" {
+ $Result = Get-NetboxIPAMAddress -Family 'IPv4'
+
+ Assert-VerifiableMock
+
+ $Result.Method | Should -Be 'GET'
+ $Result.Uri | Should -Be 'https://netbox.domain.com/api/ipam/ip-addresses/?family=4'
$Result.Headers.Keys.Count | Should -BeExactly 1
}
- #>
- #endregion
}
Context -Name "Get-NetboxIPAMAvailableIP" -Fixture {
@@ -233,7 +233,7 @@ Describe -Name "IPAM tests" -Tag 'Ipam' -Fixture {
}
}
- Context -Name "Get-NetboxIPAMPrefix" {
+ Context -Name "Get-NetboxIPAMPrefix" -Fixture {
It "Should request the default number of prefixes" {
$Result = Get-NetboxIPAMPrefix
@@ -311,11 +311,7 @@ Describe -Name "IPAM tests" -Tag 'Ipam' -Fixture {
$Result.Headers.Authorization | Should -Be "Token faketoken"
}
- <#
It "Should request with family of 4" {
- Mock -CommandName "VerifyIPAMChoices" -ModuleName 'NetboxPS' -MockWith {
- return 4
- } -Verifiable
$Result = Get-NetboxIPAMPrefix -Family 4
Assert-VerifiableMock
@@ -325,7 +321,24 @@ Describe -Name "IPAM tests" -Tag 'Ipam' -Fixture {
$Result.Headers.Keys.Count | Should -BeExactly 1
$Result.Headers.Authorization | Should -Be "Token faketoken"
}
- #>
+
+ It "Should throw because the mask length is too large" {
+ {
+ Get-NetboxIPAMPrefix -Mask_length 128
+ } | Should -Throw
+ }
+
+ It "Should throw because the mask length is too small" {
+ {
+ Get-NetboxIPAMPrefix -Mask_length -1
+ } | Should -Throw
+ }
+
+ It "Should not throw because the mask length is just right" {
+ {
+ Get-NetboxIPAMPrefix -Mask_length 24
+ } | Should -Not -Throw
+ }
It "Should request with mask length 24" {
$Result = Get-NetboxIPAMPrefix -Mask_length 24
@@ -337,11 +350,118 @@ Describe -Name "IPAM tests" -Tag 'Ipam' -Fixture {
$Result.Headers.Keys.Count | Should -BeExactly 1
$Result.Headers.Authorization | Should -Be "Token faketoken"
}
+ }
+
+ Context -Name "Add-NetboxIPAMAddress" -Fixture {
+ It "Should add a basic IP address" {
+ $Result = Add-NetboxIPAMAddress -Address '10.0.0.1/24'
+
+ Assert-VerifiableMock
+
+ $Result.Method | Should -Be 'POST'
+ $Result.Uri | Should -Be 'https://netbox.domain.com/api/ipam/ip-addresses/'
+ $Result.Headers.Keys.Count | Should -BeExactly 1
+ $Result.Body | Should -Be '{"status":1,"address":"10.0.0.1/24"}'
+ }
- It "Should throw because the mask length is too large" {
- {
- Get-NetboxIPAMPrefix -Mask_length 128
- } | Should -Throw
+ It "Should add an IP with a status and role names" {
+ $Result = Add-NetboxIPAMAddress -Address '10.0.0.1/24' -Status 'Reserved' -Role 'Anycast'
+
+ Assert-VerifiableMock
+
+ $Result.Method | Should -Be 'POST'
+ $Result.Uri | Should -Be 'https://netbox.domain.com/api/ipam/ip-addresses/'
+ $Result.Headers.Keys.Count | Should -BeExactly 1
+ $Result.Body | Should -Be '{"status":2,"address":"10.0.0.1/24","role":30}'
+ }
+
+ It "Should add an IP with a status and role values" {
+ $Result = Add-NetboxIPAMAddress -Address '10.0.1.1/24' -Status '1' -Role '10'
+
+ Assert-VerifiableMock
+
+ $Result.Method | Should -Be 'POST'
+ $Result.Uri | Should -Be 'https://netbox.domain.com/api/ipam/ip-addresses/'
+ $Result.Headers.Keys.Count | Should -BeExactly 1
+ $Result.Body | Should -Be '{"status":1,"address":"10.0.1.1/24","role":10}'
+ }
+ }
+
+ 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
+ }
+ }
+
+ $Result = Remove-NetboxIPAMAddress -Id '4109' -Force
+
+ Assert-VerifiableMock
+ Assert-MockCalled -CommandName "Get-NetboxIPAMAddress" -Times 1
+
+ $Result.Method | Should -Be 'DELETE'
+ $Result.Uri | Should -Be 'https://netbox.domain.com/api/ipam/ip-addresses/4109/'
+ $Result.Headers.Keys.Count | Should -BeExactly 1
+ $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
+ }
+ )
+ }
+
+ $Result = Remove-NetboxIPAMAddress -Id 4109, 4110 -Force
+
+ Assert-VerifiableMock
+ Assert-MockCalled -CommandName "Get-NetboxIPAMAddress" -Times 2
+
+ $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
+ }
+ }
+
+ 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
+ }
+ }
+
+ $Result = Set-NetboxIPAMAddress -Id '4109' -Status 2 -Force
+
+ Assert-VerifiableMock
+ Assert-MockCalled -CommandName "Get-NetboxIPAMAddress" -Times 1
+
+ $Result.Method | Should -Be 'PATCH'
+ $Result.Uri | Should -Be 'https://netbox.domain.com/api/ipam/ip-addresses/4109/'
+ $Result.Headers.Keys.Count | Should -BeExactly 1
+ $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
+
+ Assert-VerifiableMock
+ Assert-MockCalled -CommandName "Get-NetboxIPAMAddress" -Times 1
+
+ $Result.Method | Should -Be 'PATCH'
+ $Result.Uri | Should -Be 'https://netbox.domain.com/api/ipam/ip-addresses/4109/'
+ $Result.Headers.Keys.Count | Should -BeExactly 1
+ $Result.Body | Should -Be '{"vrf":10,"description":"Test description","tenant":14}'
}
}
}
diff --git a/Staging/Tests/Virtualization.Tests.ps1 b/Staging/Tests/Virtualization.Tests.ps1
index 8174020..6b68819 100644
--- a/Staging/Tests/Virtualization.Tests.ps1
+++ b/Staging/Tests/Virtualization.Tests.ps1
@@ -46,6 +46,8 @@ Describe -Name "Virtualization tests" -Tag 'Virtualization' -Fixture {
}
InModuleScope -ModuleName 'NetboxPS' -ScriptBlock {
+ $script:NetboxConfig.Choices.Virtualization = (Get-Content "$PSScriptRoot\VirtualizationChoices.json" -ErrorAction Stop | ConvertFrom-Json)
+
Context -Name "Get-NetboxVirtualMachine" -Fixture {
It "Should request the default number of VMs" {
$Result = Get-NetboxVirtualMachine
@@ -128,7 +130,7 @@ Describe -Name "Virtualization tests" -Tag 'Virtualization' -Fixture {
}
}
- Context -Name "Get-VirtualMachineInterface" -Fixture {
+ Context -Name "Get-NetboxVirtualMachineInterface" -Fixture {
It "Should request the default number of interfaces" {
$Result = Get-NetboxVirtualMachineInterface
@@ -190,7 +192,7 @@ Describe -Name "Virtualization tests" -Tag 'Virtualization' -Fixture {
}
}
- Context -Name "Get-VirtualMachineCluster" -Fixture {
+ Context -Name "Get-NetboxVirtualMachineCluster" -Fixture {
It "Should request the default number of clusters" {
$Result = Get-NetboxVirtualizationCluster
@@ -262,7 +264,7 @@ Describe -Name "Virtualization tests" -Tag 'Virtualization' -Fixture {
}
}
- Context -Name "Get-VirtualMachineClusterGroup" -Fixture {
+ Context -Name "Get-NetboxVirtualMachineClusterGroup" -Fixture {
It "Should request the default number of cluster groups" {
$Result = Get-NetboxVirtualizationClusterGroup
@@ -351,6 +353,43 @@ Describe -Name "Virtualization tests" -Tag 'Virtualization' -Fixture {
$Result.Body | Should -Be '{"mtu":1500,"description":"Test description","enabled":true,"virtual_machine":10,"name":"Ethernet0","mac_address":"11:22:33:44:55:66"}'
}
}
+
+ Context -Name "Set-NetboxVirtualMachine" -Fixture {
+ Mock -CommandName "Get-NetboxVirtualMachine" -ModuleName NetboxPS -MockWith {
+ return @{
+ 'Id' = 1234
+ 'Name' = 'TestVM'
+ }
+ }
+
+ It "Should set a VM to a new name" {
+ $Result = Set-NetboxVirtualMachine -Id 1234 -Name 'newtestname' -Force
+
+ Assert-VerifiableMock
+
+ $Result.Method | Should -Be 'PATCH'
+ $Result.URI | Should -Be 'https://netbox.domain.com/api/virtualization/virtual-machines/1234/'
+ $Result.Headers.Keys.Count | Should -BeExactly 1
+ $Result.Body | Should -Be '{"name":"newtestname"}'
+ }
+
+ It "Should set a VM with a new name, cluster, platform, and status" {
+ $Result = Set-NetboxVirtualMachine -Id 1234 -Name 'newtestname' -Cluster 10 -Platform 15 -Status 'Offline' -Force
+
+ Assert-VerifiableMock
+
+ $Result.Method | Should -Be 'PATCH'
+ $Result.URI | Should -Be 'https://netbox.domain.com/api/virtualization/virtual-machines/1234/'
+ $Result.Headers.Keys.Count | Should -BeExactly 1
+ $Result.Body | Should -Be '{"cluster":10,"platform":15,"name":"newtestname","status":0}'
+ }
+
+ It "Should throw because of an invalid status" {
+ { Set-NetboxVirtualMachine -Id 1234 -Status 'Fake' -Force } | Should -Throw
+
+ Assert-VerifiableMock
+ }
+ }
}
}
diff --git a/Tests/Helpers.Tests.ps1 b/Tests/Helpers.Tests.ps1
index 395c666..331da0f 100644
--- a/Tests/Helpers.Tests.ps1
+++ b/Tests/Helpers.Tests.ps1
@@ -31,8 +31,8 @@ Describe "Helpers tests" -Tag 'Core', 'Helpers' -Fixture {
return $true
} -ModuleName 'NetboxPS'
- Context "Building URI tests" {
- InModuleScope -ModuleName 'NetboxPS' -ScriptBlock {
+ InModuleScope -ModuleName 'NetboxPS' -ScriptBlock {
+ Context -Name "Building URIBuilder" -Fixture {
It "Should give a basic URI object" {
BuildNewURI -HostName 'netbox.domain.com' | Should -BeOfType [System.UriBuilder]
}
@@ -85,10 +85,70 @@ Describe "Helpers tests" -Tag 'Core', 'Helpers' -Fixture {
$URIBuilder.URI.AbsoluteURI | Should -BeExactly 'https://netbox.domain.com/api/seg1/seg2/?param1=paramval1¶m2=paramval2'
}
}
- }
-
- Context "Invoking request tests" {
- InModuleScope -ModuleName 'NetboxPS' -ScriptBlock {
+
+ Context -Name "Building URI components" -Fixture {
+ It "Should give a basic hashtable" {
+ $URIComponents = BuildURIComponents -URISegments @('segment1', 'segment2') -ParametersDictionary @{'param1' = 1}
+
+ $URIComponents | Should -BeOfType [hashtable]
+ $URIComponents.Keys.Count | Should -BeExactly 2
+ $URIComponents.Keys | Should -Be @("Segments", "Parameters")
+ $URIComponents.Segments | Should -Be @("segment1", "segment2")
+ $URIComponents.Parameters.Count | Should -BeExactly 1
+ $URIComponents.Parameters | Should -BeOfType [hashtable]
+ $URIComponents.Parameters['param1'] | Should -Be 1
+ }
+
+ It "Should add a single ID parameter to the segments" {
+ $URIComponents = BuildURIComponents -URISegments @('segment1', 'segment2') -ParametersDictionary @{'id' = 123}
+
+ $URIComponents | Should -BeOfType [hashtable]
+ $URIComponents.Keys.Count | Should -BeExactly 2
+ $URIComponents.Keys | Should -Be @("Segments", "Parameters")
+ $URIComponents.Segments | Should -Be @("segment1", "segment2", '123')
+ $URIComponents.Parameters.Count | Should -BeExactly 0
+ $URIComponents.Parameters | Should -BeOfType [hashtable]
+ }
+
+ It "Should add multiple IDs to the parameters id__in" {
+ $URIComponents = BuildURIComponents -URISegments @('segment1', 'segment2') -ParametersDictionary @{'id' = "123", "456"}
+
+ $URIComponents | Should -BeOfType [hashtable]
+ $URIComponents.Keys.Count | Should -BeExactly 2
+ $URIComponents.Keys | Should -Be @("Segments", "Parameters")
+ $URIComponents.Segments | Should -Be @("segment1", "segment2")
+ $URIComponents.Parameters.Count | Should -BeExactly 1
+ $URIComponents.Parameters | Should -BeOfType [hashtable]
+ $URIComponents.Parameters['id__in'] | Should -Be '123,456'
+ }
+
+ It "Should skip a particular parameter name" {
+ $URIComponents = BuildURIComponents -URISegments @('segment1', 'segment2') -ParametersDictionary @{'param1' = 1; 'param2' = 2} -SkipParameterByName 'param2'
+
+ $URIComponents | Should -BeOfType [hashtable]
+ $URIComponents.Keys.Count | Should -BeExactly 2
+ $URIComponents.Keys | Should -Be @("Segments", "Parameters")
+ $URIComponents.Segments | Should -Be @("segment1", "segment2")
+ $URIComponents.Parameters.Count | Should -BeExactly 1
+ $URIComponents.Parameters | Should -BeOfType [hashtable]
+ $URIComponents.Parameters['param1'] | Should -Be 1
+ $URIComponents.Parameters['param2'] | Should -BeNullOrEmpty
+ }
+
+ It "Should add a query (q) parameter" {
+ $URIComponents = BuildURIComponents -URISegments @('segment1', 'segment2') -ParametersDictionary @{'query' = 'mytestquery'}
+
+ $URIComponents | Should -BeOfType [hashtable]
+ $URIComponents.Keys.Count | Should -BeExactly 2
+ $URIComponents.Keys | Should -Be @("Segments", "Parameters")
+ $URIComponents.Segments | Should -Be @("segment1", "segment2")
+ $URIComponents.Parameters.Count | Should -BeExactly 1
+ $URIComponents.Parameters | Should -BeOfType [hashtable]
+ $URIComponents.Parameters['q'] | Should -Be 'mytestquery'
+ }
+ }
+
+ Context -Name "Invoking request tests" -Fixture {
Mock -CommandName 'Invoke-RestMethod' -Verifiable -MockWith {
# Return an object of the items we would normally pass to Invoke-RestMethod
return [pscustomobject]@{
@@ -123,7 +183,7 @@ Describe "Helpers tests" -Tag 'Core', 'Helpers' -Fixture {
$Result = InvokeNetboxRequest -URI $URIBuilder -Raw
Assert-VerifiableMock
-
+
$Result.Method | Should -Be 'GET'
$Result.Uri | Should -Be $URIBuilder.Uri.AbsoluteUri
$Result.Headers | Should -BeOfType [System.Collections.HashTable]
@@ -136,7 +196,9 @@ Describe "Helpers tests" -Tag 'Core', 'Helpers' -Fixture {
It "Should generate a POST request with body" {
$URIBuilder = BuildNewURI -Hostname "netbox.domain.com" -Segments 'seg1', 'seg2'
- $Result = InvokeNetboxRequest -URI $URIBuilder -Method POST -Body @{'bodyparam1' = 'val1'} -Raw
+ $Result = InvokeNetboxRequest -URI $URIBuilder -Method POST -Body @{
+ 'bodyparam1' = 'val1'
+ } -Raw
Assert-VerifiableMock
@@ -161,6 +223,7 @@ Describe "Helpers tests" -Tag 'Core', 'Helpers' -Fixture {
$Result.Method | Should -Be 'POST'
$Result.Body | Should -Be '{"bodyparam1":"val1"}'
+ $Result.Headers.Count | Should -BeExactly 2
$Result.Headers.Authorization | Should -Be "Token faketoken"
$Result.Headers.Connection | Should -Be "keep-alive"
}
@@ -179,6 +242,235 @@ Describe "Helpers tests" -Tag 'Core', 'Helpers' -Fixture {
} | Should -Throw
}
}
+
+ 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'
+
+ It "Should return a valid integer for status when provided a name" {
+ $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName 'virtual-machine:status' -ProvidedValue 'Active'
+
+ $Result | Should -BeOfType [uint16]
+ $Result | Should -BeExactly 1
+ }
+
+ It "Should return a valid integer for status when provided an integer" {
+ $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName 'virtual-machine:status' -ProvidedValue 0
+
+ $Result | Should -BeOfType [uint16]
+ $Result | Should -BeExactly 0
+ }
+
+ It "Should throw because of an invalid choice" {
+ {
+ ValidateChoice -MajorObject $MajorObject -ChoiceName 'virtual-machine:status' -ProvidedValue 'Fake'
+ } | Should -Throw
+ }
+ }
+
+ Context -Name "IPAM choices" -Fixture {
+ $MajorObject = 'IPAM'
+
+ Context -Name "aggregate:family" -Fixture {
+ $ChoiceName = 'aggregate:family'
+
+ It "Should return a valid integer when provided a name" {
+ $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 'IPv4'
+
+ $Result | Should -BeOfType [uint16]
+ $Result | Should -BeExactly 4
+ }
+
+ It "Should return a valid integer when provided an integer" {
+ $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 4
+
+ $Result | Should -BeOfType [uint16]
+ $Result | Should -BeExactly 4
+ }
+
+ It "Should throw because of an invalid choice" {
+ {
+ ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 0
+ } | Should -Throw
+ }
+ }
+
+ Context -Name "prefix:family" {
+ $ChoiceName = 'prefix:family'
+
+ It "Should return a valid integer when provided a name" {
+ $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 'IPv4'
+
+ $Result | Should -BeOfType [uint16]
+ $Result | Should -BeExactly 4
+ }
+
+ It "Should return a valid integer when provided an integer" {
+ $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 4
+
+ $Result | Should -BeOfType [uint16]
+ $Result | Should -BeExactly 4
+ }
+
+ It "Should throw because of an invalid choice" {
+ {
+ ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 0
+ } | Should -Throw
+ }
+ }
+
+ Context -Name "prefix:status" {
+ $ChoiceName = 'prefix: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 1
+
+ $Result | Should -BeOfType [uint16]
+ $Result | Should -BeExactly 1
+ }
+
+ It "Should throw because of an invalid choice" {
+ {
+ ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 10
+ } | Should -Throw
+ }
+ }
+
+ Context -Name "ip-address:family" {
+ $ChoiceName = 'ip-address:family'
+
+ It "Should return a valid integer when provided a name" {
+ $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 'IPv4'
+
+ $Result | Should -BeOfType [uint16]
+ $Result | Should -BeExactly 4
+ }
+
+ It "Should return a valid integer when provided an integer" {
+ $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 4
+
+ $Result | Should -BeOfType [uint16]
+ $Result | Should -BeExactly 4
+ }
+
+ It "Should throw because of an invalid choice" {
+ {
+ ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 10
+ } | Should -Throw
+ }
+ }
+
+ Context -Name "ip-address:status" {
+ $ChoiceName = 'ip-address: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 1
+
+ $Result | Should -BeOfType [uint16]
+ $Result | Should -BeExactly 1
+ }
+
+ It "Should throw because of an invalid choice" {
+ {
+ ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 10
+ } | Should -Throw
+ }
+ }
+
+ Context -Name "ip-address:role" {
+ $ChoiceName = 'ip-address:role'
+
+ It "Should return a valid integer when provided a name" {
+ $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 'Anycast'
+
+ $Result | Should -BeOfType [uint16]
+ $Result | Should -BeExactly 30
+ }
+
+ It "Should return a valid integer when provided an integer" {
+ $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 30
+
+ $Result | Should -BeOfType [uint16]
+ $Result | Should -BeExactly 30
+ }
+
+ It "Should throw because of an invalid choice" {
+ {
+ ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 1
+ } | Should -Throw
+ }
+ }
+
+ Context -Name "vlan:status" {
+ $ChoiceName = 'vlan: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 1
+
+ $Result | Should -BeOfType [uint16]
+ $Result | Should -BeExactly 1
+ }
+
+ It "Should throw because of an invalid choice" {
+ {
+ ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 0
+ } | Should -Throw
+ }
+ }
+
+ Context -Name "service:protocol" {
+ $ChoiceName = 'service:protocol'
+
+ It "Should return a valid integer when provided a name" {
+ $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 'TCP'
+
+ $Result | Should -BeOfType [uint16]
+ $Result | Should -BeExactly 6
+ }
+
+ It "Should return a valid integer when provided an integer" {
+ $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 6
+
+ $Result | Should -BeOfType [uint16]
+ $Result | Should -BeExactly 6
+ }
+
+ It "Should throw because of an invalid choice" {
+ {
+ ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 0
+ } | Should -Throw
+ }
+ }
+ }
+
+
+ }
+
+
}
}
diff --git a/Tests/IPAM.Tests.ps1 b/Tests/IPAM.Tests.ps1
index 6e6485b..fd21b2d 100644
--- a/Tests/IPAM.Tests.ps1
+++ b/Tests/IPAM.Tests.ps1
@@ -49,6 +49,10 @@ 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
@@ -368,7 +372,7 @@ Describe -Name "IPAM tests" -Tag 'Ipam' -Fixture {
$Result.Method | Should -Be 'POST'
$Result.Uri | Should -Be 'https://netbox.domain.com/api/ipam/ip-addresses/'
$Result.Headers.Keys.Count | Should -BeExactly 1
- $Result.Body | Should -Be '{"status":2,"role":30,"address":"10.0.0.1/24"}'
+ $Result.Body | Should -Be '{"status":2,"address":"10.0.0.1/24","role":30}'
}
It "Should add an IP with a status and role values" {
@@ -379,7 +383,7 @@ Describe -Name "IPAM tests" -Tag 'Ipam' -Fixture {
$Result.Method | Should -Be 'POST'
$Result.Uri | Should -Be 'https://netbox.domain.com/api/ipam/ip-addresses/'
$Result.Headers.Keys.Count | Should -BeExactly 1
- $Result.Body | Should -Be '{"status":1,"role":10,"address":"10.0.1.1/24"}'
+ $Result.Body | Should -Be '{"status":1,"address":"10.0.1.1/24","role":10}'
}
}
@@ -457,7 +461,7 @@ Describe -Name "IPAM tests" -Tag 'Ipam' -Fixture {
$Result.Method | Should -Be 'PATCH'
$Result.Uri | Should -Be 'https://netbox.domain.com/api/ipam/ip-addresses/4109/'
$Result.Headers.Keys.Count | Should -BeExactly 1
- $Result.Body | Should -Be '{"description":"Test description","status":1,"tenant":14,"vrf":10}'
+ $Result.Body | Should -Be '{"vrf":10,"description":"Test description","tenant":14}'
}
}
}
diff --git a/Tests/Virtualization.Tests.ps1 b/Tests/Virtualization.Tests.ps1
index 665b69a..6b68819 100644
--- a/Tests/Virtualization.Tests.ps1
+++ b/Tests/Virtualization.Tests.ps1
@@ -307,7 +307,6 @@ Describe -Name "Virtualization tests" -Tag 'Virtualization' -Fixture {
}
Context -Name "Add-NetboxVirtualMachine" -Fixture {
-
It "Should add a basic VM" {
$Result = Add-NetboxVirtualMachine -Name 'testvm' -Cluster 1
@@ -316,7 +315,7 @@ Describe -Name "Virtualization tests" -Tag 'Virtualization' -Fixture {
$Result.Method | Should -Be 'POST'
$Result.Uri | Should -Be 'https://netbox.domain.com/api/virtualization/virtual-machines/'
$Result.Headers.Keys.Count | Should -BeExactly 1
- $Result.Body | Should -Be '{"name":"testvm","cluster":1,"status":1}'
+ $Result.Body | Should -Be '{"cluster":1,"name":"testvm","status":1}'
}
It "Should add a VM with CPUs, Memory, Disk, tenancy, and comments" {
@@ -327,7 +326,7 @@ Describe -Name "Virtualization tests" -Tag 'Virtualization' -Fixture {
$Result.Method | Should -Be 'POST'
$Result.Uri | Should -Be 'https://netbox.domain.com/api/virtualization/virtual-machines/'
$Result.Headers.Keys.Count | Should -BeExactly 1
- $Result.Body | Should -Be '{"tenant":11,"name":"testvm","comments":"these are comments","cluster":1,"status":1,"memory":4096,"vcpus":4,"disk":50}'
+ $Result.Body | Should -Be '{"tenant":11,"comments":"these are comments","disk":50,"memory":4096,"name":"testvm","cluster":1,"status":1,"vcpus":4}'
}
}
@@ -340,7 +339,7 @@ Describe -Name "Virtualization tests" -Tag 'Virtualization' -Fixture {
$Result.Method | Should -Be 'POST'
$Result.Uri | Should -Be 'https://netbox.domain.com/api/virtualization/interfaces/'
$Result.Headers.Keys.Count | Should -BeExactly 1
- $Result.Body | Should -Be '{"virtual_machine":10,"enabled":true,"name":"Ethernet0"}'
+ $Result.Body | Should -Be '{"virtual_machine":10,"name":"Ethernet0","enabled":true}'
}
It "Should add an interface with a MAC, MTU, and Description" {
@@ -351,7 +350,44 @@ Describe -Name "Virtualization tests" -Tag 'Virtualization' -Fixture {
$Result.Method | Should -Be 'POST'
$Result.Uri | Should -Be 'https://netbox.domain.com/api/virtualization/interfaces/'
$Result.Headers.Keys.Count | Should -BeExactly 1
- $Result.Body | Should -Be '{"description":"Test description","virtual_machine":10,"enabled":true,"name":"Ethernet0","mtu":1500,"mac_address":"11:22:33:44:55:66"}'
+ $Result.Body | Should -Be '{"mtu":1500,"description":"Test description","enabled":true,"virtual_machine":10,"name":"Ethernet0","mac_address":"11:22:33:44:55:66"}'
+ }
+ }
+
+ Context -Name "Set-NetboxVirtualMachine" -Fixture {
+ Mock -CommandName "Get-NetboxVirtualMachine" -ModuleName NetboxPS -MockWith {
+ return @{
+ 'Id' = 1234
+ 'Name' = 'TestVM'
+ }
+ }
+
+ It "Should set a VM to a new name" {
+ $Result = Set-NetboxVirtualMachine -Id 1234 -Name 'newtestname' -Force
+
+ Assert-VerifiableMock
+
+ $Result.Method | Should -Be 'PATCH'
+ $Result.URI | Should -Be 'https://netbox.domain.com/api/virtualization/virtual-machines/1234/'
+ $Result.Headers.Keys.Count | Should -BeExactly 1
+ $Result.Body | Should -Be '{"name":"newtestname"}'
+ }
+
+ It "Should set a VM with a new name, cluster, platform, and status" {
+ $Result = Set-NetboxVirtualMachine -Id 1234 -Name 'newtestname' -Cluster 10 -Platform 15 -Status 'Offline' -Force
+
+ Assert-VerifiableMock
+
+ $Result.Method | Should -Be 'PATCH'
+ $Result.URI | Should -Be 'https://netbox.domain.com/api/virtualization/virtual-machines/1234/'
+ $Result.Headers.Keys.Count | Should -BeExactly 1
+ $Result.Body | Should -Be '{"cluster":10,"platform":15,"name":"newtestname","status":0}'
+ }
+
+ It "Should throw because of an invalid status" {
+ { Set-NetboxVirtualMachine -Id 1234 -Status 'Fake' -Force } | Should -Throw
+
+ Assert-VerifiableMock
}
}
}
diff --git a/dist/NetboxPS.psm1 b/dist/NetboxPS.psm1
index 105eddd..8968ea0 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/15/2018 4:52 PM
+ Generated on: 5/18/2018 11:21 AM
Generated by: Ben Claussen
Organization: NEOnet
--------------------------------------------------------------------------------
@@ -159,7 +159,7 @@
Write-Verbose "Building URI components"
- $URIParameters = [System.Collections.Hashtable]::new()
+ $URIParameters = @{}
foreach ($CmdletParameterName in $ParametersDictionary.Keys) {
if ($CmdletParameterName -in $CommonParameterNames) {
@@ -177,7 +177,7 @@
# Check if there is one or more values for Id and build a URI or query as appropriate
if (@($ParametersDictionary[$CmdletParameterName]).Count -gt 1) {
Write-Verbose " Joining IDs for parameter"
- $URIParameters['id__in'] = $Id -join ','
+ $URIParameters['id__in'] = $ParametersDictionary[$CmdletParameterName] -join ','
} else {
Write-Verbose " Adding ID to segments"
[void]$uriSegments.Add($ParametersDictionary[$CmdletParameterName])
@@ -199,6 +199,7 @@
function GetChoiceValidValues {
[CmdletBinding()]
+ [OutputType([System.Collections.ArrayList])]
param
(
[Parameter(Mandatory = $true)]
@@ -234,13 +235,16 @@
[string]$MajorObject,
[Parameter(Mandatory = $true)]
- [string]$ChoiceName
+ [string]$ChoiceName,
+
+ [Parameter(Mandatory = $true)]
+ [object]$ProvidedValue
)
$ValidValues = GetChoiceValidValues -MajorObject $MajorObject -Choice $ChoiceName
Write-Verbose "Validating $ChoiceName"
- Write-Verbose "Checking '$ProvidedValue' against $($ValidValues -join ', ')"
+ Write-Verbose "Checking '$ProvidedValue' against [$($ValidValues -join ', ')]"
if ($ValidValues -inotcontains $ProvidedValue) {
throw "Invalid value '$ProvidedValue' for '$ChoiceName'. Must be one of: $($ValidValues -join ', ')"
@@ -277,7 +281,7 @@
}
function InvokeNetboxRequest {
- [CmdletBinding(SupportsShouldProcess = $true)]
+ [CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
@@ -456,15 +460,17 @@ public enum $EnumName
}
function Set-NetboxHostName {
- [CmdletBinding()]
- param
- (
- [Parameter(Mandatory = $true)]
- [string]$Hostname
- )
-
- $script:NetboxConfig.Hostname = $Hostname.Trim()
- $script:NetboxConfig.Hostname
+ [CmdletBinding(ConfirmImpact = 'Medium',
+ SupportsShouldProcess = $true)]
+ [OutputType([string])]
+ param
+ (
+ [Parameter(Mandatory = $true)]
+ [string]$Hostname
+ )
+
+ $script:NetboxConfig.Hostname = $Hostname.Trim()
+ $script:NetboxConfig.Hostname
}
function Get-NetboxHostname {
@@ -472,7 +478,7 @@ public enum $EnumName
param ()
Write-Verbose "Getting Netbox hostname"
- if ($script:NetboxConfig.Hostname -eq $null) {
+ if ($null -eq $script:NetboxConfig.Hostname) {
throw "Netbox Hostname is not set! You may set it with Set-NetboxHostname -Hostname 'hostname.domain.tld'"
}
@@ -480,34 +486,37 @@ public enum $EnumName
}
function Set-NetboxCredentials {
- [CmdletBinding(DefaultParameterSetName = 'CredsObject')]
- [OutputType([pscredential], ParameterSetName = 'CredsObject')]
- [OutputType([pscredential], ParameterSetName = 'UserPass')]
- param
- (
- [Parameter(ParameterSetName = 'CredsObject',
- Mandatory = $true)]
- [pscredential]$Credentials,
-
- [Parameter(ParameterSetName = 'UserPass',
- Mandatory = $true)]
- [string]$Token
- )
-
- switch ($PsCmdlet.ParameterSetName) {
- 'CredsObject' {
- $script:NetboxConfig.Credentials = $Credentials
- break
- }
-
- 'UserPass' {
- $securePW = ConvertTo-SecureString $Token -AsPlainText -Force
- $script:NetboxConfig.Credentials = [System.Management.Automation.PSCredential]::new('notapplicable', $securePW)
- break
- }
- }
-
- $script:NetboxConfig.Credentials
+ [CmdletBinding(DefaultParameterSetName = 'CredsObject',
+ ConfirmImpact = 'Medium',
+ SupportsShouldProcess = $true)]
+ [OutputType([pscredential], ParameterSetName = 'CredsObject')]
+ [OutputType([pscredential], ParameterSetName = 'UserPass')]
+ [OutputType([pscredential])]
+ param
+ (
+ [Parameter(ParameterSetName = 'CredsObject',
+ Mandatory = $true)]
+ [pscredential]$Credentials,
+
+ [Parameter(ParameterSetName = 'UserPass',
+ Mandatory = $true)]
+ [string]$Token
+ )
+
+ switch ($PsCmdlet.ParameterSetName) {
+ 'CredsObject' {
+ $script:NetboxConfig.Credentials = $Credentials
+ break
+ }
+
+ 'UserPass' {
+ $securePW = ConvertTo-SecureString $Token -AsPlainText -Force
+ $script:NetboxConfig.Credentials = [System.Management.Automation.PSCredential]::new('notapplicable', $securePW)
+ break
+ }
+ }
+
+ $script:NetboxConfig.Credentials
}
function Get-NetboxCredentials {
@@ -582,7 +591,7 @@ public enum $EnumName
try {
Write-Verbose "Verifying API connectivity..."
- $APIInfo = VerifyAPIConnectivity
+ $null = VerifyAPIConnectivity
$script:NetboxConfig.Connected = $true
Write-Verbose "Successfully connected!"
} catch {
@@ -632,7 +641,8 @@ public enum $EnumName
#>
function Get-NetboxExtrasChoices {
- [CmdletBinding()]
+ [CmdletBinding()]
+ [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "", Justification = "These are literally 'choices' in Netbox")]
param ()
$uriSegments = [System.Collections.ArrayList]::new(@('extras', '_choices'))
@@ -671,8 +681,9 @@ public enum $EnumName
.NOTES
Additional information about the function.
#>
-
- [CmdletBinding()]
+
+ [CmdletBinding()]
+ [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "", Justification = "These are literally 'choices' in Netbox")]
param ()
$uriSegments = [System.Collections.ArrayList]::new(@('circuits', '_choices'))
@@ -827,13 +838,14 @@ public enum $EnumName
[switch]$VirtualMachineStatus
)
- ValidateChoice -MajorObject 'Virtualization' -ChoiceName $PSCmdlet.ParameterSetName
+ ValidateChoice -MajorObject 'Virtualization' -ChoiceName $PSCmdlet.ParameterSetName -ProvidedValue $ProvidedValue
}
#region GET commands
function Get-NetboxVirtualizationChoices {
[CmdletBinding()]
+ [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "", Justification = "These are literally 'choices' in Netbox")]
param ()
$uriSegments = [System.Collections.ArrayList]::new(@('virtualization', '_choices'))
@@ -972,7 +984,7 @@ public enum $EnumName
[switch]$Raw
)
- if ($Status -ne $null) {
+ if ($null -ne $Status) {
$PSBoundParameters.Status = VerifyVirtualizationChoices -ProvidedValue $Status -VirtualMachineStatus
}
@@ -1288,12 +1300,72 @@ public enum $EnumName
InvokeNetboxRequest -URI $uri -Method POST -Body $URIComponents.Parameters
}
-
-
#endregion ADD commands
- #endregion
+ #region SET commands
+
+ function Set-NetboxVirtualMachine {
+ [CmdletBinding(ConfirmImpact = 'High',
+ SupportsShouldProcess = $true)]
+ param
+ (
+ [Parameter(Mandatory = $true,
+ ValueFromPipelineByPropertyName = $true)]
+ [uint16]$Id,
+
+ [string]$Name,
+
+ [uint16]$Role,
+
+ [uint16]$Cluster,
+
+ [object]$Status,
+
+ [uint16]$Platform,
+
+ [uint16]$Primary_IPv4,
+
+ [uint16]$Primary_IPv6,
+
+ [byte]$VCPUs,
+
+ [uint16]$Memory,
+
+ [uint16]$Disk,
+
+ [uint16]$Tenant,
+
+ [string]$Comments,
+
+ [hashtable]$Custom_Fields,
+
+ [switch]$Force
+ )
+
+ if ($Status) {
+ $PSBoundParameters.Status = VerifyVirtualizationChoices -ProvidedValue $Status -VirtualMachineStatus
+ }
+
+ $Segments = [System.Collections.ArrayList]::new(@('virtualization', 'virtual-machines', $Id))
+
+ Write-Verbose "Obtaining VM from ID $Id"
+
+ $CurrentVM = Get-NetboxVirtualMachine -Id $Id -ErrorAction Stop
+
+ Write-Verbose "Finished obtaining VM"
+
+ if ($Force -or $pscmdlet.ShouldProcess($CurrentVM.Name, "Set")) {
+ $URIComponents = BuildURIComponents -URISegments $Segments -ParametersDictionary $PSBoundParameters -SkipParameterByName 'Id', 'Force'
+
+ $URI = BuildNewURI -Segments $URIComponents.Segments
+
+ InvokeNetboxRequest -URI $URI -Body $URIComponents.Parameters -Method PATCH
+ }
+ }
+
+
+ #endregion SET commands#endregion
#region Invoke-IPAM_ps1
<#
@@ -1413,12 +1485,13 @@ public enum $EnumName
[switch]$ServiceProtocol
)
- ValidateChoice -MajorObject 'IPAM' -ChoiceName $PSCmdlet.ParameterSetName
+ ValidateChoice -MajorObject 'IPAM' -ChoiceName $PSCmdlet.ParameterSetName -ProvidedValue $ProvidedValue
}
function Get-NetboxIPAMAggregate {
[CmdletBinding()]
+ [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "", Justification = "These are literally 'choices' in Netbox")]
param
(
[uint16]$Limit,
@@ -1440,7 +1513,7 @@ public enum $EnumName
[switch]$Raw
)
- if ($Family -ne $null) {
+ if ($null -ne $Family) {
$PSBoundParameters.Family = VerifyIPAMChoices -ProvidedValue $Family -AggregateFamily
}
@@ -1496,15 +1569,15 @@ public enum $EnumName
[switch]$Raw
)
- if ($Family -ne $null) {
+ if ($null -ne $Family) {
$PSBoundParameters.Family = VerifyIPAMChoices -ProvidedValue $Family -IPAddressFamily
}
- if ($Status -ne $null) {
+ if ($null -ne $Status) {
$PSBoundParameters.Status = VerifyIPAMChoices -ProvidedValue $Status -IPAddressStatus
}
- if ($Role -ne $null) {
+ if ($null -ne $Role) {
$PSBoundParameters.Role = VerifyIPAMChoices -ProvidedValue $Role -IPAddressRole
}
@@ -1693,11 +1766,11 @@ public enum $EnumName
[switch]$Raw
)
- if ($Family -ne $null) {
+ if ($null -ne $Family) {
$PSBoundParameters.Family = VerifyIPAMChoices -ProvidedValue $Family -PrefixFamily
}
- if ($Status -ne $null) {
+ if ($null -ne $Status) {
$PSBoundParameters.Status = VerifyIPAMChoices -ProvidedValue $Status -PrefixStatus
}
@@ -1783,7 +1856,7 @@ public enum $EnumName
$PSBoundParameters.Status = VerifyIPAMChoices -ProvidedValue $Status -IPAddressStatus
- if ($Role -ne $null) {
+ if ($null -ne $Role) {
$PSBoundParameters.Role = VerifyIPAMChoices -ProvidedValue $Role -IPAddressRole
}
@@ -1856,7 +1929,7 @@ public enum $EnumName
[string]$Address,
- [object]$Status = 'Active',
+ [object]$Status,
[uint16]$Tenant,
@@ -1875,7 +1948,9 @@ public enum $EnumName
[switch]$Force
)
- $PSBoundParameters.Status = VerifyIPAMChoices -ProvidedValue $Status -IPAddressStatus
+ if ($Status) {
+ $PSBoundParameters.Status = VerifyIPAMChoices -ProvidedValue $Status -IPAddressStatus
+ }
if ($Role) {
$PSBoundParameters.Role = VerifyIPAMChoices -ProvidedValue $Role -IPAddressRole
diff --git a/dist/Tests/Helpers.Tests.ps1 b/dist/Tests/Helpers.Tests.ps1
index 395c666..331da0f 100644
--- a/dist/Tests/Helpers.Tests.ps1
+++ b/dist/Tests/Helpers.Tests.ps1
@@ -31,8 +31,8 @@ Describe "Helpers tests" -Tag 'Core', 'Helpers' -Fixture {
return $true
} -ModuleName 'NetboxPS'
- Context "Building URI tests" {
- InModuleScope -ModuleName 'NetboxPS' -ScriptBlock {
+ InModuleScope -ModuleName 'NetboxPS' -ScriptBlock {
+ Context -Name "Building URIBuilder" -Fixture {
It "Should give a basic URI object" {
BuildNewURI -HostName 'netbox.domain.com' | Should -BeOfType [System.UriBuilder]
}
@@ -85,10 +85,70 @@ Describe "Helpers tests" -Tag 'Core', 'Helpers' -Fixture {
$URIBuilder.URI.AbsoluteURI | Should -BeExactly 'https://netbox.domain.com/api/seg1/seg2/?param1=paramval1¶m2=paramval2'
}
}
- }
-
- Context "Invoking request tests" {
- InModuleScope -ModuleName 'NetboxPS' -ScriptBlock {
+
+ Context -Name "Building URI components" -Fixture {
+ It "Should give a basic hashtable" {
+ $URIComponents = BuildURIComponents -URISegments @('segment1', 'segment2') -ParametersDictionary @{'param1' = 1}
+
+ $URIComponents | Should -BeOfType [hashtable]
+ $URIComponents.Keys.Count | Should -BeExactly 2
+ $URIComponents.Keys | Should -Be @("Segments", "Parameters")
+ $URIComponents.Segments | Should -Be @("segment1", "segment2")
+ $URIComponents.Parameters.Count | Should -BeExactly 1
+ $URIComponents.Parameters | Should -BeOfType [hashtable]
+ $URIComponents.Parameters['param1'] | Should -Be 1
+ }
+
+ It "Should add a single ID parameter to the segments" {
+ $URIComponents = BuildURIComponents -URISegments @('segment1', 'segment2') -ParametersDictionary @{'id' = 123}
+
+ $URIComponents | Should -BeOfType [hashtable]
+ $URIComponents.Keys.Count | Should -BeExactly 2
+ $URIComponents.Keys | Should -Be @("Segments", "Parameters")
+ $URIComponents.Segments | Should -Be @("segment1", "segment2", '123')
+ $URIComponents.Parameters.Count | Should -BeExactly 0
+ $URIComponents.Parameters | Should -BeOfType [hashtable]
+ }
+
+ It "Should add multiple IDs to the parameters id__in" {
+ $URIComponents = BuildURIComponents -URISegments @('segment1', 'segment2') -ParametersDictionary @{'id' = "123", "456"}
+
+ $URIComponents | Should -BeOfType [hashtable]
+ $URIComponents.Keys.Count | Should -BeExactly 2
+ $URIComponents.Keys | Should -Be @("Segments", "Parameters")
+ $URIComponents.Segments | Should -Be @("segment1", "segment2")
+ $URIComponents.Parameters.Count | Should -BeExactly 1
+ $URIComponents.Parameters | Should -BeOfType [hashtable]
+ $URIComponents.Parameters['id__in'] | Should -Be '123,456'
+ }
+
+ It "Should skip a particular parameter name" {
+ $URIComponents = BuildURIComponents -URISegments @('segment1', 'segment2') -ParametersDictionary @{'param1' = 1; 'param2' = 2} -SkipParameterByName 'param2'
+
+ $URIComponents | Should -BeOfType [hashtable]
+ $URIComponents.Keys.Count | Should -BeExactly 2
+ $URIComponents.Keys | Should -Be @("Segments", "Parameters")
+ $URIComponents.Segments | Should -Be @("segment1", "segment2")
+ $URIComponents.Parameters.Count | Should -BeExactly 1
+ $URIComponents.Parameters | Should -BeOfType [hashtable]
+ $URIComponents.Parameters['param1'] | Should -Be 1
+ $URIComponents.Parameters['param2'] | Should -BeNullOrEmpty
+ }
+
+ It "Should add a query (q) parameter" {
+ $URIComponents = BuildURIComponents -URISegments @('segment1', 'segment2') -ParametersDictionary @{'query' = 'mytestquery'}
+
+ $URIComponents | Should -BeOfType [hashtable]
+ $URIComponents.Keys.Count | Should -BeExactly 2
+ $URIComponents.Keys | Should -Be @("Segments", "Parameters")
+ $URIComponents.Segments | Should -Be @("segment1", "segment2")
+ $URIComponents.Parameters.Count | Should -BeExactly 1
+ $URIComponents.Parameters | Should -BeOfType [hashtable]
+ $URIComponents.Parameters['q'] | Should -Be 'mytestquery'
+ }
+ }
+
+ Context -Name "Invoking request tests" -Fixture {
Mock -CommandName 'Invoke-RestMethod' -Verifiable -MockWith {
# Return an object of the items we would normally pass to Invoke-RestMethod
return [pscustomobject]@{
@@ -123,7 +183,7 @@ Describe "Helpers tests" -Tag 'Core', 'Helpers' -Fixture {
$Result = InvokeNetboxRequest -URI $URIBuilder -Raw
Assert-VerifiableMock
-
+
$Result.Method | Should -Be 'GET'
$Result.Uri | Should -Be $URIBuilder.Uri.AbsoluteUri
$Result.Headers | Should -BeOfType [System.Collections.HashTable]
@@ -136,7 +196,9 @@ Describe "Helpers tests" -Tag 'Core', 'Helpers' -Fixture {
It "Should generate a POST request with body" {
$URIBuilder = BuildNewURI -Hostname "netbox.domain.com" -Segments 'seg1', 'seg2'
- $Result = InvokeNetboxRequest -URI $URIBuilder -Method POST -Body @{'bodyparam1' = 'val1'} -Raw
+ $Result = InvokeNetboxRequest -URI $URIBuilder -Method POST -Body @{
+ 'bodyparam1' = 'val1'
+ } -Raw
Assert-VerifiableMock
@@ -161,6 +223,7 @@ Describe "Helpers tests" -Tag 'Core', 'Helpers' -Fixture {
$Result.Method | Should -Be 'POST'
$Result.Body | Should -Be '{"bodyparam1":"val1"}'
+ $Result.Headers.Count | Should -BeExactly 2
$Result.Headers.Authorization | Should -Be "Token faketoken"
$Result.Headers.Connection | Should -Be "keep-alive"
}
@@ -179,6 +242,235 @@ Describe "Helpers tests" -Tag 'Core', 'Helpers' -Fixture {
} | Should -Throw
}
}
+
+ 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'
+
+ It "Should return a valid integer for status when provided a name" {
+ $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName 'virtual-machine:status' -ProvidedValue 'Active'
+
+ $Result | Should -BeOfType [uint16]
+ $Result | Should -BeExactly 1
+ }
+
+ It "Should return a valid integer for status when provided an integer" {
+ $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName 'virtual-machine:status' -ProvidedValue 0
+
+ $Result | Should -BeOfType [uint16]
+ $Result | Should -BeExactly 0
+ }
+
+ It "Should throw because of an invalid choice" {
+ {
+ ValidateChoice -MajorObject $MajorObject -ChoiceName 'virtual-machine:status' -ProvidedValue 'Fake'
+ } | Should -Throw
+ }
+ }
+
+ Context -Name "IPAM choices" -Fixture {
+ $MajorObject = 'IPAM'
+
+ Context -Name "aggregate:family" -Fixture {
+ $ChoiceName = 'aggregate:family'
+
+ It "Should return a valid integer when provided a name" {
+ $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 'IPv4'
+
+ $Result | Should -BeOfType [uint16]
+ $Result | Should -BeExactly 4
+ }
+
+ It "Should return a valid integer when provided an integer" {
+ $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 4
+
+ $Result | Should -BeOfType [uint16]
+ $Result | Should -BeExactly 4
+ }
+
+ It "Should throw because of an invalid choice" {
+ {
+ ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 0
+ } | Should -Throw
+ }
+ }
+
+ Context -Name "prefix:family" {
+ $ChoiceName = 'prefix:family'
+
+ It "Should return a valid integer when provided a name" {
+ $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 'IPv4'
+
+ $Result | Should -BeOfType [uint16]
+ $Result | Should -BeExactly 4
+ }
+
+ It "Should return a valid integer when provided an integer" {
+ $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 4
+
+ $Result | Should -BeOfType [uint16]
+ $Result | Should -BeExactly 4
+ }
+
+ It "Should throw because of an invalid choice" {
+ {
+ ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 0
+ } | Should -Throw
+ }
+ }
+
+ Context -Name "prefix:status" {
+ $ChoiceName = 'prefix: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 1
+
+ $Result | Should -BeOfType [uint16]
+ $Result | Should -BeExactly 1
+ }
+
+ It "Should throw because of an invalid choice" {
+ {
+ ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 10
+ } | Should -Throw
+ }
+ }
+
+ Context -Name "ip-address:family" {
+ $ChoiceName = 'ip-address:family'
+
+ It "Should return a valid integer when provided a name" {
+ $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 'IPv4'
+
+ $Result | Should -BeOfType [uint16]
+ $Result | Should -BeExactly 4
+ }
+
+ It "Should return a valid integer when provided an integer" {
+ $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 4
+
+ $Result | Should -BeOfType [uint16]
+ $Result | Should -BeExactly 4
+ }
+
+ It "Should throw because of an invalid choice" {
+ {
+ ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 10
+ } | Should -Throw
+ }
+ }
+
+ Context -Name "ip-address:status" {
+ $ChoiceName = 'ip-address: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 1
+
+ $Result | Should -BeOfType [uint16]
+ $Result | Should -BeExactly 1
+ }
+
+ It "Should throw because of an invalid choice" {
+ {
+ ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 10
+ } | Should -Throw
+ }
+ }
+
+ Context -Name "ip-address:role" {
+ $ChoiceName = 'ip-address:role'
+
+ It "Should return a valid integer when provided a name" {
+ $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 'Anycast'
+
+ $Result | Should -BeOfType [uint16]
+ $Result | Should -BeExactly 30
+ }
+
+ It "Should return a valid integer when provided an integer" {
+ $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 30
+
+ $Result | Should -BeOfType [uint16]
+ $Result | Should -BeExactly 30
+ }
+
+ It "Should throw because of an invalid choice" {
+ {
+ ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 1
+ } | Should -Throw
+ }
+ }
+
+ Context -Name "vlan:status" {
+ $ChoiceName = 'vlan: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 1
+
+ $Result | Should -BeOfType [uint16]
+ $Result | Should -BeExactly 1
+ }
+
+ It "Should throw because of an invalid choice" {
+ {
+ ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 0
+ } | Should -Throw
+ }
+ }
+
+ Context -Name "service:protocol" {
+ $ChoiceName = 'service:protocol'
+
+ It "Should return a valid integer when provided a name" {
+ $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 'TCP'
+
+ $Result | Should -BeOfType [uint16]
+ $Result | Should -BeExactly 6
+ }
+
+ It "Should return a valid integer when provided an integer" {
+ $Result = ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 6
+
+ $Result | Should -BeOfType [uint16]
+ $Result | Should -BeExactly 6
+ }
+
+ It "Should throw because of an invalid choice" {
+ {
+ ValidateChoice -MajorObject $MajorObject -ChoiceName $ChoiceName -ProvidedValue 0
+ } | Should -Throw
+ }
+ }
+ }
+
+
+ }
+
+
}
}
diff --git a/dist/Tests/IPAM.Tests.ps1 b/dist/Tests/IPAM.Tests.ps1
index 6e6485b..fd21b2d 100644
--- a/dist/Tests/IPAM.Tests.ps1
+++ b/dist/Tests/IPAM.Tests.ps1
@@ -49,6 +49,10 @@ 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
@@ -368,7 +372,7 @@ Describe -Name "IPAM tests" -Tag 'Ipam' -Fixture {
$Result.Method | Should -Be 'POST'
$Result.Uri | Should -Be 'https://netbox.domain.com/api/ipam/ip-addresses/'
$Result.Headers.Keys.Count | Should -BeExactly 1
- $Result.Body | Should -Be '{"status":2,"role":30,"address":"10.0.0.1/24"}'
+ $Result.Body | Should -Be '{"status":2,"address":"10.0.0.1/24","role":30}'
}
It "Should add an IP with a status and role values" {
@@ -379,7 +383,7 @@ Describe -Name "IPAM tests" -Tag 'Ipam' -Fixture {
$Result.Method | Should -Be 'POST'
$Result.Uri | Should -Be 'https://netbox.domain.com/api/ipam/ip-addresses/'
$Result.Headers.Keys.Count | Should -BeExactly 1
- $Result.Body | Should -Be '{"status":1,"role":10,"address":"10.0.1.1/24"}'
+ $Result.Body | Should -Be '{"status":1,"address":"10.0.1.1/24","role":10}'
}
}
@@ -457,7 +461,7 @@ Describe -Name "IPAM tests" -Tag 'Ipam' -Fixture {
$Result.Method | Should -Be 'PATCH'
$Result.Uri | Should -Be 'https://netbox.domain.com/api/ipam/ip-addresses/4109/'
$Result.Headers.Keys.Count | Should -BeExactly 1
- $Result.Body | Should -Be '{"description":"Test description","status":1,"tenant":14,"vrf":10}'
+ $Result.Body | Should -Be '{"vrf":10,"description":"Test description","tenant":14}'
}
}
}
diff --git a/dist/Tests/IPAMChoices.json b/dist/Tests/IPAMChoices.json
new file mode 100644
index 0000000..3e05e53
--- /dev/null
+++ b/dist/Tests/IPAMChoices.json
@@ -0,0 +1 @@
+{"aggregate:family":[{"label":"IPv4","value":4},{"label":"IPv6","value":6}],"prefix:family":[{"label":"IPv4","value":4},{"label":"IPv6","value":6}],"prefix:status":[{"label":"Container","value":0},{"label":"Active","value":1},{"label":"Reserved","value":2},{"label":"Deprecated","value":3}],"ip-address:family":[{"label":"IPv4","value":4},{"label":"IPv6","value":6}],"ip-address:status":[{"label":"Active","value":1},{"label":"Reserved","value":2},{"label":"Deprecated","value":3},{"label":"DHCP","value":5}],"ip-address:role":[{"label":"Loopback","value":10},{"label":"Secondary","value":20},{"label":"Anycast","value":30},{"label":"VIP","value":40},{"label":"VRRP","value":41},{"label":"HSRP","value":42},{"label":"GLBP","value":43},{"label":"CARP","value":44}],"vlan:status":[{"label":"Active","value":1},{"label":"Reserved","value":2},{"label":"Deprecated","value":3}],"service:protocol":[{"label":"TCP","value":6},{"label":"UDP","value":17}]}
\ No newline at end of file
diff --git a/dist/Tests/Virtualization.Tests.ps1 b/dist/Tests/Virtualization.Tests.ps1
index 665b69a..6b68819 100644
--- a/dist/Tests/Virtualization.Tests.ps1
+++ b/dist/Tests/Virtualization.Tests.ps1
@@ -307,7 +307,6 @@ Describe -Name "Virtualization tests" -Tag 'Virtualization' -Fixture {
}
Context -Name "Add-NetboxVirtualMachine" -Fixture {
-
It "Should add a basic VM" {
$Result = Add-NetboxVirtualMachine -Name 'testvm' -Cluster 1
@@ -316,7 +315,7 @@ Describe -Name "Virtualization tests" -Tag 'Virtualization' -Fixture {
$Result.Method | Should -Be 'POST'
$Result.Uri | Should -Be 'https://netbox.domain.com/api/virtualization/virtual-machines/'
$Result.Headers.Keys.Count | Should -BeExactly 1
- $Result.Body | Should -Be '{"name":"testvm","cluster":1,"status":1}'
+ $Result.Body | Should -Be '{"cluster":1,"name":"testvm","status":1}'
}
It "Should add a VM with CPUs, Memory, Disk, tenancy, and comments" {
@@ -327,7 +326,7 @@ Describe -Name "Virtualization tests" -Tag 'Virtualization' -Fixture {
$Result.Method | Should -Be 'POST'
$Result.Uri | Should -Be 'https://netbox.domain.com/api/virtualization/virtual-machines/'
$Result.Headers.Keys.Count | Should -BeExactly 1
- $Result.Body | Should -Be '{"tenant":11,"name":"testvm","comments":"these are comments","cluster":1,"status":1,"memory":4096,"vcpus":4,"disk":50}'
+ $Result.Body | Should -Be '{"tenant":11,"comments":"these are comments","disk":50,"memory":4096,"name":"testvm","cluster":1,"status":1,"vcpus":4}'
}
}
@@ -340,7 +339,7 @@ Describe -Name "Virtualization tests" -Tag 'Virtualization' -Fixture {
$Result.Method | Should -Be 'POST'
$Result.Uri | Should -Be 'https://netbox.domain.com/api/virtualization/interfaces/'
$Result.Headers.Keys.Count | Should -BeExactly 1
- $Result.Body | Should -Be '{"virtual_machine":10,"enabled":true,"name":"Ethernet0"}'
+ $Result.Body | Should -Be '{"virtual_machine":10,"name":"Ethernet0","enabled":true}'
}
It "Should add an interface with a MAC, MTU, and Description" {
@@ -351,7 +350,44 @@ Describe -Name "Virtualization tests" -Tag 'Virtualization' -Fixture {
$Result.Method | Should -Be 'POST'
$Result.Uri | Should -Be 'https://netbox.domain.com/api/virtualization/interfaces/'
$Result.Headers.Keys.Count | Should -BeExactly 1
- $Result.Body | Should -Be '{"description":"Test description","virtual_machine":10,"enabled":true,"name":"Ethernet0","mtu":1500,"mac_address":"11:22:33:44:55:66"}'
+ $Result.Body | Should -Be '{"mtu":1500,"description":"Test description","enabled":true,"virtual_machine":10,"name":"Ethernet0","mac_address":"11:22:33:44:55:66"}'
+ }
+ }
+
+ Context -Name "Set-NetboxVirtualMachine" -Fixture {
+ Mock -CommandName "Get-NetboxVirtualMachine" -ModuleName NetboxPS -MockWith {
+ return @{
+ 'Id' = 1234
+ 'Name' = 'TestVM'
+ }
+ }
+
+ It "Should set a VM to a new name" {
+ $Result = Set-NetboxVirtualMachine -Id 1234 -Name 'newtestname' -Force
+
+ Assert-VerifiableMock
+
+ $Result.Method | Should -Be 'PATCH'
+ $Result.URI | Should -Be 'https://netbox.domain.com/api/virtualization/virtual-machines/1234/'
+ $Result.Headers.Keys.Count | Should -BeExactly 1
+ $Result.Body | Should -Be '{"name":"newtestname"}'
+ }
+
+ It "Should set a VM with a new name, cluster, platform, and status" {
+ $Result = Set-NetboxVirtualMachine -Id 1234 -Name 'newtestname' -Cluster 10 -Platform 15 -Status 'Offline' -Force
+
+ Assert-VerifiableMock
+
+ $Result.Method | Should -Be 'PATCH'
+ $Result.URI | Should -Be 'https://netbox.domain.com/api/virtualization/virtual-machines/1234/'
+ $Result.Headers.Keys.Count | Should -BeExactly 1
+ $Result.Body | Should -Be '{"cluster":10,"platform":15,"name":"newtestname","status":0}'
+ }
+
+ It "Should throw because of an invalid status" {
+ { Set-NetboxVirtualMachine -Id 1234 -Status 'Fake' -Force } | Should -Throw
+
+ Assert-VerifiableMock
}
}
}
diff --git a/dist/Tests/VirtualizationChoices.json b/dist/Tests/VirtualizationChoices.json
new file mode 100644
index 0000000..235ed6c
--- /dev/null
+++ b/dist/Tests/VirtualizationChoices.json
@@ -0,0 +1 @@
+{"virtual-machine:status":[{"label":"Active","value":1},{"label":"Offline","value":0},{"label":"Staged","value":3}]}
\ No newline at end of file