Public/WaykBastionService.ps1
. "$PSScriptRoot/../Private/PlatformHelper.ps1" . "$PSScriptRoot/../Private/DockerHelper.ps1" . "$PSScriptRoot/../Private/TraefikHelper.ps1" . "$PSScriptRoot/../Private/CmdletService.ps1" function Get-WaykBastionImage { [CmdletBinding()] param( [WaykBastionConfig] $Config, [ValidateSet("linux", "windows")] [string] $Platform, [string] $BaseImage, [switch] $IncludeAll ) if (-Not $config) { $ConfigPath = Find-WaykBastionConfig -ConfigPath:$ConfigPath $config = Get-WaykBastionConfig -ConfigPath:$ConfigPath } if (-Not $Platform) { if ($config.DockerPlatform) { $Platform = $config.DockerPlatform } else { if (Get-IsWindows) { $Platform = "windows" } else { $Platform = "linux" } } } if (-Not $BaseImage) { $BaseImage = $config.DockerBaseImage } $LucidVersion = '3.9.5' $PickyVersion = '4.8.0' $ServerVersion = '3.8.0' $MongoVersion = '4.2' $TraefikVersion = '2.4' $NatsVersion = '2.1' $RedisVersion = '5.0' $GatewayVersion = '2021.1.4' $images = if ($Platform -ne "windows") { [ordered]@{ # Linux containers "den-lucid" = "devolutions/den-lucid:${LucidVersion}-buster"; "den-picky" = "devolutions/picky:${PickyVersion}-buster"; "den-server" = "devolutions/den-server:${ServerVersion}-buster"; "den-mongo" = "library/mongo:${MongoVersion}-bionic"; "den-traefik" = "library/traefik:${TraefikVersion}"; "den-nats" = "library/nats:${NatsVersion}-linux"; "den-redis" = "library/redis:${RedisVersion}-buster"; "den-gateway" = "devolutions/devolutions-gateway:${GatewayVersion}-buster"; } } else { [ordered]@{ # Windows containers "den-lucid" = "devolutions/den-lucid:${LucidVersion}-servercore-ltsc2019"; "den-picky" = "devolutions/picky:${PickyVersion}-servercore-ltsc2019"; "den-server" = "devolutions/den-server:${ServerVersion}-servercore-ltsc2019"; "den-mongo" = "library/mongo:${MongoVersion}-windowsservercore-1809"; "den-traefik" = "library/traefik:${TraefikVersion}-windowsservercore-1809"; "den-nats" = "library/nats:${NatsVersion}-windowsservercore-1809"; "den-redis" = ""; # not available on Windows "den-gateway" = "devolutions/devolutions-gateway:${GatewayVersion}-servercore-ltsc2019"; } } if (($Platform -eq "windows") -and ($BaseImage -Match 'nanoserver')) { @('den-lucid','den-picky','den-server','den-gateway') | ForEach-Object { $images[$_] = $images[$_] -Replace "servercore-ltsc2019", "nanoserver-1809" } #$images['den-mongo'] = "library/mongo:${MongoVersion}-nanoserver-1809"; #$images['den-traefik'] = "library/traefik:${TraefikVersion}-nanoserver"; $images['den-nats'] = "library/nats:${NatsVersion}-nanoserver"; } if ($config.LucidImage) { $images['den-lucid'] = $config.LucidImage } if ($config.PickyImage) { $images['den-picky'] = $config.PickyImage } if ($config.ServerImage) { $images['den-server'] = $config.ServerImage } if ($config.MongoImage) { $images['den-mongo'] = $config.MongoImage } if ($config.TraefikImage) { $images['den-traefik'] = $config.TraefikImage } if ($config.NatsImage) { $images['den-nats'] = $config.NatsImage } if ($config.RedisImage) { $images['den-redis'] = $config.RedisImage } if ($config.JetRelayImage) { $images['den-gateway'] = $config.JetRelayImage } if (-Not $IncludeAll) { if ($config.MongoExternal) { $images.Remove('den-mongo') } if ($config.JetExternal) { $images.Remove('den-gateway') } $ServerCount = 1 if ([int] $config.ServerCount -gt 1) { $ServerCount = [int] $config.ServerCount } if (-Not (($config.ServerMode -eq 'Public') -or ($ServerCount -gt 1))) { $images.Remove('den-nats') $images.Remove('den-redis') } } return $images } function Get-HostInfo() { param( [WaykBastionConfig] $Config ) $PSVersion = Get-PSVersion $CmdletVersion = Get-CmdletVersion $DockerVersion = Get-DockerVersion $DockerPlatform = $config.DockerPlatform $OsVersionInfo = Get-OsVersionInfo $images = Get-WaykBastionImage -Config:$Config -IncludeAll $DenServerImage = $images['den-server'] $DenPickyImage = $images['den-picky'] $DenLucidImage = $images['den-lucid'] $TraefikImage = $images['den-traefik'] $MongoImage = $images['den-mongo'] return [PSCustomObject]@{ PSVersion = $PSVersion CmdletVersion = $CmdletVersion DockerVersion = $DockerVersion DockerPlatform = $DockerPlatform OsVersionInfo = $OsVersionInfo DenServerImage = $DenServerImage DenPickyImage = $DenPickyImage DenLucidImage = $DenLucidImage TraefikImage = $TraefikImage MongoImage = $MongoImage } } function Get-WaykBastionService { param( [string] $ConfigPath, [WaykBastionConfig] $Config ) $ConfigPath = Find-WaykBastionConfig -ConfigPath:$ConfigPath $Platform = $config.DockerPlatform $Isolation = $config.DockerIsolation $RestartPolicy = $config.DockerRestartPolicy $images = Get-WaykBastionImage -Config:$Config -IncludeAll $Realm = $config.Realm $ExternalUrl = $config.ExternalUrl $ListenerUrl = $config.ListenerUrl $url = [System.Uri]::new($ListenerUrl) $TraefikPort = $url.Port $ListenerScheme = $url.Scheme $MongoUrl = $config.MongoUrl $MongoVolume = $config.MongoVolume $DenNetwork = $config.DockerNetwork $JetRelayUrl = $config.JetRelayUrl $DenApiKey = $config.DenApiKey $LucidApiKey = $config.LucidApiKey $PickyUrl = $config.PickyUrl $LucidUrl = $config.LucidUrl $DenServerUrl = $config.DenServerUrl $ServerLogLevel = $config.ServerLogLevel $LucidLogLevel = $config.LucidLogLevel $RustBacktrace = "1" if ($Platform -eq "linux") { $PathSeparator = "/" $MongoDataPath = "/data/db" $TraefikDataPath = "/etc/traefik" $DenServerDataPath = "/etc/den-server" $PickyDataPath = "/etc/picky" $GatewayDataPath = "/etc/gateway" } else { $PathSeparator = "\" $MongoDataPath = "c:\data\db" $TraefikDataPath = "c:\etc\traefik" $DenServerDataPath = "c:\den-server" $PickyDataPath = "c:\picky" $GatewayDataPath = "c:\gateway" } $ServerCount = 1 if ([int] $config.ServerCount -gt 1) { $ServerCount = [int] $config.ServerCount } $Services = @() # den-mongo service $DenMongo = [DockerService]::new() $DenMongo.ContainerName = 'den-mongo' $DenMongo.Image = $images[$DenMongo.ContainerName] $DenMongo.Platform = $Platform $DenMongo.Isolation = $Isolation $DenMongo.RestartPolicy = $RestartPolicy $DenMongo.TargetPorts = @(27017) if ($DenNetwork -NotMatch "none") { $DenMongo.Networks += $DenNetwork } else { $DenMongo.PublishAll = $true } $DenMongo.Volumes = @("$MongoVolume`:$MongoDataPath") $DenMongo.External = $config.MongoExternal $Services += $DenMongo if (($config.ServerMode -eq 'Public') -or ($ServerCount -gt 1)) { if (($config.DockerNetwork -Match "none") -and $config.DockerHost) { $config.NatsUrl = $config.DockerHost $config.RedisUrl = $config.DockerHost } if (-Not $config.NatsUrl) { $config.NatsUrl = "den-nats" } if (-Not $config.NatsUsername) { $config.NatsUsername = New-RandomString -Length 16 } if (-Not $config.NatsPassword) { $config.NatsPassword = New-RandomString -Length 16 } if (-Not $config.RedisUrl) { $config.RedisUrl = "den-redis" } if (-Not $config.RedisPassword) { $config.RedisPassword = New-RandomString -Length 16 } # den-nats service $DenNats = [DockerService]::new() $DenNats.ContainerName = 'den-nats' $DenNats.Image = $images[$DenNats.ContainerName] $DenNats.Platform = $Platform $DenNats.Isolation = $Isolation $DenNats.RestartPolicy = $RestartPolicy $DenNats.TargetPorts = @(4222) if ($DenNetwork -NotMatch "none") { $DenNats.Networks += $DenNetwork } else { $DenNats.PublishAll = $true } $DenNats.Command = "--user $($config.NatsUsername) --pass $($config.NatsPassword)" $DenNats.External = $config.NatsExternal $Services += $DenNats # den-redis service $DenRedis = [DockerService]::new() $DenRedis.ContainerName = 'den-redis' $DenRedis.Image = $images[$DenRedis.ContainerName] $DenRedis.Platform = $Platform $DenRedis.Isolation = $Isolation $DenRedis.RestartPolicy = $RestartPolicy $DenRedis.TargetPorts = @(6379) if ($DenNetwork -NotMatch "none") { $DenRedis.Networks += $DenNetwork } else { $DenRedis.PublishAll = $true } $DenRedis.Command = "redis-server --requirepass $($config.RedisPassword)" $DenRedis.External = $config.RedisExternal $Services += $DenRedis } # den-picky service $DenPicky = [DockerService]::new() $DenPicky.ContainerName = 'den-picky' $DenPicky.Image = $images[$DenPicky.ContainerName] $DenPicky.Platform = $Platform $DenPicky.Isolation = $Isolation $DenPicky.RestartPolicy = $RestartPolicy $DenPicky.DependsOn = @("den-mongo") $DenPicky.TargetPorts = @(12345) if ($DenNetwork -NotMatch "none") { $DenPicky.Networks += $DenNetwork } else { $DenPicky.PublishAll = $true } $DenPicky.Environment = [ordered]@{ "PICKY_REALM" = $Realm; "PICKY_DATABASE_URL" = $MongoUrl; "PICKY_PROVISIONER_PUBLIC_KEY_PATH" = @($PickyDataPath, "picky-public.pem") -Join $PathSeparator "RUST_BACKTRACE" = $RustBacktrace; } $DenPicky.Volumes = @("$ConfigPath/picky:$PickyDataPath`:ro") $DenPicky.External = $config.PickyExternal $Services += $DenPicky # den-lucid service $DenLucid = [DockerService]::new() $DenLucid.ContainerName = 'den-lucid' $DenLucid.Image = $images[$DenLucid.ContainerName] $DenLucid.Platform = $Platform $DenLucid.Isolation = $Isolation $DenLucid.RestartPolicy = $RestartPolicy $DenLucid.DependsOn = @("den-mongo") $DenLucid.TargetPorts = @(4242) if ($DenNetwork -NotMatch "none") { $DenLucid.Networks += $DenNetwork } else { $DenLucid.PublishAll = $true } $DenLucid.Environment = [ordered]@{ "LUCID_ADMIN__SKIP" = "true"; "LUCID_API__KEY" = $LucidApiKey; "LUCID_DATABASE__URL" = $MongoUrl; "LUCID_TOKEN__DEFAULT_ISSUER" = "$ExternalUrl"; "LUCID_TOKEN__ISSUERS" = "${ListenerScheme}://localhost:$TraefikPort"; "LUCID_API__ALLOWED_ORIGINS" = "$ExternalUrl"; "LUCID_ACCOUNT__APIKEY" = $DenApiKey; "LUCID_ACCOUNT__LOGIN_URL" = "$DenServerUrl/account/login"; "LUCID_ACCOUNT__USER_EXISTS_URL" = "$DenServerUrl/account/user-exists"; "LUCID_ACCOUNT__REFRESH_USER_URL" = "$DenServerUrl/account/refresh"; "LUCID_ACCOUNT__FORGOT_PASSWORD_URL" = "$DenServerUrl/account/forgot"; "LUCID_ACCOUNT__SEND_ACTIVATION_EMAIL_URL" = "$DenServerUrl/account/activation"; "LUCID_LOCALHOST_LISTENER" = $ListenerScheme; "LUCID_LOGIN__ALLOW_FORGOT_PASSWORD" = "false"; "LUCID_LOGIN__ALLOW_UNVERIFIED_EMAIL_LOGIN" = "true"; "LUCID_LOGIN__PATH_PREFIX" = "lucid"; "LUCID_LOGIN__PASSWORD_DELEGATION" = "true"; "LUCID_LOGIN__DEFAULT_LOCALE" = "en_US"; "LUCID_LOGIN__SKIP_COMPLETE_PROFILE" = "true"; "LUCID_LOG__LEVEL" = $LucidLogLevel; "LUCID_LOG__FORMAT" = "json"; "RUST_BACKTRACE" = $RustBacktrace; } $DenLucid.Healthcheck = [DockerHealthcheck]::new("curl -sS $LucidUrl/healthz") $DenLucid.External = $config.LucidExternal $Services += $DenLucid # den-server service $DenServer = [DockerService]::new() $DenServer.ContainerName = 'den-server' $DenServer.Image = $images[$DenServer.ContainerName] $DenServer.Platform = $Platform $DenServer.Isolation = $Isolation $DenServer.RestartPolicy = $RestartPolicy $DenServer.DependsOn = @("den-mongo", 'den-traefik') $DenServer.TargetPorts = @(4491, 10255) if ($DenNetwork -NotMatch "none") { $DenServer.Networks += $DenNetwork } else { $DenServer.PublishAll = $true } $DenServer.Environment = [ordered]@{ "DEN_LISTENER_URL" = $ListenerUrl; "DEN_EXTERNAL_URL" = $ExternalUrl; "PICKY_REALM" = $Realm; "PICKY_URL" = $PickyUrl; "PICKY_EXTERNAL_URL" = "$ExternalUrl/picky"; "MONGO_URL" = $MongoUrl; "LUCID_AUTHENTICATION_KEY" = $LucidApiKey; "DEN_ROUTER_EXTERNAL_URL" = "$ExternalUrl/cow"; "LUCID_INTERNAL_URL" = $LucidUrl; "LUCID_EXTERNAL_URL" = "$ExternalUrl/lucid"; "DEN_LOGIN_REQUIRED" = "false"; "DEN_PUBLIC_KEY_FILE" = @($DenServerDataPath, "den-public.pem") -Join $PathSeparator "DEN_PRIVATE_KEY_FILE" = @($DenServerDataPath, "den-private.key") -Join $PathSeparator "DEN_HOST_INFO_FILE" = @($DenServerDataPath, "host_info.json") -Join $PathSeparator "JET_RELAY_URL" = $JetRelayUrl; "DEN_API_KEY" = $DenApiKey; "RUST_BACKTRACE" = $RustBacktrace; } $DenServer.Volumes = @("$ConfigPath/den-server:$DenServerDataPath`:ro") $DenServer.Command = "-l $ServerLogLevel" $DenServer.Healthcheck = [DockerHealthcheck]::new("curl -sS $DenServerUrl/health") if ($config.ServerMode -eq 'Private') { $DenServer.Environment['AUDIT_TRAILS'] = "true" $DenServer.Command += " -m onprem" } elseif ($config.ServerMode -eq 'Public') { $DenServer.Command += " -m cloud" } if ($config.DenKeepAliveInterval) { $DenServer.Environment['DEN_ROUTER_KEEP_ALIVE_INTERVAL'] = $config.DenKeepAliveInterval } if ($config.DisableCors) { $DenServer.Environment['DEN_DISABLE_CORS'] = 'true' } if ($config.DisableDbSchemaValidation) { $DenServer.Environment['DEN_DISABLE_DB_SCHEMA_VALIDATION'] = 'true' } if ($config.DisableTelemetry) { $DenServer.Environment['DEN_DISABLE_TELEMETRY'] = 'true' } if ($config.ExperimentalFeatures) { $DenServer.Environment['WIP_EXPERIMENTAL_FEATURES'] = 'true' } if (![string]::IsNullOrEmpty($config.NatsUrl)) { $DenServer.Environment['NATS_HOST'] = $config.NatsUrl } if (![string]::IsNullOrEmpty($config.NatsUsername)) { $DenServer.Environment['NATS_USERNAME'] = $config.NatsUsername } if (![string]::IsNullOrEmpty($config.NatsPassword)) { $DenServer.Environment['NATS_PASSWORD'] = $config.NatsPassword } if (![string]::IsNullOrEmpty($config.RedisUrl)) { $DenServer.Environment['REDIS_HOST'] = $config.RedisUrl } if (![string]::IsNullOrEmpty($config.RedisPassword)) { $DenServer.Environment['REDIS_PASSWORD'] = $config.RedisPassword } $DenServer.External = $config.ServerExternal if ($ServerCount -gt 1) { 1 .. $ServerCount | % { $ServerIndex = $_ $Instance = [DockerService]::new([DockerService]$DenServer) $Instance.ContainerName = "den-server-$ServerIndex" $Instance.Healthcheck.Test = $Instance.Healthcheck.Test -Replace "den-server", $Instance.ContainerName $Services += $Instance } } else { $Services += $DenServer } # den-traefik service $DenTraefik = [DockerService]::new() $DenTraefik.ContainerName = 'den-traefik' $DenTraefik.Image = $images[$DenTraefik.ContainerName] $DenTraefik.Platform = $Platform $DenTraefik.Isolation = $Isolation $DenTraefik.RestartPolicy = $RestartPolicy $DenTraefik.TargetPorts = @($TraefikPort) if ($DenNetwork -NotMatch "none") { $DenTraefik.Networks += $DenNetwork } $DenTraefik.PublishAll = $true $TraefikConfigFile = @($TraefikDataPath, "traefik.yaml") -Join $PathSeparator $DenTraefik.Command = "--configfile `"$TraefikConfigFile`"" $DenTraefik.Volumes = @("$ConfigPath/traefik:$TraefikDataPath") $DenTraefik.External = $config.TraefikExternal $Services += $DenTraefik # den-gateway service if (-Not $config.JetExternal) { $DenGateway = [DockerService]::new() $DenGateway.ContainerName = 'den-gateway' $DenGateway.Image = $images[$DenGateway.ContainerName] $DenGateway.Platform = $Platform $DenGateway.Isolation = $Isolation $DenGateway.RestartPolicy = $RestartPolicy $DenGateway.TargetPorts = @() if ($config.JetTcpPort -gt 0) { # Register only the TCP port to be published automatically $DenGateway.TargetPorts += $config.JetTcpPort $DenGateway.PublishAll = $true } if ($DenNetwork -NotMatch "none") { $DenGateway.Networks += $DenNetwork } else { $DenGateway.TargetPorts += 7171 $DenGateway.PublishAll = $true } $DenGateway.Environment = [ordered]@{ "DGATEWAY_CONFIG_PATH" = $GatewayDataPath "RUST_BACKTRACE" = "1"; "RUST_LOG" = "info"; } $DenGateway.Volumes = @("$ConfigPath/den-gateway:$GatewayDataPath`:rw") $DenGateway.External = $false $Services += $DenGateway } if ($config.SyslogServer) { foreach ($Service in $Services) { $Service.Logging = [DockerLogging]::new($config.SyslogServer) } } return $Services } function Get-DockerRunCommand { [OutputType('string[]')] param( [DockerService] $Service ) $cmd = @('docker', 'run') $cmd += @('--name', $Service.ContainerName) $cmd += "-d" # detached if ($Service.Platform -eq 'windows') { if ($Service.Isolation -eq 'hyperv') { $cmd += "--isolation=$($Service.Isolation)" } } if ($Service.RestartPolicy) { $cmd += "--restart=$($Service.RestartPolicy)" } if ($Service.Networks) { foreach ($Network in $Service.Networks) { $cmd += "--network=$Network" } } if ($Service.Environment) { $Service.Environment.GetEnumerator() | foreach { $key = $_.Key $val = $_.Value $cmd += @("-e", "`"$key=$val`"") } } if ($Service.Volumes) { foreach ($Volume in $Service.Volumes) { $cmd += @("-v", "`"$Volume`"") } } if ($Service.PublishAll) { foreach ($TargetPort in $Service.TargetPorts) { $cmd += @("-p", "$TargetPort`:$TargetPort") } } if ($Service.Healthcheck) { $Healthcheck = $Service.Healthcheck if (![string]::IsNullOrEmpty($Healthcheck.Interval)) { $cmd += "--health-interval=" + $Healthcheck.Interval } if (![string]::IsNullOrEmpty($Healthcheck.Timeout)) { $cmd += "--health-timeout=" + $Healthcheck.Timeout } if (![string]::IsNullOrEmpty($Healthcheck.Retries)) { $cmd += "--health-retries=" + $Healthcheck.Retries } if (![string]::IsNullOrEmpty($Healthcheck.StartPeriod)) { $cmd += "--health-start-period=" + $Healthcheck.StartPeriod } $cmd += $("--health-cmd=`'" + $Healthcheck.Test + "`'") } if ($Service.Logging) { $Logging = $Service.Logging $cmd += '--log-driver=' + $Logging.Driver $options = @() $Logging.Options.GetEnumerator() | foreach { $key = $_.Key $val = $_.Value $options += "$key=$val" } $options = $options -Join "," $cmd += "--log-opt=" + $options } $cmd += $Service.Image $cmd += $Service.Command return $cmd } function Start-DockerService { [CmdletBinding()] param( [DockerService] $Service, [switch] $Remove ) if ($Service.External) { return # service should already be running } if (Get-ContainerExists -Name $Service.ContainerName) { if (Get-ContainerIsRunning -Name $Service.ContainerName) { Stop-Container -Name $Service.ContainerName } if ($Remove) { Remove-Container -Name $Service.ContainerName } } # Workaround for https://github.com/docker-library/mongo/issues/385 if (($Service.Platform -eq 'Windows') -and ($Service.ContainerName -Like '*mongo')) { $VolumeName = $($Service.Volumes[0] -Split ':', 2)[0] $Volume = $(docker volume inspect $VolumeName) | ConvertFrom-Json $WiredTigerLock = Join-Path $Volume.MountPoint 'WiredTiger.lock' if (Test-Path $WiredTigerLock) { Write-Host "Removing $WiredTigerLock" Remove-Item $WiredTigerLock -Force } } $RunCommand = (Get-DockerRunCommand -Service $Service) -Join " " Write-Host "Starting $($Service.ContainerName)" Write-Verbose $RunCommand $id = Invoke-Expression $RunCommand if ($Service.Healthcheck) { Wait-ContainerHealthy -Name $Service.ContainerName | Out-Null } if (Get-ContainerIsRunning -Name $Service.ContainerName) { Write-Host "$($Service.ContainerName) successfully started" } else { throw "Error starting $($Service.ContainerName)" } } function Update-WaykBastionImage { [CmdletBinding()] param( [string] $ConfigPath ) $ConfigPath = Find-WaykBastionConfig -ConfigPath:$ConfigPath $config = Get-WaykBastionConfig -ConfigPath:$ConfigPath Expand-WaykBastionConfig -Config $config $Images = Get-WaykBastionImage -Config $Config foreach ($image in $images.Values) { Request-ContainerImage -Name $image } } function Start-WaykBastion { [CmdletBinding()] param( [string] $ConfigPath, [switch] $SkipPull, [ValidateSet("", "off","error", "warn", "info", "debug", "trace", IgnoreCase = $false)] [string] $ServerLogLevel, [ValidateSet("", "off","error", "warn", "info", "debug", "trace", IgnoreCase = $false)] [string] $LucidLogLevel ) $ConfigPath = Find-WaykBastionConfig -ConfigPath:$ConfigPath $config = Get-WaykBastionConfig -ConfigPath:$ConfigPath Expand-WaykBastionConfig -Config $config if ($ServerLogLevel) { $config.ServerLogLevel = $ServerLogLevel } if ($LucidLogLevel) { $config.LucidLogLevel = $LucidLogLevel } Test-WaykBastionConfig -Config:$config Test-DockerHost $Platform = $config.DockerPlatform $Services = Get-WaykBastionService -ConfigPath:$ConfigPath -Config $config Export-TraefikConfig -ConfigPath:$ConfigPath Export-PickyConfig -ConfigPath:$ConfigPath Export-GatewayConfig -ConfigPath:$ConfigPath $HostInfo = Get-HostInfo -Platform:$Platform -Config:$config Export-HostInfo -ConfigPath:$ConfigPath -HostInfo $HostInfo if (-Not $SkipPull) { # pull docker images only if they are not cached locally foreach ($service in $services) { if (-Not (Get-ContainerImageId -Name $Service.Image)) { Request-ContainerImage -Name $Service.Image } } } # create docker network New-DockerNetwork -Name $config.DockerNetwork -Platform $Platform -Force # create docker volume New-DockerVolume -Name $config.MongoVolume -Force # start containers foreach ($Service in $Services) { Start-DockerService -Service $Service -Remove } } function Stop-WaykBastion { [CmdletBinding()] param( [string] $ConfigPath, [switch] $Remove ) $ConfigPath = Find-WaykBastionConfig -ConfigPath:$ConfigPath $config = Get-WaykBastionConfig -ConfigPath:$ConfigPath Expand-WaykBastionConfig -Config $config $Services = Get-WaykBastionService -ConfigPath:$ConfigPath -Config $config # containers have to be stopped in the reverse order that we started them [array]::Reverse($Services) # stop containers foreach ($Service in $Services) { if ($Service.External) { continue } Write-Host "Stopping $($Service.ContainerName)" Stop-Container -Name $Service.ContainerName -Quiet if ($Remove) { Remove-Container -Name $Service.ContainerName } } } function Restart-WaykBastion { [CmdletBinding()] param( [string] $ConfigPath, [ValidateSet("off","error", "warn", "info", "debug", "trace", IgnoreCase = $false)] [string] $ServerLogLevel, [ValidateSet("off","error", "warn", "info", "debug", "trace", IgnoreCase = $false)] [string] $LucidLogLevel ) $ConfigPath = Find-WaykBastionConfig -ConfigPath:$ConfigPath Stop-WaykBastion -ConfigPath:$ConfigPath Start-WaykBastion -ConfigPath:$ConfigPath -ServerLogLevel:$ServerLogLevel -LucidLogLevel:$LucidLogLevel } function Get-WaykBastionServiceDefinition() { $ServiceName = "WaykBastion" $ModuleName = "WaykBastion" $DisplayName = "Wayk Bastion" $CompanyName = "Devolutions" $Description = "Wayk Bastion service" return [PSCustomObject]@{ ServiceName = $ServiceName DisplayName = $DisplayName Description = $Description CompanyName = $CompanyName ModuleName = $ModuleName StartCommand = "Start-WaykBastion" StopCommand = "Stop-WaykBastion" WorkingDir = "%ProgramData%\${CompanyName}\${DisplayName}" } } function Register-WaykBastionService { [CmdletBinding()] param( [string] $ServicePath, [switch] $Force ) $Definition = Get-WaykBastionServiceDefinition if ($ServicePath) { $Definition.WorkingDir = $ServicePath } Register-CmdletService -Definition $Definition -Force:$Force $ServiceName = $Definition.ServiceName $ServicePath = [System.Environment]::ExpandEnvironmentVariables($Definition.WorkingDir) Write-Host "`"$ServiceName`" service has been installed to `"$ServicePath`"" } function Unregister-WaykBastionService { [CmdletBinding()] param( [string] $ServicePath, [switch] $Force ) $Definition = Get-WaykBastionServiceDefinition if ($ServicePath) { $Definition.WorkingDir = $ServicePath } Unregister-CmdletService -Definition $Definition -Force:$Force } |