heat-config-puppet: support hiera

Updates the puppet hook so that we support using Hiera in addition
to the existing Facter based input mechanism. Hiera provides
a more flexible way of dealing with puppet parameters and
seems to be prefered in the Puppet community as well.

Use of the Hiera data will also require an additional
'hiera' element which will probably live in the
triple-puppet-elements tree.

Change-Id: I497f2d2286025e48e42691bfe178fc9c491928ea
This commit is contained in:
Dan Prince 2014-12-02 15:41:59 -05:00
parent 2b6339d875
commit 94bd31e45e
3 changed files with 84 additions and 4 deletions

View File

@ -1,3 +1,9 @@
A hook which invokes ``puppet apply`` on the provided configuration.
Config inputs are passed in as facts, and output values are read from written-out
files.
Config inputs are passed in as facts and/or using hiera, and output values
are read from written-out files.
Hook Options:
-------------
use_facter: default True. Set to True to pass puppet inputs via Facter
use_hiera: default False. Set to True to pass puppet inputs via Hiera

View File

@ -23,6 +23,8 @@ WORKING_DIR = os.environ.get('HEAT_PUPPET_WORKING',
OUTPUTS_DIR = os.environ.get('HEAT_PUPPET_OUTPUTS',
'/var/run/heat-config/heat-config-puppet')
PUPPET_CMD = os.environ.get('HEAT_PUPPET_CMD', 'puppet')
HIERA_DATADIR = os.environ.get('HEAT_PUPPET_HIERA_DATADIR',
'/etc/puppet/hieradata')
def prepare_dir(path):
@ -45,11 +47,29 @@ def main(argv=sys.argv):
c = json.load(sys.stdin)
use_hiera = c['options'].get('enable_hiera', False)
use_facter = c['options'].get('enable_facter', True)
facts = {}
hiera = {}
for input in c['inputs']:
input_name = input['name']
fact_name = 'FACTER_%s' % input_name
facts[fact_name] = input.get('value', '')
input_value = input.get('value', '')
if use_facter:
fact_name = 'FACTER_%s' % input_name
facts[fact_name] = input_value
if use_hiera:
hiera[input_name] = input_value
if use_hiera:
prepare_dir(HIERA_DATADIR)
hiera_data = os.path.join(HIERA_DATADIR,
'heat_config_%s.json' % c['name'])
with os.fdopen(os.open(hiera_data, os.O_CREAT | os.O_WRONLY, 0o600),
'w') as hiera_file:
hiera_file.write(json.dumps(hiera).encode('utf8'))
facts['FACTER_deploy_config_name'] = c['name']
fn = os.path.join(WORKING_DIR, '%s.pp' % c['id'])
heat_outputs_path = os.path.join(OUTPUTS_DIR, c['id'])

View File

@ -23,7 +23,12 @@ class HookPuppetTest(common.RunScriptTest):
data = {
'id': '1234',
'name': 'fake_resource_name',
'group': 'puppet',
'options': {
'enable_hiera': True,
'enable_facter': True,
},
'inputs': [
{'name': 'foo', 'value': 'bar'},
{'name': 'another', 'value': 'input'}
@ -49,12 +54,14 @@ class HookPuppetTest(common.RunScriptTest):
self.working_dir = self.useFixture(fixtures.TempDir())
self.outputs_dir = self.useFixture(fixtures.TempDir())
self.hiera_datadir = self.useFixture(fixtures.TempDir())
self.test_state_path = self.outputs_dir.join('test_state.json')
self.env = os.environ.copy()
self.env.update({
'HEAT_PUPPET_WORKING': self.working_dir.join(),
'HEAT_PUPPET_OUTPUTS': self.outputs_dir.join(),
'HEAT_PUPPET_HIERA_DATADIR': self.hiera_datadir.join(),
'HEAT_PUPPET_CMD': self.fake_tool_path,
'TEST_STATE_PATH': self.test_state_path,
})
@ -137,3 +144,50 @@ class HookPuppetTest(common.RunScriptTest):
state['env']['FACTER_heat_outputs_path'])
with open(puppet_script) as f:
self.assertEqual('the puppet script', f.read())
def test_hook_hiera(self):
self.env.update({
'TEST_RESPONSE': json.dumps({
'stdout': 'puppet success',
'stderr': 'thing happened',
'files': {
self.outputs_dir.join('1234.first_output'): 'output 1',
self.outputs_dir.join('1234.second_output'): 'output 2',
}
}),
})
returncode, stdout, stderr = self.run_cmd(
[self.hook_path], self.env, json.dumps(self.data))
self.assertEqual(0, returncode, stderr)
self.assertEqual({
'deploy_stdout': 'puppet success',
'deploy_stderr': 'thing happened',
'deploy_status_code': 0,
'first_output': 'output 1',
'second_output': 'output 2',
}, json.loads(stdout))
state = self.json_from_file(self.test_state_path)
puppet_script = self.working_dir.join('1234.pp')
hiera_datafile = self.hiera_datadir.join('heat_config_%s.json'
% self.data['name'])
self.assertEqual(
[
self.fake_tool_path,
'apply',
'--detailed-exitcodes',
puppet_script
],
state['args'])
self.assertEqual(self.outputs_dir.join('1234'),
state['env']['FACTER_heat_outputs_path'])
with open(puppet_script) as f:
self.assertEqual('the puppet script', f.read())
with open(hiera_datafile) as f:
self.assertEqual({
'foo': 'bar',
'another': 'input',
}, json.loads(f.read()))