Skip to content

Commit 869e64d

Browse files
authored
First release of Az.HanaOnAzure (#12330)
* Az.HanaOnAzure * psd1 * suppress * clean code
1 parent 4869824 commit 869e64d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+6650
-198
lines changed

src/HanaOnAzure/.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@ test/*-TestResults.xml
1111
/*.psm1
1212
/*.snk
1313
/*.csproj
14-
/*.nuspec
14+
/*.nuspec
15+
tools

src/HanaOnAzure/Az.Hana.psd1

Lines changed: 0 additions & 25 deletions
This file was deleted.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
@{
2+
GUID = '79ad50da-e6b5-4703-885a-d36974a4d9b9'
3+
RootModule = './Az.HanaOnAzure.psm1'
4+
ModuleVersion = '0.1.0'
5+
CompatiblePSEditions = 'Core', 'Desktop'
6+
Author = 'Microsoft Corporation'
7+
CompanyName = 'Microsoft Corporation'
8+
Copyright = 'Microsoft Corporation. All rights reserved.'
9+
Description = 'Microsoft Azure PowerShell: HanaOn cmdlets'
10+
PowerShellVersion = '5.1'
11+
DotNetFrameworkVersion = '4.7.2'
12+
RequiredAssemblies = './bin/Az.HanaOnAzure.private.dll'
13+
FormatsToProcess = './Az.HanaOnAzure.format.ps1xml'
14+
FunctionsToExport = 'Get-AzSapMonitor', 'Get-AzSapMonitorProviderInstance', 'New-AzSapMonitor', 'New-AzSapMonitorProviderInstance', 'Remove-AzSapMonitor', 'Remove-AzSapMonitorProviderInstance', 'Update-AzSapMonitor'
15+
AliasesToExport = '*'
16+
PrivateData = @{
17+
PSData = @{
18+
Tags = 'Azure', 'ResourceManager', 'ARM', 'PSModule', 'HanaOn'
19+
LicenseUri = 'https://aka.ms/azps-license'
20+
ProjectUri = 'https://github.com/Azure/azure-powershell'
21+
ReleaseNotes = ''
22+
}
23+
}
24+
}
Lines changed: 271 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,271 @@
1+
2+
# ----------------------------------------------------------------------------------
3+
#
4+
# Copyright Microsoft Corporation
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
# ----------------------------------------------------------------------------------
15+
16+
<#
17+
.Synopsis
18+
Creates a provider instance for the specified subscription, resource group, SapMonitor name, and resource name.
19+
.Description
20+
Creates a provider instance for the specified subscription, resource group, SapMonitor name, and resource name.
21+
.Outputs
22+
Microsoft.Azure.PowerShell.Cmdlets.HanaOnAzure.Models.Api20200207Preview.IProviderInstance
23+
.Link
24+
https://docs.microsoft.com/en-us/powershell/module/az.hana/new-azsapproviderinstance
25+
#>
26+
function New-AzSapMonitorProviderInstance {
27+
[OutputType([Microsoft.Azure.PowerShell.Cmdlets.HanaOnAzure.Models.Api20200207Preview.IProviderInstance])]
28+
[CmdletBinding(DefaultParameterSetName = 'ByString', PositionalBinding = $false, SupportsShouldProcess, ConfirmImpact = 'Medium')]
29+
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingPlainTextForPassword', 'HanaDatabasePasswordKeyVaultResourceId', Justification = 'Not a password')]
30+
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingPlainTextForPassword', 'HanaDatabasePasswordSecretId', Justification = 'Not a password')]
31+
param(
32+
[Parameter(Mandatory)]
33+
[Alias('ProviderInstanceName')]
34+
[Microsoft.Azure.PowerShell.Cmdlets.HanaOnAzure.Category('Path')]
35+
[System.String]
36+
# Name of the provider instance.
37+
${Name},
38+
39+
[Parameter(Mandatory)]
40+
[Microsoft.Azure.PowerShell.Cmdlets.HanaOnAzure.Category('Path')]
41+
[System.String]
42+
# Name of the resource group.
43+
${ResourceGroupName},
44+
45+
[Parameter(Mandatory)]
46+
[Microsoft.Azure.PowerShell.Cmdlets.HanaOnAzure.Category('Path')]
47+
[System.String]
48+
# Name of the SAP monitor resource.
49+
${SapMonitorName},
50+
51+
[Parameter()]
52+
[Microsoft.Azure.PowerShell.Cmdlets.HanaOnAzure.Category('Path')]
53+
[Microsoft.Azure.PowerShell.Cmdlets.HanaOnAzure.Runtime.DefaultInfo(Script = '(Get-AzContext).Subscription.Id')]
54+
[System.String]
55+
# Subscription ID which uniquely identify Microsoft Azure subscription.
56+
# The subscription ID forms part of the URI for every service call.
57+
${SubscriptionId},
58+
59+
[Parameter()]
60+
[Microsoft.Azure.PowerShell.Cmdlets.HanaOnAzure.Category('Body')]
61+
[System.Collections.Hashtable]
62+
# A JSON string containing metadata of the provider instance.
63+
${Metadata},
64+
65+
[Parameter(Mandatory)]
66+
[Microsoft.Azure.PowerShell.Cmdlets.HanaOnAzure.Category('Body')]
67+
[System.String]
68+
# The type of provider instance. Supported values are: "SapHana".
69+
${ProviderType},
70+
71+
[Parameter(Mandatory)]
72+
[Microsoft.Azure.PowerShell.Cmdlets.HanaOnAzure.Category('Body')]
73+
[System.String]
74+
# The hostname of SAP HANA instance.
75+
${HanaHostname},
76+
77+
[Parameter(Mandatory)]
78+
[Alias('HanaDbName')]
79+
[Microsoft.Azure.PowerShell.Cmdlets.HanaOnAzure.Category('Body')]
80+
[System.String]
81+
# The database name of SAP HANA instance.
82+
${HanaDatabaseName},
83+
84+
[Parameter(Mandatory)]
85+
[Alias('HanaDbSqlPort')]
86+
[Microsoft.Azure.PowerShell.Cmdlets.HanaOnAzure.Category('Body')]
87+
[System.Int32]
88+
# The SQL port of the database of SAP HANA instance.
89+
${HanaDatabaseSqlPort},
90+
91+
[Parameter(Mandatory)]
92+
[Alias('HanaDbUsername')]
93+
[Microsoft.Azure.PowerShell.Cmdlets.HanaOnAzure.Category('Body')]
94+
[System.String]
95+
# The username of the database of SAP HANA instance.
96+
${HanaDatabaseUsername},
97+
98+
[Parameter(ParameterSetName = 'ByString', Mandatory)]
99+
[Alias('HanaDbPassword')]
100+
[Microsoft.Azure.PowerShell.Cmdlets.HanaOnAzure.Category('Body')]
101+
[SecureString]
102+
# The password of the database of SAP HANA instance.
103+
${HanaDatabasePassword},
104+
105+
[Parameter(ParameterSetName = 'ByKeyVault', Mandatory)]
106+
[Alias('HanaDbPasswordKeyVaultId', 'KeyVaultId')]
107+
[Microsoft.Azure.PowerShell.Cmdlets.HanaOnAzure.Category('Body')]
108+
[System.String]
109+
# Resource ID of the Key Vault that contains the HANA credentials.
110+
${HanaDatabasePasswordKeyVaultResourceId},
111+
112+
[Parameter(ParameterSetName = 'ByKeyVault', Mandatory)]
113+
[Alias('HanaDbPasswordSecretId', 'SecretId')]
114+
[Microsoft.Azure.PowerShell.Cmdlets.HanaOnAzure.Category('Body')]
115+
[System.String]
116+
# Secret identifier to the Key Vault secret that contains the HANA credentials.
117+
${HanaDatabasePasswordSecretId},
118+
119+
[Parameter()]
120+
[Alias('AzureRMContext', 'AzureCredential')]
121+
[ValidateNotNull()]
122+
[Microsoft.Azure.PowerShell.Cmdlets.HanaOnAzure.Category('Azure')]
123+
[System.Management.Automation.PSObject]
124+
# The credentials, account, tenant, and subscription used for communication with Azure.
125+
${DefaultProfile},
126+
127+
[Parameter()]
128+
[Microsoft.Azure.PowerShell.Cmdlets.HanaOnAzure.Category('Runtime')]
129+
[System.Management.Automation.SwitchParameter]
130+
# Run the command as a job
131+
${AsJob},
132+
133+
[Parameter(DontShow)]
134+
[Microsoft.Azure.PowerShell.Cmdlets.HanaOnAzure.Category('Runtime')]
135+
[System.Management.Automation.SwitchParameter]
136+
# Wait for .NET debugger to attach
137+
${Break},
138+
139+
[Parameter(DontShow)]
140+
[ValidateNotNull()]
141+
[Microsoft.Azure.PowerShell.Cmdlets.HanaOnAzure.Category('Runtime')]
142+
[Microsoft.Azure.PowerShell.Cmdlets.HanaOnAzure.Runtime.SendAsyncStep[]]
143+
# SendAsync Pipeline Steps to be appended to the front of the pipeline
144+
${HttpPipelineAppend},
145+
146+
[Parameter(DontShow)]
147+
[ValidateNotNull()]
148+
[Microsoft.Azure.PowerShell.Cmdlets.HanaOnAzure.Category('Runtime')]
149+
[Microsoft.Azure.PowerShell.Cmdlets.HanaOnAzure.Runtime.SendAsyncStep[]]
150+
# SendAsync Pipeline Steps to be prepended to the front of the pipeline
151+
${HttpPipelinePrepend},
152+
153+
[Parameter()]
154+
[Microsoft.Azure.PowerShell.Cmdlets.HanaOnAzure.Category('Runtime')]
155+
[System.Management.Automation.SwitchParameter]
156+
# Run the command asynchronously
157+
${NoWait},
158+
159+
[Parameter(DontShow)]
160+
[Microsoft.Azure.PowerShell.Cmdlets.HanaOnAzure.Category('Runtime')]
161+
[System.Uri]
162+
# The URI for the proxy server to use
163+
${Proxy},
164+
165+
[Parameter(DontShow)]
166+
[ValidateNotNull()]
167+
[Microsoft.Azure.PowerShell.Cmdlets.HanaOnAzure.Category('Runtime')]
168+
[System.Management.Automation.PSCredential]
169+
# Credentials for a proxy server to use for the remote call
170+
${ProxyCredential},
171+
172+
[Parameter(DontShow)]
173+
[Microsoft.Azure.PowerShell.Cmdlets.HanaOnAzure.Category('Runtime')]
174+
[System.Management.Automation.SwitchParameter]
175+
# Use the default credentials for the proxy
176+
${ProxyUseDefaultCredentials}
177+
)
178+
179+
process {
180+
$null = $PSBoundParameters.Remove('ResourceGroupName')
181+
$null = $PSBoundParameters.Remove('Name')
182+
$null = $PSBoundParameters.Remove('SapMonitorName')
183+
$null = $PSBoundParameters.Remove('ProviderType')
184+
$null = $PSBoundParameters.Remove('Metadata')
185+
186+
$null = $PSBoundParameters.Remove('HanaHostname')
187+
$null = $PSBoundParameters.Remove('HanaDatabaseName')
188+
$null = $PSBoundParameters.Remove('HanaDatabaseSqlPort')
189+
$null = $PSBoundParameters.Remove('HanaDatabaseUsername')
190+
$null = $PSBoundParameters.Remove('HanaDatabasePasswordSecretId')
191+
$null = $PSBoundParameters.Remove('HanaDatabasePasswordKeyVaultResourceId')
192+
193+
$null = $PSBoundParameters.Remove('Confirm')
194+
$null = $PSBoundParameters.Remove('WhatIf')
195+
$hasAsJob = $PSBoundParameters.Remove('AsJob')
196+
197+
$parameterSet = $PSCmdlet.ParameterSetName
198+
switch ($parameterSet) {
199+
'ByString' {
200+
$null = $PSBoundParameters.Remove('HanaDatabasePassword')
201+
$property = @{
202+
hanaHostname = $HanaHostname
203+
hanaDbName = $HanaDatabaseName
204+
hanaDbSqlPort = $HanaDatabaseSqlPort
205+
hanaDbUsername = $HanaDatabaseUsername
206+
hanaDbPassword = ConvertFrom-SecureString $HanaDatabasePassword -AsPlainText
207+
}
208+
}
209+
'ByKeyVault' {
210+
# Referencing to CLI's implementation
211+
# https://github.com/Azure/azure-hanaonazure-cli-extension/blob/master/azext_hanaonazure/custom.py#L312-L338
212+
213+
# 1. Get MSI
214+
$sapMonitor = Get-AzSapMonitor -ResourceGroupName $ResourceGroupName -Name $SapMonitorName @PSBoundParameters
215+
$managedResourceGroupName = $sapMonitor.ManagedResourceGroupName
216+
$sapMonitorId = $managedResourceGroupName.Split("-")[2]
217+
218+
$msiName = "sapmon-msi-$sapMonitorId"
219+
$msi = Az.HanaOnAzure.internal\Get-AzUserAssignedIdentity -ResourceGroupName $managedResourceGroupName -ResourceName $msiName @PSBoundParameters
220+
221+
# 2. Grant key vault access to MSI
222+
$null = $HanaDatabasePasswordKeyVaultResourceId -match "^/subscriptions/(?<subscriptionId>[^/]+)/resourceGroups/(?<resourceGroupName>[^/]+)/providers/Microsoft.KeyVault/vaults/(?<vaultName>[^/]+)$"
223+
$vaultSubscriptionId = $Matches['subscriptionId']
224+
$vaultResourceGroupName = $Matches['resourceGroupName']
225+
$vaultName = $Matches['vaultName']
226+
227+
# Need to use vault's sub ID, not the sub ID of this cmdlet
228+
$null = $PSBoundParameters.Remove('SubscriptionId')
229+
$null = Az.HanaOnAzure.internal\Set-AzVaultAccessPolicy -OperationKind add -ResourceGroupName $vaultResourceGroupName -VaultName $vaultName -SubscriptionId $vaultSubscriptionId -AccessPolicy @{
230+
ObjectId = $msi.PrincipalId
231+
TenantId = (Get-AzContext).Tenant.Id
232+
PermissionSecret = 'get'
233+
} @PSBoundParameters
234+
$PSBoundParameters.Add('SubscriptionId', $SubscriptionId)
235+
236+
# Service accepts secret ID without port
237+
# but (Get-AzKeyVaultSecret).Id contains port (":443")
238+
# need to remove it
239+
$vaultPort = ":443"
240+
if ($HanaDatabasePasswordSecretId.Contains($vaultPort)) {
241+
$HanaDatabasePasswordSecretId = $HanaDatabasePasswordSecretId.Replace($vaultPort, "")
242+
}
243+
244+
$property = @{
245+
hanaHostname = $HanaHostname
246+
hanaDbName = $HanaDatabaseName
247+
hanaDbSqlPort = $HanaDatabaseSqlPort
248+
hanaDbUsername = $HanaDatabaseUsername
249+
hanaDbPasswordKeyVaultUrl = $HanaDatabasePasswordSecretId
250+
keyVaultId = $HanaDatabasePasswordKeyVaultResourceId # key vault id is keyvault resource id
251+
keyVaultCredentialsMsiClientID = $msi.ClientId # FIXME: this property is not needed in newer service backend, can we remove it?
252+
}
253+
}
254+
}
255+
$PSBoundParameters.Add('ResourceGroupName', $ResourceGroupName)
256+
$PSBoundParameters.Add('Name', $Name)
257+
$PSBoundParameters.Add('SapMonitorName', $SapMonitorName)
258+
$PSBoundParameters.Add('ProviderType', $ProviderType)
259+
$PSBoundParameters.Add('Metadata', ($Metadata | ConvertTo-Json))
260+
261+
$PSBoundParameters.Add('ProviderInstanceProperty', ($property | ConvertTo-Json))
262+
263+
if ($hasAsJob) {
264+
$PSBoundParameters.Add('AsJob', $true)
265+
}
266+
267+
if ($PSCmdlet.ShouldProcess("SAP monitor provider instance $Name", "Create")) {
268+
Az.HanaOnAzure.internal\New-AzSapMonitorProviderInstance @PSBoundParameters
269+
}
270+
}
271+
}

0 commit comments

Comments
 (0)