module Chef::Mixin::Securable::WindowsMacros
Defines methods for adding attributes to a chef resource to describe Windows file security metadata.
This module is meant to be used to extend a class (instead of ‘include`-ing). A class is automatically extended with this module when it includes WindowsSecurableAttributes
. @todo should this be separated into different files?
Public Instance Methods
“meta-method” for dynamically creating rights attributes on resources.
Multiple rights attributes can be declared. This enables resources to have multiple rights attributes with separate runtime states.
For example, Chef::Resource::RemoteDirectory
supports different rights on the directories and files by declaring separate rights attributes for each (rights and files_rights).
User
Level API¶ ↑
Given a resource that calls
rights_attribute(:rights)
Then the resource DSL
could be used like this:
rights :read, ["Administrators","Everyone"] rights :deny, "Pinky" rights :full_control, "Users", :applies_to_children => true rights :write, "John Keiser", :applies_to_children => :containers_only, :applies_to_self => false, :one_level_deep => true
Internal Data Structure¶ ↑
rights attributes support multiple right declarations in a single resource block–the data will be merged into a single internal hash.
The internal representation is a hash with the following keys:
-
‘:permissions`: Integer of Windows permissions flags, 1..2^32
or one of ‘[:full_control, :modify, :read_execute, :read, :write]`
-
‘:principals`:
String
or Array of Strings representing usernames on
the system.
-
‘:applies_to_children` (optional): Boolean
-
‘:applies_to_self` (optional): Boolean
-
‘:one_level_deep` (optional): Boolean
# File lib/chef/mixin/securable.rb, line 106 def rights_attribute(name) # equivalent to something like: # def rights(permissions=nil, principals=nil, args_hash=nil) define_method(name) do |permissions = nil, principals = nil, args_hash = nil| rights = instance_variable_get("@#{name}".to_sym) unless permissions.nil? input = { permissions: permissions, principals: principals, } input.merge!(args_hash) unless args_hash.nil? validations = { permissions: { required: true }, principals: { required: true, kind_of: [String, Array] }, applies_to_children: { equal_to: [ true, false, :containers_only, :objects_only ] }, applies_to_self: { kind_of: [ TrueClass, FalseClass ] }, one_level_deep: { kind_of: [ TrueClass, FalseClass ] }, } validate(input, validations) [ permissions ].flatten.each do |permission| if permission.is_a?(Integer) if permission < 0 || permission > 1 << 32 raise ArgumentError, "permissions flags must be positive and <= 32 bits (#{permission})" end elsif !(%i{full_control modify read_execute read write}.include?(permission.to_sym)) raise ArgumentError, "permissions property must be :full_control, :modify, :read_execute, :read, :write or an integer representing Windows permission flags" end end [ principals ].flatten.each do |principal| unless principal.is_a?(String) raise ArgumentError, "principals property must be a string or array of strings representing usernames" end end if input[:applies_to_children] == false if input[:applies_to_self] == false raise ArgumentError, "'rights' property must specify either :applies_to_children or :applies_to_self." end if input[:one_level_deep] == true raise ArgumentError, "'rights' property specified :one_level_deep without specifying :applies_to_children." end end rights ||= [] rights << input end set_or_return( name, rights, {} ) end end