Skip to content
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

(#230) Add Admin Only Source For Chocolatey Core Packages #255

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
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
22 changes: 11 additions & 11 deletions OfflineInstallPreparation.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,8 @@ if (-not $Licensed) {
}
Copy-Item $LicensePath $InstalledLicensePath -Force
}
$ExtensionSource = if (Test-Path $PSScriptRoot\files\chocolatey.extension.*.nupkg) {
Convert-Path $PSScriptRoot\files\
$ExtensionSource = if (Test-Path $PSScriptRoot\packages\chocolatey.extension.*.nupkg) {
Convert-Path $PSScriptRoot\packages\
} else {
'https://licensedpackages.chocolatey.org/api/v2/'
}
Expand All @@ -103,7 +103,7 @@ $PackageWorkingDirectory = Join-Path $WorkingDirectory "Packages"
if (-not (Test-Path $PackageWorkingDirectory)) {
$null = New-Item -Path $PackageWorkingDirectory -ItemType Directory -Force
}
foreach ($Package in (Get-Content $PSScriptRoot\files\chocolatey.json | ConvertFrom-Json).packages) {
foreach ($Package in (Get-Content $PSScriptRoot\packages\chocolatey.json | ConvertFrom-Json).packages) {
$ChocoArgs = @(
"download", "$($Package.Name)"
"--output-directory", $PackageWorkingDirectory
Expand All @@ -118,7 +118,7 @@ foreach ($Package in (Get-Content $PSScriptRoot\files\chocolatey.json | ConvertF
}

try {
if (-not (Get-ChocolateyPackageMetadata -Path $PackageWorkingDirectory -Id $Package.Name) -and -not (Get-ChocolateyPackageMetadata -Path "$PSScriptRoot\files\" -Id $Package.Name)) {
if (-not (Get-ChocolateyPackageMetadata -Path $PackageWorkingDirectory -Id $Package.Name) -and -not (Get-ChocolateyPackageMetadata -Path "$PSScriptRoot\packages\" -Id $Package.Name)) {
Write-Host "Downloading '$($Package.Name)'"

while ((Get-ChildItem $PackageWorkingDirectory -Filter *.nupkg).Where{$_.CreationTime -gt (Get-Date).AddMinutes(-1)}.Count -gt 5) {
Expand All @@ -132,18 +132,18 @@ foreach ($Package in (Get-Content $PSScriptRoot\files\chocolatey.json | ConvertF
throw $_
}
}
Move-Item -Path $PackageWorkingDirectory\*.nupkg -Destination $PSScriptRoot\files\
Move-Item -Path $PackageWorkingDirectory\*.nupkg -Destination $PSScriptRoot\packages\

# Jenkins Plugins
$PluginsWorkingDirectory = Join-Path $WorkingDirectory "JenkinsPlugins"
if (-not (Test-Path $PluginsWorkingDirectory)) {
$null = New-Item -Path $PluginsWorkingDirectory -ItemType Directory -Force
}
if (Test-Path $PSScriptRoot\files\JenkinsPlugins.zip) {
Expand-Archive -Path $PSScriptRoot\files\JenkinsPlugins.zip -DestinationPath $PluginsWorkingDirectory -Force
if (Test-Path $PSScriptRoot\packages\JenkinsPlugins.zip) {
Expand-Archive -Path $PSScriptRoot\packages\JenkinsPlugins.zip -DestinationPath $PluginsWorkingDirectory -Force
}
$ProgressPreference = "Ignore"
foreach ($Plugin in (Get-Content $PSScriptRoot\files\jenkins.json | ConvertFrom-Json).plugins) {
foreach ($Plugin in (Get-Content $PSScriptRoot\packages\jenkins.json | ConvertFrom-Json).plugins) {
$RestArgs = @{
Uri = "https://updates.jenkins-ci.org/latest/$($Plugin.Name).hpi"
OutFile = Join-Path $PluginsWorkingDirectory "$($Plugin.Name).hpi"
Expand All @@ -155,12 +155,12 @@ foreach ($Plugin in (Get-Content $PSScriptRoot\files\jenkins.json | ConvertFrom-
Invoke-WebRequest @RestArgs -UseBasicParsing
}
}
Compress-Archive -Path $PluginsWorkingDirectory\* -Destination $PSScriptRoot\files\JenkinsPlugins.zip -Force
Compress-Archive -Path $PluginsWorkingDirectory\* -Destination $PSScriptRoot\packages\JenkinsPlugins.zip -Force

# BCryptDll
$null = Get-BcryptDll

# License
if ($LicensePath -ne "$PSScriptRoot\files\chocolatey.license.xml") {
Copy-Item -Path (Convert-Path $LicensePath) -Destination $PSScriptRoot\files\chocolatey.license.xml
if ($LicensePath -ne "$PSScriptRoot\packages\chocolatey.license.xml") {
Copy-Item -Path (Convert-Path $LicensePath) -Destination $PSScriptRoot\packages\chocolatey.license.xml
}
26 changes: 12 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

This repository contains a set of supporting scripts used for the Chocolatey for Business (C4B) Quick-Start Guide (QSG).

These scripts can be used to assist in setup of a brand new Windows Server as a C4B Server.
These scripts can be used to assist in the setup of a brand-new Windows Server as a C4B Server.

Below is the Quick Start Guide as it exists currently on the [Chocolatey Docs](https://docs.chocolatey.org/en-us/guides/organizations/quick-start-guide/chocolatey-for-business-quick-start-guide).

Expand Down Expand Up @@ -34,14 +34,16 @@ As illustrated in the diagram above, there are four main components to a Chocola

1. **C4B Licensed components**: A licensed version of Chocolatey includes:
- Installation of the Chocolatey OSS client package itself (`chocolatey`)
- Chocolatey license file (`chocolatey.license.xml`) installed in the correct directory (`ProgramData\chocolatey\license`)
- The Chocolatey license file (`chocolatey.license.xml`) installed in the correct directory (`ProgramData\chocolatey\license`)
- Installation of the Chocolatey Licensed extension (`chocolatey.extension`), giving you access to features like Package Builder, Package Internalizer, etc. (full list [here](https://docs.chocolatey.org/en-us/features/)).

1. **NuGet V3 Repository Server App (Nexus)**: Chocolatey works best with a NuGet V3 repository. This application hosts and manages versioning of your Chocolatey package artifacts, in their enhanced NuGet package (.nupkg) file format. The quick start guide helps you setup [Sonatype Nexus Repository Manager (OSS)](https://www.sonatype.com/products/nexus-repository).
1. **Repository Server (Sonatype Nexus)**: Chocolatey works best with a NuGet repository. This repository hosts and manages the versioning of your Chocolatey package artifacts, in their enhanced NuGet package (.nupkg) file format. The quick start guide helps you set up [Sonatype Nexus Repository Manager (OSS)](https://www.sonatype.com/products/nexus-repository).

1. **Chocolatey Central Management (CCM)**: CCM is the Web UI portal for your entire Chocolatey environment. Your endpoints check-in to CCM to report their package status. This includes the Chocolatey packages they have installed, and whether any of these packages are outdated. And now, with CCM Deployments, you can also deploy packages or package updates to groups of endpoints, as well as ad-hoc PowerShell commands. CCM is backed by an MS SQL Database. This guide will set up MS SQL Express for you.
1. **Chocolatey Central Management (CCM)**: CCM is a web-based application for managing the state of Chocolatey packages in your environment. Your endpoints check in via the Chocolatey agent and report basic computer information (host name, IP address), and what Chocolatey packages are installed, as well as if any of those packages are outdated. A deployment capability allows you to install, upgrade, or uninstall packages, and for more advanced scenarios run ad-hoc PowerShell code on your endpoints.

1. **Automation Pipeline (Jenkins)**: A pipeline tool will help you automate repetitive tasks, such checking for updates to a set of Chocolatey Packages from the Chocolatey Community Repository (CCR). If updates exist, the pipeline task will auto-internalize your list of packages, and push them into your NuGet repository for you. This guide will help you set up Jenkins as your automation pipeline.
CCM is backed by an MS SQL Database, which this guide will set up and configure for you based on Microsoft SQL Server Express.

1. **Automation Pipeline (Jenkins)**: A pipeline tool will help you automate repetitive tasks, such as checking for updates to a set of Chocolatey Packages from the Chocolatey Community Repository (CCR). If updates exist, the pipeline task will auto-internalize your list of packages, and push them into your NuGet repository for you. This guide will help you set up Jenkins as your automation pipeline.

## Requirements

Expand All @@ -62,7 +64,7 @@ Below are the minimum requirements for setting up your C4B server via this guide

1. Install all Windows Updates.

1. If you plan on joining this server to your Active Directory domain, do so now before beginning setup below.
1. If you plan on joining this server to your Active Directory domain, do so now before beginning the setup below.

1. If you plan to use a Purchased/Acquired or Domain SSL certificate, please ensure the CN/Subject value matches the DNS-resolvable Fully Qualified Domain Name (FQDN) of your C4B Server. Place this certificate in the `Local Machine > Personal` certificate store, and ensure that the private key is exportable.

Expand Down Expand Up @@ -120,9 +122,11 @@ Below are the minimum requirements for setting up your C4B server via this guide
> <ul class="list-style-type-disc">
> <li>Installs Sonatype Nexus Repository Manager OSS instance</li>
> <li>Cleans up all demo repositories on Nexus</li>
> <li>Creates a "ChocolateyCore" NuGet repository</li>
> <li>Creates a "ChocolateyInternal" NuGet repository</li>
> <li>Creates a "ChocolateyTest" NuGet repository</li>
> <li>Creates a "choco-install" raw repository</li>
> <li>Sets up "ChocolateyCore" on C4B Server as source, with API key</li>
> <li>Sets up "ChocolateyInternal" on C4B Server as source, with API key</li>
> <li>Adds firewall rule for repository access</li>
> <li>Installs MS Edge, and disables first-run experience</li>
Expand Down Expand Up @@ -177,7 +181,7 @@ Below are the minimum requirements for setting up your C4B server via this guide
.\Set-SslSecurity.ps1
```

**ALTERNATIVE 1 : Custom SSL Certificate** - If you have your own custom SSL certificate (purchased/acquired, or from your Domain CA), you can paste and run the following script with the `Thumbprint` value of your SSL certificate specified:
**ALTERNATIVE 1: Custom SSL Certificate** - If you have your own custom SSL certificate (purchased/acquired, or from your Domain CA), you can paste and run the following script with the `Thumbprint` value of your SSL certificate specified:

```powershell
Set-Location "$env:SystemDrive\choco-setup\files"
Expand All @@ -189,7 +193,7 @@ Below are the minimum requirements for setting up your C4B server via this guide
> :memo: **NOTE**
> You may have noticed the `-Hardened` parameter we've added above. When using a custom SSL certificate, this parameter will further secure access to your C4B Server. A Role and User credential will be configured to limit access to your Nexus repositories. As well, CCM Client and Service Salts are configured to further encrypt your connection between CCM and your endpoint clients. These additional settings are also incorporated into your `Register-C4bEndpoint.ps1` script for onboarding endpoints. We do require you to enable this option if your C4B Server will be Internet-facing, with a FQDN that resolves to a public IP.

**ALTERNATIVE 2 : Wildcard SSL Certificate** - If you have a wildcard certificate, you will also need to provide a DNS name you wish to use for that certificate:
**ALTERNATIVE 2: Wildcard SSL Certificate** - If you have a wildcard certificate, you will also need to provide a DNS name you wish to use for that certificate:

```powershell
Set-Location "$env:SystemDrive\choco-setup\files"
Expand Down Expand Up @@ -272,9 +276,3 @@ Below are the minimum requirements for setting up your C4B server via this guide
Congratulations! If you followed all the steps detailed above, you should now have a fully functioning Chocolatey for Business implementation deployed in your environment.

It is worth mentioning that some customers may have a more bespoke environment, with the presence of proxies and additional configuration management applications. Chocolatey is engineered to be quite flexible, specifically to account for these scenarios. Please refer to the many options for installation referenced on the [Installation page](https://docs.chocolatey.org/en-us/licensed-extension/setup#more-install-options). Again, If you have any questions or would like to discuss more involved implementations, please feel free to reach out to your Chocolatey representative.

### See it in Action

If you'd prefer to watch and follow along, here is a recording of our Chocolatey Team going through this guide live on our Twitch stream:

[YouTube Video](https://www.youtube.com/embed/qbIclPMEgig)
40 changes: 33 additions & 7 deletions Set-SslSecurity.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,10 @@ process {
Write-Host "Nexus is ready!"

Invoke-Choco source remove --name="'ChocolateyInternal'"
$RepositoryUrl = "https://${SubjectWithoutCn}:8443/repository/ChocolateyInternal/index.json"
$InternalRepositoryUrl = "https://${SubjectWithoutCn}:8443/repository/ChocolateyInternal/index.json"

Invoke-Choco source remove --name="'ChocolateyCore'"
$CoreRepositoryUrl = "https://${SubjectWithoutCn}:8443/repository/ChocolateyCore/index.json"

# Build Credential Object, Connect to Nexus
$securePw = (Get-Content 'C:\programdata\sonatype-work\nexus3\admin.password') | ConvertTo-SecureString -AsPlainText -Force
Expand Down Expand Up @@ -185,35 +188,58 @@ process {
'source',
'add',
"--name='ChocolateyInternal'",
"--source='$RepositoryUrl'",
"--source='$InternalRepositoryUrl'",
'--priority=1',
"--user='chocouser'",
"--password='$NexusPw'"
)
& Invoke-Choco @ChocoArgs
& choco @ChocoArgs

$ChocoArgs = @(
'source',
'add',
"--name='ChocolateyCore'",
"--source='$CoreRepositoryUrl'",
'--priority=0',
"--user='chocouser'",
"--password='$NexusPw'"
)
& choco @ChocoArgs
}

else {
$ChocoArgs = @(
'source',
'add',
"--name='ChocolateyInternal'",
"--source='$RepositoryUrl'",
"--source='$InternalRepositoryUrl'",
'--priority=1'
)
& Invoke-Choco @ChocoArgs

$ChocoArgs = @(
'source',
'add',
"--name='ChocolateyCore'",
"--source='$CoreRepositoryUrl'",
'--priority=0'
)
& Invoke-Choco @ChocoArgs
}

# Update Repository API key
$chocoArgs = @('apikey', "--source='$RepositoryUrl'", "--api-key='$NuGetApiKey'")
$chocoArgs = @('apikey', "--source='$InternalRepositoryUrl'", "--api-key='$NuGetApiKey'")
& Invoke-Choco @chocoArgs

$chocoArgs = @('apikey', "--source='$CoreRepositoryUrl'", "--api-key='$NuGetApiKey'")
& Invoke-Choco @chocoArgs

# Reset the NuGet v3 cache, such that it doesn't capture localhost as the FQDN
Remove-NexusRepositoryFolder -RepositoryName ChocolateyInternal -Name v3

Update-Clixml -Properties @{
NexusUri = "https://$($SubjectWithoutCn):8443"
NexusRepo = $RepositoryUrl
NexusRepo = $CoreRepositoryUrl
ryanrichter94 marked this conversation as resolved.
Show resolved Hide resolved
ChocoUserPassword = $NexusPw
}

Expand Down Expand Up @@ -268,7 +294,7 @@ process {
# Touch NOTHING below this line
`$User = 'chocouser'
`$SecurePassword = `$NexusUserPW | ConvertTo-SecureString -AsPlainText -Force
`$RepositoryUrl = "https://`$(`$fqdn):8443/repository/ChocolateyInternal/index.json"
`$RepositoryUrl = "https://`$(`$fqdn):8443/repository/ChocolateyCore/index.json"
ryanrichter94 marked this conversation as resolved.
Show resolved Hide resolved

`$credential = [pscredential]::new(`$user, `$securePassword)

Expand Down
2 changes: 1 addition & 1 deletion Start-C4bCcmSetup.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ process {
$ErrorActionPreference = 'Stop'
Start-Transcript -Path "$env:SystemDrive\choco-setup\logs\Start-C4bCcmSetup-$(Get-Date -Format 'yyyyMMdd-HHmmss').txt"

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

Set-ChocoEnvironmentProperty -Name DatabaseUser -Value $DatabaseCredential

Expand Down
6 changes: 3 additions & 3 deletions Start-C4bJenkinsSetup.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,10 @@ process {
Stop-Service -Name Jenkins

#region Jenkins Plugin Install & Update
$JenkinsPlugins = (Get-Content $PSScriptRoot\files\jenkins.json | ConvertFrom-Json).plugins
$JenkinsPlugins = (Get-Content $PSScriptRoot\packages\jenkins.json | ConvertFrom-Json).plugins

if (Test-Path $PSScriptRoot\files\JenkinsPlugins.zip) {
Expand-Archive -Path $PSScriptRoot\files\JenkinsPlugins.zip -DestinationPath $jenkinsHome\plugins\ -Force
if (Test-Path $PSScriptRoot\packages\JenkinsPlugins.zip) {
Expand-Archive -Path $PSScriptRoot\packages\JenkinsPlugins.zip -DestinationPath $jenkinsHome\plugins\ -Force
}

# Performance is killed by Invoke-WebRequest's progress bars, turning them off to speed this up
Expand Down
Loading
Loading