Skip to content

New cmdlets to create/enter PSSession in remote container app #7423

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Oct 2, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2395,6 +2395,8 @@
"Get-AzDeletedWebApp": "Get-AzureRmDeletedWebApp",
"Restore-AzDeletedWebApp": "Restore-AzureRmDeletedWebApp",
"Get-AzWebAppContainerContinuousDeploymentUrl": "Get-AzureRmWebAppContainerContinuousDeploymentUrl",
"Swap-AzWebAppSlot": "Swap-AzureRmWebAppSlot"
"Swap-AzWebAppSlot": "Swap-AzureRmWebAppSlot",
"Enter-AzWebAppContainerPSSession" : "Enter-AzureRmWebAppContainerPSSession",
"New-AzWebAppContainerPSSession" : "New-AzureRmWebAppContainerPSSession"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,12 @@
<None Include="SessionRecords\Microsoft.Azure.Commands.Websites.Test.ScenarioTests.WebAppBackupRestoreTests\TestRestoreDeletedWebAppToNew.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="SessionRecords\Microsoft.Azure.Commands.Websites.Test.ScenarioTests.WebAppTests\TestWindowsContainerWebAppCanIssuePSSession.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="SessionRecords\Microsoft.Azure.Commands.Websites.Test.ScenarioTests.WebAppTests\TestWindowsContainerWebAppPSSessionOpened.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\Storage\Commands.Storage\Commands.Storage.csproj">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,5 +129,19 @@ public void TestRemoveWebApp()
{
WebsitesController.NewInstance.RunPsTest(_logger, "Test-RemoveWebApp");
}

[Fact(Skip = "Skipping while investigation regarding PowerShell version in Travis continues")]
[Trait(Category.AcceptanceType, Category.CheckIn)]
public void TestWindowsContainerWebAppCanIssuePSSession()
{
WebsitesController.NewInstance.RunPsTest(_logger, "Test-WindowsContainerCanIssueWebAppPSSession");
}

[Fact(Skip = "Expected to fail during playback because it validates that a PsSession into a real container web app can be established")]
[Trait(Category.AcceptanceType, Category.CheckIn)]
public void TestWindowsContainerWebAppPSSessionOpened()
{
WebsitesController.NewInstance.RunPsTest(_logger, "Test-WindowsContainerWebAppPSSessionOpened");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,276 @@ function Test-EnableContainerContinuousDeploymentAndGetUrl
}
}

<#
.SYNOPSIS
Tests issuing an EnterPsSession command to a Windows container web app.
.DESCRIPTION
SmokeTest
#>
function Test-WindowsContainerCanIssueWebAppPSSession
{
# Setup
$rgname = Get-ResourceGroupName
$wname = Get-WebsiteName
$location = Get-WebLocation
$whpName = Get-WebHostPlanName
$tier = "PremiumContainer"
$apiversion = "2015-08-01"
$resourceType = "Microsoft.Web/sites"
$containerImageName = "mcr.microsoft.com/azure-app-service/samples/aspnethelloworld:latest"
$containerRegistryUrl = "https://mcr.microsoft.com"
$containerRegistryUser = "testregistry"
$pass = "7Dxo9p79Ins2K3ZU"
$containerRegistryPassword = ConvertTo-SecureString -String $pass -AsPlainText -Force
$dockerPrefix = "DOCKER|"

try
{

Write-Debug "Creating app service plan..."

#Setup
New-AzureRmResourceGroup -Name $rgname -Location $location
$serverFarm = New-AzureRmAppServicePlan -ResourceGroupName $rgname -Name $whpName -Location $location -Tier $tier -WorkerSize Large -HyperV

Write-Debug "App service plan created"

Write-Debug "Creating web app plan..."

# Create new web app
$job = New-AzureRmWebApp -ResourceGroupName $rgname -Name $wname -Location $location -AppServicePlan $whpName -ContainerImageName $containerImageName -ContainerRegistryUrl $containerRegistryUrl -ContainerRegistryUser $containerRegistryUser -ContainerRegistryPassword $containerRegistryPassword -AsJob
$job | Wait-Job
$actual = $job | Receive-Job

Write-Debug "Webapp created"

# Assert
Assert-AreEqual $wname $actual.Name
Assert-AreEqual $serverFarm.Id $actual.ServerFarmId
# Get new web app
$result = Get-AzureRmWebApp -ResourceGroupName $rgname -Name $wname

Write-Debug "Webapp retrieved"

Write-Debug "Validating web app properties..."

# Assert
Assert-AreEqual $wname $result.Name
Assert-AreEqual $serverFarm.Id $result.ServerFarmId
Assert-AreEqual $true $result.IsXenon
Assert-AreEqual ($dockerPrefix + $containerImageName) $result.SiteConfig.WindowsFxVersion

$actualAppSettings = @{}

foreach ($kvp in $result.SiteConfig.AppSettings)
{
$actualAppSettings[$kvp.Name] = $kvp.Value
}

# Validate Appsettings

$expectedAppSettings = @{}
$expectedAppSettings["DOCKER_REGISTRY_SERVER_URL"] = $containerRegistryUrl;
$expectedAppSettings["DOCKER_REGISTRY_SERVER_USERNAME"] = $containerRegistryUser;
$expectedAppSettings["DOCKER_REGISTRY_SERVER_PASSWORD"] = $pass;

foreach ($key in $expectedAppSettings.Keys)
{
Assert-True {$actualAppSettings.Keys -contains $key}
Assert-AreEqual $actualAppSettings[$key] $expectedAppSettings[$key]
}

Write-Debug "Enabling Win-RM..."

# Adding Appsetting: enabling WinRM
$actualAppSettings["CONTAINER_WINRM_ENABLED"] = "1"
$webApp = Set-AzureRmWebApp -ResourceGroupName $rgname -Name $wName -AppSettings $actualAppSettings

# Validating that the client can at least issue the EnterPsSession command.
# This will validate that this cmdlet will run succesfully in Cloud Shell.
# If the current PsVersion is 5.1 or less (Windows PowerShell) and the current WSMAN settings will not allow the user
# to connect (for example: invalid Trusted Hosts, Basic Auth not enabled) this command will issue a Warning instructing the user
# to fix WSMAN settings. It will not attempt to run EnterPsSession.
#
# If the current version is 6.0 (PowerShell Core) this command will not attempt to validate WSMAN settings and
# just try to run EnterPsSession. EnterPsSession is available in Cloud Shell
#
# We need an real Windows Container app running to fully validate the returned PsSession object, which is not
# possible in 'Playback' mode.
#
# This assert at least verifies that the EnterPsSession command is attempted and that the behavior is the expected in
# Windows PowerShell and PowerShell Core.
New-AzureRmWebAppContainerPSSession -ResourceGroupName $rgname -Name $wname -WarningVariable wv -WarningAction SilentlyContinue -ErrorAction SilentlyContinue -Force


if ((Get-WebsitesTestMode) -ne 'Playback')
{
# Message for Recording mode
$message = "Connecting to remote server $wname.azurewebsites.net failed with the following error message : The connection to the specified remote host was refused."
$resultError = $Error[0] -like "*$($message)*"
Write-Debug "Expected Message: $message"
}
else
{
# Two possible messages in Playback mode since the site will not exist.
$messageDNS = "Connecting to remote server $wname.azurewebsites.net failed with the following error message : The WinRM client cannot process the request because the server name cannot be resolved"
$messageUnavailable = "Connecting to remote server $wname.azurewebsites.net failed with the following error message : The WinRM client sent a request to an HTTP server and got a response saying the requested HTTP URL was not available."
$resultError = ($Error[0] -like "*$($messageDNS)*") -or ($Error[0] -like "*$($messageUnavailable)*")
Write-Debug "Expected Message 1: $messageDNS"
Write-Debug "Expected Message 2: $messageUnavailable"
}

Write-Debug "Error: $Error[0]"
Write-Debug "Warnings: $wv"

Write-Debug "Printing PsVersion"
foreach ($key in $PsVersionTable.Keys)
{
Write-Debug "$key"
foreach($v in $PsVersionTable[$key])
{
Write-Debug " $v"
}
}


If(!$resultError)
{
Write-Output "expected error $($message), actual error $($Error[0])"
Write-Output "Warnings: $wv"
}
Assert-True {$resultError}
}
finally
{
# Cleanup
Remove-AzureRmWebApp -ResourceGroupName $rgname -Name $wname -Force
Remove-AzureRmAppServicePlan -ResourceGroupName $rgname -Name $whpName -Force
Remove-AzureRmResourceGroup -Name $rgname -Force
}
}

<#
.SYNOPSIS
Tests that a PsSession can be established to a Windows Container App. It is expected to fail in Playback mode
.DESCRIPTION
SmokeTest
#>
function Test-WindowsContainerWebAppPSSessionOpened
{
# Setup
$rgname = Get-ResourceGroupName
$wname = Get-WebsiteName
$location = Get-WebLocation
$whpName = Get-WebHostPlanName
$tier = "PremiumContainer"
$apiversion = "2015-08-01"
$resourceType = "Microsoft.Web/sites"
$containerImageName = "mcr.microsoft.com/azure-app-service/samples/aspnethelloworld:latest"
$containerRegistryUrl = "https://mcr.microsoft.com"
$containerRegistryUser = "testregistry"
$pass = "7Dxo9p79Ins2K3ZU"
$containerRegistryPassword = ConvertTo-SecureString -String $pass -AsPlainText -Force
$dockerPrefix = "DOCKER|"

try
{

Write-Debug "Creating app service plan..."

#Setup
New-AzureRmResourceGroup -Name $rgname -Location $location
$serverFarm = New-AzureRmAppServicePlan -ResourceGroupName $rgname -Name $whpName -Location $location -Tier $tier -WorkerSize Large -HyperV

Write-Debug "App service plan created"

Write-Debug "Creating web app plan..."

# Create new web app
$job = New-AzureRmWebApp -ResourceGroupName $rgname -Name $wname -Location $location -AppServicePlan $whpName -ContainerImageName $containerImageName -ContainerRegistryUrl $containerRegistryUrl -ContainerRegistryUser $containerRegistryUser -ContainerRegistryPassword $containerRegistryPassword -AsJob
$job | Wait-Job
$actual = $job | Receive-Job

Write-Debug "Webapp created"

# Assert
Assert-AreEqual $wname $actual.Name
Assert-AreEqual $serverFarm.Id $actual.ServerFarmId
# Get new web app
$result = Get-AzureRmWebApp -ResourceGroupName $rgname -Name $wname

Write-Debug "Webapp retrieved"

Write-Debug "Validating web app properties..."

# Assert
Assert-AreEqual $wname $result.Name
Assert-AreEqual $serverFarm.Id $result.ServerFarmId
Assert-AreEqual $true $result.IsXenon
Assert-AreEqual ($dockerPrefix + $containerImageName) $result.SiteConfig.WindowsFxVersion

$actualAppSettings = @{}

foreach ($kvp in $result.SiteConfig.AppSettings)
{
$actualAppSettings[$kvp.Name] = $kvp.Value
}

# Validate Appsettings

$expectedAppSettings = @{}
$expectedAppSettings["DOCKER_REGISTRY_SERVER_URL"] = $containerRegistryUrl;
$expectedAppSettings["DOCKER_REGISTRY_SERVER_USERNAME"] = $containerRegistryUser;
$expectedAppSettings["DOCKER_REGISTRY_SERVER_PASSWORD"] = $pass;

foreach ($key in $expectedAppSettings.Keys)
{
Assert-True {$actualAppSettings.Keys -contains $key}
Assert-AreEqual $actualAppSettings[$key] $expectedAppSettings[$key]
}

Write-Debug "Enabling Win-RM..."

# Adding Appsetting: enabling WinRM
$actualAppSettings["CONTAINER_WINRM_ENABLED"] = "1"
$webApp = Set-AzureRmWebApp -ResourceGroupName $rgname -Name $wName -AppSettings $actualAppSettings

$status = PingWebApp($webApp)
Write-Debug "Just pinged the web app"
Write-Debug "Status: $status"

# Wait for the container app to return 200.
# Windows Container apps return 503 when starting up. Usualy takes 8-9 minutes.
# Timing out at 15 minutes

$count=0
while (($status -like "ServiceUnavailable") -and $count -le 15)
{
Wait-Seconds 60
$status = PingWebApp($webApp)
Write-Debug $count
$count++
}

# Asserting status of the last ping to the web app
Assert-AreEqual $status "200"

$ps_session = New-AzureRmWebAppContainerPSSession -ResourceGroupName $rgname -Name $wname -Force

Write-Debug "After PSSession"

Assert-AreEqual $ps_session.ComputerName $wname".azurewebsites.net"
Assert-AreEqual $ps_session.State "Opened"
}
finally
{
# Cleanup
Remove-AzureRmWebApp -ResourceGroupName $rgname -Name $wname -Force
Remove-AzureRmAppServicePlan -ResourceGroupName $rgname -Name $whpName -Force
Remove-AzureRmResourceGroup -Name $rgname -Force
}
}

<#
.SYNOPSIS
Tests creating a new website on an ase
Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ CmdletsToExport = 'Get-AzAppServicePlan', 'Set-AzAppServicePlan',
'Set-AzWebApp', 'Start-AzWebApp', 'Stop-AzWebApp',
'Get-AzWebAppSnapshot', 'Restore-AzWebAppSnapshot',
'Get-AzDeletedWebApp', 'Restore-AzDeletedWebApp',
'Get-AzWebAppContainerContinuousDeploymentUrl'
'Get-AzWebAppContainerContinuousDeploymentUrl',
'Enter-AzWebAppContainerPSSession', 'New-AzWebAppContainerPSSession'

# Variables to export from this module
# VariablesToExport = @()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ CmdletsToExport = 'Get-AzureRmAppServicePlan', 'Set-AzureRmAppServicePlan',
'Set-AzureRmWebApp', 'Start-AzureRmWebApp', 'Stop-AzureRmWebApp',
'Get-AzureRmWebAppSnapshot', 'Restore-AzureRmWebAppSnapshot',
'Get-AzureRmDeletedWebApp', 'Restore-AzureRmDeletedWebApp',
'Get-AzureRmWebAppContainerContinuousDeploymentUrl'
'Get-AzureRmWebAppContainerContinuousDeploymentUrl',
'Enter-AzureRmWebAppContainerPSSession', 'New-AzureRmWebAppContainerPSSession'

# Variables to export from this module
# VariablesToExport = @()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
-->
## Current Release
* New Cmdlet Get-AzureRMWebAppContainerContinuousDeploymentUrl - Gets the Container Continuous Deployment Webhook URL
* New Cmdlets New-AzureRMWebAppContainerPSSession and Enter-WebAppContainerPSSession - Initiates a PowerShell remote session into a windows container app

## Version 5.1.0
* Updating to use the latest .NET SDK version (2.0.0)
Expand Down
Loading