chef/cookbooks/cpe_chefclient/resources/cpe_chefctl.rb (91 lines of code) (raw):
#
# Cookbook:: cpe_chefclient
# Resources:: cpe_chefclient
#
# vim: syntax=ruby:expandtab:shiftwidth=2:softtabstop=2:tabstop=2
#
# Copyright:: (c) 2019-present, Uber Technologies, Inc.
# All rights reserved.
#
# This source code is licensed under the Apache 2.0 license found in the
# LICENSE file in the root directory of this source tree.
#
unified_mode true
resource_name :cpe_chefclient
provides :cpe_chefclient, :os => ['darwin', 'linux', 'windows']
default_action :manage
action :manage do
configure if configure? && !unmanage?
unmanage if unmanage?
end
action_class do # rubocop:disable Metrics/BlockLength
def configure?
node['cpe_chefclient']['configure']
end
def unmanage?
node['cpe_chefclient']['unmanage']
end
def configure
configs = node['cpe_chefclient']['config'].to_hash
configs_to_manage = []
chef_path = node['cpe_chefclient']['path']
chef_run_list = node['cpe_chefclient']['run_list'].to_hash
configs.each do |conf_name, conf|
chef = conf.key?('chef') ? conf['chef'].compact : {}
ohai = conf.key?('ohai') ? conf['ohai'].compact : {}
## This should work even if only one has contents
next if chef.empty? && ohai.empty?
config_path = ::File.join(
chef_path,
"#{conf_name}.rb",
)
# Lay down config for this config version
template config_path do
source 'client.rb.erb'
variables(
'chef' => chef,
'ohai' => ohai,
)
end
configs_to_manage << config_path
end
config_json = ::File.join(chef_path, '.cpe_chefclient.json')
cleanup(configs_to_manage, config_json)
update_json_file(configs_to_manage, config_json)
# Lay down the run-list
unless chef_run_list.nil? || chef_run_list.empty?
run_list_json = ::File.join(chef_path, 'run-list.json')
update_json_file(chef_run_list, run_list_json)
end
end
def unmanage
config_json = ::File.join(
node['cpe_chefclient']['path'],
'.cpe_chefclient.json',
)
configs_to_manage = [] # Unmanage, so remove all existing configs
cleanup(configs_to_manage, config_json) if ::File.exist?(config_json)
file config_json do
path config_json # In case it is a symlink
action :delete
end
run_list_json = ::File.join(
node['cpe_chefclient']['path'],
'run-list.json',
)
file run_list_json do
path run_list_json # In case it is a symlink
action :delete
end
end
def cleanup(configs_to_manage, json_path)
current_managed_configs = []
# Parse the current json and see which files were installed last run
if ::File.exists?(json_path)
current_managed_configs = Chef::JSONCompat.parse(::File.read(json_path))
else
Chef::Log.warn('cpe_chefclient cannot find JSON or track/process files')
return
end
# Loop through the managed files from last chef run
current_managed_configs.each do |managed_config|
# If file is not in our new list of items to manage, we need to delete it
unless configs_to_manage.include?(managed_config)
file managed_config do
path managed_config # In case it is a symlink
action :delete
end
end
end
end
def update_json_file(configs_to_manage, json_path)
# Update our json file (if needed) with the new contents of our items
file json_path do
mode '0644' unless windows?
owner root_owner unless windows?
group node['root_group'] unless windows?
content Chef::JSONCompat.to_json_pretty(configs_to_manage)
end
end
end