144 lines
4.0 KiB
Ruby
144 lines
4.0 KiB
Ruby
|
|
require 'chef/mixin/shell_out'
|
|
require 'fileutils'
|
|
include Chef::Mixin::ShellOut
|
|
|
|
def load_current_resource
|
|
find_fmri unless new_resource.fmri
|
|
|
|
@current_resource = Chef::Resource::Smf.new(new_resource.name)
|
|
@current_resource.fmri(new_resource.fmri)
|
|
@current_resource.load
|
|
end
|
|
|
|
action :install do
|
|
create_directories
|
|
write_manifest
|
|
create_rbac_definitions
|
|
import_manifest
|
|
deduplicate_manifest
|
|
add_rbac_permissions
|
|
|
|
new_resource.updated_by_last_action(smf_changed?)
|
|
new_resource.save_checksum if smf_changed?
|
|
end
|
|
|
|
action :add_rbac do
|
|
create_rbac_definitions
|
|
service new_resource.name
|
|
|
|
manage = execute "add SMF authorization to allow RBAC for #{new_resource.name}" do
|
|
command "svccfg -s #{new_resource.name} " \
|
|
'setprop general/action_authorization=astring:' \
|
|
"'solaris.smf.manage.#{new_resource.authorization_name}'"
|
|
not_if { SMFManifest::RBACHelper.new(node, new_resource).authorization_set? }
|
|
notifies :reload, "service[#{new_resource.name}]"
|
|
end
|
|
|
|
value = execute "add SMF value to allow RBAC for #{new_resource.name}" do
|
|
command "svccfg -s #{new_resource.name} " \
|
|
'setprop general/value_authorization=astring: ' \
|
|
'solaris.smf.value.#{new_resource.authorization_name}'
|
|
not_if { SMFManifest::RBACHelper.new(node, new_resource).value_authorization_set? }
|
|
notifies :reload, "service[#{new_resource.name}]"
|
|
end
|
|
|
|
new_resource.updated_by_last_action(manage.updated_by_last_action? || value.updated_by_last_action?)
|
|
end
|
|
|
|
action :delete do
|
|
new_resource.updated_by_last_action(false)
|
|
|
|
if @current_resource.smf_exists?
|
|
service new_resource.name do
|
|
action [:stop, :disable]
|
|
end
|
|
|
|
execute "remove service #{new_resource.name} from SMF" do
|
|
command "svccfg delete #{new_resource.name}"
|
|
end
|
|
|
|
delete_manifest
|
|
new_resource.remove_checksum
|
|
|
|
new_resource.updated_by_last_action(true)
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def smf_changed?
|
|
@current_resource.checksum != new_resource.checksum || !@current_resource.smf_exists?
|
|
end
|
|
|
|
def find_fmri
|
|
fmri_check = shell_out(%(svcs -H -o FMRI #{new_resource.name}))
|
|
if fmri_check.exitstatus == 0
|
|
new_resource.fmri fmri_check.stdout.chomp.split(':')[1]
|
|
else
|
|
new_resource.fmri "/#{new_resource.manifest_type}/management/#{new_resource.name}"
|
|
end
|
|
end
|
|
|
|
def create_directories
|
|
Chef::Log.debug "Creating manifest directory at #{new_resource.xml_path}"
|
|
FileUtils.mkdir_p new_resource.xml_path
|
|
end
|
|
|
|
def write_manifest
|
|
return unless smf_changed?
|
|
|
|
Chef::Log.debug "Writing SMF manifest for #{new_resource.name}"
|
|
::File.open(new_resource.xml_file, 'w') do |file|
|
|
file.puts SMFManifest::XMLBuilder.new(new_resource, node).to_xml
|
|
end
|
|
end
|
|
|
|
def delete_manifest
|
|
return unless ::File.exist?(new_resource.xml_file)
|
|
|
|
Chef::Log.debug "Removing SMF manifest for #{new_resource.name}"
|
|
::File.delete(new_resource.xml_file)
|
|
end
|
|
|
|
def create_rbac_definitions
|
|
rbac new_resource.authorization_name do
|
|
action :create
|
|
end
|
|
end
|
|
|
|
def add_rbac_permissions
|
|
user = new_resource.user || new_resource.credentials_user || 'root'
|
|
|
|
rbac_auth "Add RBAC for #{new_resource.name} to #{user}" do
|
|
user user
|
|
auth new_resource.authorization_name
|
|
not_if { user == 'root' }
|
|
end
|
|
end
|
|
|
|
def import_manifest
|
|
return unless smf_changed?
|
|
|
|
Chef::Log.debug("importing SMF manifest #{new_resource.xml_file}")
|
|
shell_out!("svccfg import #{new_resource.xml_file}")
|
|
end
|
|
|
|
def deduplicate_manifest
|
|
# If we are overwriting properties from an old SMF definition (from pkgsrc, etc)
|
|
# there may be redundant XML files that we want to dereference
|
|
name = new_resource.name
|
|
|
|
duplicate_manifest = shell_out("svcprop #{name} | grep -c manifestfiles").stdout.strip.to_i > 1
|
|
return unless duplicate_manifest
|
|
|
|
Chef::Log.debug "Removing duplicate SMF manifest reference from #{name}"
|
|
shell_out! "svccfg -s #{name} delprop " \
|
|
"`svcprop #{name} | grep manifestfiles | grep -v #{new_resource.xml_file} | awk '{ print $1 }'` " \
|
|
"&& svcadm refresh #{name}"
|
|
end
|
|
|
|
def smf_defined?(fmri)
|
|
shell_out("svcs #{fmri}").exitstatus == 0
|
|
end
|