<commit_before>require 'pathname'
require 'json'
if Puppet::Util::Platform.windows?
  require_relative '../../../puppet_x/puppetlabs/powershell_manager'
  require_relative '../../../puppet_x/puppetlabs/compatible_powershell_version'
end

Puppet::Type.type(:base_dsc).provide(:powershell) do
  confine :operatingsystem => :windows
  defaultfor :operatingsystem => :windows

  commands :powershell =>
    if File.exists?("#{ENV['SYSTEMROOT']}\\sysnative\\WindowsPowershell\\v1.0\\powershell.exe")
      "#{ENV['SYSTEMROOT']}\\sysnative\\WindowsPowershell\\v1.0\\powershell.exe"
    elsif File.exists?("#{ENV['SYSTEMROOT']}\\system32\\WindowsPowershell\\v1.0\\powershell.exe")
      "#{ENV['SYSTEMROOT']}\\system32\\WindowsPowershell\\v1.0\\powershell.exe"
    else
      'powershell.exe'
    end

  desc <<-EOT
Applies DSC Resources by generating a configuration file and applying it.
EOT

  PUPPET_UPGRADE_MSG = <<-UPGRADE
  Currently, the dsc module has reduced functionality on this agent
  due to one or more of the following conditions:
  - Puppet 3.x (non-x64 version)
    Puppet 3.x uses a Ruby version that requires a library to support a colored
    console. Unfortunately this library prevents the PowerShell module from
    using a shared PowerShell process to dramatically improve the performance of
    resource application.
  To enable these improvements, it is suggested to upgrade to any x64 version of
  Puppet (including 3.x), or to a Puppet version newer than 3.x.
  UPGRADE

  POWERSHELL_UPGRADE_MSG = <<-UPGRADE
  Currently, the dsc module has reduced functionality on this agent
  due to one or more of the following conditions:
  - A PowerShell less than 5.0
    The dsc module requires PowerShell v5.0 or greater to function. THe cmdlet
    Invoke-DscResource was introduced in v5.0, and is necessary for the dsc module
    to work
  To enable these improvements, it is suggested to upgrade to any x64 version of
  Puppet (including 3.x), or to a Puppet version newer than 3.x and ensure you
  have at least PowerShell v5.0 installed.
  UPGRADE

  def self.upgrade_message
    Puppet.warning PUPPET_UPGRADE_MSG if !@upgrade_warning_issued
    @upgrade_warning_issued = true
  end

  def self.vendored_modules_path
    File.expand_path(Pathname.new(__FILE__).dirname + '../../../' + 'puppet_x/dsc_resources')
  end

  def dsc_parameters
    resource.parameters_with_value.select do |p|
      p.name.to_s =~ /dsc_/
    end
  end

  def self.template_path
    File.expand_path('../../templates', __FILE__)
  end

  def self.powershell_args
    ps_args = ['-NoProfile', '-NonInteractive', '-NoLogo', '-ExecutionPolicy', 'Bypass']
    ps_args << '-Command' if !PuppetX::Dsc::PowerShellManager.supported?
    ps_args
  end

  def ps_manager
    debug_output = Puppet::Util::Log.level == :debug
    manager_args = "#{command(:powershell)} #{self.class.powershell_args().join(' ')}"
    PuppetX::Dsc::PowerShellManager.instance(manager_args, debug_output)
  end

  COMMAND_TIMEOUT = 1200000 # 20 minutes

  def exists?
    version = Facter.value(:powershell_version)
    Puppet.debug "PowerShell Version: #{version}"
    script_content = ps_script_content('test')
    Puppet.debug "\n" + script_content
    
    fail POWERSHELL_UPGRADE_MSG if !PuppetX::Dsc::PowerShellManager.compatible_version_of_powershell?

    if !PuppetX::Dsc::PowerShellManager.supported?
      self.class.upgrade_message
      output = powershell(self.class.powershell_args, script_content)
    else
      output = ps_manager.execute(script_content, COMMAND_TIMEOUT)[:stdout]
    end
    Puppet.debug "Dsc Resource returned: #{output}"
    data = JSON.parse(output)
    fail(data['errormessage']) if !data['errormessage'].empty?
    exists = data['indesiredstate']
    Puppet.debug "Dsc Resource Exists?: #{exists}"
    Puppet.debug "dsc_ensure: #{resource[:dsc_ensure]}" if resource.parameters.has_key?(:dsc_ensure)
    Puppet.debug "ensure: #{resource[:ensure]}"
    exists
  end

  def create
    script_content = ps_script_content('set')
    Puppet.debug "\n" + script_content

    fail POWERSHELL_UPGRADE_MSG if !PuppetX::Dsc::PowerShellManager.compatible_version_of_powershell?

    if !PuppetX::Dsc::PowerShellManager.supported?
      self.class.upgrade_message
      output = powershell(self.class.powershell_args, script_content)
    else
      output = ps_manager.execute(script_content, COMMAND_TIMEOUT)[:stdout]
    end
    Puppet.debug "Create Dsc Resource returned: #{output}"
    data = JSON.parse(output)

    fail(data['errormessage']) if !data['errormessage'].empty?

    notify_reboot_pending if data['rebootrequired'] == true

    data
  end

  def destroy
    script_content = ps_script_content('set')
    Puppet.debug "\n" + script_content

    fail POWERSHELL_UPGRADE_MSG if !PuppetX::Dsc::PowerShellManager.compatible_version_of_powershell?

    if !PuppetX::Dsc::PowerShellManager.supported?
      self.class.upgrade_message
      output = powershell(self.class.powershell_args, script_content)
    else
      output = ps_manager.execute(script_content, COMMAND_TIMEOUT)[:stdout]<commit_msg>(MODULES-5224) Fix Global Warning variable<commit_after>require 'pathname'
require 'json'
if Puppet::Util::Platform.windows?
  require_relative '../../../puppet_x/puppetlabs/powershell_manager'
  require_relative '../../../puppet_x/puppetlabs/compatible_powershell_version'
end

Puppet::Type.type(:base_dsc).provide(:powershell) do
  confine :operatingsystem => :windows
  defaultfor :operatingsystem => :windows

  commands :powershell =>
    if File.exists?("#{ENV['SYSTEMROOT']}\\sysnative\\WindowsPowershell\\v1.0\\powershell.exe")
      "#{ENV['SYSTEMROOT']}\\sysnative\\WindowsPowershell\\v1.0\\powershell.exe"
    elsif File.exists?("#{ENV['SYSTEMROOT']}\\system32\\WindowsPowershell\\v1.0\\powershell.exe")
      "#{ENV['SYSTEMROOT']}\\system32\\WindowsPowershell\\v1.0\\powershell.exe"
    else
      'powershell.exe'
    end

  desc <<-EOT
Applies DSC Resources by generating a configuration file and applying it.
EOT

  PUPPET_UPGRADE_MSG = <<-UPGRADE
  Currently, the dsc module has reduced functionality on this agent
  due to one or more of the following conditions:
  - Puppet 3.x (non-x64 version)
    Puppet 3.x uses a Ruby version that requires a library to support a colored
    console. Unfortunately this library prevents the PowerShell module from
    using a shared PowerShell process to dramatically improve the performance of
    resource application.
  To enable these improvements, it is suggested to upgrade to any x64 version of
  Puppet (including 3.x), or to a Puppet version newer than 3.x.
  UPGRADE

  DSC_MODULE_POWERSHELL_UPGRADE_MSG = <<-UPGRADE
  Currently, the dsc module has reduced functionality on this agent
  due to one or more of the following conditions:
  - A PowerShell less than 5.0
    The dsc module requires PowerShell v5.0 or greater to function. THe cmdlet
    Invoke-DscResource was introduced in v5.0, and is necessary for the dsc module
    to work
  To enable these improvements, it is suggested to upgrade to any x64 version of
  Puppet (including 3.x), or to a Puppet version newer than 3.x and ensure you
  have at least PowerShell v5.0 installed.
  UPGRADE

  def self.upgrade_message
    Puppet.warning PUPPET_UPGRADE_MSG if !@upgrade_warning_issued
    @upgrade_warning_issued = true
  end

  def self.vendored_modules_path
    File.expand_path(Pathname.new(__FILE__).dirname + '../../../' + 'puppet_x/dsc_resources')
  end

  def dsc_parameters
    resource.parameters_with_value.select do |p|
      p.name.to_s =~ /dsc_/
    end
  end

  def self.template_path
    File.expand_path('../../templates', __FILE__)
  end

  def self.powershell_args
    ps_args = ['-NoProfile', '-NonInteractive', '-NoLogo', '-ExecutionPolicy', 'Bypass']
    ps_args << '-Command' if !PuppetX::Dsc::PowerShellManager.supported?
    ps_args
  end

  def ps_manager
    debug_output = Puppet::Util::Log.level == :debug
    manager_args = "#{command(:powershell)} #{self.class.powershell_args().join(' ')}"
    PuppetX::Dsc::PowerShellManager.instance(manager_args, debug_output)
  end

  COMMAND_TIMEOUT = 1200000 # 20 minutes

  def exists?
    version = Facter.value(:powershell_version)
    Puppet.debug "PowerShell Version: #{version}"
    script_content = ps_script_content('test')
    Puppet.debug "\n" + script_content
    
    fail DSC_MODULE_POWERSHELL_UPGRADE_MSG if !PuppetX::Dsc::PowerShellManager.compatible_version_of_powershell?

    if !PuppetX::Dsc::PowerShellManager.supported?
      self.class.upgrade_message
      output = powershell(self.class.powershell_args, script_content)
    else
      output = ps_manager.execute(script_content, COMMAND_TIMEOUT)[:stdout]
    end
    Puppet.debug "Dsc Resource returned: #{output}"
    data = JSON.parse(output)
    fail(data['errormessage']) if !data['errormessage'].empty?
    exists = data['indesiredstate']
    Puppet.debug "Dsc Resource Exists?: #{exists}"
    Puppet.debug "dsc_ensure: #{resource[:dsc_ensure]}" if resource.parameters.has_key?(:dsc_ensure)
    Puppet.debug "ensure: #{resource[:ensure]}"
    exists
  end

  def create
    script_content = ps_script_content('set')
    Puppet.debug "\n" + script_content

    fail DSC_MODULE_POWERSHELL_UPGRADE_MSG if !PuppetX::Dsc::PowerShellManager.compatible_version_of_powershell?

    if !PuppetX::Dsc::PowerShellManager.supported?
      self.class.upgrade_message
      output = powershell(self.class.powershell_args, script_content)
    else
      output = ps_manager.execute(script_content, COMMAND_TIMEOUT)[:stdout]
    end
    Puppet.debug "Create Dsc Resource returned: #{output}"
    data = JSON.parse(output)

    fail(data['errormessage']) if !data['errormessage'].empty?

    notify_reboot_pending if data['rebootrequired'] == true

    data
  end

  def destroy
    script_content = ps_script_content('set')
    Puppet.debug "\n" + script_content

    fail DSC_MODULE_POWERSHELL_UPGRADE_MSG if !PuppetX::Dsc::PowerShellManager.compatible_version_of_powershell?

    if !PuppetX::Dsc::PowerShellManager.supported?
      self.class.upgrade_message
      output = powershell(self.class.powershell_args, script_content)
    else
      output = ps_manager.execute(script_content, COMMAND_TIMEOUT)[:stdout]
{'fraction_non_alphanumeric': 0.10650714911000875, 'fraction_numerical': 0.008364945044256396, 'mean_word_length': 4.110337972166998, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1357544', 'n_tokens_mistral': 3446, 'n_tokens_neox': 3263, 'n_words': 783}