Icinga / icinga-powershell-framework

This PowerShell module will allow to fetch data from Windows hosts and use them for inventory and monitoring solutions. Together with the Icinga Web 2 module, a detailed overview of your Windows infrastructure will be drawn.
MIT License
78 stars 33 forks source link

Creating own module with 'New-IcingaForWindowsComponent' - module don't load correctly #577

Open stevie-sy opened 2 years ago

stevie-sy commented 2 years ago

After upgrading and testing 1.10. I have to do some adjustment to ower own module to be also more compatible to (our own) icinga repo. So I tried the (new) command New-IcingaForWindowsComponent to create a new module skeleton.

After editing the skelleton, the the module loads only 'Import-IcingaPowerShellComponent___' no own functions.

So I compared the docs, the plugin-module and the own module and I found following diffrences:

This means there is a discrepancy between the documentation, the result of function New-IcingaForWindowsComponent and the plugin module.

LordHepipud commented 2 years ago

Hello,

Thank you for the issue and the details. I will have a closer look on the description and the details. In general, all you need to do is the following:

Create a new component:

 New-IcingaForWindowsComponent -Name 'custom_plugin'

This will create the project as intended. Once done, you can start adding your own providers and plugins code for example and publish the module afterwards:

Publish-IcingaForWindowsComponent -Name 'custom_plugin'

This will update the .psd1 file with all functions which should be available in the public space and reset the plugin cache file to the default state. Functions either placed inside a public or the plugin folder as well as functions with the Global: flag are exported to a new PowerShell instance and should be callable.

LordHepipud commented 2 years ago

After some digging through the docs I know where the confusing part starts. The NestedModules variable does not need to be changed anymore, as it will hard-link the cache file which contains all later code. I will review and update the entire docs to explain this properly and enforce the dev tools more for easier usability.

stevie-sy commented 2 years ago

sounds goods. But pls control also the cache file. After running the new-IcingaForWindowsComponent-cmdlet, into the cache file is written an empty function (in the docs I didn't found anything what to do with it). So nothing is loaded after importing the module. If I copy the code of the cache file from plugin-module everything is fine.

But what I see yesterday and today the Publish-IcingaForWindowsComponent-cmdlet overwrite this cache file again with the content of an empty function. If I correct it again and run the import-module-cmdlet, the cache file has the same content like after creating the module skellton - an empty function. For me this is something weird.

LordHepipud commented 2 years ago

You don't need to copy anything manually. The module handler will create an empty function Import-IcingaPowerShellComponent<modulename>

This function is just present to ensure that once Icinga for Windows loads, all modules and dependencies are present. There is no need to add code into this function or do something with this. It is just for internal handling.

Once a plugin function is added to the plugins function or a provider, you require to publish the module with Publish-IcingaForWindowsComponent -Name '<component name>'to update the .psd1 and reset the cache file.

Once you start a new PowerShell and execute a module function, the cache is created and the function is executed, as long as the function is exported publicly.

You can also use

icinga {
# Your code to test
} -DeveloperMode:

to always reset the cache and rebuild it, to instantly apply changes.

stevie-sy commented 2 years ago

I debugged Publish-IcingaForWindowsComponent a little bit and noticed a very strange behavior. But I found the issue. I will described it and helps you.

First of all I defined the required modules like this:

RequiredModules   = @(
        @{ ModuleName = 'icinga-powershell-framework'; ModuleVersion = '1.10.0'; }
    )

Publish-IcingaForWindowsComponent is doing this:

RequiredModules   = @(
        @{ ModuleName = 'icinga-powershell-framework'; ModuleVersion = '1.7.0'; }
    )

same with the the FunctionToExport-Array. From this

FunctionsToExport     = @(
        'Import-IcingaPowerShellComponent__',
        'Invoke-IcingaCheck__',
        'Invoke-IcingaCheck__',
        'Invoke-IcingaCheck__',
    )

Publish-IcingaForWindowsComponent is doing this:

FunctionsToExport     = @(
        'Import-IcingaPowerShellComponent__'
    )

So I ran every code line manually. The funny thing $ManifestContent = Get-Content -Path $ModuleManifest; had the correct file content. But during foreach loop happens something weird, that the content has changed like written above. Why? It's incomprehensible.

It looks like PowerShell had some old information (like the empty module skeleton) in the memory. So the cmdlet generates a wrong manifest and some files were missing in the ZIP. Somehow the problem solved itself. After running the code multiple times, the content of $ManifestScript was correct. So also the Manfifest- and CodeCache files.

So maybe at the beginning of the function should be something like Import-Module $ModuleName -force to be save?

danopt commented 2 years ago

ref/NC/762829

LordHepipud commented 2 years ago

Have you placed the .psm1 files for the plugins inside the plugins folder or used Global:Invoke-IcingaCheck to make them available for the public?

I tried to duplicate your results without any luck. The publish function, manifest writer and dependencies work as expected in my environments.