Skip to content

Commit

Permalink
Merge pull request voxpupuli#399 from spacedog/cs_rsc_defaults_pcs_pr…
Browse files Browse the repository at this point in the history
…ovider

Add pcs provider for cs_rsc_defaults type
  • Loading branch information
roidelapluie authored Apr 9, 2017
2 parents 075aa47 + 7372e65 commit 527cda5
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 1 deletion.
2 changes: 1 addition & 1 deletion .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ Style/EmptyLiteral:
Metrics/LineLength:
Enabled: False

Style/MethodCallParentheses:
Style/MethodCallWithoutArgsParentheses:
Enabled: True

Style/MethodDefParentheses:
Expand Down
87 changes: 87 additions & 0 deletions lib/puppet/provider/cs_rsc_defaults/pcs.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
begin
require 'puppet_x/voxpupuli/corosync/provider/pcs'
rescue LoadError
require 'pathname' # WORKAROUND #14073, #7788 and SERVER-973
corosync = Puppet::Module.find('corosync', Puppet[:environment].to_s)
raise(LoadError, "Unable to find corosync module in modulepath #{Puppet[:basemodulepath] || Puppet[:modulepath]}") unless corosync
require File.join corosync.path, 'lib/puppet_x/voxpupuli/corosync/provider/pcs'
end

Puppet::Type.type(:cs_rsc_defaults).provide(:pcs, parent: PuppetX::Voxpupuli::Corosync::Provider::Pcs) do
desc 'Specific provider for a rather specific type since I currently have no plan to
abstract corosync/pacemaker vs. keepalived. This provider will check the state
of Corosync global defaults for resource options.'

defaultfor operatingsystem: [:fedora, :centos, :redhat]

# Path to the pcs binary for interacting with the cluster configuration.
commands pcs: 'pcs'

def self.instances
block_until_ready

instances = []

cmd = [command(:pcs), 'cluster', 'cib']
raw, = PuppetX::Voxpupuli::Corosync::Provider::Pcs.run_command_in_cib(cmd)
doc = REXML::Document.new(raw)

REXML::XPath.each(doc, '//configuration/rsc_defaults/meta_attributes/nvpair') do |e|
items = e.attributes
rsc_defaults = { name: items['name'], value: items['value'] }

rsc_defaults_instance = {
name: rsc_defaults[:name],
ensure: :present,
value: rsc_defaults[:value],
provider: name
}
instances << new(rsc_defaults_instance)
end
instances
end

# Create just adds our resource to the property_hash and flush will take care
# of actually doing the work.
def create
@property_hash = {
name: @resource[:name],
ensure: :present,
value: @resource[:value]
}
end

# Unlike create we actually immediately delete the item.
def destroy
debug('Removing resource default')
cmd = [command(:pcs), 'resource', 'defaults', (@property_hash[:name]).to_s + '=']
PuppetX::Voxpupuli::Corosync::Provider::Pcs.run_command_in_cib(cmd, @resource[:cib])
@property_hash.clear
end

# Getters that obtains the first and second primitives and score in our
# ordering definintion that have been populated by prefetch or instances
# (depends on if your using puppet resource or not).
def value
@property_hash[:value]
end

# Our setters for the first and second primitives and score. Setters are
# used when the resource already exists so we just update the current value
# in the property hash and doing this marks it to be flushed.
def value=(should)
@property_hash[:value] = should
end

# Flush is triggered on anything that has been detected as being
# modified in the property_hash. It generates a temporary file with
# the updates that need to be made. The temporary file is then used
# as stdin for the pcs command.
def flush
return if @property_hash.empty?
# clear this on properties, in case it's set from a previous
# run of a different corosync type
cmd = [command(:pcs), 'resource', 'defaults', "#{@property_hash[:name]}=#{@property_hash[:value]}"]
PuppetX::Voxpupuli::Corosync::Provider::Pcs.run_command_in_cib(cmd, @resource[:cib])
end
end
47 changes: 47 additions & 0 deletions spec/unit/puppet/provider/cs_rsc_defaults_pcs_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
require 'spec_helper'

describe Puppet::Type.type(:cs_rsc_defaults).provider(:pcs) do
include_context 'pcs'

context 'when getting instances' do
let :instances do
cib = <<-EOS
<cib>
<configuration>
<rsc_defaults>
<meta_attributes id="rsc-options">
<nvpair id="rsc-options-resource-stickiness" name="resource-stickiness" value="INFINITY"/>
<nvpair id="rsc-options-migration-threshold" name="migration-threshold" value="1"/>
</meta_attributes>
</rsc_defaults>
</configuration>
</cib>
EOS

pcs_load_cib(cib)
described_class.instances
end

it 'has an instance for each <nvpair> in <cluster_property_set>' do
expect(instances.count).to eq(2)
end

describe 'each instance' do
let :instance do
instances.first
end

it "is a kind of #{described_class.name}" do
expect(instance).to be_a_kind_of(described_class)
end

it "is named by the <nvpair>'s name attribute" do
expect(instance.name).to eq('resource-stickiness')
end

it "has a value corresponding to the <nvpair>'s value attribute" do
expect(instance.value).to eq('INFINITY')
end
end
end
end

0 comments on commit 527cda5

Please sign in to comment.