Created
July 31, 2017 23:56
-
-
Save jpadams/1205817e885f96c454d00ac871182992 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # install.ps1 : This powershell script installs the puppet-agent package from a Puppet Enterprise master | |
| # you could call this script like this: | |
| # install.ps1 main:certname=foo custom_attributes:challengePassword=SECRET extension_requests:pp_role=webserver | |
| [CmdletBinding()] | |
| Param( | |
| [Parameter(Mandatory = $false, ValueFromRemainingArguments = $true)] | |
| [String[]] | |
| # This value would be $null when no parameters are passed in; however, a PS2 bug causes foreach to iterate once | |
| # over $null, which is undesirable. Setting the default to an empty array gets around that PS2 bug. | |
| $arguments = @() | |
| ) | |
| # If an error is encountered, the script will stop instead of the default of "Continue" | |
| $ErrorActionPreference = "Stop" | |
| $server = 'tse-puppetmaster2-prod.tse.puppetlabs.net' | |
| $port = '8140' | |
| $puppet_bin_dir = Join-Path ([Environment]::GetFolderPath('ProgramFiles')) 'Puppet Labs\Puppet\bin' | |
| $puppet_conf_dir = Join-Path ([Environment]::GetFolderPath('CommonApplicationData')) 'Puppetlabs\puppet\etc' | |
| $date_time_stamp = (Get-Date -format s) -replace ':', '-' | |
| $install_log = Join-Path ([System.IO.Path]::GetTempPath()) "$date_time_stamp-puppet-install.log" | |
| # Start with assumption of 64 bit agent package unless probe detects 32 bit. | |
| $arch = 'x64' | |
| $msi_path = 'windows-x86_64' | |
| if ((Get-WmiObject Win32_OperatingSystem).OSArchitecture -match '^32') { | |
| $arch = 'x86' | |
| $msi_path = 'windows-i386' | |
| } | |
| $msi_source = "https://${server}:$port/packages/current/$msi_path/puppet-agent-$arch.msi" | |
| $msi_dest = Join-Path ([System.IO.Path]::GetTempPath()) "puppet-agent-$arch.msi" | |
| $class_arch = $msi_path -replace '-', '_' | |
| $pe_repo_class = "pe_repo::platform::$class_arch" | |
| function CustomPuppetConfiguration { | |
| # Parse optional pre-installation configuration of Puppet settings via | |
| # command-line arguments. Arguments should be of the form | |
| # | |
| # <section>:<setting>=<value> | |
| # | |
| # There are four valid section settings in puppet.conf: "main", "master", | |
| # "agent", "user". If you provide valid setting and value for one of these | |
| # four sections, it will end up in <confdir>/puppet.conf. | |
| # | |
| # There are two sections in csr_attributes.yaml: "custom_attributes" and | |
| # "extension_requests". If you provide valid setting and value for one | |
| # of these two sections, it will end up in <confdir>/csr_attributes.yaml. | |
| # | |
| # note:Custom Attributes are only present in the CSR, while Extension | |
| # Requests are both in the CSR and included as X509 extensions in the | |
| # signed certificate (and are thus available as "trusted facts" in Puppet). | |
| # | |
| # Regex is authoritative for valid sections, settings, and values. Any input | |
| # that fails regex will trigger this script to fail with error message. | |
| $regex = '^(main|master|agent|user|custom_attributes|extension_requests):(.+?)=(.*)$' | |
| $attr_array = @() | |
| $extn_array = @() | |
| $match = $null | |
| foreach ($entry in $arguments) { | |
| if (! ($match = [regex]::Match($entry,$regex)).Success) { | |
| Throw "Unable to interpret argument: '$entry'. Expected '<section>:<setting>=<value>' matching regex: '$regex'" | |
| } | |
| else { | |
| $section = $match.groups[1].value | |
| $setting = $match.groups[2].value | |
| $value = $match.groups[3].value | |
| switch ($section) { | |
| 'custom_attributes' { | |
| # Store the entry in attr_array for later addition to csr_attributes.yaml | |
| $attr_array += "${setting}: '${value}'" | |
| break | |
| } | |
| 'extension_requests' { | |
| # Store the entry in extn_array for later addition to csr_attributes.yaml | |
| $extn_array += "${setting}: '${value}'" | |
| break | |
| } | |
| default { | |
| # Set the specified entry in puppet.conf | |
| & $puppet_bin_dir\puppet config set $setting $value --section $section | |
| break | |
| } | |
| } | |
| } | |
| } | |
| # If the the length of the attr_array or extn_array is greater than zero, it | |
| # means we have settings, so we'll create the csr_attributes.yaml file. | |
| if ($attr_array.length -gt 0 -or $extn_array.length -gt 0) { | |
| echo('---') | out-file -filepath $puppet_conf_dir\csr_attributes.yaml -encoding UTF8 | |
| if ($attr_array.length -gt 0) { | |
| echo('custom_attributes:') | out-file -filepath $puppet_conf_dir\csr_attributes.yaml -append -encoding UTF8 | |
| for ($i = 0; $i -lt $attr_array.length; $i++) { | |
| echo(' ' + $attr_array[$i]) | out-file -filepath $puppet_conf_dir\csr_attributes.yaml -append -encoding UTF8 | |
| } | |
| } | |
| if ($extn_array.length -gt 0) { | |
| echo('extension_requests:') | out-file -filepath $puppet_conf_dir\csr_attributes.yaml -append -encoding UTF8 | |
| for ($i = 0; $i -lt $extn_array.length; $i++) { | |
| echo(' ' + $extn_array[$i]) | out-file -filepath $puppet_conf_dir\csr_attributes.yaml -append -encoding UTF8 | |
| } | |
| } | |
| } | |
| } | |
| function DownloadPuppet { | |
| Write-Verbose "Downloading the Puppet Agent for Puppet Enterprise on $env:COMPUTERNAME..." | |
| [System.Net.ServicePointManager]::ServerCertificateValidationCallback={$true} | |
| $webclient = New-Object system.net.webclient | |
| try { | |
| $webclient.DownloadFile($msi_source,$msi_dest) | |
| } | |
| catch { | |
| Throw "Failed to download the Puppet Agent installer: $msi_source. Does the Puppet Master have the $pe_repo_class class applied to it?" | |
| } | |
| } | |
| function InstallPuppet { | |
| Write-Verbose "Installing the Puppet Agent on $env:COMPUTERNAME..." | |
| Write-Verbose "Saving the install log to $install_log" | |
| $msiexec_args = "/qn /log $install_log /i $msi_dest PUPPET_MASTER_SERVER=$server PUPPET_AGENT_STARTUP_MODE=Manual" | |
| $msiexec_proc = [System.Diagnostics.Process]::Start('msiexec', $msiexec_args) | |
| $msiexec_proc.WaitForExit() | |
| if (@(0, 1641, 3010) -NotContains $msiexec_proc.ExitCode) { | |
| Throw "Something went wrong with the installation on $env:COMPUTERNAME. Exit code: " + $msiexec_proc.ExitCode + ". Check the install log at $install_log" | |
| } | |
| $certname = & $puppet_bin_dir\puppet config print certname | |
| & $puppet_bin_dir\puppet config set certname $certname --section main | |
| } | |
| function StartPuppetService { | |
| & $puppet_bin_dir\puppet resource service puppet ensure=running enable=true | |
| } | |
| DownloadPuppet | |
| InstallPuppet | |
| CustomPuppetConfiguration | |
| StartPuppetService | |
| Write-Verbose "Installation has completed." |
Author
@ycx356 good question. I believe this functionality is built in to Puppet Enterprise these days. I'm sure tons has changed. I've been away from Puppet for a couple of years. I'm sure folks have ideas in community channels. Cheers!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
how can we bootstrap with class name as parameter ?