support changing of attributes in primitives

This commit is contained in:
Adam Spiers 2014-01-21 19:09:44 +00:00
parent 54c66607a2
commit bcafd6ff31
2 changed files with 105 additions and 44 deletions

View File

@ -26,30 +26,15 @@ include Chef::Libraries::Pacemaker::CIBObjects
action :create do
name = new_resource.name
agent = new_resource.agent
next if cib_object_exists?(name)
cmd = "crm configure primitive #{name} #{agent}"
cmd << resource_params_string(new_resource.params)
cmd << resource_meta_string(new_resource.meta)
cmd << resource_op_string(new_resource.op)
# 'Execute' resource doesn't throw exception even when command fails..
# So, Mixlib::ShellOut was used instead.
cmd_ = Mixlib::ShellOut.new(cmd)
cmd_.environment['HOME'] = ENV.fetch('HOME', '/root')
cmd_.run_command
begin
cmd_.error!
if cib_object_exists?(name)
new_resource.updated_by_last_action(true)
Chef::Log.info "Successfully configured primitive '#{name}'."
else
Chef::Log.error "Failed to configure primitive #{name}."
if @current_resource_definition.nil?
create_resource(name)
else
if @current_resource.agent != new_resource.agent
raise "Existing primitive '#{name}' has agent but recipe wanted #{new_resource.agent}"
end
rescue
Chef::Log.error "Failed to configure primitive #{name}."
modify_resource(name)
end
end
@ -91,24 +76,68 @@ end
def load_current_resource
name = @new_resource.name
return unless cib_object_exists?(name)
obj_definition = get_cib_object_definition(name)
if obj_definition.nil?
raise "CIB object '#{name}' existed but definition was nil?!"
end
if obj_definition.empty?
return unless obj_definition
if obj_definition.empty? # probably overly paranoid
raise "CIB object '#{name}' existed but definition was empty?!"
end
return unless cib_object_type(obj_definition) =~ /\Aprimitive #{name} (\S+)/
unless obj_definition =~ /\Aprimitive #{name} (\S+)/
Chef::Log.warn "Resource '#{name}' was not a primitive"
return
end
agent = $1
@current_resource_definition = obj_definition
@current_resource = Chef::Resource::PacemakerPrimitive.new(name)
@current_resource.agent(agent)
%w(params meta op).each do |data_type|
extract_hash(obj_definition, data_type)
%w(params meta).each do |data_type|
h = extract_hash(name, obj_definition, data_type)
@current_resource.send(data_type.to_sym, h)
end
end
def create_resource(name)
cmd = "crm configure primitive #{name} #{new_resource.agent}"
cmd << resource_params_string(new_resource.params)
cmd << resource_meta_string(new_resource.meta)
cmd << resource_op_string(new_resource.op)
Chef::Log.debug "creating new primitive #{name} via #{cmd}"
execute cmd do
action :nothing
end.run_action(:run)
if cib_object_exists?(name)
new_resource.updated_by_last_action(true)
Chef::Log.info "Successfully configured primitive '#{name}'."
else
Chef::Log.error "Failed to configure primitive #{name}."
end
end
def modify_resource(name)
configure_cmd_prefix = "crm_resource --resource keystone"
cmds = []
new_resource.params.each do |k, v|
if @current_resource.params[k] == v
Chef::Log.debug("#{name}'s #{k} param didn't change")
else
Chef::Log.info("#{name}'s #{k} param changed to #{v}")
cmds << configure_cmd_prefix + " --set-parameter #{k} --parameter-value #{v}"
end
end
cmds.each do |cmd|
converge_by("execute #{cmd}") do
result = shell_out!(cmd)
Chef::Log.info("#{cmd} ran successfully")
end
end
new_resource.updated_by_last_action(true) unless cmds.empty?
end

View File

@ -4,13 +4,13 @@ require_relative File.join(%w(.. helpers keystone_config))
describe "Chef::Provider::PacemakerPrimitive" do
before do
@chef_run = ::ChefSpec::Runner.new(step_into: ['pacemaker_primitive']) #::OPENSUSE_OPTS
runner_opts = {
:step_into => ['pacemaker_primitive']
}
@chef_run = ::ChefSpec::Runner.new(runner_opts) #::OPENSUSE_OPTS
@chef_run.converge "pacemaker::default"
@node = @chef_run.node
@cookbook_collection = Chef::CookbookCollection.new([])
@events = Chef::EventDispatch::Dispatcher.new
@run_context = Chef::RunContext.new(@node, @cookbook_collection, @events)
@run_context = @chef_run.run_context
@resource = Chef::Resource::PacemakerPrimitive.new("keystone", @run_context)
@ -24,18 +24,50 @@ describe "Chef::Provider::PacemakerPrimitive" do
describe ":create action" do
let(:ra) { Chef::RSpec::Pacemaker::Config::RA }
it "should do nothing if the primitive already exists" do
it "should modify the primitive if it already exists" do
provider = Chef::Provider::PacemakerPrimitive.new(@resource, @run_context)
expect(provider).to receive(:cib_object_exists?).at_least(:once).and_return(true)
# get_cib_object_definition is invoked by load_current_resource
# and later used to see whether to create or modify.
expect(provider).to receive(:get_cib_object_definition).and_return(ra[:config])
expect(Mixlib::ShellOut).not_to receive(:new)
configure_cmd_prefix = "crm_resource --resource keystone"
expected_configure_cmd_args = [
"--set-parameter os_password --parameter-value newpasswd",
"--delete-parameter os_tenant_name",
"--set-parameter target-role --parameter-value Stopped --meta",
]
provider.run_action :create
expected_configure_cmd_args.each do |args|
cmd = configure_cmd_prefix + " " + args
expect(@chef_run).to run_execute(cmd)
end
expect(@resource).to be_updated
end
# it "should create a primitive" do
# pending "foo"
# @resource.run_action :create
# end
end
it "should create a primitive if it doesn't already exist" do
provider = Chef::Provider::PacemakerPrimitive.new(@resource, @run_context)
# get_cib_object_definition is invoked by load_current_resource
# and later used to see whether to create or modify.
expect(provider).to receive(:get_cib_object_definition).and_return(nil)
cmd = "crm configure primitive keystone #{ra[:agent]}" + \
ra[:params_string] + ra[:meta_string] + ra[:op_string]
# Later, the :create action calls cib_object_exists? to check
# that creation succeeded.
expect(provider).to receive(:cib_object_exists?).and_return(true)
provider.run_action :create
expect(@chef_run).to run_execute(cmd)
expect(@resource).to be_updated
end
it "should barf if the primitive has the wrong agent" do
pending "not implemented yet"
end
end
end