Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
(#14529) Add registry::value defined type
Without this patch we don't have an easy to use way to abstract away the management of a value and the key it's in. This patch fixes the problem by creating a new defined resource type in Puppet that builds on top of the native `registry_key` and `registry_value` resource types. This registry::value type allows the user to manage values without worrying about also managing the key the value exists in. For example: registry::value { 'MyAPP - Owner Email': key => 'HKLM\Software\Puppet Labs', value => 'Owner Email', data => 'jeff@puppetlabs.com', } This resource will automatically manage the parent key if it does not exist and manage the value. The key and value will be created in the native architecture of the hive. That is to say, the 64 bit hive on a 64 bit system and the 32 bit hive on a 32 bit system.
- Loading branch information
Jeff McCune
committed
May 16, 2012
1 parent
2e9e45e
commit bf44208
Showing
5 changed files
with
192 additions
and
2 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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
105 changes: 105 additions & 0 deletions
105
acceptance/tests/resource/registry/should_have_defined_type.rb
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
require 'pathname' | ||
require Pathname.new(__FILE__).dirname.dirname.dirname.dirname + 'lib/systest/util/registry' | ||
# Include our utility methods in the singleton class of the test case instance. | ||
class << self | ||
include Systest::Util::Registry | ||
end | ||
|
||
test_name "registry::value defined type" | ||
|
||
# Generate a unique key name | ||
keyname = "PuppetLabsTest_MixedCase_#{randomstring(8)}" | ||
# This is the keypath we'll use for this entire test. We will actually create this key and delete it. | ||
vendor_path = "HKLM\\Software\\Vendor" | ||
keypath = "#{vendor_path}\\#{keyname}" | ||
|
||
master_manifest_content = <<HERE | ||
notify { fact_phase: message => "fact_phase: $fact_phase" } | ||
registry_key { '#{vendor_path}': ensure => present } | ||
class phase1 { | ||
registry::value { 'Setting1': | ||
key => '#{keypath}', | ||
value => 'Setting1', | ||
data => "fact_phase=${fact_phase}", | ||
} | ||
registry::value { 'Setting2': | ||
key => '#{keypath}', | ||
data => "fact_phase=${fact_phase}", | ||
} | ||
registry::value { 'Setting3': | ||
key => '#{keypath}', | ||
value => 'Setting3', | ||
data => "fact_phase=${fact_phase}", | ||
} | ||
registry::value { 'Setting0': | ||
key => '#{keypath}', | ||
value => '(default)', | ||
data => "fact_phase=${fact_phase}", | ||
} | ||
} | ||
case $fact_phase { | ||
default: { include phase1 } | ||
} | ||
HERE | ||
|
||
# Setup the master to use the modules specified in the --modules option | ||
setup_master master_manifest_content | ||
|
||
step "Start the master" do | ||
with_master_running_on(master, master_options) do | ||
# A set of keys we expect Puppet to create | ||
phase1_resources_created = [ | ||
/Registry_key\[HKLM.Software.Vendor.PuppetLabsTest\w+\].ensure: created/, | ||
/Registry_value\[HKLM.Software.Vendor.PuppetLabsTest\w+\\\].ensure: created/, | ||
/Registry_value\[HKLM.Software.Vendor.PuppetLabsTest\w+\\Setting1\].ensure: created/, | ||
/Registry_value\[HKLM.Software.Vendor.PuppetLabsTest\w+\\Setting2\].ensure: created/, | ||
/Registry_value\[HKLM.Software.Vendor.PuppetLabsTest\w+\\Setting3\].ensure: created/, | ||
] | ||
|
||
phase2_resources_changed = [ | ||
/Registry_value\[HKLM.Software.Vendor.PuppetLabsTest\w+\\\].data: data changed 'fact_phase=1' to 'fact_phase=2'/, | ||
/Registry_value\[HKLM.Software.Vendor.PuppetLabsTest\w+\\Setting1\].data: data changed 'fact_phase=1' to 'fact_phase=2'/, | ||
/Registry_value\[HKLM.Software.Vendor.PuppetLabsTest\w+\\Setting2\].data: data changed 'fact_phase=1' to 'fact_phase=2'/, | ||
/Registry_value\[HKLM.Software.Vendor.PuppetLabsTest\w+\\Setting3\].data: data changed 'fact_phase=1' to 'fact_phase=2'/, | ||
] | ||
|
||
windows_agents.each do |agent| | ||
this_agent_args = agent_args % get_test_file_path(agent, agent_lib_dir) | ||
|
||
step "Phase 1.a - Create some values" | ||
on agent, puppet_agent(this_agent_args, :environment => { 'FACTER_FACT_PHASE' => '1' }), :acceptable_exit_codes => agent_exit_codes do | ||
phase1_resources_created.each do |val_re| | ||
assert_match(val_re, result.stdout, "Expected output to contain #{val_re.inspect}.") | ||
end | ||
assert_no_match(/err:/, result.stdout, "Expected no error messages.") | ||
end | ||
|
||
step "Phase 1.b - Make sure Puppet is idempotent" | ||
on agent, puppet_agent(this_agent_args, :environment => { 'FACTER_FACT_PHASE' => '1' }), :acceptable_exit_codes => agent_exit_codes do | ||
phase1_resources_created.each do |val_re| | ||
assert_no_match(val_re, result.stdout, "Expected output not to contain #{val_re.inspect}.") | ||
end | ||
assert_no_match(/err:/, result.stdout, "Expected no error messages.") | ||
end | ||
|
||
step "Phase 2.a - Change some values" | ||
on agent, puppet_agent(this_agent_args, :environment => { 'FACTER_FACT_PHASE' => '2' }), :acceptable_exit_codes => agent_exit_codes do | ||
phase2_resources_changed.each do |val_re| | ||
assert_match(val_re, result.stdout, "Expected output to contain #{val_re.inspect}.") | ||
end | ||
assert_no_match(/err:/, result.stdout, "Expected no error messages.") | ||
end | ||
|
||
step "Phase 2.b - Make sure Puppet is idempotent" | ||
on agent, puppet_agent(this_agent_args, :environment => { 'FACTER_FACT_PHASE' => '2' }), :acceptable_exit_codes => agent_exit_codes do | ||
(phase1_resources_created + phase2_resources_changed).each do |val_re| | ||
assert_no_match(val_re, result.stdout, "Expected output not to contain #{val_re.inspect}.") | ||
end | ||
assert_no_match(/err:/, result.stdout, "Expected no error messages.") | ||
end | ||
end | ||
end | ||
end |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
# = Define: registry::value | ||
# | ||
# This defined resource type provides a higher level of abstraction on top of | ||
# the registry_key and registry_value resources. Using this defined resource | ||
# type, you do not need to explicitly manage the parent key for a particular | ||
# value. Puppet will automatically manage the parent key for you. | ||
# | ||
# == Parameters: | ||
# | ||
# key:: The path of key the value will placed inside. | ||
# | ||
# value:: The name of the registry value to manage. This will be copied from | ||
# the resource title if not specified. The special value of | ||
# '(default)' may be used to manage the default value of the key. | ||
# | ||
# type:: The type the registry value. Defaults to 'string'. See the output of | ||
# `puppet describe registry_value` for a list of supported types in the | ||
# "type" parameter. | ||
# | ||
# data:: The data to place inside the registry value. | ||
# | ||
# == Actions: | ||
# - Manage the parent key if not already managed. | ||
# - Manage the value | ||
# | ||
# == Requires: | ||
# - Registry Module | ||
# - Stdlib Module | ||
# | ||
# == Sample Usage: | ||
# | ||
# This example will automatically manage the key. It will also create a value | ||
# named 'puppetmaster' inside this key. | ||
# | ||
# class myapp { | ||
# registry::value { 'puppetmaster': | ||
# key => 'HKLM\Software\Vendor\PuppetLabs', | ||
# data => 'puppet.puppetlabs.com', | ||
# } | ||
# } | ||
# | ||
define registry::value($key, $value=undef, $type='string', $data=undef) { | ||
# validate our inputs. | ||
validate_re($key, '^\w+', "key parameter must not be empty but it is key => '$key'") | ||
validate_re($type, '^\w+', "type parameter must not be empty but it is type => '$type'") | ||
|
||
$value_real = $value ? { | ||
undef => $name, | ||
'(default)' => '', | ||
default => $value, | ||
} | ||
|
||
# Resource defaults. | ||
Registry_key { ensure => present } | ||
Registry_value { ensure => present } | ||
|
||
if !defined(Registry_key["${key}"]) { | ||
registry_key { "${key}": } | ||
} | ||
|
||
# If value_real is an empty string then the default value of the key will be | ||
# managed. | ||
registry_value { "${key}\\${value_real}": | ||
type => $type, | ||
data => $data, | ||
} | ||
} | ||
|