diff --git a/lib/puppet/provider/exec/windows.rb b/lib/puppet/provider/exec/windows.rb index 9ce29f12b..367b30bcc 100644 --- a/lib/puppet/provider/exec/windows.rb +++ b/lib/puppet/provider/exec/windows.rb @@ -1,35 +1,35 @@ require 'puppet/provider/exec' Puppet::Type.type(:exec).provide :windows, :parent => Puppet::Provider::Exec do include Puppet::Util::Execution - confine :feature => :microsoft_windows - defaultfor :feature => :microsoft_windows + confine :operatingsystem => :windows + defaultfor :operatingsystem => :windows desc "Execute external binaries directly, on Windows systems. This does not pass through a shell, or perform any interpolation, but only directly calls the command with the arguments given." # Verify that we have the executable def checkexe(command) exe = extractexe(command) if absolute_path?(exe) if !File.exists?(exe) raise ArgumentError, "Could not find command '#{exe}'" elsif !File.file?(exe) raise ArgumentError, "'#{exe}' is a #{File.ftype(exe)}, not a file" end return end path = resource[:path] || [] exts = [".exe", ".ps1", ".bat", ".com", ""] withenv :PATH => path.join(File::PATH_SEPARATOR) do return if exts.any? {|ext| which(exe + ext) } end raise ArgumentError, "Could not find command '#{exe}'" end end diff --git a/lib/puppet/provider/file/windows.rb b/lib/puppet/provider/file/windows.rb index d71e7d43c..5a7b9adf5 100644 --- a/lib/puppet/provider/file/windows.rb +++ b/lib/puppet/provider/file/windows.rb @@ -1,100 +1,100 @@ Puppet::Type.type(:file).provide :windows do desc "Uses Microsoft Windows functionality to manage file's users and rights." - confine :feature => :microsoft_windows + confine :operatingsystem => :windows include Puppet::Util::Warnings if Puppet.features.microsoft_windows? require 'puppet/util/windows' require 'puppet/util/adsi' include Puppet::Util::Windows::Security end ERROR_INVALID_SID_STRUCTURE = 1337 def id2name(id) # If it's a valid sid, get the name. Otherwise, it's already a name, so # just return it. begin if string_to_sid_ptr(id) name = nil Puppet::Util::ADSI.execquery( "SELECT Name FROM Win32_Account WHERE SID = '#{id}' AND LocalAccount = true" ).each { |a| name ||= a.name } return name end rescue Puppet::Util::Windows::Error => e raise unless e.code == ERROR_INVALID_SID_STRUCTURE end id end # Determine if the account is valid, and if so, return the UID def name2id(value) # If it's a valid sid, then return it. Else, it's a name we need to convert # to sid. begin return value if string_to_sid_ptr(value) rescue Puppet::Util::Windows::Error => e raise unless e.code == ERROR_INVALID_SID_STRUCTURE end Puppet::Util::ADSI.sid_for_account(value) rescue nil end # We use users and groups interchangeably, so use the same methods for both # (the type expects different methods, so we have to oblige). alias :uid2name :id2name alias :gid2name :id2name alias :name2gid :name2id alias :name2uid :name2id def owner return :absent unless resource.exist? get_owner(resource[:path]) end def owner=(should) begin set_owner(should, resource[:path]) rescue => detail raise Puppet::Error, "Failed to set owner to '#{should}': #{detail}" end end def group return :absent unless resource.exist? get_group(resource[:path]) end def group=(should) begin set_group(should, resource[:path]) rescue => detail raise Puppet::Error, "Failed to set group to '#{should}': #{detail}" end end def mode if resource.exist? get_mode(resource[:path]).to_s(8) else :absent end end def mode=(value) begin set_mode(value.to_i(8), resource[:path]) rescue => detail error = Puppet::Error.new("failed to set mode #{mode} on #{resource[:path]}: #{detail.message}") error.set_backtrace detail.backtrace raise error end :file_changed end end diff --git a/lib/puppet/provider/group/windows_adsi.rb b/lib/puppet/provider/group/windows_adsi.rb index 4ddc83bc1..83dd00b29 100644 --- a/lib/puppet/provider/group/windows_adsi.rb +++ b/lib/puppet/provider/group/windows_adsi.rb @@ -1,55 +1,54 @@ require 'puppet/util/adsi' Puppet::Type.type(:group).provide :windows_adsi do desc "Group management for Windows" defaultfor :operatingsystem => :windows - confine :operatingsystem => :windows - confine :feature => :microsoft_windows + confine :operatingsystem => :windows has_features :manages_members def group @group ||= Puppet::Util::ADSI::Group.new(@resource[:name]) end def members group.members end def members=(members) group.set_members(members) end def create @group = Puppet::Util::ADSI::Group.create(@resource[:name]) @group.commit self.members = @resource[:members] end def exists? Puppet::Util::ADSI::Group.exists?(@resource[:name]) end def delete Puppet::Util::ADSI::Group.delete(@resource[:name]) end # Only flush if we created or modified a group, not deleted def flush @group.commit if @group end def gid Puppet::Util::ADSI.sid_for_account(@resource[:name]) end def gid=(value) fail "gid is read-only" end def self.instances Puppet::Util::ADSI::Group.map { |g| new(:ensure => :present, :name => g.name) } end end diff --git a/lib/puppet/provider/service/windows.rb b/lib/puppet/provider/service/windows.rb index 289be697a..162dc8381 100644 --- a/lib/puppet/provider/service/windows.rb +++ b/lib/puppet/provider/service/windows.rb @@ -1,110 +1,110 @@ # Windows Service Control Manager (SCM) provider require 'win32/service' if Puppet.features.microsoft_windows? Puppet::Type.type(:service).provide :windows do desc "Support for Windows Service Control Manager (SCM). Services are controlled according to win32-service gem. * All SCM operations (start/stop/enable/disable/query) are supported. * Control of service groups (dependencies) is not yet supported." defaultfor :operatingsystem => :windows - confine :operatingsystem => :windows + confine :operatingsystem => :windows has_feature :refreshable def enable w32ss = Win32::Service.configure( 'service_name' => @resource[:name], 'start_type' => Win32::Service::SERVICE_AUTO_START ) raise Puppet::Error.new("Win32 service enable of #{@resource[:name]} failed" ) if( w32ss.nil? ) rescue Win32::Service::Error => detail raise Puppet::Error.new("Cannot enable #{@resource[:name]}, error was: #{detail}" ) end def disable w32ss = Win32::Service.configure( 'service_name' => @resource[:name], 'start_type' => Win32::Service::SERVICE_DISABLED ) raise Puppet::Error.new("Win32 service disable of #{@resource[:name]} failed" ) if( w32ss.nil? ) rescue Win32::Service::Error => detail raise Puppet::Error.new("Cannot disable #{@resource[:name]}, error was: #{detail}" ) end def manual_start w32ss = Win32::Service.configure( 'service_name' => @resource[:name], 'start_type' => Win32::Service::SERVICE_DEMAND_START ) raise Puppet::Error.new("Win32 service manual enable of #{@resource[:name]} failed" ) if( w32ss.nil? ) rescue Win32::Service::Error => detail raise Puppet::Error.new("Cannot enable #{@resource[:name]} for manual start, error was: #{detail}" ) end def enabled? w32ss = Win32::Service.config_info( @resource[:name] ) raise Puppet::Error.new("Win32 service query of #{@resource[:name]} failed" ) unless( !w32ss.nil? && w32ss.instance_of?( Struct::ServiceConfigInfo ) ) debug("Service #{@resource[:name]} start type is #{w32ss.start_type}") case w32ss.start_type when Win32::Service.get_start_type(Win32::Service::SERVICE_AUTO_START), Win32::Service.get_start_type(Win32::Service::SERVICE_BOOT_START), Win32::Service.get_start_type(Win32::Service::SERVICE_SYSTEM_START) :true when Win32::Service.get_start_type(Win32::Service::SERVICE_DEMAND_START) :manual when Win32::Service.get_start_type(Win32::Service::SERVICE_DISABLED) :false else raise Puppet::Error.new("Unknown start type: #{w32ss.start_type}") end rescue Win32::Service::Error => detail raise Puppet::Error.new("Cannot get start type for #{@resource[:name]}, error was: #{detail}" ) end def start if enabled? == :false # If disabled and not managing enable, respect disabled and fail. if @resource[:enable].nil? raise Puppet::Error, "Will not start disabled service #{@resource[:name]} without managing enable. Specify 'enable => false' to override." # Otherwise start. If enable => false, we will later sync enable and # disable the service again. elsif @resource[:enable] == :true enable else manual_start end end Win32::Service.start( @resource[:name] ) rescue Win32::Service::Error => detail raise Puppet::Error.new("Cannot start #{@resource[:name]}, error was: #{detail}" ) end def stop Win32::Service.stop( @resource[:name] ) rescue Win32::Service::Error => detail raise Puppet::Error.new("Cannot stop #{@resource[:name]}, error was: #{detail}" ) end def restart self.stop self.start end def status w32ss = Win32::Service.status( @resource[:name] ) raise Puppet::Error.new("Win32 service query of #{@resource[:name]} failed" ) unless( !w32ss.nil? && w32ss.instance_of?( Struct::ServiceStatus ) ) state = case w32ss.current_state when "stopped", "pause pending", "stop pending", "paused" then :stopped when "running", "continue pending", "start pending" then :running else raise Puppet::Error.new("Unknown service state '#{w32ss.current_state}' for service '#{@resource[:name]}'") end debug("Service #{@resource[:name]} is #{w32ss.current_state}") return state rescue Win32::Service::Error => detail raise Puppet::Error.new("Cannot get status of #{@resource[:name]}, error was: #{detail}" ) end # returns all providers for all existing services and startup state def self.instances Win32::Service.services.collect { |s| new(:name => s.service_name) } end end diff --git a/lib/puppet/provider/user/windows_adsi.rb b/lib/puppet/provider/user/windows_adsi.rb index 1470e17b2..3a5c716b7 100644 --- a/lib/puppet/provider/user/windows_adsi.rb +++ b/lib/puppet/provider/user/windows_adsi.rb @@ -1,88 +1,87 @@ require 'puppet/util/adsi' Puppet::Type.type(:user).provide :windows_adsi do desc "User management for Windows" defaultfor :operatingsystem => :windows - confine :operatingsystem => :windows - confine :feature => :microsoft_windows + confine :operatingsystem => :windows has_features :manages_homedir, :manages_passwords def user @user ||= Puppet::Util::ADSI::User.new(@resource[:name]) end def groups user.groups.join(',') end def groups=(groups) user.set_groups(groups, @resource[:membership] == :minimum) end def create @user = Puppet::Util::ADSI::User.create(@resource[:name]) @user.commit [:comment, :home, :groups].each do |prop| send("#{prop}=", @resource[prop]) if @resource[prop] end end def exists? Puppet::Util::ADSI::User.exists?(@resource[:name]) end def delete Puppet::Util::ADSI::User.delete(@resource[:name]) end # Only flush if we created or modified a user, not deleted def flush @user.commit if @user end def comment user['Description'] end def comment=(value) user['Description'] = value end def home user['HomeDirectory'] end def home=(value) user['HomeDirectory'] = value end def password user.password_is?( @resource[:password] ) ? @resource[:password] : :absent end def password=(value) user.password = value end def uid Puppet::Util::ADSI.sid_for_account(@resource[:name]) end def uid=(value) fail "uid is read-only" end [:gid, :shell].each do |prop| define_method(prop) { nil } define_method("#{prop}=") do |v| fail "No support for managing property #{prop} of user #{@resource[:name]} on Windows" end end def self.instances Puppet::Util::ADSI::User.map { |u| new(:ensure => :present, :name => u.name) } end end