Public/Connection.ps1

#
# Copyright 2021, Alexis La Goutte <alexis dot lagoutte at gmail dot com>
#
# SPDX-License-Identifier: Apache-2.0
#

function Connect-ArubaCL {

    <#
      .SYNOPSIS
      Connect to Aruba Central

      .DESCRIPTION
      Connect to Aruba Central

      .EXAMPLE
      Connect-ArubaCL -region EU-1 -client_id MyClientID -client_secret MyClientSecret -customer_id MyCustomerId

      Connect to Aruba Central on region EU-1 using (Get-)credential and client id/secret and customer(id)

      .EXAMPLE
      $cred = get-credential
      PS C:\>Connect-ArubaCL -region EU-1 -client_id MyClientID -client_secret MyClientSecret -customer_id MyCustomerId -credential $cred

      Connect to Aruba Central on region EU-1 and passing (Get-)credential and client id/secret and customer(id)

      .EXAMPLE
      $mysecpassword = ConvertTo-SecureString aruba -AsPlainText -Force
      PS C:\>Connect-ArubaCL -region EU-1 -client_id MyClientID -client_secret MyClientSecret -customer_id MyCustomerId -Username admin -Password $mysecpassword

      Connect to Aruba Central on region EU-1 using Username and Password and client id/secret and customer(id)
  #>


    Param(
        [Parameter(Mandatory = $true, position = 1)]
        [ValidateSet('APAC-1', 'APAC-EAST1', 'APAC-SOUTH1', 'Canada-1', 'China-1', 'EU-1', 'US-1', 'US-2', 'US-WEST4', 'EU-CENTRAL3')]
        [String]$region,
        [Parameter(Mandatory = $false)]
        [String]$Username,
        [Parameter(Mandatory = $false)]
        [SecureString]$Password,
        [Parameter(Mandatory = $false)]
        [PSCredential]$Credential,
        [Parameter(Mandatory = $true)]
        [String]$client_id,
        [Parameter(Mandatory = $true)]
        [String]$client_secret,
        [Parameter(Mandatory = $true)]
        [String]$customer_id,
        [Parameter(Mandatory = $false)]
        [boolean]$DefaultConnection = $true
    )

    Begin {
    }

    Process {

        $token = @{access_token = ""; refresh_token = ""; expire = ""; client_id = ""; client_secret = ""; }
        $connection = @{server = ""; session = ""; token = $token; headers = ""; invokeParams = "" }
        $invokeParams = @{ UseBasicParsing = $true; }

        #If there is a password (and a user), create a credential
        if ($Password) {
            $Credential = New-Object System.Management.Automation.PSCredential($Username, $Password)
        }

        #Not Credential (and no password)
        if ($null -eq $Credential) {
            $Credential = Get-Credential -Message 'Please enter administrative credential for your Aruba Central'
        }

        #for PowerShell (<=) 5 (Desktop), Enable TLS 1.1, 1.2
        if ("Desktop" -eq $PSVersionTable.PsEdition) {
            #Enable TLS 1.1 and 1.2
            Set-ArubaCLCipherSSL
            #Remove System Array type for avoid count when convert to json
            Remove-TypeData -TypeName System.Array
        }
        else {
            #Core Edition
            #Remove -UseBasicParsing (Enable by default with PowerShell 6/Core)
            $invokeParams.remove("UseBasicParsing")
        }

        #Region
        switch ($region) {
            'APAC-1' {
                $server = "api-ap.central.arubanetworks.com"
            }
            'APAC-EAST1' {
                $server = "apigw-apaceast.central.arubanetworks.com"
            }
            'APAC-SOUTH1' {
                $server = "apigw-apacsouth.central.arubanetworks.com"
            }
            'Canada-1' {
                $server = "apigw-ca.central.arubanetworks.com"
            }
            'China-1' {
                $server = "apigw.central.arubanetworks.com.cn"
            }
            'EU-1' {
                $server = "eu-apigw.central.arubanetworks.com"
            }
            'EU-CENTRAL3' {
                $server = "apigw-eucentral3.central.arubanetworks.com"
            }
            'US-1' {
                $server = "app1-apigw.central.arubanetworks.com"
            }
            'US-2' {
                $server = "apigw-prod2.central.arubanetworks.com"
            }
            'US-WEST4' {
                $server = "apigw-uswest4.central.arubanetworks.com"
            }
        }

        $postParams = @{username = $Credential.username; password = $Credential.GetNetworkCredential().Password }

        $url = "https://${Server}/oauth2/authorize/central/api/login"
        $url += "?client_id=${client_id}"
        $headers = @{ Accept = "application/json"; "Content-type" = "application/json" }
        Write-Verbose ($postParams | ConvertTo-Json)
        try {
            $response = Invoke-RestMethod $url -Method POST -Body ($postParams | ConvertTo-Json) -SessionVariable ArubaCL -headers $headers @invokeParams
        }
        catch {
            Show-ArubaCLException $_
            throw "Unable to login"
        }

        if ($response.status -ne "True") {
            $errormsg = $response.message
            throw "Unable to connect ($errormsg)"
        }

        #Search crsf cookie and session
        $cookies = $ArubaCL.Cookies.GetCookies($url)
        foreach ($cookie in $cookies) {
            #$cookie.name
            if ($cookie.name -eq "csrftoken") {
                $cookie_csrf = $cookie.value
            }
            if ($cookie.name -eq "session") {
                $cookie_session = $cookie.value
            }
        }

        $url = "https://${Server}/oauth2/authorize/central/api"
        $url += "?client_id=${client_id}&response_type=code&scope=all"
        $headers = @{ Accept = "application/json"; "Content-type" = "application/json" ; "Cookie" = $cookie_session ; "X-CSRF-TOKEN" = $cookie_csrf }
        $postParams = @{ customer_id = $customer_id }

        try {
            $response = Invoke-RestMethod $url -Method POST -Body ($postParams | ConvertTo-Json) -WebSession $ArubaCL -headers $headers @invokeParams
        }
        catch {
            Show-ArubaCLException $_
            throw "Unable to authorize"
        }

        $auth_code = $response.auth_code

        $url = "https://${Server}/oauth2/token"
        $url += "?client_id=${client_id}&client_secret=${client_secret}&grant_type=authorization_code&code=${auth_code}"
        $headers = @{ Accept = "application/json"; "Content-type" = "application/json" }

        try {
            $response = Invoke-RestMethod $url -Method POST -WebSession $ArubaCL -headers $headers @invokeParams
        }
        catch {
            Show-ArubaCLException $_
            throw "Unable to get token"
        }

        #Add Access token to headers
        $headers.add( "Authorization", "Bearer " + $response.access_token)

        $connection.server = $server
        $connection.session = $ArubaCL
        $connection.headers = $headers
        $connection.invokeParams = $invokeParams
        #Store token..
        $connection.token.client_id = $client_id
        $connection.token.client_secret = $client_secret
        $connection.token.access_token = $response.access_token
        $connection.token.refresh_token = $response.refresh_token
        #Get when token will be expire
        $connection.token.expire = [int]((Get-Date -UFormat %s) -split ",")[0] + $response.expires_in

        if ( $DefaultConnection ) {
            Set-Variable -name DefaultArubaCLConnection -value $connection -scope Global
        }

        $connection
    }

    End {
    }
}

function Disconnect-ArubaCL {

    <#
        .SYNOPSIS
        Disconnect to Aruba Central

        .DESCRIPTION
        Disconnect the connection on Aruba Central

        .EXAMPLE
        Disconnect-ArubaCL

        Disconnect the connection

        .EXAMPLE
        Disconnect-ArubaCL -confirm:$false

        Disconnect the connection with no confirmation

    #>


    [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')]
    Param(
        [Parameter (Mandatory = $False)]
        [ValidateNotNullOrEmpty()]
        [PSObject]$connection = $DefaultArubaCLConnection
    )

    Begin {
    }

    Process {

        if ($PSCmdlet.ShouldProcess($connection.server, 'Remove Aruba Central connection ?')) {
            #Not really connection on CPPM with token
            if ( ($connection -eq $DefaultArubaCLConnection) -and (Test-Path variable:global:DefaultArubaCLConnection) ) {
                Remove-Variable -name DefaultArubaCLConnection -scope global
            }
        }

    }

    End {
    }
}