puppetlabs / ruby-pwsh

A ruby gem for interacting with PowerShell
MIT License
15 stars 21 forks source link

Dsc resources parameters should be case insensitive #254

Closed Clebam closed 10 months ago

Clebam commented 11 months ago

Describe the Bug

Here is an error message I have from DSC

Error: Failed to apply catalog: Parameter dsc_ensure failed on Dsc_xwebapppool[test_site.fr]: dsc_xwebapppool.dsc_ensure expects an undef value or a match for Enum['Absent', 'Present'], got 'present'

We can see the resource fails to apply because the enum expects a capitalized Present

Expected Behavior

The casing should not matter.

Whether 'present' or 'Present' is provided should be accepted. At least when dealing with enforced values (like Enum)

  1. 'present' is provided
  2. dsc_base_provider compares to Enum entries case_insensitively ('present' -imatch 'Present')
  3. Then converts to the expected casing ('present' becomes 'Present')
  4. Then delivers 'Present' is provided to the resource

Steps to Reproduce

Steps to reproduce the behavior: Set ensure: present (all downcased)

Environment

Additional Context

gavindidrichsen commented 11 months ago

Hi @Clebam. Thanks for submitting this issue.

To help me replicate this on my Windows test server, can you please include some sample code? If relevant, could you send some code snippets:

What Windows version are you running the above on?

Many thanks,

Clebam commented 11 months ago

Hi @gavindidrichsen,

This would fail

  dsc_xwebapppool { 'my_pool':
    dsc_ensure                => 'present',
    dsc_state                 => 'started',
    dsc_enable32bitapponwin64 => false,
    dsc_managedpipelinemode   => 'integrated',
    dsc_managedruntimeversion => 'v4.0',
  }

This would run (notice both 'Present' and 'Started' and 'Integrated' were upcased)

  dsc_xwebapppool { 'my_pool':
    dsc_ensure                => 'Present',
    dsc_state                 => 'Started',
    dsc_enable32bitapponwin64 => false,
    dsc_managedpipelinemode   => 'Integrated',
    dsc_managedruntimeversion => 'v4.0',
  }

Running on windows 2019 (but would be similar on other version)

The whole issue is linked to the fact that upon conversion from .ps1 file to puppet resource, the casing of Enum is preserved.

Clebam commented 11 months ago

I can find this comment that concerns this issue : https://github.com/puppetlabs/ruby-pwsh/blob/main/lib/puppet/provider/dsc_base_provider/dsc_base_provider.rb#L86

Edit : Found this PR : https://github.com/puppetlabs/ruby-pwsh/pull/131

It seems to purposefully exclude enum from matching insensitively.

Is there a good reason for this ?

Thanks

Clebam commented 11 months ago

I learned about validation_mode => 'resource', parameter. Setting this to resource prevents the issue from happening.

Though, it updates each params when one of them is changed. (that is the expected behavior of validation_mode)

I wonder if the issue still needs to stay opened of if the definitive answer to this type of problems is the validation_mode

Clebam commented 11 months ago

Well it appears validation_mode slows down a lot the resource.

I experience the casing issue on every resource (for instance fordsc_ensure => 'present', every resource will have this kind of constant changes

For 30ish windowsfeatures.
time with validation_mode (and dsc_ensure => 'present') : 45s
time without validation_mode (and dsc_ensure => 'Present') : 0.5s
Notice: /Stage[main]/Sw_iis::Features::Default/Dsc_windowsfeature[Web-Windows-Auth]/dsc_ensure: dsc_ensure changed 'Present' to 'present' (corrective)
Notice: dsc_windowsfeature[{:name=>"Web-Windows-Auth", :dsc_name=>"Web-Windows-Auth"}]: Updating: Finished in 1.18 seconds
Clebam commented 11 months ago

Hi, there is one thing I would like to figure out. Does every one using pwshlib face the "casing" issue (like 'Present' != 'present) ? Everything let me think it should work (ie the casing should not matter):

Therefore I really think it may be something from my environment. But I would like some confirmation that it does work as intented for everyone. I tried to dig for a few days in my env without finding anything that would explain the issue I'm facing. But if I have the confirmation it definitely should work, I'll keep digging. (For now, I don't know if it's a bug, a feature or my env 😓)

jordanbreen28 commented 10 months ago

@Clebam thanks for raising this. Closing as per discussion https://puppetcommunity.slack.com/archives/CFD8Z9A4T/p1696342031154069.

Root cause was use of the deprecated and unmaintained dsc_xWebAdministration module, which has problems in the underlying dsc module code. Use of the favoured dsc_webadministrationdsc module resolved this issue. Action items are on us to update the badging of these modules on the forge ASAP to reflect their status.

Thanks again!

jesusvila commented 7 months ago

Also we have problems updating iis site certificates. (Creating sites works perfectly) In previous versions (Server 2016 and Puppet 6), it works perfectly, but now in Server 2022 and Puppet 8, it is not working. We are using dsc-webadministrationdsc (v4.1.0-0-5). The following code is the one causing the error upon execution:

dsc_website{ $title:
    dsc_ensure => 'Present',
    dsc_name => "${prefixSiteName}${title}",
    dsc_state => 'Started',
    dsc_physicalpath => "${webRootFolder}\\${title}",
    dsc_logpath => $logPath,
    dsc_applicationpool => $title,
    dsc_bindinginfo => [{
        protocol => 'http',
        port => 80,
        bindinginformation => "*:80",
        hostname => $title,
    },{
        protocol => 'https',
        port => 443,
        bindinginformation => "*:443",
        hostname => $title,
        certificatestorename => 'My',   # <------------- here 
        certificatethumbprint => $certificateHash,
        sslflags => '1'
    }]
}
Could not evaluate: Provider returned data that does not match the Type Schema for `dsc_website[xxx.site.com]`
(index 0 entry 'certificatestorename' expects an undef value or a match for Enum['My', 'WebHosting', 'my', 'webhosting'], got 'MY')

if we edit this file /etc/puppetlabs/code/environments/production/modules/webadministrationdsc/lib/puppet/type/dsc_website.rb and modify this line:

dsc_bindinginfo: {
      type: "Optional[Array[Struct[{
              sslflags => Optional[Enum['0', '1', '2', '3']],
              certificatestorename => Optional[Enum['MY', 'My', 'my', 'WebHosting', 'webhosting']],

and in the enum we add 'MY' it works perfectly.