- move containerfolder away from c:\demo (to c:\programdata\navcontainerhelper)
- Support generic image
- support database credentials
- add tests for external SQL
This commit is contained in:
freddydk 2017-11-27 14:02:43 +01:00
Родитель 6fba575cb9
Коммит 83ef0582fb
19 изменённых файлов: 169 добавлений и 55 удалений

Просмотреть файл

@ -16,9 +16,9 @@ function Replace-NavServerContainer {
[string]$imageName = ""
)
$SetupNavContainerScript = "c:\demo\SetupNavContainer.ps1"
$setupDesktopScript = "c:\demo\SetupDesktop.ps1"
$settingsScript = "c:\demo\settings.ps1"
$SetupNavContainerScript = "$containerHelperFolder\SetupNavContainer.ps1"
$setupDesktopScript = "$containerHelperFolder\SetupDesktop.ps1"
$settingsScript = "$containerHelperFolder\settings.ps1"
if (!((Test-Path $SetupNavContainerScript) -and (Test-Path $setupDesktopScript) -and (Test-Path $settingsScript))) {
throw "The Replace-NavServerContainer is designed to work inside the Nav on Azure DEMO VMs"

Просмотреть файл

@ -21,6 +21,16 @@ function Get-NavContainerSession {
Process {
$containerId = Get-NavContainerId -containerName $containerName
if ($sessions.ContainsKey($containerId)) {
$session = $sessions[$containerId]
try {
$ok = Invoke-Command -Session $session -ScriptBlock { $true }
}
catch {
Remove-PSSession -Session $session
$sessions.Remove($containerId)
}
}
if (!($sessions.ContainsKey($containerId))) {
$session = New-PSSession -ContainerId $containerId -RunAsAdministrator
Invoke-Command -Session $session -ScriptBlock {

Просмотреть файл

@ -12,7 +12,7 @@
.Parameter imageName
Name of the image you want to use for your CSide Development container (default is to grab the imagename from the navserver container)
.Parameter licenseFile
Path or Secure Url of the licenseFile you want to use (default c:\demo\license.flf)
Path or Secure Url of the licenseFile you want to use (default c:\programdata\navcontainerhelper\license.flf)
.Parameter credential
Username and Password for the NAV Container
.Parameter memoryLimit

Просмотреть файл

@ -8,10 +8,14 @@
Switch, which you need to specify if you accept the eula for running Nav on Docker containers (See https://go.microsoft.com/fwlink/?linkid=861843)
.Parameter containerName
Name of the new Nav container (if the container already exists it will be replaced)
.Parameter devImageName
.Parameter imageName
Name of the image you want to use for your Nav container (default is to grab the imagename from the navserver container)
.Parameter navDvdPath
When you are spinning up a Generic image, you need to specify the NAV DVD path
.Parameter navDvdCountry
When you are spinning up a Generic image, you need to specify the country version (w1, dk, etc.)
.Parameter licenseFile
Path or Secure Url of the licenseFile you want to use (default c:\demo\license.flf)
Path or Secure Url of the licenseFile you want to use (default c:\programdata\navcontainerhelper\license.flf)
.Parameter credential
Username and Password for the NAV Container
.Parameter memoryLimit
@ -48,9 +52,15 @@ function New-NavContainer {
[Parameter(Mandatory=$true)]
[string]$containerName,
[string]$imageName = "",
[string]$navDvdPath = "",
[string]$navDvdCountry = "w1",
[string]$licenseFile = "",
[System.Management.Automation.PSCredential]$Credential = $null,
[string]$memoryLimit = "4G",
[string]$databaseServer = "",
[string]$databaseInstance = "",
[string]$databaseName = "",
[System.Management.Automation.PSCredential]$databaseCredential = $null,
[switch]$updateHosts,
[switch]$useSSL,
[switch]$includeCSide,
@ -72,11 +82,14 @@ function New-NavContainer {
} else {
$credential = get-credential -Message "Using NavUserPassword Authentication. Please enter username/password for the Containter."
}
if ($Credential -eq $null -or $credential -eq [System.Management.Automation.PSCredential]::Empty) {
throw "You have to specify credentials for your Container"
}
}
if ($includeCSide) {
if ($licenseFile -eq "") {
$licenseFile = "C:\DEMO\license.flf"
$licenseFile = "c:\programdata\navcontainerhelper\license.flf"
if (!(Test-Path -Path $licenseFile)) {
if ($doNotExportObjectsToText) {
$licenseFile = ""
@ -96,11 +109,16 @@ function New-NavContainer {
}
}
$devCountry = ""
$navVersion = ""
if ($imageName -eq "") {
if (!(Test-NavContainer -containerName navserver)) {
if ("$navDvdPath" -ne "") {
$imageName = "microsoft/dynamics-nav:generic"
} elseif (Test-NavContainer -containerName navserver) {
$imageName = Get-NavContainerImageName -containerName navserver
} else {
throw "You need to specify the name of the docker image you want to use for your Nav container."
}
$imageName = Get-NavContainerImageName -containerName navserver
} else {
$imageId = docker images -q $imageName
if (!($imageId)) {
@ -112,7 +130,13 @@ function New-NavContainer {
Write-Host "Pulling docker Image $imageName"
docker pull $imageName
}
$devCountry = Get-NavContainerCountry -containerOrImageName $imageName
if ("$navDvdPath" -ne "") {
$navversion = (Get-Item -Path (Join-Path $navDvdPath "setup.exe")).VersionInfo.FileVersion
$devCountry = $navDvdCountry
} elseif ($devCountry -eq "") {
$devCountry = Get-NavContainerCountry -containerOrImageName $imageName
}
Write-Host "Creating Nav container $containerName"
Write-Host "Using image $imageName"
@ -121,7 +145,9 @@ function New-NavContainer {
Write-Host "Using license file $licenseFile"
}
$navversion = Get-NavContainerNavversion -containerOrImageName $imageName
if ($navVersion -eq "") {
$navversion = Get-NavContainerNavversion -containerOrImageName $imageName
}
Write-Host "NAV Version: $navversion"
$version = [System.Version]($navversion.split('-')[0])
$genericTag = Get-NavContainerGenericTag -containerOrImageName $imageName
@ -133,6 +159,7 @@ function New-NavContainer {
}
$containerFolder = Join-Path $ExtensionsFolder $containerName
Remove-Item -Path $containerFolder -Force -Recurse -ErrorAction Ignore
New-Item -Path $containerFolder -ItemType Directory -ErrorAction Ignore | Out-Null
$myFolder = Join-Path $containerFolder "my"
New-Item -Path $myFolder -ItemType Directory -ErrorAction Ignore | Out-Null
@ -156,12 +183,18 @@ function New-NavContainer {
"--env ExitOnError=N",
"--env locale=$locale",
"--env licenseFile=""$containerLicenseFile""",
"--env databaseServer=""$databaseServer""",
"--env databaseInstance=""$databaseInstance""",
"--memory $memoryLimit",
"--volume ""${demoFolder}:$containerDemoFolder""",
"--volume ""${hostHelperFolder}:$containerHelperFolder""",
"--volume ""${myFolder}:C:\Run\my""",
"--restart always"
)
if ("$databaseName" -ne "") {
$parameters += "--env databaseName=""$databaseName"""
}
if ($includeCSide) {
$programFilesFolder = Join-Path $containerFolder "Program Files"
New-Item -Path $programFilesFolder -ItemType Directory -ErrorAction Ignore | Out-Null
@ -207,6 +240,10 @@ function New-NavContainer {
$parameters += "--volume ""${programFilesFolder}:C:\navpfiles"""
}
if ("$navDvdPath" -ne "") {
$parameters += "--volume ""${navDvdPath}:c:\NAVDVD"""
}
if ($updateHosts) {
$parameters += "--volume ""c:\windows\system32\drivers\etc:C:\driversetc"""
Copy-Item -Path (Join-Path $PSScriptRoot "updatehosts.ps1") -Destination $myfolder -Force
@ -219,19 +256,30 @@ function New-NavContainer {
$passwordKeyFile = "$myfolder\aes.key"
$passwordKey = New-Object Byte[] 16
[Security.Cryptography.RNGCryptoServiceProvider]::Create().GetBytes($passwordKey)
$containerPasswordKeyFile = "c:\run\my\aes.key"
try {
Set-Content -Path $passwordKeyFile -Value $passwordKey
$encPassword = ConvertFrom-SecureString -SecureString $credential.Password -Key $passwordKey
$parameters += @(
"--env securePassword=$encPassword",
"--env passwordKeyFile=""$passwordKeyFile""",
"--env passwordKeyFile=""$containerPasswordKeyFile""",
"--env removePasswordKeyFile=Y"
)
if ($databaseCredential -ne $null -and $databaseCredential -ne [System.Management.Automation.PSCredential]::Empty) {
$encDatabasePassword = ConvertFrom-SecureString -SecureString $databaseCredential.Password -Key $passwordKey
$parameters += @(
"--env databaseUsername=$($databaseCredential.UserName)",
"--env databaseSecurePassword=$encDatabasePassword"
)
}
$parameters += $additionalParameters
$id = DockerRun -accept_eula -accept_outdated:$accept_outdated -imageName $imageName -parameters $parameters
Wait-NavContainerReady $containerName
} finally {
Remove-Item -Path $passwordKeyFile -Force -ErrorAction Ignore
@ -251,7 +299,9 @@ function New-NavContainer {
Write-Host "Create Desktop Shortcuts for $containerName"
$publicWebBaseUrl = $customConfig.SelectSingleNode("//appSettings/add[@key='PublicWebBaseUrl']").Value
New-DesktopShortcut -Name "$containerName Web Client" -TargetPath "$publicWebBaseUrl" -IconLocation "C:\Program Files\Internet Explorer\iexplore.exe, 3"
if ("$publicWebBaseUrl" -ne "") {
New-DesktopShortcut -Name "$containerName Web Client" -TargetPath "$publicWebBaseUrl" -IconLocation "C:\Program Files\Internet Explorer\iexplore.exe, 3"
}
New-DesktopShortcut -Name "$containerName Command Prompt" -TargetPath "CMD.EXE" -IconLocation "C:\Program Files\Docker\docker.exe, 0" -Arguments "/C docker.exe exec -it $containerName cmd"
New-DesktopShortcut -Name "$containerName PowerShell Prompt" -TargetPath "CMD.EXE" -IconLocation "C:\Program Files\Docker\docker.exe, 0" -Arguments "/C docker.exe exec -it $containerName powershell -noexit c:\run\prompt.ps1"
@ -261,8 +311,10 @@ function New-NavContainer {
$databaseInstance = $customConfig.SelectSingleNode("//appSettings/add[@key='DatabaseInstance']").Value
$databaseName = $customConfig.SelectSingleNode("//appSettings/add[@key='DatabaseName']").Value
$databaseName = $customConfig.SelectSingleNode("//appSettings/add[@key='DatabaseName']").Value
$databaseServer = "$containerName"
$databaseServer = $customConfig.SelectSingleNode("//appSettings/add[@key='DatabaseServer']").Value
if ($databaseServer -eq "localhost") {
$databaseServer = "$containerName"
}
if ($databaseInstance) { $databaseServer += "\$databaseInstance" }
$csideParameters = "servername=$databaseServer, Database=$databaseName, ntauthentication=yes"

Просмотреть файл

@ -8,7 +8,7 @@
.Parameter path
Path of a file in the host file system
.Example
$containerPath = Get-NavContainerPath -containerName navserver -path c:\demo\extensions\test2\my
$containerPath = Get-NavContainerPath -containerName navserver -path c:\programdata\navcontainerhelper\extensions\test2\my
#>
function Get-NavContainerPath {
[CmdletBinding()]

Просмотреть файл

@ -9,7 +9,7 @@
.Example
Get-NavContainerSharedFolders -containerName navserver
.Example
(Get-NavContainerSharedFolders -containerName navserver)["c:\demo"]
(Get-NavContainerSharedFolders -containerName navserver)["c:\programdata\navcontainerhelper"]
.Example
((Get-NavContainerSharedFolders -containerName navserver).GetEnumerator() | Where-Object { $_.Value -eq "c:\run\my" }).Key
#>

Просмотреть файл

@ -8,10 +8,10 @@ function Get-DefaultCredential {
[string]$DefaultUserName
)
if (Test-Path "$demoFolder\settings.ps1") {
. "$demoFolder\settings.ps1"
if (Test-Path "$demoFolder\aes.key") {
$key = Get-Content -Path "$demoFolder\aes.key"
if (Test-Path "$hostHelperFolder\settings.ps1") {
. "$hostHelperFolder\settings.ps1"
if (Test-Path "$hostHelperFolder\aes.key") {
$key = Get-Content -Path "$hostHelperFolder\aes.key"
New-Object System.Management.Automation.PSCredential ($DefaultUserName, (ConvertTo-SecureString -String $adminPassword -Key $key))
} else {
New-Object System.Management.Automation.PSCredential ($DefaultUserName, (ConvertTo-SecureString -String $adminPassword))

Просмотреть файл

@ -4,12 +4,12 @@ $verbosePreference = "SilentlyContinue"
$warningPreference = "SilentlyContinue"
$errorActionPreference = 'Stop'
$demoFolder = "C:\DEMO"
New-Item -Path $demoFolder -ItemType Container -Force -ErrorAction Ignore
$extensionsFolder = Join-Path $demoFolder "Extensions"
$hostHelperFolder = "C:\ProgramData\NavContainerHelper"
New-Item -Path $hostHelperFolder -ItemType Container -Force -ErrorAction Ignore
$extensionsFolder = Join-Path $hostHelperFolder "Extensions"
New-Item -Path $extensionsFolder -ItemType Container -Force -ErrorAction Ignore
$containerDemoFolder = "C:\DEMO"
$containerHelperFolder = "C:\ProgramData\NavContainerHelper"
$sessions = @{}

Просмотреть файл

@ -7,7 +7,7 @@
2. Create-MyOriginalFolder
3. Create-MyDeltaFolder
4. Convert-Txt2Al
A folder with the name of the container is created underneath c:\demo\extensions for holding all the temp and the final output.
A folder with the name of the container is created underneath c:\programdata\navcontainerhelper\extensions for holding all the temp and the final output.
The command will open a windows explorer window with the output
.Parameter containerName
Name of the container for which you want to export and convert objects

Просмотреть файл

@ -14,7 +14,7 @@
.Parameter startId
Starting offset for objects created by the tool (table and page extensions)
.Example
Convert-Txt2Al -containerName test -mydeltaFolder c:\demo\mydeltafiles -myAlFolder c:\demo\myAlFiles -startId 50100
Convert-Txt2Al -containerName test -mydeltaFolder c:\programdata\navcontainerhelper\mydeltafiles -myAlFolder c:\programdata\navcontainerhelper\myAlFiles -startId 50100
#>
function Convert-Txt2Al {
Param(

Просмотреть файл

@ -13,7 +13,7 @@
.Parameter myDeltaFolder
Folder in which the delta files are created
.Example
Create-MyDeltaFolder -containerName test -modifiedFolder c:\demo\myobjects -myoriginalFolder c:\demo\myoriginalobjects -mydeltaFolder c:\demo\mydeltafiles
Create-MyDeltaFolder -containerName test -modifiedFolder c:\programdata\navcontainerhelper\myobjects -myoriginalFolder c:\programdata\navcontainerhelper\myoriginalobjects -mydeltaFolder c:\programdata\navcontainerhelper\mydeltafiles
#>
function Create-MyDeltaFolder {
Param(

Просмотреть файл

@ -11,7 +11,7 @@
.Parameter $myoriginalFolder
Folder in which the original objects for your modified objects are copied to
.Example
Create-MyOriginalFolder -originalFolder c:\demo\baseobjects -modifiedFolder c:\demo\myobjects -myoriginalFolder c:\demo\mybaseobjects
Create-MyOriginalFolder -originalFolder c:\programdata\navcontainerhelper\baseobjects -modifiedFolder c:\programdata\navcontainerhelper\myobjects -myoriginalFolder c:\programdata\navcontainerhelper\mybaseobjects
#>
function Create-MyOriginalFolder {
Param(

Просмотреть файл

@ -6,7 +6,7 @@
1. Export-NavContainerObjects
2. Create-MyOriginalFolder
3. Create-MyDeltaFolder
A folder with the name of the container is created underneath c:\demo\extensions for holding all the temp and the final output.
A folder with the name of the container is created underneath c:\programdata\navcontainerhelper\extensions for holding all the temp and the final output.
The command will open a windows explorer window with the output
.Parameter containerName
Name of the container for which you want to export and convert objects
@ -32,8 +32,8 @@ function Export-ModifiedObjectsAsDeltas {
$sqlCredential = Get-DefaultSqlCredential -containerName $containerName -sqlCredential $sqlCredential
if ((Get-NavContainerSharedFolders -containerName $containerName)[$demoFolder] -ne $containerDemoFolder) {
throw "In order to run Export-ModifiedObjectsAsDeltas you need to have shared $demoFolder to $containerDemoFolder in the container (docker run ... -v ${demoFolder}:$containerDemoFolder ... <image>)."
if ((Get-NavContainerSharedFolders -containerName $containerName)[$hostHelperFolder] -ne $containerHelperFolder) {
throw "In order to run Export-ModifiedObjectsAsDeltas you need to have shared $hostHelperFolder to $containerHelperFolder in the container (docker run ... -v ${hostHelperFolder}:$containerHelperFolder ... <image>)."
}
$suffix = ""

Просмотреть файл

@ -14,9 +14,9 @@
.Parameter exportToNewSyntax
Specifies whether or not to export objects in new syntax (default is true)
.Example
Export-NavContainerObject -containerName test -objectsFolder c:\demo\objects
Export-NavContainerObject -containerName test -objectsFolder c:\programdata\navcontainerhelper\objects
.Example
Export-NavContainerObject -containerName test -objectsFolder c:\demo\objects -sqlCredential (get-credential -credential 'sa') -filter ""
Export-NavContainerObject -containerName test -objectsFolder c:\programdata\navcontainerhelper\objects -sqlCredential (get-credential -credential 'sa') -filter ""
#>
function Export-NavContainerObjects {
Param(

Просмотреть файл

@ -0,0 +1,48 @@
$ErrorActionPreference = "Stop"
. (Join-Path $PSScriptRoot "..\..\NavContainerHelper.ps1")
. (Join-Path $PSScriptRoot "..\settings.ps1")
$txtPath = (Join-Path $PSScriptRoot "test.txt")
New-NavContainer -accept_eula `
-containerName server1 `
-imageName $imageName `
-Credential $credential `
-updateHosts `
-useSSL:$false `
-includeCSide `
-doNotExportObjectsToText
New-NavContainer -accept_eula `
-containerName server2 `
-imageName $imageName `
-Credential $credential `
-updateHosts `
-useSSL:$false `
-includeCSide `
-doNotExportObjectsToText `
-databaseServer server1 `
-databaseInstance SQLEXPRESS `
-databaseName CRONUS `
-databaseCredential $sqlCredential
New-NavContainer -accept_eula `
-containerName server3 `
-imageName $imageName `
-Credential $credential `
-updateHosts `
-useSSL:$false `
-includeCSide `
-doNotExportObjectsToText `
-databaseServer server1 `
-databaseInstance SQLEXPRESS `
-databaseName CRONUS `
-databaseCredential $sqlCredential `
-additionalParameters ("--env encryptionPassword=P@ssword1")
Import-ObjectsToNavContainer -containerName server3 -objectsFile $txtPath -sqlCredential $sqlCredential
Export-NavContainerObjects -containerName server3 -objectsFolder "C:\ProgramData\NavContainerHelper\Extensions\server3\Objects" -sqlCredential $sqlCredential
Remove-NavContainer -containerName server3
Remove-NavContainer -containerName server2
Remove-NavContainer -containerName server1

Просмотреть файл

@ -1,23 +1,11 @@
# This script performs a simple happy-path test of most navcontainerhelper functions
$ErrorActionPreference = "Stop"
. (Join-Path $PSScriptRoot "..\..\NavContainerHelper.ps1")
. (Join-Path $PSScriptRoot "..\settings.ps1")
$imageName = "microsoft/dynamics-nav:devpreview"
$imageName2 = "microsoft/dynamics-nav:devpreview-finus"
$containerName = "test"
$licenseFile = "c:\demo\license.flf"
if (!(Test-Path $licenseFile)) {
throw "License file must be in $licenseFile to run test"
}
if ($credential -eq $null -or $credential -eq [System.Management.Automation.PSCredential]::Empty) {
$credential = Get-Credential -Username $env:USERNAME -Message "Enter a set of credentials to use for containers in the tests"
}
$sqlCredential = New-Object System.Management.Automation.PSCredential ('sa', $credential.Password)
$fobPath = (Join-Path $PSScriptRoot "test.fob")
$txtPath = (Join-Path $PSScriptRoot "test.txt")
$deltaPath = (Join-Path $PSScriptRoot "delta")
@ -26,9 +14,6 @@ $v1AppName = "Test"
$v2AppPath = (Join-Path $PSScriptRoot "test.app")
$v2AppName = "Test"
docker pull $imageName
docker pull $imageName2
# New-CSideDevContainer
New-CSideDevContainer -accept_eula `
-containerName $containerName `
@ -88,7 +73,7 @@ Write-Host "Shared Folders with $containerName are:"
$sharedFolders.GetEnumerator() | % { Write-Host ($_.Name + " -> " + $_.Value) }
# Get-NavContainerPath
$path = "c:\demo\extensions\$containerName\my\AdditionalSetup.ps1"
$path = "c:\programdata\navcontainerhelper\extensions\$containerName\my\AdditionalSetup.ps1"
$containerPath = Get-NavContainerPath -containerName $containerName -path $path
Write-Host "Container Path of $path in $containerName is $containerPath"
@ -210,7 +195,7 @@ Write-Host "Shared Folders with $containerName are:"
$sharedFolders.GetEnumerator() | % { Write-Host ($_.Name + " -> " + $_.Value) }
# Get-NavContainerPath
$path = "c:\demo\extensions\$containerName\my\AdditionalSetup.ps1"
$path = "c:\programdata\navcontainerhelper\extensions\$containerName\my\AdditionalSetup.ps1"
$containerPath = Get-NavContainerPath -containerName $containerName -path $path
Write-Host "Container Path of $path in $containerName is $containerPath"

Просмотреть файл

@ -17,7 +17,7 @@ OBJECT Modification "Customer Card"(Page 21)
{ Insertion ;InsertAfter=Action 74;
ChangedElements=ActionCollection
{
{ 159 ;2 ;Action ;
{ 50100 ;2 ;Action ;
Name=Test;
RunObject=Codeunit 50000 }
}
@ -25,7 +25,7 @@ OBJECT Modification "Customer Card"(Page 21)
{ Insertion ;InsertAfter=Control 69;
ChangedElements=ControlCollection
{
{ 155 ;2 ;Field ;
{ 50101 ;2 ;Field ;
SourceExpr=test }
}

Просмотреть файл

@ -3,3 +3,4 @@
$credential = Get-Credential -Username $env:USERNAME -Message "Enter a set of credentials to use for containers in the tests"
. (Join-Path $PSScriptRoot "Happy-path\test.ps1")
#. (Join-Path $PSScriptRoot "ExternalSQL\test.ps1")

18
Tests/settings.ps1 Normal file
Просмотреть файл

@ -0,0 +1,18 @@
$imageName = "microsoft/dynamics-nav:devpreview"
$imageName2 = "microsoft/dynamics-nav:devpreview-finus"
#$imageName = "navdocker.azurecr.io/dynamics-nav:11.0.19378.0"
#$imageName2 = "navdocker.azurecr.io/dynamics-nav:11.0.19378.0-finus"
$licenseFile = "c:\programdata\navcontainerhelper\license.flf"
if (!(Test-Path $licenseFile)) {
throw "License file must be in $licenseFile to run test"
}
if ($credential -eq $null -or $credential -eq [System.Management.Automation.PSCredential]::Empty) {
$credential = Get-Credential -Username $env:USERNAME -Message "Enter a set of credentials to use for containers in the tests"
}
$sqlCredential = New-Object System.Management.Automation.PSCredential ('sa', $credential.Password)
docker pull $imageName
docker pull $imageName2