Api/Invoke-NavContainerApi.ps1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
<#
 .Synopsis
  Invoke Api in Container
 .Description
  Invoke an Api in a Container.
 .Parameter containerName
  Name of the container in which you want to invoke an api
 .Parameter tenant
  Name of the tenant in which context you want to invoke an api
 .Parameter CompanyId
  Id the Company in which context you want to invoke an api (Use Get-NavContainerApiCompanyId
 .Parameter Codeunitid
  Id of the codeunit you want to invoke
 .Parameter Credential
  Credentials for the user making invoking the api (do not specify if using Windows auth)
 .Parameter APIPublisher
  Publisher of the custom api you want to invoke (empty for built in api)
 .Parameter APIGroup
  Group of the custom api you want to invoke (empty for built in api)
 .Parameter APIVersion
  Version of the API you want to invoke (beta, v1.0, ...)
 .Parameter Method
  API Method to invoke (GET, POST, PATCH, DELETE)
 .Parameter Query
  API Query (ex. salesInvoices?$filter=totalAmountIncludingTax gt 10000)
 .Parameter headers
  Additional headers for the api (example: @{ "If-Match" = $etag } )
 .Parameter body
  Parameters for the api (example: @{ "name" = "The Name"; "phoneNumber" = "12 34 56 78" })
 .Example
  $result = Invoke-NavContainerApi -containerName $containerName -tenant $tenant -APIVersion "beta" -Query "companies?`$filter=$companyFilter" -credential $credential
 .Example
  Invoke-NavContainerApi -containerName $containerName -CompanyId $companyId -APIVersion "beta" -Query "customers" -credential $credential | Select-Object -ExpandProperty value
 .Example
  Invoke-NavContainerApi -containerName $containerName -CompanyId $companyId -APIVersion "beta" -Query "customers?`$filter=$([Uri]::EscapeDataString("number eq '10000'"))" -credential $credential | Select-Object -ExpandProperty value
 .Example
  Invoke-NavContainerApi -containerName $containerName -CompanyId $companyId -APIVersion "beta" -Query "salesInvoices?`$filter=$([Uri]::EscapeDataString("status eq 'Open' and totalAmountExcludingTax gt 1000.00"))" -credential $credential | Select-Object -ExpandProperty value
#>

function Invoke-NavContainerApi {
    Param(
        [Parameter(Mandatory=$true)]
        [string]$containerName, 
        [Parameter(Mandatory=$false)]
        [string]$tenant = "default",
        [Parameter(Mandatory=$false)]
        [string]$CompanyId,
        [Parameter(Mandatory=$false)]
        [System.Management.Automation.PSCredential]$credential = $null,
        [Parameter(Mandatory=$false)]
        [string]$APIPublisher = "",
        [Parameter(Mandatory=$false)]
        [string]$APIGroup = "",
        [Parameter(Mandatory=$true)]
        [string]$APIVersion,
        [Parameter(Mandatory=$false)]
        [string]$Method = "GET",
        [Parameter(Mandatory=$false)]
        [string]$Query,
        [Parameter(Mandatory=$false)]
        [hashtable]$headers = @{},
        [Parameter(Mandatory=$false)]
        [hashtable]$body = $null
    )

    $customConfig = Get-NavContainerServerConfiguration -ContainerName $containerName

    $parameters = @{}
    if ($customConfig.ClientServicesCredentialType -eq "Windows") {
        $parameters += @{ "usedefaultcredential" = $true }
    }
    else {
        if (!($credential)) {
            throw "You need to specify credentials when you are not using Windows Authentication"
        }
        $parameters += @{ "credential" = $credential }
    }

    $serverInstance = $customConfig.ServerInstance

    if ($customConfig.ODataServicesSSLEnabled -eq "true") {
        $protocol = "https://"
    } else {
        $protocol = "http://"
    }
    
    $ip = Get-NavContainerIpAddress -containerName $containerName
    if ($ip) {
        $url = "${protocol}${ip}:$($customConfig.ODataServicesPort)/$($customConfig.ServerInstance)/api"
    }
    else {
        $url = $customconfig.PublicODataBaseUrl.Replace("/OData","/api")
    }

    $sslVerificationDisabled = ($protocol -eq "https://")
    if ($sslVerificationDisabled) {
        if (-not ([System.Management.Automation.PSTypeName]"SslVerification").Type)
        {
            Add-Type -TypeDefinition "
                using System.Net.Security;
                using System.Security.Cryptography.X509Certificates;
                public static class SslVerification
                {
                    private static bool ValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; }
                    public static void Disable() { System.Net.ServicePointManager.ServerCertificateValidationCallback = ValidationCallback; }
                    public static void Enable() { System.Net.ServicePointManager.ServerCertificateValidationCallback = null; }
                }"

        }
        [SslVerification]::Disable()
    }

    if ($APIPublisher) {
        $url += "/$APIPublisher"
    }

    if ($APIGroup) {
        $url += "/$APIGroup"
    }

    $url += "/$APIVersion"

    if ($companyId) {
        $url += "/companies($CompanyId)"
    }

    $url += "/$Query"

    if ($Query.Contains('?')) {
        $url += "&tenant=$tenant"
    }
    else {
        $url += "?tenant=$tenant"
    }

    $headers += @{"Content-Type" = "application/json" }
    
    if ($body) {
        $parameters += @{ "body" = $body | ConvertTo-Json }
    }

    Write-Host "Invoke $Method on $url"
    Invoke-RestMethod -Method $Method -uri "$url" -Headers $headers @parameters

    if ($sslverificationdisabled) {
        [SslVerification]::Enable()
    }

}
Set-Alias -Name Invoke-BCContainerApi -Value Invoke-NavContainerApi
Export-ModuleMember -Function Invoke-NavContainerApi -Alias Invoke-BCContainerApi