diff --git a/docs/preview/03-Features/powershell/azure-iot-hub.md b/docs/preview/03-Features/powershell/azure-iot-hub.md new file mode 100644 index 00000000..460ed926 --- /dev/null +++ b/docs/preview/03-Features/powershell/azure-iot-hub.md @@ -0,0 +1,34 @@ +--- +title: "Azure Iot Hub" +layout: default +--- + +# Azure Iot Hub + +## Installation + +To have access to the following features, you have to import the module: + +```powershell +PS> Install-Module -Name Arcus.Scripting.IotHub +``` + +## Getting quota metrics from Azure IoT Hub +As part of the setup for alert-creations for Azure IoT Hub, a script has been included which allows you to determine the current quota of messages. +The result can be used when creating an alert on IoT Hub that is triggered when the daily amount of messages that you have received, is reaching the quota / limit of that IoT Hub. + +| Parameter | Mandatory | Description | +| ------------------- | --------- | -------------------------------------------------------------------------------------- | +| `IotHubName` | yes | The name of the Azure IoT Hub from where the message quota metric should be retrieved. | +| `ResourceGroupName` | yes | The resource group containing the Azure IoT Hub. | +| `QuotaPercentage` | yes | The requested percentage of the quota metric of the Azure IoT Hub's total messages. | + +**Example** + +```powershell +PS> Get-AzIotHubDailyMessageQuotaThreshold ` +-IotHubName "" +-ResourceGroupName "" +-QuotaPercentage 0.3 +# Calculated '321' as quota percentage of Azure IoT Hub metric from '' in resource group '' +``` \ No newline at end of file diff --git a/src/Arcus.Scripting.IotHub/Arcus.Scripting.IoTHub.psm1 b/src/Arcus.Scripting.IotHub/Arcus.Scripting.IoTHub.psm1 new file mode 100644 index 00000000..095d50ab --- /dev/null +++ b/src/Arcus.Scripting.IotHub/Arcus.Scripting.IoTHub.psm1 @@ -0,0 +1,26 @@ +<# + .Synopsis + Return the the current quota of Azure IoT Hub messages. + + .Description + Retrieves one specific percentage quota metric of an Azure IoT Hub's total messages. + + .Parameter IotHubName + The name of the Azure IoT Hub from where the message quota metric should be retrieved. + + .Parameter ResourceGroupName + The resource group containing the Azure IoT Hub. + + .Parameter QuotaPercentage + The requested percentage of the quota metric of the Azure IoT Hub's total messages. +#> +function Get-AzIotHubDailyMessageQuotaThreshold { + param( + [Parameter(Mandatory=$True)][string] $IotHubName = $(throw "Name of the Azure IoT Hub instance is required"), + [Parameter(Mandatory=$True)][single] $QuotaPercentage = $(throw "Quota percentage is required"), + [Parameter(Mandatory=$False)][string] $ResourceGroupName = "" + ) + . $PSScriptRoot\Scripts\Get-AzIotHubDailyMessageQuotaThreshold.ps1 -IotHubName $IoTHubName -QuotaPercentage $QuotaPercentage -ResourceGroupName $ResourceGroupName +} + +Export-ModuleMember -Function Get-AzIotHubDailyMessageQuotaThreshold \ No newline at end of file diff --git a/src/Arcus.Scripting.IotHub/Arcus.Scripting.IoTHub.pssproj b/src/Arcus.Scripting.IotHub/Arcus.Scripting.IoTHub.pssproj new file mode 100644 index 00000000..9ce04f92 --- /dev/null +++ b/src/Arcus.Scripting.IotHub/Arcus.Scripting.IoTHub.pssproj @@ -0,0 +1,40 @@ + + + Debug + 2.0 + {336aa7bf-1bd2-4067-bbf7-f2844766a8dd} + Exe + Arcus.Scripting.IotHub + Arcus.Scripting.IotHub + Arcus.Scripting.IotHub + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Arcus.Scripting.IotHub/Arcus.Scripting.IotHub.psd1 b/src/Arcus.Scripting.IotHub/Arcus.Scripting.IotHub.psd1 new file mode 100644 index 00000000..0e1167a8 Binary files /dev/null and b/src/Arcus.Scripting.IotHub/Arcus.Scripting.IotHub.psd1 differ diff --git a/src/Arcus.Scripting.IotHub/Scripts/Get-AzIotHubDailyMessageQuotaThreshold.ps1 b/src/Arcus.Scripting.IotHub/Scripts/Get-AzIotHubDailyMessageQuotaThreshold.ps1 new file mode 100644 index 00000000..ef9e8da3 --- /dev/null +++ b/src/Arcus.Scripting.IotHub/Scripts/Get-AzIotHubDailyMessageQuotaThreshold.ps1 @@ -0,0 +1,14 @@ +param( + [Parameter(Mandatory=$true)][string] $IotHubName = $(throw "Name of the Azure IoT Hub instance is required"), + [Parameter(Mandatory=$true)][single] $QuotaPercentage = $(throw "Quota percentage is required"), + [Parameter(Mandatory=$false)][string] $ResourceGroupName = "" +) + +Write-Verbose "Getting single Azure IoT hub metric from '$IotHubName' in resource group '$ResourceGroupName'..." +$quotaMetric = Get-AzIotHubQuotaMetric -Name $IotHubName -ResourceGroupName $ResourceGroupName + +Write-Verbose "Calculate quota percentage of Azure IoT hub metric from '$IotHubName' in resource group '$ResourceGroupName'..." +$result = [Math]::Round($quotaMetric.MaxValue * $QuotaPercentage) + +Write-Host "Calculated '$result' as quota percentage of Azure IoT Hub metric from '$IotHubName' in resource group '$ResourceGroupName'" +return $result \ No newline at end of file diff --git a/src/Arcus.Scripting.Tests.Integration/Arcus.Scripting.IotHub.tests.ps1 b/src/Arcus.Scripting.Tests.Integration/Arcus.Scripting.IotHub.tests.ps1 new file mode 100644 index 00000000..5c9e88cb --- /dev/null +++ b/src/Arcus.Scripting.Tests.Integration/Arcus.Scripting.IotHub.tests.ps1 @@ -0,0 +1,23 @@ +Import-Module Az.IotHub +Import-Module -Name $PSScriptRoot\..\Arcus.Scripting.IotHub -ErrorAction Stop + +InModuleScope Arcus.Scripting.IotHub { + Describe "Arcus Azure IoT Hub integration tests" { + BeforeEach { + $config = & $PSScriptRoot\Load-JsonAppsettings.ps1 + & $PSScriptRoot\Connect-AzAccountFromConfig.ps1 -config $config + } + Context "Get daily IoT Hub quota threshold" { + It "Get daily IoT Hub quota threshold gets quota percentage" { + # Act + $result = Get-AzIotHubDailyMessageQuotaThreshold ` + -IoTHubName $config.Arcus.IotHub.Name ` + -ResourceGroupName $config.Arcus.ResourceGroupName ` + -QuotaPercentage 0.1 + + # Assert + $result | Should -Be 0 + } + } + } +} \ No newline at end of file diff --git a/src/Arcus.Scripting.Tests.Integration/Arcus.Scripting.Tests.Integration.pssproj b/src/Arcus.Scripting.Tests.Integration/Arcus.Scripting.Tests.Integration.pssproj index 136606e6..786b5ee9 100644 --- a/src/Arcus.Scripting.Tests.Integration/Arcus.Scripting.Tests.Integration.pssproj +++ b/src/Arcus.Scripting.Tests.Integration/Arcus.Scripting.Tests.Integration.pssproj @@ -39,6 +39,7 @@ + diff --git a/src/Arcus.Scripting.Tests.Integration/appsettings.json b/src/Arcus.Scripting.Tests.Integration/appsettings.json index 0185f796..6aee24ba 100644 --- a/src/Arcus.Scripting.Tests.Integration/appsettings.json +++ b/src/Arcus.Scripting.Tests.Integration/appsettings.json @@ -18,6 +18,9 @@ "IntegrationAccount": { "Name": "#{Arcus.IntegrationAccount.Name}#" }, + "IotHub": { + "Name": "#{Arcus.IotHub.Name}#" + }, "AppService": { "Name": "#{Arcus.AppService.Name}#" }, diff --git a/src/Arcus.Scripting.sln b/src/Arcus.Scripting.sln index ea000e16..ec233d4f 100644 --- a/src/Arcus.Scripting.sln +++ b/src/Arcus.Scripting.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.4.32916.344 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31702.278 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{5C8B7391-D202-4B09-8991-3EBAC09A585E}" EndProject @@ -43,6 +43,8 @@ Project("{F5034706-568F-408A-B7B3-4D38C6DB8A32}") = "Arcus.Scripting.Management" EndProject Project("{F5034706-568F-408A-B7B3-4D38C6DB8A32}") = "Arcus.Scripting.ActiveDirectory", "Arcus.Scripting.ActiveDirectory\Arcus.Scripting.ActiveDirectory.pssproj", "{8C0379AD-D886-491F-9E1C-FCE0A7D144E8}" EndProject +Project("{F5034706-568F-408A-B7B3-4D38C6DB8A32}") = "Arcus.Scripting.IotHub", "Arcus.Scripting.IotHub\Arcus.Scripting.IotHub.pssproj", "{336AA7BF-1BD2-4067-BBF7-F2844766A8DD}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -125,6 +127,10 @@ Global {8C0379AD-D886-491F-9E1C-FCE0A7D144E8}.Debug|Any CPU.Build.0 = Debug|Any CPU {8C0379AD-D886-491F-9E1C-FCE0A7D144E8}.Release|Any CPU.ActiveCfg = Release|Any CPU {8C0379AD-D886-491F-9E1C-FCE0A7D144E8}.Release|Any CPU.Build.0 = Release|Any CPU + {336AA7BF-1BD2-4067-BBF7-F2844766A8DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {336AA7BF-1BD2-4067-BBF7-F2844766A8DD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {336AA7BF-1BD2-4067-BBF7-F2844766A8DD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {336AA7BF-1BD2-4067-BBF7-F2844766A8DD}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE