Fix support for policy.yaml

This change fixes support for policy.yaml, which was broken because
of the following problems.
 - The default content was still formatted in json
 - Augeas doesn't support flat yaml contents required

Change-Id: Ie308a481eb70d5f930633b18d8044f9542a142af
This commit is contained in:
Takashi Kajinami 2021-01-07 11:51:05 +09:00
parent 083c01dcf9
commit 0ffc8e1c4b
3 changed files with 118 additions and 40 deletions

View File

@ -43,48 +43,58 @@ define openstacklib::policy::base (
$file_format = 'json',
) {
ensure_resource('file', $file_path, {
mode => $file_mode,
owner => $file_user,
group => $file_group,
replace => false, # augeas will manage the content, we just need to make sure it exists
content => '{}'
})
case $file_format {
'json': {
$file_lens = 'Json.lns'
ensure_resource('file', $file_path, {
mode => $file_mode,
owner => $file_user,
group => $file_group,
replace => false, # augeas will manage the content, we just need to make sure it exists
content => '{}'
})
# Add entry if it doesn't exists
augeas { "${file_path}-${key}-${value}-add":
lens => 'Json.lns',
incl => $file_path,
changes => [
"set dict/entry[last()+1] \"${key}\"",
"set dict/entry[last()]/string \"${value}\"",
],
onlyif => "match dict/entry[*][.=\"${key}\"] size == 0",
}
# Requires that the entry is added before this call or it will fail.
augeas { "${file_path}-${key}-${value}" :
lens => 'Json.lns',
incl => $file_path,
changes => "set dict/entry[*][.=\"${key}\"]/string \"${value}\"",
}
File<| title == $file_path |>
-> Augeas<| title == "${file_path}-${key}-${value}-add" |>
~> Augeas<| title == "${file_path}-${key}-${value}" |>
}
'yaml': {
$file_lens = 'Yaml.lns'
ensure_resource('file', $file_path, {
mode => $file_mode,
owner => $file_user,
group => $file_group,
replace => false, # augeas will manage the content, we just need to make sure it exists
content => ''
})
file_line { "${file_path}-${key}" :
path => $file_path,
line => "'${key}': '${value}'",
match => "^['\"]?${key}['\"]?\\s*:.+"
}
File<| title == $file_path |>
-> File_line<| title == "${file_path}-${key}" |>
}
default: {
fail("${file_format} is an unsupported policy file format. Choose 'json' or 'yaml'.")
}
}
# Add entry if it doesn't exists
augeas { "${file_path}-${key}-${value}-add":
lens => $file_lens,
incl => $file_path,
changes => [
"set dict/entry[last()+1] \"${key}\"",
"set dict/entry[last()]/string \"${value}\"",
],
onlyif => "match dict/entry[*][.=\"${key}\"] size == 0",
}
# Requires that the entry is added before this call or it will fail.
augeas { "${file_path}-${key}-${value}" :
lens => $file_lens,
incl => $file_path,
changes => "set dict/entry[*][.=\"${key}\"]/string \"${value}\"",
}
File<| title == $file_path |>
-> Augeas<| title == "${file_path}-${key}-${value}-add" |>
~> Augeas<| title == "${file_path}-${key}-${value}" |>
}

View File

@ -0,0 +1,36 @@
require 'spec_helper_acceptance'
describe 'policy file management' do
context 'with policy.yaml' do
it 'should work with no errors' do
pp= <<-EOS
Exec { logoutput => 'on_failure' }
openstacklib::policy::base { 'is_admin':
file_path => '/tmp/policy.yaml',
key => 'is_admin',
value => 'role:admin',
file_format => 'yaml',
}
openstacklib::policy::base { 'is_member':
file_path => '/tmp/policy.yaml',
key => 'is_member',
value => 'role:member',
file_format => 'yaml',
}
EOS
# Run it twice and test for idempotency
apply_manifest(pp, :catch_failures => true)
apply_manifest(pp, :catch_changes => true)
end
describe file('/tmp/policy.yaml') do
it { should exist }
it { should contain("'is_admin': 'role:admin'") }
it { should contain("'is_member': 'role:member'") }
end
end
end

View File

@ -2,19 +2,20 @@ require 'spec_helper'
describe 'openstacklib::policy::base' do
shared_examples 'openstacklib::policy::base' do
context 'with some basic parameters' do
context 'with policy.json' do
let :title do
'nova-contest_is_admin'
end
let :params do
{
:file_path => '/etc/nova/policy.json',
:key => 'context_is_admin or owner',
:value => 'foo:bar',
:file_mode => '0644',
:file_user => 'foo',
:file_group => 'bar'
:file_path => '/etc/nova/policy.json',
:key => 'context_is_admin or owner',
:value => 'foo:bar',
:file_mode => '0644',
:file_user => 'foo',
:file_group => 'bar',
:file_format => 'json',
}
end
@ -40,6 +41,37 @@ describe 'openstacklib::policy::base' do
:onlyif => 'match dict/entry[*][.="context_is_admin or owner"] size == 0'
)}
end
context 'with policy.yaml' do
let :title do
'nova-contest_is_admin'
end
let :params do
{
:file_path => '/etc/nova/policy.yaml',
:key => 'context_is_admin or owner',
:value => 'foo:bar',
:file_mode => '0644',
:file_user => 'foo',
:file_group => 'bar',
:file_format => 'yaml',
}
end
it { should contain_file('/etc/nova/policy.yaml').with(
:mode => '0644',
:owner => 'foo',
:group => 'bar'
)}
it { should contain_file_line('/etc/nova/policy.yaml-context_is_admin or owner').with(
:path => '/etc/nova/policy.yaml',
:line => '\'context_is_admin or owner\': \'foo:bar\'',
:match => '^[\'"]?context_is_admin or owner[\'"]?\s*:.+'
) }
end
end
on_supported_os({