Public/WaykBastionConfig.ps1
. "$PSScriptRoot/../Private/CaseHelper.ps1" . "$PSScriptRoot/../Private/YamlHelper.ps1" . "$PSScriptRoot/../Private/TraefikHelper.ps1" . "$PSScriptRoot/../Private/RandomGenerator.ps1" . "$PSScriptRoot/../Private/CertificateHelper.ps1" class WaykBastionConfig { # DenServer [string] $Realm [string] $ExternalUrl [string] $ListenerUrl [string] $ServerMode [string] $ServerLogLevel [int] $ServerCount [string] $DenServerUrl [string] $DenRouterUrl [int] $DenKeepAliveInterval [string] $DenApiKey [bool] $DisableCors = $false [bool] $DisableDbSchemaValidation = $false [bool] $DisableTelemetry = $false [bool] $ExperimentalFeatures = $false [bool] $ServerExternal = $false [string] $ServerImage # MongoDB [string] $MongoUrl [string] $MongoVolume [bool] $MongoExternal = $false [string] $MongoImage # Traefik [bool] $TraefikExternal = $false [string] $TraefikImage # Jet [string] $JetRelayUrl [string] $JetInternalUrl [int] $JetTcpPort [string] $JetTcpExternalUrl [bool] $JetExternal = $false [string] $JetRelayImage # Picky [string] $PickyUrl [bool] $PickyExternal = $false [string] $PickyImage # Lucid [string] $LucidUrl [string] $LucidApiKey [bool] $LucidExternal = $false [string] $LucidImage [string] $LucidLogLevel # NATS [string] $NatsUrl [string] $NatsUsername [string] $NatsPassword [bool] $NatsExternal = $false [string] $NatsImage # Redis [string] $RedisUrl [string] $RedisPassword [bool] $RedisExternal = $false [string] $RedisImage # Docker [string] $DockerNetwork [string] $DockerPlatform [string] $DockerIsolation [string] $DockerRestartPolicy [string] $DockerHost [string] $DockerBaseImage [string] $SyslogServer } $script:WaykBastionConfigFormat = "json" function Find-WaykBastionConfig { param( [string] $ConfigPath ) if (-Not $ConfigPath) { $ConfigPath = Get-WaykBastionPath 'ConfigPath' if ($Env:WAYK_BASTION_CONFIG_PATH) { $ConfigPath = $Env:WAYK_BASTION_CONFIG_PATH } } return $ConfigPath } function Enter-WaykBastionConfig { [CmdletBinding()] param( [string] $ConfigPath, [switch] $ChangeDirectory ) if ($ConfigPath) { $ConfigPath = Resolve-Path $ConfigPath $Env:WAYK_BASTION_CONFIG_PATH = $ConfigPath } $ConfigPath = Find-WaykBastionConfig -ConfigPath:$ConfigPath if ($ChangeDirectory) { Set-Location $ConfigPath } } function Exit-WaykBastionConfig { Remove-Item Env:WAYK_BASTION_CONFIG_PATH } function Get-WaykBastionPath() { [CmdletBinding()] param( [Parameter(Position=0)] [ValidateSet("ConfigPath","GlobalPath","LocalPath")] [string] $PathType = "ConfigPath" ) $DisplayName = "Wayk Bastion" $LowerName = "wayk-bastion" $CompanyName = "Devolutions" $HomePath = Resolve-Path '~' if (Get-IsWindows) { $LocalPath = $Env:AppData + "\${CompanyName}\${DisplayName}"; $GlobalPath = $Env:ProgramData + "\${CompanyName}\${DisplayName}" } elseif ($IsMacOS) { $LocalPath = "$HomePath/Library/Application Support/${DisplayName}" $GlobalPath = "/Library/Application Support/${DisplayName}" } elseif ($IsLinux) { $LocalPath = "$HomePath/.config/${LowerName}" $GlobalPath = "/etc/${LowerName}" } switch ($PathType) { 'LocalPath' { $LocalPath } 'GlobalPath' { $GlobalPath } 'ConfigPath' { $GlobalPath } default { throw("Invalid path type: $PathType") } } } function Expand-WaykBastionConfigKeys { param( [WaykBastionConfig] $Config ) if (-Not $config.DenApiKey) { $config.DenApiKey = New-RandomString -Length 32 } if (-Not $config.LucidApiKey) { $config.LucidApiKey = New-RandomString -Length 32 } } function Expand-WaykBastionConfigImage { param( [WaykBastionConfig] $Config ) $images = Get-WaykBastionImage -Config:$Config if (-Not $config.LucidImage) { $config.LucidImage = $images['den-lucid'] } if (-Not $config.PickyImage) { $config.PickyImage = $images['den-picky'] } if (-Not $config.ServerImage) { $config.ServerImage = $images['den-server'] } if (-Not $config.MongoImage) { $config.MongoImage = $images['den-mongo'] } if (-Not $config.TraefikImage) { $config.TraefikImage = $images['den-traefik'] } if (-Not $config.NatsImage) { $config.NatsImage = $images['nats-image'] } if (-Not $config.RedisImage) { $config.RedisImage = $images['den-redis'] } } function Expand-WaykBastionConfig { param( [WaykBastionConfig] $Config ) $DockerNetworkDefault = "den-network" $MongoUrlDefault = "mongodb://den-mongo:27017" $MongoVolumeDefault = "den-mongodata" $ServerModeDefault = "Private" $ServerLogLevelDefault = "info" $LucidLogLevelDefault = "warn" $ListenerUrlDefault = "http://0.0.0.0:4000" $PickyUrlDefault = "http://den-picky:12345" $LucidUrlDefault = "http://den-lucid:4242" $DenServerUrlDefault = "http://den-server:10255" $DenRouterUrlDefault = "http://den-server:4491" $JetRelayUrlDefault = "https://api.jet-relay.net" $JetInternalUrlDefault = "http://den-gateway:7171" if (-Not $config.DockerNetwork) { $config.DockerNetwork = $DockerNetworkDefault } if (($config.DockerNetwork -Match "none") -and $config.DockerHost) { $MongoUrlDefault = $MongoUrlDefault -Replace "den-mongo", $config.DockerHost $PickyUrlDefault = $PickyUrlDefault -Replace "den-picky", $config.DockerHost $LucidUrlDefault = $LucidUrlDefault -Replace "den-lucid", $config.DockerHost $DenServerUrlDefault = $DenServerUrlDefault -Replace "den-server", $config.DockerHost $DenRouterUrlDefault = $DenRouterUrlDefault -Replace "den-server", $config.DockerHost $JetInternalUrlDefault = $JetInternalUrlDefault -Replace "den-gateway", $config.DockerHost } if (-Not $config.DockerPlatform) { if (Get-IsWindows) { $config.DockerPlatform = "windows" } else { $config.DockerPlatform = "linux" } } if (-Not $config.DockerRestartPolicy) { $config.DockerRestartPolicy = "on-failure" } if (-Not $config.ServerMode) { $config.ServerMode = $ServerModeDefault } if (-Not $config.ServerLogLevel) { $config.ServerLogLevel = $ServerLogLevelDefault } if (-Not $config.LucidLogLevel) { $config.LucidLogLevel = $LucidLogLevelDefault } if (-Not $config.ServerCount) { $config.ServerCount = 1 } if (-Not $config.ListenerUrl) { $config.ListenerUrl = $ListenerUrlDefault } if (-Not $config.MongoUrl) { $config.MongoUrl = $MongoUrlDefault } if (-Not $config.MongoVolume) { $config.MongoVolume = $MongoVolumeDefault } if (-Not $config.PickyUrl) { $config.PickyUrl = $PickyUrlDefault } if (-Not $config.LucidUrl) { $config.LucidUrl = $LucidUrlDefault } if (-Not $config.DenServerUrl) { $config.DenServerUrl = $DenServerUrlDefault } if (-Not $config.DenRouterUrl) { $config.DenRouterUrl = $DenRouterUrlDefault } if (-Not $config.JetInternalUrl) { $config.JetInternalUrl = $JetInternalUrlDefault } if ($config.JetExternal) { if (-Not $config.JetRelayUrl) { $config.JetRelayUrl = $JetRelayUrlDefault } } else { $config.JetRelayUrl = $config.ExternalUrl if (-Not $config.JetTcpPort) { $config.JetTcpPort = 8080 } if (-Not $config.JetTcpExternalUrl) { $config.JetTcpExternalUrl = "tcp://*:$($config.JetTcpPort)" } } Expand-WaykBastionConfigImage -Config:$Config } function Remove-WaykBastionConfigSensitiveData { param( [WaykBastionConfig] $Config ) $HiddenValue = "***Hidden value***" if ($config.DenApiKey) { $config.DenApiKey = $HiddenValue } if ($config.LucidApiKey) { $config.LucidApiKey = $HiddenValue } if ($config.NatsUsername) { $config.NatsUsername = $HiddenValue } if ($config.NatsPassword) { $config.NatsPassword = $HiddenValue } if ($config.RedisPassword) { $config.RedisPassword = $HiddenValue } } function Test-WaykBastionConfig { param( [WaykBastionConfig] $Config ) if ($config.ListenerUrl) { $url = [System.Uri]::new($config.ListenerUrl) if (-Not (($url.Scheme -eq 'http') -Or ($url.Scheme -eq 'https'))) { Write-Warning "Invalid ListenerUrl: $($url.OriginalString) (should begin with 'http://' or 'https://')" } } if ($config.ExternalUrl) { $url = [System.Uri]::new($config.ExternalUrl) if (-Not (($url.Scheme -eq 'http') -Or ($url.Scheme -eq 'https'))) { Write-Warning "Invalid ExternalUrl: $($url.OriginalString) (should begin with 'http://' or 'https://')" } elseif ($url.Scheme -ne 'https') { Write-Warning "HTTPS is not configured for external access, peer-to-peer sessions will be disabled" } } if ($config.DisableCors) { Write-Warning "Disabling CORS could be a security issue. It should be disabled only for development purposes" } if ($config.DisableDbSchemaValidation) { Write-Warning "Disabling database schema version validation could create situations where database would be corrupted. It should be disabled only if you know what you are doing." } } function Export-TraefikConfig() { param( [string] $ConfigPath ) $ConfigPath = Find-WaykBastionConfig -ConfigPath:$ConfigPath $config = Get-WaykBastionConfig -ConfigPath:$ConfigPath Expand-WaykBastionConfig $config $TraefikPath = Join-Path $ConfigPath "traefik" New-Item -Path $TraefikPath -ItemType "Directory" -Force | Out-Null $TraefikYamlFile = Join-Path $TraefikPath "traefik.yaml" $TraefikYaml = New-TraefikConfig -Platform $config.DockerPlatform ` -ListenerUrl $config.ListenerUrl ` -ExternalUrl $config.ExternalUrl ` -LucidUrl $config.LucidUrl ` -PickyUrl $config.PickyUrl ` -DenRouterUrl $config.DenRouterUrl ` -DenServerUrl $config.DenServerUrl ` -JetExternal $config.JetExternal ` -GatewayUrl $config.JetInternalUrl Set-Content -Path $TraefikYamlFile -Value $TraefikYaml } function Export-PickyConfig() { param( [string] $ConfigPath ) $ConfigPath = Find-WaykBastionConfig -ConfigPath:$ConfigPath $config = Get-WaykBastionConfig -ConfigPath:$ConfigPath Expand-WaykBastionConfig $config $PickyPath = Join-Path $ConfigPath "picky" New-Item -Path $PickyPath -ItemType "Directory" -Force | Out-Null $DenServerPath = Join-Path $ConfigPath "den-server" $DenServerPublicKey = Join-Path $DenServerPath "den-public.pem" $PickyPublicKey = Join-Path $PickyPath "picky-public.pem" Copy-Item -Path $DenServerPublicKey -Destination $PickyPublicKey -Force } function Export-GatewayConfig() { param( [string] $ConfigPath ) if ($config.JetExternal) { return } $ConfigPath = Find-WaykBastionConfig -ConfigPath:$ConfigPath $config = Get-WaykBastionConfig -ConfigPath:$ConfigPath Expand-WaykBastionConfig $config $GatewayPath = Join-Path $ConfigPath "den-gateway" New-Item -Path $GatewayPath -ItemType "Directory" -Force | Out-Null $DenServerPath = Join-Path $ConfigPath "den-server" $DenServerPublicKey = Join-Path $DenServerPath "den-public.pem" $ProvisionerPublicKey = Join-Path $GatewayPath "provisioner.pem" Copy-Item -Path $DenServerPublicKey -Destination $ProvisionerPublicKey -Force $url = [System.Uri]::new($config.ExternalUrl) $GatewayHostname = $url.Host $JetWebPort = $url.Port $JetWebScheme = $url.Scheme -Replace 'http', 'ws' $GatewayListeners = @() if ($config.JetTcpPort -gt 0) { $JetTcpPort = $config.JetTcpPort $GatewayListeners += [PSCustomObject]@{ InternalUrl = "tcp://*:${JetTcpPort}"; ExternalUrl = $config.JetTcpExternalUrl; } } $GatewayListeners += [PSCustomObject]@{ InternalUrl = "ws://*:7171"; ExternalUrl = "${JetWebScheme}://*:${JetWebPort}"; } $GatewayConfig = [PSCustomObject]@{ Hostname = $GatewayHostname Listeners = $GatewayListeners ProvisionerPublicKeyFile = "provisioner.pem" } $ConfigData = $GatewayConfig | ConvertTo-Json -Depth 8 $AsByteStream = if ($PSEdition -eq 'Core') { @{AsByteStream = $true} } else { @{'Encoding' = 'Byte'} } $ConfigBytes = $([System.Text.Encoding]::UTF8).GetBytes($ConfigData) $ConfigFile = Join-Path $GatewayPath "gateway.json" Set-Content -Path $ConfigFile -Value $ConfigBytes @AsByteStream -Force } function Export-HostInfo() { param( [string] $ConfigPath, [PSCustomObject] $HostInfo ) $ConfigPath = Find-WaykBastionConfig -ConfigPath:$ConfigPath $config = Get-WaykBastionConfig -ConfigPath:$ConfigPath Expand-WaykBastionConfig $config $DenServerPath = Join-Path $ConfigPath "den-server" New-Item -Path $DenServerPath -ItemType "Directory" -Force | Out-Null $JsonValue = $($HostInfo | ConvertTo-Json) $HostInfoFile = Join-Path $DenServerPath "host_info.json" Set-Content -Path $HostInfoFile -Value $JsonValue -Force } function Save-WaykBastionConfig { [CmdletBinding()] param( [string] $ConfigPath, [Parameter(Mandatory=$true)] [WaykBastionConfig] $Config, [ValidateSet("yaml","json")] [string] $ConfigFormat = "json" ) $ConfigPath = Find-WaykBastionConfig -ConfigPath:$ConfigPath $Config = Remove-DefaultProperties $Config $([WaykBastionConfig]::new()) New-Item -Path $ConfigPath -ItemType "Directory" -Force | Out-Null if ($ConfigFormat -eq 'json') { $ConfigFile = Join-Path $ConfigPath "bastion.json" $Properties = $Config.PSObject.Properties.Name $NonNullProperties = $Properties.Where({ -Not [string]::IsNullOrEmpty($Config.$_) }) $ConfigData = $Config | Select-Object $NonNullProperties | ConvertTo-Json $AsByteStream = if ($PSEdition -eq 'Core') { @{AsByteStream = $true} } else { @{'Encoding' = 'Byte'} } $ConfigBytes = $([System.Text.Encoding]::UTF8).GetBytes($ConfigData) Set-Content -Path $ConfigFile -Value $ConfigBytes @AsByteStream } elseif ($ConfigFormat -eq 'yaml') { $ConfigFile = Join-Path $ConfigPath "wayk-den.yml" ConvertTo-Yaml -Data (ConvertTo-SnakeCaseObject -Object $Config) -OutFile $ConfigFile -Force } } function New-WaykBastionConfig { [CmdletBinding()] param( [string] $ConfigPath, # Server [Parameter(Mandatory=$true)] [string] $Realm, [Parameter(Mandatory=$true)] [string] $ExternalUrl, [string] $ListenerUrl, [string] $ServerMode, [ValidateSet("off","error", "warn", "info", "debug", "trace", IgnoreCase = $false)] [string] $ServerLogLevel, [int] $ServerCount, [string] $DenServerUrl, [string] $DenRouterUrl, [int] $DenKeepAliveInterval, [string] $DenApiKey, [bool] $DisableCors, [bool] $DisableDbSchemaValidation, [bool] $DisableTelemetry, [bool] $ExperimentalFeatures, [bool] $ServerExternal, [string] $ServerImage, # MongoDB [string] $MongoUrl, [string] $MongoVolume, [bool] $MongoExternal, [string] $MongoImage, # Traefik [bool] $TraefikExternal, [string] $TraefikImage, # Jet [string] $JetRelayUrl, [string] $JetInternalUrl, [int] $JetTcpPort, [string] $JetTcpExternalUrl, [bool] $JetExternal, [string] $JetRelayImage, # Picky [string] $PickyUrl, [bool] $PickyExternal, [string] $PickyImage, # Lucid [string] $LucidUrl, [string] $LucidApiKey, [bool] $LucidExternal, [string] $LucidImage, [ValidateSet("off","error", "warn", "info", "debug", "trace", IgnoreCase = $false)] [string] $LucidLogLevel, # NATS [string] $NatsUrl, [string] $NatsUsername, [string] $NatsPassword, [bool] $NatsExternal, [string] $NatsImage, # Redis [string] $RedisUrl, [string] $RedisPassword, [bool] $RedisExternal, [string] $RedisImage, # Docker [string] $DockerNetwork, [ValidateSet("linux","windows")] [string] $DockerPlatform, [ValidateSet("process","hyperv")] [string] $DockerIsolation, [ValidateSet("no","on-failure","always","unless-stopped")] [string] $DockerRestartPolicy, [string] $DockerHost, [string] $DockerBaseImage, [string] $SyslogServer, [switch] $Force ) $ConfigPath = Find-WaykBastionConfig -ConfigPath:$ConfigPath New-Item -Path $ConfigPath -ItemType "Directory" -Force | Out-Null $DenServerPath = Join-Path $ConfigPath "den-server" $DenPublicKeyFile = Join-Path $DenServerPath "den-public.pem" $DenPrivateKeyFile = Join-Path $DenServerPath "den-private.key" New-Item -Path $DenServerPath -ItemType "Directory" -Force | Out-Null if (!((Test-Path -Path $DenPublicKeyFile -PathType "Leaf") -and (Test-Path -Path $DenPrivateKeyFile -PathType "Leaf"))) { $KeyPair = New-RsaKeyPair -KeySize 2048 Set-Content -Path $DenPublicKeyFile -Value $KeyPair.PublicKey -Force Set-Content -Path $DenPrivateKeyFile -Value $KeyPair.PrivateKey -Force } $config = [WaykBastionConfig]::new() $properties = [WaykBastionConfig].GetProperties() | ForEach-Object { $_.Name } foreach ($param in $PSBoundParameters.GetEnumerator()) { if ($properties -Contains $param.Key) { if ($param.Key -like "*Url") { $config.($param.Key) = ConvertTo-NormalizedUrlString $param.Value } else { $config.($param.Key) = $param.Value } } } Expand-WaykBastionConfigKeys -Config:$config Save-WaykBastionConfig -ConfigPath:$ConfigPath -Config:$Config -ConfigFormat $WaykBastionConfigFormat -ErrorAction 'Stop' Export-TraefikConfig -ConfigPath:$ConfigPath } function Set-WaykBastionConfig { [CmdletBinding()] param( [string] $ConfigPath, # Server [string] $Realm, [string] $ExternalUrl, [string] $ListenerUrl, [string] $ServerMode, [ValidateSet("off","error", "warn", "info", "debug", "trace", IgnoreCase = $false)] [string] $ServerLogLevel, [int] $ServerCount, [string] $DenServerUrl, [string] $DenRouterUrl, [int] $DenKeepAliveInterval, [string] $DenApiKey, [bool] $DisableCors, [bool] $DisableDbSchemaValidation, [bool] $DisableTelemetry, [bool] $ExperimentalFeatures, [bool] $ServerExternal, [string] $ServerImage, # MongoDB [string] $MongoUrl, [string] $MongoVolume, [bool] $MongoExternal, [string] $MongoImage, # Traefik [bool] $TraefikExternal, [string] $TraefikImage, # Jet [string] $JetRelayUrl, [string] $JetInternalUrl, [int] $JetTcpPort, [string] $JetTcpExternalUrl, [bool] $JetExternal, [string] $JetRelayImage, # Picky [string] $PickyUrl, [bool] $PickyExternal, [string] $PickyImage, # Lucid [string] $LucidUrl, [string] $LucidApiKey, [bool] $LucidExternal, [string] $LucidImage, [ValidateSet("off","error", "warn", "info", "debug", "trace", IgnoreCase = $false)] [string] $LucidLogLevel, # NATS [string] $NatsUrl, [string] $NatsUsername, [string] $NatsPassword, [bool] $NatsExternal, [string] $NatsImage, # Redis [string] $RedisUrl, [string] $RedisPassword, [bool] $RedisExternal, [string] $RedisImage, # Docker [string] $DockerNetwork, [ValidateSet("linux","windows")] [string] $DockerPlatform, [ValidateSet("process","hyperv")] [string] $DockerIsolation, [ValidateSet("no","on-failure","always","unless-stopped")] [string] $DockerRestartPolicy, [string] $DockerHost, [string] $DockerBaseImage, [string] $SyslogServer, [switch] $Force ) $ConfigPath = Find-WaykBastionConfig -ConfigPath:$ConfigPath $config = Get-WaykBastionConfig -ConfigPath:$ConfigPath New-Item -Path $ConfigPath -ItemType "Directory" -Force | Out-Null $properties = [WaykBastionConfig].GetProperties() | ForEach-Object { $_.Name } foreach ($param in $PSBoundParameters.GetEnumerator()) { if ($properties -Contains $param.Key) { if ($param.Key -like "*Url") { $config.($param.Key) = ConvertTo-NormalizedUrlString $param.Value } else { $config.($param.Key) = $param.Value } } } Expand-WaykBastionConfigKeys -Config:$config Save-WaykBastionConfig -ConfigPath:$ConfigPath -Config:$Config -ConfigFormat $WaykBastionConfigFormat -ErrorAction 'Stop' Export-TraefikConfig -ConfigPath:$ConfigPath } function Get-WaykBastionConfig { [CmdletBinding()] [OutputType('WaykBastionConfig')] param( [string] $ConfigPath, [switch] $Expand, [switch] $NonDefault, [switch] $RemoveSensitiveData ) $ConfigPath = Find-WaykBastionConfig -ConfigPath:$ConfigPath $config = [WaykBastionConfig]::new() $ConfigFileJson = Join-Path $ConfigPath "bastion.json" $ConfigFileYaml = Join-Path $ConfigPath "wayk-den.yml" if (Test-Path -Path $ConfigFileJson -PathType 'Leaf') { $ConfigFile = $ConfigFileJson $ConfigFormat = 'json' } elseif (Test-Path -Path $ConfigFileYaml -PathType 'Leaf') { $ConfigFile = $ConfigFileYaml $ConfigFormat = 'yaml' } else { throw "Config file not found in $ConfigPath" } if ($ConfigFormat -eq 'json') { $ConfigData = Get-Content -Path $ConfigFile -Encoding UTF8 -ErrorAction Stop $json = $ConfigData | ConvertFrom-Json [WaykBastionConfig].GetProperties() | ForEach-Object { $Name = $_.Name if ($json.PSObject.Properties[$Name]) { $Property = $json.PSObject.Properties[$Name] $Value = $Property.Value $config.$Name = $Value } } } else { $ConfigData = Get-Content -Path $ConfigFile -Raw -ErrorAction Stop $yaml = ConvertFrom-Yaml -Yaml $ConfigData -UseMergingParser -AllDocuments -Ordered [WaykBastionConfig].GetProperties() | ForEach-Object { $Name = $_.Name $snake_name = ConvertTo-SnakeCase -Value $Name if ($yaml.Contains($snake_name)) { if ($yaml.$snake_name -is [string]) { if (![string]::IsNullOrEmpty($yaml.$snake_name)) { $config.$Name = ($yaml.$snake_name).Trim() } } else { $config.$Name = $yaml.$snake_name } } } # automatically convert to bastion.json format for next time (fail silently if we can't write config file) Save-WaykBastionConfig -ConfigPath:$ConfigPath -Config:$Config -ConfigFormat 'json' -ErrorAction 'SilentlyContinue' } if ($Expand) { Expand-WaykBastionConfig $config } if ($NonDefault) { # remove default properties from object $config = Remove-DefaultProperties $config $([WaykBastionConfig]::new()) } if ($RemoveSensitiveData) { Remove-WaykBastionConfigSensitiveData $config } return $config } function Clear-WaykBastionConfig { [CmdletBinding()] param( [string] $ConfigPath, [Parameter(Mandatory=$true,Position=0)] [string] $Filter ) $ConfigPath = Find-WaykBastionConfig -ConfigPath:$ConfigPath $config = [WaykBastionConfig]::new() $ConfigFileJson = Join-Path $ConfigPath "bastion.json" $ConfigFileYaml = Join-Path $ConfigPath "wayk-den.yml" if (Test-Path -Path $ConfigFileJson -PathType 'Leaf') { $ConfigFile = $ConfigFileJson $ConfigFormat = 'json' } elseif (Test-Path -Path $ConfigFileYaml -PathType 'Leaf') { $ConfigFile = $ConfigFileYaml $ConfigFormat = 'yaml' } else { throw "Config file not found in $ConfigPath" } if ($ConfigFormat -eq 'json') { $ConfigData = Get-Content -Path $ConfigFile -Encoding UTF8 -ErrorAction Stop $json = $ConfigData | ConvertFrom-Json [WaykBastionConfig].GetProperties() | ForEach-Object { $Name = $_.Name if ($Name -NotLike $Filter) { if ($json.PSObject.Properties[$Name]) { if ($json.$Name -is [string]) { if (![string]::IsNullOrEmpty($json.$Name)) { $config.$Name = ($json.$Name).Trim() } } else { $config.$Name = $json.$Name } } } } } else { $ConfigData = Get-Content -Path $ConfigFile -Raw -ErrorAction Stop $yaml = ConvertFrom-Yaml -Yaml $ConfigData -UseMergingParser -AllDocuments -Ordered [WaykBastionConfig].GetProperties() | ForEach-Object { $Name = $_.Name if ($Name -NotLike $Filter) { $snake_name = ConvertTo-SnakeCase -Value $Name if ($yaml.Contains($snake_name)) { if ($yaml.$snake_name -is [string]) { if (![string]::IsNullOrEmpty($yaml.$snake_name)) { $config.$Name = ($yaml.$snake_name).Trim() } } else { $config.$Name = $yaml.$snake_name } } } } } Save-WaykBastionConfig -ConfigPath:$ConfigPath -Config:$Config -ConfigFormat $WaykBastionConfigFormat -ErrorAction 'Stop' } function Remove-WaykBastionConfig { [CmdletBinding()] param( [string] $ConfigPath ) $ConfigPath = Find-WaykBastionConfig -ConfigPath:$ConfigPath Remove-Item -Path $(Join-Path $ConfigPath 'bastion.json') -Force Remove-Item -Path $(Join-Path $ConfigPath 'wayk-den.yml') -Force Remove-Item -Path $(Join-Path $ConfigPath 'den-server') -Recurse Remove-Item -Path $(Join-Path $ConfigPath 'traefik') -Recurse } function ConvertTo-NormalizedUrlString { [OutputType('System.String')] param( [Parameter(Position=0)] [string] $Value ) if (-Not [string]::IsNullOrEmpty($Value)) { $url = [System.Uri]::new($Value) $start = $url.Scheme + "://" + $url.DnsSafeHost $Value = $Value -IReplace $start, $start $Value = $Value.TrimEnd("/") } $Value } |