Merge "Support image property protections configuration"
This commit is contained in:
commit
4a3666c103
|
@ -0,0 +1,8 @@
|
|||
Puppet::Type.type(:glance_property_protections_config).provide(
|
||||
:ini_setting,
|
||||
:parent => Puppet::Type.type(:openstack_config).provider(:ini_setting)
|
||||
) do
|
||||
def self.file_path
|
||||
'/etc/glance/property-protections.conf'
|
||||
end
|
||||
end
|
|
@ -0,0 +1,27 @@
|
|||
Puppet::Type.newtype(:glance_property_protections_config) do
|
||||
|
||||
ensurable
|
||||
|
||||
newparam(:name, :namevar => true) do
|
||||
desc 'Section/setting name to manage from property-protections.conf'
|
||||
newvalues(/\S+\/\S+/)
|
||||
end
|
||||
|
||||
newparam(:ensure_absent_val) do
|
||||
desc 'A value that is specified as the value property will behave as if ensure => absent was specified'
|
||||
defaultto('<SERVICE DEFAULT>')
|
||||
end
|
||||
|
||||
autorequire(:anchor) do
|
||||
['glance::install::end']
|
||||
end
|
||||
|
||||
newproperty(:value) do
|
||||
desc 'The value of the setting to be defined.'
|
||||
munge do |value|
|
||||
value = value.to_s.strip
|
||||
value.capitalize! if value =~ /^(true|false)$/i
|
||||
value
|
||||
end
|
||||
end
|
||||
end
|
|
@ -50,6 +50,7 @@ class glance::deps {
|
|||
Anchor['glance::config::begin'] -> Glance_image_import_config<||> ~> Anchor['glance::config::end']
|
||||
Anchor['glance::config::begin'] -> Glance_swift_config<||> ~> Anchor['glance::config::end']
|
||||
Anchor['glance::config::begin'] -> Glance_rootwrap_config<||> ~> Anchor['glance::config::end']
|
||||
Anchor['glance::config::begin'] -> Glance_property_protections_config<||> ~> Anchor['glance::config::end']
|
||||
|
||||
# glance-cache.conf is used by CLI commands so service restart is not needed
|
||||
Anchor['glance::config::begin'] -> Glance_cache_config<||> -> Anchor['glance::config::end']
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
# == Class: glance::property_protection
|
||||
#
|
||||
# Configure property protection
|
||||
#
|
||||
# === Parameters
|
||||
#
|
||||
# [*property_protection_rule_format*]
|
||||
# (Optional) Rule format for property protection.
|
||||
# Defaults to undef
|
||||
#
|
||||
# [*rules*]
|
||||
# (Optional) Property protection rules
|
||||
# Defaults to undef
|
||||
#
|
||||
# [*purge_config*]
|
||||
# (Optional) Whether to set only the specified config options
|
||||
# in the property protections config.
|
||||
# Defaults to false.
|
||||
#
|
||||
class glance::property_protection(
|
||||
Optional[Enum['roles', 'policies']] $property_protection_rule_format = undef,
|
||||
Hash[String[1], Hash] $rules = {},
|
||||
Boolean $purge_config = false,
|
||||
) {
|
||||
|
||||
include glance::deps
|
||||
include glance::params
|
||||
|
||||
resources { 'glance_property_protections_config':
|
||||
purge => $purge_config,
|
||||
}
|
||||
|
||||
case $property_protection_rule_format {
|
||||
'roles', 'policies': {
|
||||
glance_api_config {
|
||||
'DEFAULT/property_protection_file': value => '/etc/glance/property-protections.conf';
|
||||
'DEFAULT/property_protection_rule_format': value => $property_protection_rule_format;
|
||||
}
|
||||
|
||||
# NOTE(tkajinam): property-protections.conf is not installed by
|
||||
# the packages so create the file in advance.
|
||||
file { '/etc/glance/property-protections.conf':
|
||||
ensure => 'file',
|
||||
owner => 'root',
|
||||
group => $::glance::params::group,
|
||||
mode => '0640',
|
||||
require => Anchor['glance::config::begin'],
|
||||
notify => Anchor['glance::config::end'],
|
||||
}
|
||||
|
||||
$rules.each |$key, $value| {
|
||||
$value_override = $value['value'] ? {
|
||||
undef => {},
|
||||
default => {'value' => join(any2array($value['value']), ',')},
|
||||
}
|
||||
|
||||
create_resources(
|
||||
'glance_property_protections_config',
|
||||
{ $key => merge($value, $value_override)}
|
||||
)
|
||||
}
|
||||
|
||||
File['/etc/glance/property-protections.conf'] -> Glance_property_protections_config<||>
|
||||
}
|
||||
default: {
|
||||
glance_api_config {
|
||||
'DEFAULT/property_protection_file': value => $facts['os_service_default'];
|
||||
'DEFAULT/property_protection_rule_format': value => $facts['os_service_default'];
|
||||
}
|
||||
|
||||
file { '/etc/glance/property-protections.conf':
|
||||
ensure => absent,
|
||||
require => Anchor['glance::config::begin'],
|
||||
notify => Anchor['glance::config::end'],
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
features:
|
||||
- |
|
||||
The new ``glance::property_protections`` class has been added. This class
|
||||
allows configuration of the image property protections feature.
|
|
@ -14,6 +14,7 @@ describe 'basic glance config resource' do
|
|||
File <||> -> Glance_swift_config <||>
|
||||
File <||> -> Glance_api_paste_ini <||>
|
||||
File <||> -> Glance_rootwrap_config <||>
|
||||
File <||> -> Glance_property_protections_config <||>
|
||||
|
||||
file { '/etc/glance' :
|
||||
ensure => directory,
|
||||
|
@ -33,6 +34,9 @@ describe 'basic glance config resource' do
|
|||
file { '/etc/glance/rootwrap.conf' :
|
||||
ensure => file,
|
||||
}
|
||||
file { '/etc/glance/property-protections.conf' :
|
||||
ensure => file,
|
||||
}
|
||||
|
||||
glance_api_config { 'DEFAULT/thisshouldexist' :
|
||||
value => 'foo',
|
||||
|
@ -154,6 +158,24 @@ describe 'basic glance config resource' do
|
|||
value => 'toto',
|
||||
ensure_absent_val => 'toto',
|
||||
}
|
||||
|
||||
glance_property_protections_config { 'DEFAULT/thisshouldexist' :
|
||||
value => 'foo',
|
||||
}
|
||||
|
||||
glance_property_protections_config { 'DEFAULT/thisshouldnotexist' :
|
||||
value => '<SERVICE DEFAULT>',
|
||||
}
|
||||
|
||||
glance_property_protections_config { 'DEFAULT/thisshouldexist2' :
|
||||
value => '<SERVICE DEFAULT>',
|
||||
ensure_absent_val => 'toto',
|
||||
}
|
||||
|
||||
glance_property_protections_config { 'DEFAULT/thisshouldnotexist2' :
|
||||
value => 'toto',
|
||||
ensure_absent_val => 'toto',
|
||||
}
|
||||
EOS
|
||||
|
||||
|
||||
|
@ -232,5 +254,16 @@ describe 'basic glance config resource' do
|
|||
it { is_expected.not_to match /thisshouldnotexist/ }
|
||||
end
|
||||
end
|
||||
|
||||
describe file('/etc/glance/property-protections.conf') do
|
||||
it { is_expected.to exist }
|
||||
it { is_expected.to contain('thisshouldexist=foo') }
|
||||
it { is_expected.to contain('thisshouldexist2=<SERVICE DEFAULT>') }
|
||||
|
||||
describe '#content' do
|
||||
subject { super().content }
|
||||
it { is_expected.not_to match /thisshouldnotexist/ }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe 'glance::property_protection' do
|
||||
shared_examples 'glance::property_protection' do
|
||||
|
||||
context 'with defaults' do
|
||||
it 'configures the property protection parameters' do
|
||||
is_expected.to contain_glance_api_config('DEFAULT/property_protection_file')
|
||||
.with_value('<SERVICE DEFAULT>')
|
||||
is_expected.to contain_glance_api_config('DEFAULT/property_protection_rule_format')
|
||||
.with_value('<SERVICE DEFAULT>')
|
||||
end
|
||||
|
||||
it 'shoul remove the property protection config file' do
|
||||
is_expected.to contain_file('/etc/glance/property-protections.conf').with(
|
||||
:ensure => 'absent',
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with parameters (policies format)' do
|
||||
let :params do
|
||||
{
|
||||
:property_protection_rule_format => 'policies',
|
||||
:rules => {
|
||||
'^x_.*/create' => { 'value' => 'default' },
|
||||
'^x_.*/read' => { 'value' => 'default' },
|
||||
'^x_.*/update' => { 'value' => 'default' },
|
||||
'^x_.*/delete' => { 'value' => 'default' },
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
it 'configures the property protection parameters' do
|
||||
is_expected.to contain_glance_api_config('DEFAULT/property_protection_file')
|
||||
.with_value('/etc/glance/property-protections.conf')
|
||||
is_expected.to contain_glance_api_config('DEFAULT/property_protection_rule_format')
|
||||
.with_value('policies')
|
||||
end
|
||||
|
||||
it 'should configure the property protection config file' do
|
||||
is_expected.to contain_file('/etc/glance/property-protections.conf').with(
|
||||
:ensure => 'file',
|
||||
:owner => 'root',
|
||||
:group => 'glance',
|
||||
:mode => '0640',
|
||||
)
|
||||
is_expected.to contain_glance_property_protections_config('^x_.*/create')
|
||||
.with_value('default')
|
||||
is_expected.to contain_glance_property_protections_config('^x_.*/read')
|
||||
.with_value('default')
|
||||
is_expected.to contain_glance_property_protections_config('^x_.*/update')
|
||||
.with_value('default')
|
||||
is_expected.to contain_glance_property_protections_config('^x_.*/delete')
|
||||
.with_value('default')
|
||||
end
|
||||
end
|
||||
|
||||
context 'with parameters (roles format)' do
|
||||
let :params do
|
||||
{
|
||||
:property_protection_rule_format => 'roles',
|
||||
:rules => {
|
||||
'^x_.*/create' => { 'value' => ['admin', 'member', '_member_'] },
|
||||
'^x_.*/read' => { 'value' => ['admin', 'member', '_member_'] },
|
||||
'^x_.*/update' => { 'value' => ['admin', 'member', '_member_'] },
|
||||
'^x_.*/delete' => { 'value' => ['admin', 'member', '_member_'] },
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
it 'configures the property protection parameters' do
|
||||
is_expected.to contain_glance_api_config('DEFAULT/property_protection_file')
|
||||
.with_value('/etc/glance/property-protections.conf')
|
||||
is_expected.to contain_glance_api_config('DEFAULT/property_protection_rule_format')
|
||||
.with_value('roles')
|
||||
end
|
||||
|
||||
it 'should configure the property protection config file' do
|
||||
is_expected.to contain_file('/etc/glance/property-protections.conf').with(
|
||||
:ensure => 'file',
|
||||
:owner => 'root',
|
||||
:group => 'glance',
|
||||
:mode => '0640',
|
||||
)
|
||||
is_expected.to contain_glance_property_protections_config('^x_.*/create')
|
||||
.with_value('admin,member,_member_')
|
||||
is_expected.to contain_glance_property_protections_config('^x_.*/read')
|
||||
.with_value('admin,member,_member_')
|
||||
is_expected.to contain_glance_property_protections_config('^x_.*/update')
|
||||
.with_value('admin,member,_member_')
|
||||
is_expected.to contain_glance_property_protections_config('^x_.*/delete')
|
||||
.with_value('admin,member,_member_')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
on_supported_os({
|
||||
:supported_os => OSDefaults.get_supported_os
|
||||
}).each do |os,facts|
|
||||
context "on #{os}" do
|
||||
let (:facts) do
|
||||
facts.merge!(OSDefaults.get_facts())
|
||||
end
|
||||
|
||||
it_behaves_like 'glance::property_protection'
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,41 @@
|
|||
require 'spec_helper'
|
||||
provider_class = Puppet::Type.type(:glance_property_protections_config).provider(:ini_setting)
|
||||
describe provider_class do
|
||||
|
||||
it 'should default to the default setting when no other one is specified' do
|
||||
resource = Puppet::Type::Glance_property_protections_config.new(
|
||||
{:name => 'DEFAULT/foo', :value => 'bar'}
|
||||
)
|
||||
provider = provider_class.new(resource)
|
||||
expect(provider.section).to eq('DEFAULT')
|
||||
expect(provider.setting).to eq('foo')
|
||||
end
|
||||
|
||||
it 'should allow setting to be set explicitly' do
|
||||
resource = Puppet::Type::Glance_property_protections_config.new(
|
||||
{:name => 'dude/foo', :value => 'bar'}
|
||||
)
|
||||
provider = provider_class.new(resource)
|
||||
expect(provider.section).to eq('dude')
|
||||
expect(provider.setting).to eq('foo')
|
||||
end
|
||||
|
||||
it 'should ensure absent when <SERVICE DEFAULT> is specified as a value' do
|
||||
resource = Puppet::Type::Glance_property_protections_config.new(
|
||||
{:name => 'dude/foo', :value => '<SERVICE DEFAULT>'}
|
||||
)
|
||||
provider = provider_class.new(resource)
|
||||
provider.exists?
|
||||
expect(resource[:ensure]).to eq :absent
|
||||
end
|
||||
|
||||
it 'should ensure absent when value matches ensure_absent_val' do
|
||||
resource = Puppet::Type::Glance_property_protections_config.new(
|
||||
{:name => 'dude/foo', :value => 'foo', :ensure_absent_val => 'foo' }
|
||||
)
|
||||
provider = provider_class.new(resource)
|
||||
provider.exists?
|
||||
expect(resource[:ensure]).to eq :absent
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,64 @@
|
|||
require 'puppet'
|
||||
require 'puppet/type/glance_property_protections_config'
|
||||
|
||||
describe 'Puppet::Type.type(:glance_property_protections_config)' do
|
||||
before :each do
|
||||
@glance_property_protections_config = Puppet::Type.type(:glance_property_protections_config).new(:name => 'DEFAULT/foo', :value => 'bar')
|
||||
end
|
||||
|
||||
it 'should require a name' do
|
||||
expect {
|
||||
Puppet::Type.type(:glance_property_protections_config).new({})
|
||||
}.to raise_error(Puppet::Error, 'Title or name must be provided')
|
||||
end
|
||||
|
||||
it 'should not expect a name with whitespace' do
|
||||
expect {
|
||||
Puppet::Type.type(:glance_property_protections_config).new(:name => 'f oo')
|
||||
}.to raise_error(Puppet::Error, /Parameter name failed/)
|
||||
end
|
||||
|
||||
it 'should fail when there is no section' do
|
||||
expect {
|
||||
Puppet::Type.type(:glance_property_protections_config).new(:name => 'foo')
|
||||
}.to raise_error(Puppet::Error, /Parameter name failed/)
|
||||
end
|
||||
|
||||
it 'should not require a value when ensure is absent' do
|
||||
Puppet::Type.type(:glance_property_protections_config).new(:name => 'DEFAULT/foo', :ensure => :absent)
|
||||
end
|
||||
|
||||
it 'should accept a valid value' do
|
||||
@glance_property_protections_config[:value] = 'bar'
|
||||
expect(@glance_property_protections_config[:value]).to eq('bar')
|
||||
end
|
||||
|
||||
it 'should accept a value with whitespace' do
|
||||
@glance_property_protections_config[:value] = 'b ar'
|
||||
expect(@glance_property_protections_config[:value]).to eq('b ar')
|
||||
end
|
||||
|
||||
it 'should accept valid ensure values' do
|
||||
@glance_property_protections_config[:ensure] = :present
|
||||
expect(@glance_property_protections_config[:ensure]).to eq(:present)
|
||||
@glance_property_protections_config[:ensure] = :absent
|
||||
expect(@glance_property_protections_config[:ensure]).to eq(:absent)
|
||||
end
|
||||
|
||||
it 'should not accept invalid ensure values' do
|
||||
expect {
|
||||
@glance_property_protections_config[:ensure] = :latest
|
||||
}.to raise_error(Puppet::Error, /Invalid value/)
|
||||
end
|
||||
|
||||
it 'should autorequire the package that install the file' do
|
||||
catalog = Puppet::Resource::Catalog.new
|
||||
anchor = Puppet::Type.type(:anchor).new(:name => 'glance::install::end')
|
||||
catalog.add_resource anchor, @glance_property_protections_config
|
||||
dependency = @glance_property_protections_config.autorequire
|
||||
expect(dependency.size).to eq(1)
|
||||
expect(dependency[0].target).to eq(@glance_property_protections_config)
|
||||
expect(dependency[0].source).to eq(anchor)
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in New Issue