-
Notifications
You must be signed in to change notification settings - Fork 100
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
New Resource for managing choco config #132
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,180 @@ | ||
# Copyright (c) 2017 Chocolatey Software, Inc. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
<# | ||
.SYNOPSIS | ||
DSC Resource to set/unset chocolatey config settings | ||
|
||
.NOTES | ||
This resource supports querying the XML file directly. This is faster but not recommended as it does not respect the chocolatey api. | ||
Use this feature if you will not be upgrading chocolatey as updates may change the xml format and break this resource! | ||
#> | ||
function Get-TargetResource { | ||
[CmdletBinding()] | ||
[OutputType([System.Collections.Hashtable])] | ||
param ( | ||
[Parameter(Mandatory)] | ||
[System.String]$Key, | ||
|
||
[Parameter()] | ||
[System.String]$Value, | ||
|
||
[Parameter()] | ||
[ValidateSet('Present', 'Absent')] | ||
[System.String]$Ensure = 'Present', | ||
|
||
[Parameter()] | ||
[System.Boolean]$QueryXML | ||
Comment on lines
+25
to
+38
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The OutputType and Parameter types all use the .NET types. Can we stick with the PowerShell types? |
||
) | ||
|
||
$return = @{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you rename this as |
||
'Key' = $Key | ||
'Value' = $Value | ||
'Ensure' = $Ensure | ||
'QueryXML' = $QueryXML | ||
} | ||
|
||
if ($Ensure -eq 'Absent') { | ||
# if value and absent specified remove value as it can be confusing output | ||
$return['Value'] = $null | ||
} | ||
Comment on lines
+48
to
+51
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm confused a little but this. The comment says 'if value and absent specified ...' but the if statement only checks for absent. As $Value is an optional parameter it might not be provided. |
||
|
||
return $return | ||
} | ||
|
||
function Set-TargetResource { | ||
[CmdletBinding()] | ||
param ( | ||
[Parameter(Mandatory)] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
[System.String]$Key, | ||
|
||
[Parameter()] | ||
[System.String]$Value, | ||
|
||
[Parameter()] | ||
[ValidateSet('Present', 'Absent')] | ||
[System.String]$Ensure = 'Present', | ||
|
||
[Parameter()] | ||
[System.Boolean]$QueryXML | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a Boolean here but a switch in |
||
) | ||
Comment on lines
+60
to
+71
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use the PowerShell types and not the .NET ones. |
||
|
||
# validate value is given when ensure present | ||
if ($Ensure -eq 'Present' -and -not $PSBoundParameters.ContainsKey('Value')) { | ||
throw "Missing parameter 'Value' when ensuring config is present!" | ||
} | ||
|
||
# query config to determine current setting | ||
$ChocoConfig = @{ | ||
'Key' = $Key | ||
'QueryXML' = $QueryXML | ||
} | ||
$CurrentValue = Get-ChocoConfig @ChocoConfig | ||
|
||
# make it so | ||
if ($Ensure -eq 'Absent' -and -not [String]::IsNullOrEmpty($CurrentValue)) { | ||
Write-Verbose "Unsetting $Key..." | ||
& choco config unset $Key | ||
} | ||
else { | ||
Write-Verbose "Setting $Key to '$Value'..." | ||
& choco config set --name $Key --value $Value | ||
} | ||
|
||
} | ||
|
||
function Test-TargetResource { | ||
[CmdletBinding()] | ||
[OutputType([System.Boolean])] | ||
param ( | ||
[Parameter(Mandatory)] | ||
[System.String]$Key, | ||
|
||
[Parameter()] | ||
[System.String]$Value, | ||
|
||
[Parameter()] | ||
[ValidateSet('Present', 'Absent')] | ||
[System.String]$Ensure = 'Present', | ||
|
||
[Parameter()] | ||
[System.Boolean]$QueryXML | ||
) | ||
|
||
# validate value is given when ensure present | ||
if ($Ensure -eq 'Present' -and -not $PSBoundParameters.ContainsKey('Value')) { | ||
throw "Missing parameter 'Value' when ensuring config is present!" | ||
} | ||
|
||
# query config to determine current setting | ||
$ChocoConfig = @{ | ||
'Key' = $Key | ||
'QueryXML' = $QueryXML | ||
} | ||
$CurrentValue = Get-ChocoConfig @ChocoConfig | ||
|
||
# determine if in desired state | ||
if ($Ensure -eq 'Absent') { | ||
if ([String]::IsNullOrEmpty($CurrentValue)) { | ||
Write-Verbose "$Key is in desired state" | ||
return $true | ||
} | ||
else { | ||
Write-Verbose "$key not in desired state: value should be unset but was '$CurrentValue'" | ||
return $false | ||
} | ||
} | ||
else { | ||
if ($Value -eq $CurrentValue) { | ||
Write-Verbose "$Key is in desired state" | ||
return $true | ||
} | ||
else { | ||
Write-Verbose "$key not in desired state: value should be '$Value' but was '$CurrentValue'" | ||
return $false | ||
} | ||
} | ||
} | ||
|
||
function Get-ChocoConfig { | ||
[CmdletBinding()] | ||
[OutputType([System.String])] | ||
param ( | ||
[Parameter(Mandatory)] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same with Mandatory parameter. |
||
[System.String]$Key, | ||
Comment on lines
+152
to
+155
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. PowerShell types to be used. |
||
|
||
[Parameter()] | ||
[Switch]$QueryXML | ||
) | ||
|
||
if ($QueryXML.IsPresent) { | ||
Write-Verbose "Querying chco config via chocolatey.config xml..." | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Typo in 'choco' |
||
$ConfigXmlPath = Join-Path $env:ChocolateyInstall -ChildPath "config\chocolatey.config" | ||
try { | ||
$ConfigXml = [xml](Get-Content -Path $ConfigXmlPath) | ||
# xpath is case sensitive so we must convert all to lower case | ||
$XPath = "/chocolatey/config/add[translate(@key, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz') = '$($Key.ToLower())']" | ||
$ConfigValue = $ConfigXml.SelectSingleNode($XPath).value | ||
} | ||
catch { | ||
$PSCmdlet.ThrowTerminatingError($_) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just use a |
||
} | ||
Comment on lines
+164
to
+172
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm a little unsure about this. The code catches any exceptions being thrown but just throws the same exception. This would be no different than not having the try / catch block. So I'm wondering why it's there? |
||
} | ||
else { | ||
Write-Verbose "Querying choco config via CLI" | ||
$ConfigValue = & choco config get $Key -r | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please don't use aliases ( There is no sanity check being done on the output of this command. What if the key does not exist? The caller will get a response back that is not what they are expecting. |
||
} | ||
|
||
return $ConfigValue | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
[ClassVersion("1.0.0.0"), FriendlyName("cChocoConfig")] | ||
class cChocoConfig : OMI_BaseResource | ||
{ | ||
[Key] String Key; | ||
[Write] String Value; | ||
[Write,ValueMap{"Present", "Absent"},Values{"Present", "Absent"}] String Ensure; | ||
[Write] Boolean QueryXML; | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# Copyright (c) 2017 Chocolatey Software, Inc. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
|
||
configuration ChocoConfig { | ||
|
||
Import-DscResource -ModuleName cChoco | ||
|
||
Node 'localhost' { | ||
|
||
cChocoConfig webRequestTimeoutSeconds { | ||
Key = "webRequestTimeoutSeconds" | ||
Ensure = 'Present' | ||
Value = 30 | ||
} | ||
|
||
cChocoConfig proxy { | ||
Key = "proxy" | ||
Ensure = 'Absent' | ||
} | ||
} | ||
|
||
} | ||
|
||
|
||
$config = ChocoConfig | ||
|
||
Start-DscConfiguration -Path $config.psparentpath -Wait -Verbose -Force |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,163 @@ | ||
# Copyright (c) 2017 Chocolatey Software, Inc. | ||
# Copyright (c) 2013 - 2017 Lawrence Gripper & original authors/contributors from https://github.com/chocolatey/cChoco | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
#----------------------------------------# | ||
# Pester tests for cChocoPackageInstall # | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wrong one 😄 |
||
#----------------------------------------# | ||
$ResourceName = ((Split-Path -Path $MyInvocation.MyCommand.Path -Leaf) -split '_')[0] | ||
$ResourceFile = (Get-DscResource -Name $ResourceName).Path | ||
|
||
$TestsPath = (split-path -path $MyInvocation.MyCommand.Path -Parent) | ||
$ResourceFile = Get-ChildItem -Recurse $TestsPath\.. -File | Where-Object {$_.name -eq "$ResourceName.psm1"} | ||
|
||
Import-Module -Name $ResourceFile.FullName | ||
|
||
Describe -Name "Testing $ResourceName loaded from $ResourceFile" -Fixture { | ||
$MyProxyUrl = 'http://foo' | ||
Context -Name "Proxy config is set to '$MyProxyUrl'" -Fixture { | ||
Mock -CommandName 'Get-ChocoConfig' -ModuleName 'cChocoConfig' -MockWith { | ||
return 'http://foo' | ||
} | ||
|
||
# returns true if config matches supplied value | ||
$Scenario1 = @{ | ||
Key = 'Proxy' | ||
Ensure = 'Present' | ||
Value = $MyProxyUrl | ||
} | ||
It -name "Test-TargetResource -ensure 'Present' -Value '$MyProxyUrl' should return True" -test { | ||
Test-TargetResource @Scenario1 | Should Be $true | ||
} | ||
|
||
# returns true if config matches supplied value (via xml) | ||
$Scenario2 = @{ | ||
Key = 'Proxy' | ||
Ensure = 'Present' | ||
Value = $MyProxyUrl | ||
QueryXML = $true | ||
} | ||
It -name "Test-TargetResource -ensure 'Present' -Value '$MyProxyUrl' -QueryXML `$true should return True" -test { | ||
Test-TargetResource @Scenario2 | Should Be $true | ||
} | ||
|
||
# returns false if config does not match supplied value | ||
$Scenario3 = @{ | ||
Key = 'Proxy' | ||
Ensure = 'Present' | ||
Value = 'http://some/other/url' | ||
} | ||
It -name "Test-TargetResource -ensure 'Present' -Value 'http://some/other/url' should return False" -test { | ||
Test-TargetResource @Scenario3 | Should Be $false | ||
} | ||
|
||
# returns false if config does not match supplied value (via xml) | ||
$Scenario4 = @{ | ||
Key = 'Proxy' | ||
Ensure = 'Present' | ||
Value = 'http://some/other/url' | ||
QueryXML = $true | ||
} | ||
It -name "Test-TargetResource -ensure 'Present' -Value 'http://some/other/url' -QueryXML `$true should return False" -test { | ||
Test-TargetResource @Scenario4 | Should Be $false | ||
} | ||
|
||
# returns false if ensure absent | ||
$Scenario5 = @{ | ||
Key = 'Proxy' | ||
Ensure = 'Absent' | ||
} | ||
It -name "Test-TargetResource -ensure 'Absent' should return False" -test { | ||
Test-TargetResource @Scenario5 | Should Be $false | ||
} | ||
|
||
# returns false if ensure absent (via xml) | ||
$Scenario6 = @{ | ||
Key = 'Proxy' | ||
Ensure = 'Absent' | ||
QueryXML = $true | ||
} | ||
It -name "Test-TargetResource -ensure 'Absent' -QueryXML `$true should return False" -test { | ||
Test-TargetResource @Scenario6 | Should Be $false | ||
} | ||
|
||
# throws when ensure present but no value given | ||
$Scenario7 = @{ | ||
Key = 'Proxy' | ||
Ensure = 'Present' | ||
} | ||
It -name "Test-TargetResource -ensure 'Present' should throw" -test { | ||
{Test-TargetResource @Scenario7} | Should -Throw "Missing parameter 'Value' when ensuring config is present!" | ||
} | ||
|
||
# throws when ensure present but no value given (via xml) | ||
$Scenario8 = @{ | ||
Key = 'Proxy' | ||
Ensure = 'Present' | ||
QueryXML = $true | ||
} | ||
It -name "Test-TargetResource -ensure 'Present' -QueryXML `$true should throw" -test { | ||
{Test-TargetResource @Scenario8} | Should -Throw "Missing parameter 'Value' when ensuring config is present!" | ||
} | ||
} | ||
|
||
Context -Name "Proxy config is not set" -Fixture { | ||
Mock -CommandName 'Get-ChocoConfig' -ModuleName 'cChocoConfig' -MockWith { | ||
return '' | ||
} | ||
|
||
# returns false if value supplied | ||
$Scenario1 = @{ | ||
Key = 'Proxy' | ||
Ensure = 'Present' | ||
Value = $MyProxyUrl | ||
} | ||
It -name "Test-TargetResource -ensure 'Present' -Value '$MyProxyUrl' should return False" -test { | ||
Test-TargetResource @Scenario1 | Should Be $false | ||
} | ||
|
||
# returns true if value supplied (via xml) | ||
$Scenario2 = @{ | ||
Key = 'Proxy' | ||
Ensure = 'Present' | ||
Value = $MyProxyUrl | ||
QueryXML = $true | ||
} | ||
It -name "Test-TargetResource -ensure 'Present' -Value '$MyProxyUrl' -QueryXML `$true should return False" -test { | ||
Test-TargetResource @Scenario2 | Should Be $false | ||
} | ||
|
||
# returns true if ensure absent | ||
$Scenario5 = @{ | ||
Key = 'Proxy' | ||
Ensure = 'Absent' | ||
} | ||
It -name "Test-TargetResource -ensure 'Absent' should return True" -test { | ||
Test-TargetResource @Scenario5 | Should Be $true | ||
} | ||
|
||
# returns true if ensure absent (via xml) | ||
$Scenario6 = @{ | ||
Key = 'Proxy' | ||
Ensure = 'Absent' | ||
QueryXML = $true | ||
} | ||
It -name "Test-TargetResource -ensure 'Absent' -QueryXML `$true should return True" -test { | ||
Test-TargetResource @Scenario6 | Should Be $true | ||
} | ||
} | ||
} | ||
|
||
#Clean-up | ||
Remove-Module cChocoConfig |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To avoid confusion can we use
Mandatory = $true
?