Skip to content

Commit

Permalink
(chocolatey#251) Use Single Store for Variables
Browse files Browse the repository at this point in the history
As there's little point separating the store out into CCM / Jenkins / etc anymore, we might as well start treating this like a KeyVault.

As an initial step, we add Get and Set commands to the helpers, and default the path to a shared file.
  • Loading branch information
JPRuskin committed Sep 18, 2024
1 parent c62dd1e commit 8be9910
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 48 deletions.
40 changes: 22 additions & 18 deletions Set-SslSecurity.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,10 @@ param(
[Parameter(ParameterSetName='Subject')]
[Parameter(ParameterSetName='Thumbprint')]
[string]
$CertificateDnsName,
$CertificateDnsName = $(
if (-not (Get-Command Get-ChocoEnvironmentProperty -ErrorAction SilentlyContinue)) {. $PSScriptRoot\scripts\Get-Helpers.ps1}
Get-ChocoEnvironmentProperty CertSubject
),

# This option security hardens your C4B server, in scenarios where you have a non-self-signed certificate.
# It adds a role and user credential to the Nexus server, which is used to authenticate the source setup on a client endpoint.
Expand All @@ -60,7 +63,10 @@ param(
$Hostname = [System.Net.Dns]::GetHostName(),

# API key of your Nexus repo, to add to the source setup on C4B Server.
[string]$NuGetApiKey = $($x = Import-Clixml "C:\choco-setup\clixml\nexus.xml" ; [System.Net.NetworkCredential]::new('',$x.NuGetApiKey).Password),
[string]$NuGetApiKey = $(
if (-not (Get-Command Get-ChocoEnvironmentProperty -ErrorAction SilentlyContinue)) {. $PSScriptRoot\scripts\Get-Helpers.ps1}
Get-ChocoEnvironmentProperty NuGetApiKey -AsPlainText
),

# If provided, will skip launching the browser
[switch]$SkipBrowserLaunch
Expand Down Expand Up @@ -207,7 +213,7 @@ process {
# Reset the NuGet v3 cache, such that it doesn't capture localhost as the FQDN
Remove-NexusRepositoryFolder -RepositoryName ChocolateyInternal -Name v3

Update-Clixml -Path "$env:SystemDrive\choco-setup\clixml\nexus.xml" -Properties @{
Update-Clixml -Properties @{
NexusUri = "https://$($SubjectWithoutCn):8443"
NexusRepo = $RepositoryUrl
ChocoUserPassword = $NexusPw
Expand All @@ -227,7 +233,7 @@ process {
# Add firewall rule for Jenkins
netsh advfirewall firewall add rule name="Jenkins-7443" dir=in action=allow protocol=tcp localport=7443

Update-Clixml -Path "$env:SystemDrive\choco-setup\clixml\jenkins.xml" -Properties @{
Update-Clixml -Properties @{
JenkinsUri = "https://$($SubjectWithoutCn):7443"
}

Expand Down Expand Up @@ -294,12 +300,9 @@ process {
}

Install-ChocolateyAgent @agentArgs
}

else {

# Agent Setup
$agentArgs = @{
} else {
# Agent Setup
$agentArgs = @{
CentralManagementServiceUrl = "https://$($SubjectWithoutCn):24020/ChocolateyManagementService"
}

Expand All @@ -316,20 +319,21 @@ Invoke-Expression (`$downloader.DownloadString("http://`$(`$HostName):80/Import-
}
}

Update-Clixml -Path "$env:SystemDrive\choco-setup\clixml\ccm.xml" -Properties @{
Update-Clixml -Properties @{
CCMWebPortal = "https://$($SubjectWithoutCn)/Account/Login"
CCMServiceURL = "https://$($SubjectWithoutCn):24020/ChocolateyManagementService"
ServiceSalt = $ServiceSaltValue | ConvertTo-SecureString -AsPlainText -Force
ClientSalt = $ClientSaltValue | ConvertTo-SecureString -AsPlainText -Force
}

# Save useful params to JSON
[PSCustomObject]@{
CertSubject = $SubjectWithoutCn
CertThumbprint = $Certificate.Thumbprint
CertExpiry = $Certificate.NotAfter
IsSelfSigned = $IsSelfSigned
} | Export-Clixml "$env:SystemDrive\choco-setup\clixml\ssl.xml"
}

if ($Hardened) {
Update-Clixml -Properties @{
ServiceSalt = ConvertTo-SecureString $ServiceSaltValue -AsPlainText -Force
ClientSalt = ConvertTo-SecureString $ClientSaltValue -AsPlainText -Force
}
}
}

end {
Expand Down
6 changes: 4 additions & 2 deletions Start-C4bCcmSetup.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ process {

$Packages = (Get-Content $PSScriptRoot\files\chocolatey.json | ConvertFrom-Json).packages

Set-ChocoEnvironmentProperty -Name DatabaseUser -Value $DatabaseCredential

# DB Setup
Write-Host "Installing SQL Server Express"
$chocoArgs = @('upgrade', 'sql-server-express', '-y', '--no-progress')
Expand Down Expand Up @@ -147,13 +149,13 @@ process {
& choco @chocoArgs

$CcmSvcUrl = choco config get centralManagementServiceUrl -r
[pscustomobject]@{
Update-Clixml -Properties @{
CCMServiceURL = $CcmSvcUrl
CCMWebPortal = "http://localhost/Account/Login"
DefaultUser = "ccmadmin"
DefaultPwToBeChanged = "123qwe"
CCMDBUser = $DatabaseUser
} | Export-Clixml "$env:SystemDrive\choco-setup\clixml\ccm.xml"
}

Write-Host "Chocolatey Central Management Setup has now completed" -ForegroundColor Green

Expand Down
8 changes: 4 additions & 4 deletions Start-C4bJenkinsSetup.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ param(
[string]$HostName = $env:ComputerName,

# API key of your Nexus repo, for Chocolatey Jenkins jobs to use
[string]$NuGetApiKey = $($x = Import-Clixml "C:\choco-setup\clixml\nexus.xml" ; [System.Net.NetworkCredential]::new('',$x.NuGetApiKey).Password)
[string]$NuGetApiKey = $(Get-ChocoEnvironmentProperty NuGetApiKey -AsPlainText)
)
process {
$DefaultEap = $ErrorActionPreference
Expand Down Expand Up @@ -114,11 +114,11 @@ process {
Write-Host "Starting Jenkins service back up" -ForegroundColor Green
Start-Service -Name Jenkins

# Save useful params to JSON
[PSCustomObject]@{
# Save useful params
Update-Clixml -Properties @{
JenkinsUri = "http://$($HostName):8080"
JenkinsCredential = $JenkinsCred
} | Export-Clixml "$env:SystemDrive\choco-setup\clixml\jenkins.xml"
}

Write-Host 'Jenkins setup complete' -ForegroundColor Green

Expand Down
6 changes: 3 additions & 3 deletions Start-C4bNexusSetup.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -114,13 +114,13 @@ process {
}
$null = New-NetFirewallRule @FwRuleParams

# Save useful params to JSON
[PSCustomObject]@{
# Save useful params
Update-Clixml -Properties @{
NexusUri = "http://localhost:8081"
NexusCredential = $Credential
NexusRepo = "$((Get-NexusRepository -Name 'ChocolateyInternal').url)/index.json"
NuGetApiKey = $NugetApiKey | ConvertTo-SecureString -AsPlainText -Force
} | Export-Clixml "$env:SystemDrive\choco-setup\clixml\nexus.xml"
}

$ErrorActionPreference = $DefaultEap
Stop-Transcript
Expand Down
100 changes: 79 additions & 21 deletions scripts/Get-Helpers.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ function Invoke-Choco {
}
}

Update-TypeData -TypeName SecureString -MemberType ScriptMethod -MemberName ToPlainText -Force -Value {
[System.Net.NetworkCredential]::new("TempCredential", $this).Password
}

#region Package functions (OfflineInstallPreparation.ps1)
if (-not ("System.IO.Compression.ZipArchive" -as [type])) {
Add-Type -Assembly 'System.IO.Compression'
Expand Down Expand Up @@ -2059,21 +2063,77 @@ function Invoke-TextReplacementInFile {
function Update-Clixml {
[CmdletBinding()]
param(
[Parameter(Mandatory)]
[string]$Path,
[Parameter()]
[string]$Path = "$env:SystemDrive\choco-setup\clixml\chocolatey-for-business.xml",

[Parameter(Mandatory)]
[hashtable]$Properties
)
#$Json = Get-Content -Path $Path | ConvertFrom-Json
$CliXml = Import-Clixml $Path
$CliXml = if (Test-Path $Path) {
Import-Clixml $Path
} else {
if (-not (Test-Path (Split-Path $Path -Parent))) {
$null = mkdir (Split-Path $Path -Parent) -Force
}
[PSCustomObject]@{}
}

$Properties.GetEnumerator().ForEach{
Add-Member -InputObject $CliXml -MemberType NoteProperty -Name $_.Key -Value $_.Value -Force
}

$CliXml | Export-Clixml $Path -Force
}

function Get-ChocoEnvironmentProperty {
[CmdletBinding(DefaultParameterSetName="All")]
param(
[Parameter(ParameterSetName="Specific", Mandatory, ValueFromPipeline, Position=0)]
[string]$Name,

[Parameter(ParameterSetName="Specific")]
[switch]$AsPlainText
)
begin {
$Content = Import-Clixml -Path "$env:SystemDrive\choco-setup\clixml\chocolatey-for-business.xml"
}
process {
if ($Name) {
if ($AsPlainText -and $Content.$Name -is [System.Security.SecureString]) {
return $Content.$Name.ToPlainText()
} else {
return $Content.$Name
}
} else {
$Content
}
}
}

function Set-ChocoEnvironmentProperty {
[CmdletBinding(DefaultParameterSetName="Key")]
param(
[Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName="Key", Position=0)]
[Alias('Key')]
[string]$Name,

[Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName="Key", Position=1)]
$Value,

[Parameter(Mandatory, ValueFromPipeline, ParameterSetName="Hashtable")]
[hashtable]$InputObject = @{}
)
begin {
$Properties = $InputObject
}
process {
$Properties.$Name = $Value
}
end {
Update-Clixml -Path "$env:SystemDrive\choco-setup\clixml\chocolatey-for-business.xml" -Properties $Properties
}
}

function Set-JenkinsCertificate {
<#
.Synopsis
Expand Down Expand Up @@ -2173,38 +2233,36 @@ The host name of the C4B instance.
param()
process {
try {
$CCMData = Import-Clixml "$env:SystemDrive\choco-setup\clixml\ccm.xml"
$NexusData = Import-Clixml "$env:SystemDrive\choco-setup\clixml\nexus.xml"
$JenkinsData = Import-Clixml "$env:SystemDrive\choco-setup\clixml\jenkins.xml"
$Data = Get-ChocoEnvironmentProperty
} catch {
Write-Error "Unable to read JSON files. Ensure the Quickstart Guide has been completed."
Write-Error "Unable to read stored values. Ensure the Quickstart Guide has been completed."
}

Copy-Item $PSScriptRoot\ReadmeTemplate.html.j2 -Destination $env:Public\Desktop\Readme.html -Force

# Working around the existing j2 template, so we can keep them roughly in sync
Invoke-TextReplacementInFile -Path $env:Public\Desktop\Readme.html -Replacement @{
# CCM Values
"{{ ccm_fqdn .*?}}" = ([uri]$CCMData.CCMWebPortal).DnsSafeHost
"{{ ccm_port .*?}}" = ([uri]$CCMData.CCMWebPortal).Port
"{{ ccm_password .*?}}" = [System.Web.HttpUtility]::HtmlEncode($CCMData.DefaultPwToBeChanged)
"{{ ccm_fqdn .*?}}" = ([uri]$Data.CCMWebPortal).DnsSafeHost
"{{ ccm_port .*?}}" = ([uri]$Data.CCMWebPortal).Port
"{{ ccm_password .*?}}" = [System.Web.HttpUtility]::HtmlEncode($Data.DefaultPwToBeChanged)

# Chocolatey Configuration Values
"{{ ccm_encryption_password .*?}}" = "Requested on first run."
"{{ ccm_client_salt .*?}}" = [System.Web.HttpUtility]::HtmlEncode([System.Net.NetworkCredential]::new('',$CCMData.ClientSalt).Password)
"{{ ccm_service_salt .*?}}" = [System.Web.HttpUtility]::HtmlEncode([System.Net.NetworkCredential]::new('',$CCMData.ServiceSalt).Password)
"{{ chocouser_password .*?}}" = [System.Web.HttpUtility]::HtmlEncode($NexusData.NexusCredential.GetNetworkCredential().Password)
"{{ ccm_client_salt .*?}}" = [System.Web.HttpUtility]::HtmlEncode((Get-ChocoEnvironmentProperty ClientSalt -AsPlainText))
"{{ ccm_service_salt .*?}}" = [System.Web.HttpUtility]::HtmlEncode((Get-ChocoEnvironmentProperty ServiceSalt -AsPlainText))
"{{ chocouser_password .*?}}" = [System.Web.HttpUtility]::HtmlEncode($Data.NexusCredential.Password.ToPlainText())

# Nexus Values
"{{ nexus_fqdn .*?}}" = ([uri]$NexusData.NexusUri).DnsSafeHost
"{{ nexus_port .*?}}" = ([uri]$NexusData.NexusUri).Port
"{{ nexus_password .*?}}" = [System.Web.HttpUtility]::HtmlEncode($NexusData.NexusCredential.GetNetworkCredential().Password)
"{{ lookup\('file', 'credentials\/nexus_apikey'\) .*?}}" = [System.Net.NetworkCredential]::new('',$NexusData.NugetApiKey).Password
"{{ nexus_fqdn .*?}}" = ([uri]$Data.NexusUri).DnsSafeHost
"{{ nexus_port .*?}}" = ([uri]$Data.NexusUri).Port
"{{ nexus_password .*?}}" = [System.Web.HttpUtility]::HtmlEncode($Data.NexusCredential.Password.ToPlainText())
"{{ lookup\('file', 'credentials\/nexus_apikey'\) .*?}}" = Get-ChocoEnvironmentProperty NugetApiKey -AsPlainText

# Jenkins Values
"{{ jenkins_fqdn .*?}}" = ([uri]$JenkinsData.JenkinsUri).DnsSafeHost
"{{ jenkins_port .*?}}" = ([uri]$JenkinsData.JenkinsUri).Port
"{{ jenkins_password .*?}}" = [System.Web.HttpUtility]::HtmlEncode($JenkinsData.JenkinsCredential.GetNetworkCredential().Password)
"{{ jenkins_fqdn .*?}}" = ([uri]$Data.JenkinsUri).DnsSafeHost
"{{ jenkins_port .*?}}" = ([uri]$Data.JenkinsUri).Port
"{{ jenkins_password .*?}}" = [System.Web.HttpUtility]::HtmlEncode($Data.JenkinsCredential.Password.ToPlainText())
}
}
}
Expand Down

0 comments on commit 8be9910

Please sign in to comment.