UMN-Infoblox.psm1

###
# Copyright 2017 University of Minnesota, Office of Information Technology

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with Foobar. If not, see <http://www.gnu.org/licenses/>.
## Modules for infoblox
# It is assumed that a Connection has already been established and the cookie is being passed to many of these functions.
# Use 'Connect-Infoblox' to return a $cookie --

Function Get-InfobloxHost{

<#
.SYNOPSIS
    Get host by FQDN
.DESCRIPTION
    
.EXAMPLE
    Get-InfobloxHost -cookie $cookie -uriBase $uriBase -host_name $host_name
.NOTES
    General notes
#>

    
    [CmdletBinding()]
    Param
    (
        [ValidateNotNullOrEmpty()]
        [Microsoft.PowerShell.Commands.WebRequestSession]$cookie,

        [ValidateNotNullOrEmpty()]
        [string]$uriBase,

        [ValidateNotNullOrEmpty()]
        [string]$host_name
    )
    
    $host_name = $host_name.ToLower()
    $uri  = "$uriBase/record:host?name=$host_name"
    Invoke-RestMethod -uri $uri -Method Get -WebSession $cookie
}


Function Remove-InfobloxHost{
<#
.SYNOPSIS
    Remove Host Record
.DESCRIPTION
    
.EXAMPLE
    Remove-InfobloxHost -cookie $cookie -uriBase $uriBase -host_name $host_name
.NOTES
    General notes
#>


  ##

    [CmdletBinding()]
    Param
    (
        [ValidateNotNullOrEmpty()]
        [Microsoft.PowerShell.Commands.WebRequestSession]$cookie,

        [ValidateNotNullOrEmpty()]
        [string]$uriBase,

        [ValidateNotNullOrEmpty()]
        [string]$host_name
    )
    $host_name = $host_name.ToLower()
    ## Validate Host exists
    $host_ref = (Get-InfobloxHost -cookie $cookie -uriBase $uriBase -host_name $host_name)._ref
    if ($host_ref -eq $null){throw "Infoblox Host Doesn't Exist"}    
    $uri  = "$uriBase/$host_ref"
    #validate response
    if ((Invoke-RestMethod -uri $uri -Method Delete -WebSession $cookie) -ne $host_ref){throw "Infoblox Delete Failed"}

}


Function Get-InfobloxIPv4Net{
<#
.SYNOPSIS
    Get IPv4 Network
.DESCRIPTION
    Get a network stack from infoblox
.EXAMPLE
    Get-InflobloxIPv4Net -cookie $cookie -uriBase $uriBase -ipv4Net $ipv4net
.NOTES
    General notes
#>


    [CmdletBinding()]
    Param
    (
        [ValidateNotNullOrEmpty()]
        [Microsoft.PowerShell.Commands.WebRequestSession]$cookie,

        [ValidateNotNullOrEmpty()]
        [string]$uriBase,

        [ValidateNotNullOrEmpty()]
        [string]$ipv4Net
    )
    $uri = "$uriBase/network?network=$ipv4Net"
    Invoke-RestMethod -uri $uri -Method Get -WebSession $cookie
}


Function Get-InfobloxIPv4IP{
<#
.SYNOPSIS
    Get reference to specific IPv4 address
.DESCRIPTION
    
.EXAMPLE
    Get-InflobloxIPv4IP -cookie $cookie -uriBase $uriBase -ipv4Address $ipv4Address
.NOTES
    Check 'types' and look for HOST (NOT BULKHOST). If types contains HOST, its in use
#>



    [CmdletBinding()]
    Param
    (
        [ValidateNotNullOrEmpty()]
        [Microsoft.PowerShell.Commands.WebRequestSession]$cookie,

        [ValidateNotNullOrEmpty()]
        [string]$uriBase,

        [ValidateNotNullOrEmpty()]
        [string]$ipv4Address
    )

    $uri = "$uriBase/ipv4address?ip_address=$ipv4Address"
    Invoke-RestMethod -uri $uri -Method Get -WebSession $cookie

}


Function Get-InfobloxIPv4IPs{
<#
.SYNOPSIS
    Get reference to specific IPv4 network
.DESCRIPTION
    Get all Hosts in a specific IPv4 Network
.EXAMPLE
    Get-InfobloxIPv4ips -cookie $cookie -uriBase $uriBase -ipv4net $ipv4net
.NOTES
    
#>


    [CmdletBinding()]
    Param
    (
        [ValidateNotNullOrEmpty()]
        [Microsoft.PowerShell.Commands.WebRequestSession]$cookie,

        [ValidateNotNullOrEmpty()]
        [string]$uriBase,

        [ValidateNotNullOrEmpty()]
        [string]$ipv4Net
    )

    $uri = "$uriBase/ipv4address?network=$ipv4Net"
    Invoke-RestMethod -uri $uri -Method Get -WebSession $cookie

}


Function Get-InfobloxIPv4Available{

<#
.SYNOPSIS
    Get an available IPv4 address
.DESCRIPTION
    Check for, and retrieve an available IPv4 address
.EXAMPLE
    Get-InfobloxIP4Available -cookie $cookie -uriBase $uriBase -ipv4net $ipv4net -domainSuffix -$domainSuffix
.NOTES
    
#>



    [CmdletBinding()]
    Param
    (
        [ValidateNotNullOrEmpty()]
        [Microsoft.PowerShell.Commands.WebRequestSession]$cookie,

        [ValidateNotNullOrEmpty()]
        [string]$uriBase,

        [ValidateNotNullOrEmpty()]
        [string]$ipv4Net,
        
        [ValidateNotNullOrEmpty()]
        [string]$domainSuffix
    )
    
    $ipv4IPs = Get-InfobloxIPv4IPs -cookie $cookie -uriBase $uriBase -ipv4Net $ipv4Net
    $ipFound = $false
    foreach ($ip in $ipv4IPs){
        if (($ip.names).count -eq 1 -and $ip.types -notcontains "HOST" -and $ip.lease_state -eq "FREE") # IF it returns a single entry this should be the bulk host. < 1 = router, >1 its tied to host record so don't touch it
        {
            ## ONE LAST CHECK just to be sure, match on bulk host name
            if ($ip.names -match "x-\d{1,3}-\d{1,3}-\d{1,3}-\d{1,3}\.$domainSuffix")
            {
                #$new_IPv4 = $ip.ip_address
                $ipFound = $true 
                return $ip.ip_address
            }
        }
    }
    if(-not $ipFound){return "unable to find IPv4 Address, exiting"}

}


Function Get-InfobloxIPv6IP{
<#
.SYNOPSIS
    Get reference to specific IPv6 address
.DESCRIPTION
    
.EXAMPLE
    Get-InflobloxIPv6IP -cookie $cookie -uriBase $uriBase -ipv6Address $ipv6Address
.NOTES
    
#>



    [CmdletBinding()]
    Param
    (
        [ValidateNotNullOrEmpty()]
        [Microsoft.PowerShell.Commands.WebRequestSession]$cookie,

        [ValidateNotNullOrEmpty()]
        [string]$uriBase,

        [ValidateNotNullOrEmpty()]
        [string]$ipv6address
    )

    $uri  = "$uriBase/record:host_ipv6addr?ipv6addr=$ipv6address"
    Invoke-RestMethod -uri $uri -Method Get -WebSession $cookie

}


Function New-InfobloxHost{

<#
.SYNOPSIS
    Create a new Host object with IPv4 and IPv6 Address
.DESCRIPTION
    
.EXAMPLE
    New-InfobloxHost -cookie $cookie -uribase $uriBase -host_name $host_name -new_IPv4 $new_ipV4 -new_IPv6 $new_ipv6 -ipv4net $ipv4net
.NOTES
    Use other module commands to generate a list of IP's to associate to a new host entry.
#>




    [CmdletBinding()]
    Param
    (
        [ValidateNotNullOrEmpty()]
        [Microsoft.PowerShell.Commands.WebRequestSession]$cookie,

        [ValidateNotNullOrEmpty()]
        [string]$uriBase,

        [ValidateNotNullOrEmpty()]
        [string]$host_name,

        [ValidateNotNullOrEmpty()]
        [string]$new_IPv4,

        [string]$new_IPv6,

        [ValidateNotNullOrEmpty()]
        [string]$ipv4Net
    )
    $host_name = $host_name.ToLower()
    $uri = "$uriBase/record:host"
    if ($new_IPv6)
    {
        $JSON = @{name=$host_name;ipv4addrs=@(@{ipv4addr=$new_IPv4;configure_for_dhcp=$true;match_client="RESERVED"});
            ipv6addrs=@(@{ipv6addr=$new_IPv6});
            extattrs=@{Custom1=@{value=$ipv4Net};Custom2=@{value="default 2 hour"}}} | ConvertTo-Json
    }
    else
    {
        $JSON = @{name=$host_name;ipv4addrs=@(@{ipv4addr=$new_IPv4;configure_for_dhcp=$true;match_client="RESERVED"});
            extattrs=@{Custom1=@{value=$ipv4Net};Custom2=@{value="default 2 hour"}}} | ConvertTo-Json
    }
    Invoke-RestMethod -Uri $uri -Body $JSON -ContentType "application/json" -Method Post -WebSession $cookie

}


Function New-InfobloxDhcpReservation{
<#
.SYNOPSIS
    Create a new host object for doing DHCP reservations
.DESCRIPTION
    For use with DHCP reservations by mac address
.EXAMPLE
    New-InfobloxDhcpReservation -cookie $cookie -uriBase $uriBase -host_name $host_name -new_IPv4 $new_ipV4 -ipv4Net $ipv4net -mac $mac
.NOTES
    
#>

    [CmdletBinding()]
    Param
    (
        [ValidateNotNullOrEmpty()]
        [Microsoft.PowerShell.Commands.WebRequestSession]$cookie,

        [ValidateNotNullOrEmpty()]
        [string]$uriBase,

        [ValidateNotNullOrEmpty()]
        [string]$host_name,

        [ValidatePattern("\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}")]
        [string]$new_IPv4,

        [ValidateNotNullOrEmpty()]
        [string]$ipv4Net,

        [ValidatePattern("([a-zA-Z0-9]{2}:){5}[a-zA-Z0-9]{2}")]
        [string]$mac
    )
    $host_name = $host_name.ToLower()
    $uri = "$uriBase/record:host"
    $JSON = @{name=$host_name;ipv4addrs=@(@{ipv4addr=$new_IPv4;configure_for_dhcp=$true;match_client="MAC_ADDRESS";mac=$mac});
        extattrs=@{Custom1=@{value=$ipv4Net};Custom2=@{value="default 2 hour"}}} | ConvertTo-Json    
    Invoke-RestMethod -Uri $uri -Body $JSON -ContentType "application/json" -Method Post -WebSession $cookie

}


Function Connect-Infoblox{
<#
.SYNOPSIS
    Core function - retrieve cookie for API access to infoblox
.DESCRIPTION
    
.EXAMPLE
    Connect-Infoblox -InfobloxCreds $infobloxCreds -uriBase $uriBase
.NOTES
    For legacy automation systems dealing with cookies -
    -UseBasicParsing is included on the InvokeWebRequest - needed parsing for Orchestrator
#>



    [CmdletBinding()]
    param(

        [ValidateNotNullOrEmpty()]
        [System.Management.Automation.PSCredential]$InfobloxCreds,

        [string]$uriBase

    )
        
add-type @"
    using System.Net;
    using System.Security.Cryptography.X509Certificates;
    public class TrustAllCertsPolicy : ICertificatePolicy {
        public bool CheckValidationResult(
            ServicePoint srvPoint, X509Certificate certificate,
            WebRequest request, int certificateProblem) {
            return true;
        }
    }
"@

            [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
            $uri  = "$uriBase/grid"
            $grid = Invoke-WebRequest -uri $uri -Method Get -Credential $InfobloxCreds -SessionVariable cookie -UseBasicParsing
            return ($cookie)
}


function Get-InfobloxIPbyMac {
<#
.SYNOPSIS
    Get IP information by MAC address
.DESCRIPTION
    
.EXAMPLE
    Get-InfobloxIPbyMac -cookie $cookie -uriBase $uriBase -ipv4net $ipv4net -mac $mac
.NOTES
#>

    
    [CmdletBinding()]
    param(

        [ValidateNotNullOrEmpty()]
        [Microsoft.PowerShell.Commands.WebRequestSession]$cookie,

        [string]$uriBase,

        [ValidateNotNullOrEmpty()]
        [string]$ipv4Net,

        [ValidatePattern("([a-zA-Z0-9]{2}:){5}[a-zA-Z0-9]{2}")]
        [string]$mac

    )

    $uri = "$uriBase/ipv4address?network=$ipv4Net&mac_address=$mac"
    $ipv4IPs =  Invoke-RestMethod -uri $uri -Method Get -WebSession $cookie
    $activeIP = $ipv4IPs | Where-Object {$_.lease_state -eq 'ACTIVE'}
    if ($activeIP -ne $null){return ($activeIP.ip_address)}
    else{throw "Failed to get single IP info $ipv4IPs"}
}

Export-ModuleMember -Function *