Skip to content

Commit

Permalink
(PE-19049,PE-11353) Ensure puppet service is stopped in 2017.1+ builds
Browse files Browse the repository at this point in the history
We began managing the puppet service in 2017.1.0 and need to ensure it
is stopped and disabled after installation, otherwise each subsequent
puppet agent run will restart the agent service, causing potential havoc
in smoke tests or other setup steps.
  • Loading branch information
jpartlow committed Feb 23, 2017
1 parent 7154c00 commit ed5d149
Show file tree
Hide file tree
Showing 2 changed files with 173 additions and 0 deletions.
104 changes: 104 additions & 0 deletions lib/beaker-pe/install/pe_utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ module PEUtils
# PE-18718 switch flag to true once beaker-pe, beaker-answers,
# beaker-pe-large-environments and pe_acceptance_tests are ready
DEFAULT_MEEP_CLASSIFICATION = false
MEEP_DATA_DIR = '/etc/puppetlabs/enterprise'
PE_CONF_FILE = "#{MEEP_DATA_DIR}/conf.d/pe.conf"

# @!macro [new] common_opts
# @param [Hash{Symbol=>String}] opts Options to alter execution.
Expand Down Expand Up @@ -507,6 +509,11 @@ def do_install hosts, opts = {}
on dashboard, "/opt/puppet/bin/rake -sf /opt/puppet/share/puppet-dashboard/Rakefile #{task} RAILS_ENV=production"
end

# PE-18799 replace the version_is_less with a use_meep_for_classification? test
if !version_is_less(master[:pe_ver], '2017.1.0')
configure_puppet_agent_service(:ensure => 'stopped', :enabled => false)
end

step "Final puppet agent run" do
# Now that all hosts are in the dashbaord, run puppet one more
# time to configure mcollective
Expand Down Expand Up @@ -1112,6 +1119,103 @@ def get_console_dispatcher_for_beaker_pe(raise_exception = false)
def get_console_dispatcher_for_beaker_pe!
get_console_dispatcher_for_beaker_pe(true)
end

# In PE versions >= 2017.1.0, allows you to configure the puppet agent
# service for all nodes.
#
# @param parameters [Hash] - agent profile parameters
# @option parameters [Boolean] :managed - whether or not to manage the
# agent resource at all (Optional, defaults to true).
# @option parameters [String] :ensure - 'stopped', 'running'
# @option parameters [Boolean] :enabled - whether the service will be
# enabled (for restarts)
# @raise [StandardError] if master version is less than 2017.1.0
def configure_puppet_agent_service(parameters)
raise(StandardError, "Can only manage puppet service in PE versions >= 2017.1.0; tried for #{master['pe_ver']}") if version_is_less(master['pe_ver'], '2017.1.0')
puppet_managed = parameters.include?(:managed) ? parameters[:managed] : true
puppet_ensure = parameters[:ensure]
puppet_enabled = parameters[:enabled]

msg = puppet_managed ?
"Configure agents '#{puppet_ensure}' and #{puppet_enabled ? 'enabled' : 'disabled'}" :
"Do not manage agents"

step msg do
# PE-18799 and remove this conditional
if use_meep_for_classification?(master[:pe_ver], options)
group_name = 'Puppet Enterprise Agent'
class_name = 'pe_infrastructure::agent'
else
group_name = 'PE Agent'
class_name = 'puppet_enterprise::profile::agent'
end

# update pe conf
# only the pe_infrastructure::agent parameters are relevant in pe.conf
update_pe_conf({
"pe_infrastructure::agent::puppet_service_managed" => puppet_managed,
"pe_infrastructure::agent::puppet_service_ensure" => puppet_ensure,
"pe_infrastructure::agent::puppet_service_enabled" => puppet_enabled,
})

if _console_dispatcher = get_console_dispatcher_for_beaker_pe
agent_group = _console_dispatcher.get_node_group_by_name(group_name)
agent_class = agent_group['classes'][class_name]
agent_class['puppet_service_managed'] = puppet_managed
agent_class['puppet_service_ensure'] = puppet_ensure
agent_class['puppet_service_enabled'] = puppet_enabled

_console_dispatcher.update_node_group(agent_group['id'], agent_group)
end
end
end

# Given a hash of parameters, updates the primary master's pe.conf, adding or
# replacing the given parameters.
#
# Handles stringifying and quoting namespaced keys, and also preparing non
# string values using Hocon::ConfigValueFactory.
#
# Logs the state of pe.conf before and after.
#
# @param parameters [Hash] Hash of parameters to be included in pe.conf.
# @param pe_conf_file [String] The file to update
# (/etc/puppetlabs/enterprise/conf.d/pe.conf by default)
def update_pe_conf(parameters, pe_conf_file = PE_CONF_FILE)
step "Update #{pe_conf_file} with #{parameters}" do
hocon_file_edit_in_place_on(master, pe_conf_file) do |host,doc|
updated_doc = parameters.reduce(doc) do |pe_conf,param|
key, value = param

hocon_key = case key
when /^[^"][^.]+/
# if the key is unquoted and does not contain pathing ('.')
# quote to ensure that puppet namespaces are protected
# ("puppet_enterprise::database_host" for example...)
then %Q{"#{key}"}
else key
end

hocon_value = case value
when String
# ensure unquoted string values are quoted for uniformity
then value.match(/^[^"]/) ? %Q{"#{value}"} : value
else Hocon::ConfigValueFactory.from_any_ref(value, nil)
end

updated = value.kind_of?(String) ?
pe_conf.set_value(hocon_key, hocon_value) :
pe_conf.set_config_value(hocon_key, hocon_value)

updated
end

# return the modified document
updated_doc
end
on(master, 'cat /etc/puppetlabs/enterprise/conf.d/pe.conf')
end
end
end
end
end
Expand Down
69 changes: 69 additions & 0 deletions spec/beaker-pe/install/pe_utils_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1611,4 +1611,73 @@ def test_setup(mock_values)
)
end
end

describe 'configure_puppet_agent_service' do
let(:pe_version) { '2017.1.0' }
let(:master) { hosts[0] }

before(:each) do
hosts.each { |h| h[:pe_ver] = pe_version }
allow( subject ).to receive( :hosts ).and_return( hosts )
end

it 'requires parameters' do
expect { subject.configure_puppet_agent_service }.to raise_error(ArgumentError, /wrong number/)
end

context 'master prior to 2017.1.0' do
let(:pe_version) { '2016.5.1' }

it 'raises an exception about version' do
expect { subject.configure_puppet_agent_service({}) }.to(
raise_error(StandardError, /Can only manage.*2017.1.0; tried.* 2016.5.1/)
)
end
end

context '2017.1.0 master' do
let(:pe_conf_path) { '/etc/puppetlabs/enterprise/conf.d/pe.conf' }
let(:pe_conf) do
<<-EOF
"node_roles": {
"pe_role::monolithic::primary_master": ["#{master.name}"],
}
EOF
end
let(:gold_pe_conf) do
<<-EOF
"node_roles": {
"pe_role::monolithic::primary_master": ["#{master.name}"],
}
"pe_infrastructure::agent::puppet_service_managed": true
"pe_infrastructure::agent::puppet_service_ensure": "stopped"
"pe_infrastructure::agent::puppet_service_enabled": false
EOF
end

it do
# mock reading pe.conf
expect(master).to receive(:exec).with(
have_attributes(:command => match(%r{cat .*/pe\.conf})),
anything
).and_return(
double('result', :stdout => pe_conf)
)

# mock hitting the console
dispatcher = double('dispatcher').as_null_object
expect(subject).to receive(:get_console_dispatcher_for_beaker_pe)
.and_return(dispatcher)

# mock writing pe.conf and check for parameters
expect(subject).to receive(:create_remote_file).with(
master,
pe_conf_path,
gold_pe_conf
)

subject.configure_puppet_agent_service(:ensure => 'stopped', :enabled => false)
end
end
end
end

0 comments on commit ed5d149

Please sign in to comment.