-
Notifications
You must be signed in to change notification settings - Fork 177
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
In order to explicitly manage sections of an ini file regardless of their content, we introduce a new ini_section type. This make it possible to remove a whole section of an ini file, regardless of its content: ```puppet ini_section { 'remove puppet.conf agent section': ensure => abent, path => '/etc/puppetlabs/puppet/puppet.conf', section => 'agent', } ``` Just like the ini_setting type, ini_section can be subclassed: ```puppet puppet_config { 'remove agent section': ensure => abent, section => 'agent', } ``` Fixes #524
- Loading branch information
Showing
9 changed files
with
637 additions
and
5 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
# frozen_string_literal: true | ||
|
||
require File.expand_path('../../util/ini_file', __dir__) | ||
|
||
Puppet::Type.type(:ini_section).provide(:ruby) do | ||
def self.instances | ||
desc ' | ||
Creates new ini_section file, a specific config file with a provider that uses | ||
this as its parent and implements the method | ||
self.file_path, and that will provide the value for the path to the | ||
ini file.' | ||
raise(Puppet::Error, 'Ini_section only support collecting instances when a file path is hard coded') unless respond_to?(:file_path) | ||
|
||
# figure out what to do about the seperator | ||
ini_file = Puppet::Util::IniFile.new(file_path, '=') | ||
resources = [] | ||
ini_file.section_names.each do |section_name| | ||
next if section_name.empty? | ||
resources.push( | ||
new( | ||
name: namevar(section_name), | ||
ensure: :present, | ||
), | ||
) | ||
end | ||
resources | ||
end | ||
|
||
def self.namevar(section_name) | ||
section_name | ||
end | ||
|
||
def exists? | ||
ini_file.section_names.include?(section) | ||
end | ||
|
||
def create | ||
ini_file.set_value(section) | ||
ini_file.save | ||
@ini_file = nil | ||
end | ||
|
||
def destroy | ||
ini_file.remove_section(section) | ||
ini_file.save | ||
@ini_file = nil | ||
end | ||
|
||
def file_path | ||
# this method is here to support purging and sub-classing. | ||
# if a user creates a type and subclasses our provider and provides a | ||
# 'file_path' method, then they don't have to specify the | ||
# path as a parameter for every ini_section declaration. | ||
# This implementation allows us to support that while still | ||
# falling back to the parameter value when necessary. | ||
if self.class.respond_to?(:file_path) | ||
self.class.file_path | ||
else | ||
resource[:path] | ||
end | ||
end | ||
|
||
def section | ||
# this method is here so that it can be overridden by a child provider | ||
resource[:section] | ||
end | ||
|
||
def section_prefix | ||
if resource.class.validattr?(:section_prefix) | ||
resource[:section_prefix] || '[' | ||
else | ||
'[' | ||
end | ||
end | ||
|
||
def section_suffix | ||
if resource.class.validattr?(:section_suffix) | ||
resource[:section_suffix] || ']' | ||
else | ||
']' | ||
end | ||
end | ||
|
||
private | ||
|
||
def ini_file | ||
@ini_file ||= Puppet::Util::IniFile.new(file_path, '=', section_prefix, section_suffix, ' ', 2) | ||
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,52 @@ | ||
# frozen_string_literal: true | ||
|
||
Puppet::Type.newtype(:ini_section) do | ||
desc 'ini_section is used to manage a single section in an INI file' | ||
ensurable do | ||
desc 'Ensurable method handles modeling creation. It creates an ensure property' | ||
newvalue(:present) do | ||
provider.create | ||
end | ||
newvalue(:absent) do | ||
provider.destroy | ||
end | ||
def insync?(current) | ||
if @resource[:refreshonly] | ||
true | ||
else | ||
current == should | ||
end | ||
end | ||
defaultto :present | ||
end | ||
|
||
newparam(:name, namevar: true) do | ||
desc 'An arbitrary name used as the identity of the resource.' | ||
end | ||
|
||
newparam(:section) do | ||
desc 'The name of the section in the ini file which should be managed.' | ||
defaultto('') | ||
end | ||
|
||
newparam(:path) do | ||
desc 'The ini file Puppet will ensure contains the specified section.' | ||
validate do |value| | ||
raise(Puppet::Error, _("File paths must be fully qualified, not '%{value}'") % { value: value }) unless Puppet::Util.absolute_path?(value) | ||
end | ||
end | ||
|
||
newparam(:section_prefix) do | ||
desc 'The prefix to the section name\'s header.' | ||
defaultto('[') | ||
end | ||
|
||
newparam(:section_suffix) do | ||
desc 'The suffix to the section name\'s header.' | ||
defaultto(']') | ||
end | ||
|
||
autorequire(:file) do | ||
Pathname.new(self[:path]).parent.to_s | ||
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
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
12 changes: 12 additions & 0 deletions
12
spec/fixtures/inherit_ini_section/lib/puppet/provider/inherit_ini_section/ini_section.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,12 @@ | ||
Puppet::Type.type(:inherit_ini_section).provide( | ||
:ini_section, | ||
parent: Puppet::Type.type(:ini_section).provider(:ruby), | ||
) do | ||
def self.namevar(section) | ||
section | ||
end | ||
|
||
def self.file_path | ||
File.expand_path(File.dirname(__FILE__) + '/../../../../../../tmp/inherit_inifile.cfg') | ||
end | ||
end |
5 changes: 5 additions & 0 deletions
5
spec/fixtures/inherit_ini_section/lib/puppet/type/inherit_ini_section.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,5 @@ | ||
Puppet::Type.newtype(:inherit_ini_section) do | ||
ensurable | ||
newparam(:section, namevar: true) | ||
newproperty(:value) | ||
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,63 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'spec_helper' | ||
|
||
# This is a reduced version of ruby_spec.rb just to ensure we can subclass as | ||
# documented | ||
$LOAD_PATH << './spec/fixtures/inherit_ini_section/lib' | ||
|
||
describe Puppet::Type.type(:inherit_ini_section).provider(:ini_section) do | ||
include PuppetlabsSpec::Files | ||
|
||
let(:tmpfile) { tmpfilename('inherit_ini_section_test') } | ||
|
||
def validate_file(expected_content, tmpfile) | ||
expect(File.read(tmpfile)).to eq(expected_content) | ||
end | ||
|
||
before :each do | ||
File.write(tmpfile, orig_content) | ||
end | ||
|
||
context 'when calling instances' do | ||
let(:orig_content) { '' } | ||
|
||
it 'parses nothing when the file is empty' do | ||
allow(described_class).to receive(:file_path).and_return(tmpfile) | ||
expect(described_class.instances).to eq([]) | ||
end | ||
|
||
context 'when the file has contents' do | ||
let(:orig_content) do | ||
<<-INIFILE | ||
[red] | ||
# A comment | ||
red = blue | ||
[green] | ||
green = purple | ||
INIFILE | ||
end | ||
|
||
it 'parses the results' do | ||
allow(described_class).to receive(:file_path).and_return(tmpfile) | ||
instances = described_class.instances | ||
expect(instances.size).to eq(2) | ||
# inherited version of namevar flattens the names | ||
names = instances.map do |instance| instance.instance_variable_get(:@property_hash)[:name] end # rubocop:disable Style/BlockDelimiters | ||
expect(names.sort).to eq(['green', 'red']) | ||
end | ||
end | ||
end | ||
|
||
context 'when ensuring that a setting is present' do | ||
let(:orig_content) { '' } | ||
|
||
it 'adds a value to the file' do | ||
allow(described_class).to receive(:file_path).and_return(tmpfile) | ||
resource = Puppet::Type::Inherit_ini_section.new(section: 'set_this') | ||
provider = described_class.new(resource) | ||
provider.create | ||
expect(validate_file("[set_this]\n", tmpfile)).to be_truthy | ||
end | ||
end | ||
end |
Oops, something went wrong.