Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

win_nssm AppEnvironmentExtra support #31748

Closed
wants to merge 12 commits into from
111 changes: 111 additions & 0 deletions lib/ansible/modules/windows/win_nssm.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ $appParameters = Get-AnsibleParam -obj $params -name "app_parameters" -type "str
$appParametersFree = Get-AnsibleParam -obj $params -name "app_parameters_free_form" -type "str"
$startMode = Get-AnsibleParam -obj $params -name "start_mode" -type "str" -default "auto" -validateset "auto","manual","disabled" -resultobj $result

$appEnvironmentExtra = Get-AnsibleParam -obj $params -name "environment" -type "dict" -default @{}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a few things on this;

  • It is preferable to use the same name as the parameter, makes it easier to see what is happening
  • An FYI, there is no dict so it is technically not doing anything but nice to see how the module is expecting data
  • I would remove the default value so that it is $null if not set. Currently you have no way of knowing when someone wants an empty environment $var = @{} or whether they don't care what the current setting it $null. It would require some further work below but we do need to make the distinction.


$stdoutFile = Get-AnsibleParam -obj $params -name "stdout_file" -type "str"
$stderrFile = Get-AnsibleParam -obj $params -name "stderr_file" -type "str"
$dependencies = Get-AnsibleParam -obj $params -name "dependencies" -type "str"
Expand Down Expand Up @@ -482,6 +484,114 @@ Function Nssm-Update-Dependencies
}
}

Function Convert-Hash
{
<#
Convert a hash into a variable length string of KEY=VALUE seperated by spaces

Input:
{
key1: value1,
key2: value2
}

Output:
"key1=value1 key2=value2"
#>
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
[hashtable]$hash
)

return ($hash.GetEnumerator() | % { "$($_.Key)=$($_.Value)" }) -join " "
}

Function Convert-Array-to-Hash
{
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
[array]$array
)

$hash = @{}

foreach ($element in $array)
{
$hash = $hash + (ConvertFrom-StringData $element)
}
return $hash
}

Function Nssm-Update-Extra-Environment
{
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
[string]$name,
[Parameter(Mandatory=$true)]
[hashtable]$env_vars
)

$env_vars_string = Convert-Hash $env_vars

$cmd = "get ""$name"" AppEnvironmentExtra"
$results = Nssm-Invoke $cmd

if ($LastExitCode -ne 0)
{
$result.nssm_error_cmd = $cmd
$result.nssm_error_log = "$results"
Throw "Error updating environment variables for service ""$name"""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would change the error message to be more in line with what you are trying to do (get current env vars).

}

$current_env_vars = Convert-Array-to-Hash $results

<#
Update the appEnvironmentExtra values if:
- The services current environment variables does not match the desired environment variables.
- env_vars is not an empty hashtable
#>
If (((Convert-Hash $env_vars) -ne (Convert-Hash $current_env_vars)) -and ($env_vars.Count -gt 0))
{
$cmd = "set ""$name"" AppEnvironmentExtra ""$env_vars_string"""
$results = Nssm-Invoke $cmd

if ($LastExitCode -ne 0)
{
$result.nssm_error_cmd = $cmd
$result.nssm_error_log = "$results"
Throw "Error updating environment variables for service ""$name"""
}

$result.changed_by = "update-environment"
$result.previous_environment = (Convert-Hash $current_env_vars)
$result.changed = $true
}

<#
Reset appEnvironmentExtra if there are currently environment variables in the service, but
none were passed to the function.
#>
If (($current_env_vars.Count -ne 0 ) -and ($env_vars.Count -eq 0))
{
$cmd = "reset ""$name"" AppEnvironmentExtra"
$results = Nssm-Invoke $cmd

if ($LastExitCode -ne 0)
{
$result.nssm_error_cmd = $cmd
$result.nssm_error_log = "$results"
Throw "Error updating environment variables for service ""$name"""
}

$result.changed_by = "update-environment"
$result.previous_environment = $current_env_vars
$result.changed = $true
}
}

Function Nssm-Update-StartMode
{
[CmdletBinding()]
Expand Down Expand Up @@ -665,6 +775,7 @@ Function NssmProcedure
Nssm-Update-Dependencies -name $name -dependencies $dependencies
Nssm-Update-Credentials -name $name -user $user -password $password
Nssm-Update-StartMode -name $name -mode $startMode
Nssm-Update-Extra-Environment -name $name -env_vars $appEnvironmentExtra
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You would probably only run this if $appEnvironmentExtra is not $null

}

Try
Expand Down
4 changes: 4 additions & 0 deletions lib/ansible/modules/windows/win_nssm.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@
- auto
- manual
- disabled
environment:
version_added: "2.5.0"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should just be the major.minor, e.g. 2.5

description:
- Add extra environemnt variables to the service's default environment
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs a full stop at the end. Would also be good to see an example of how to use this.

author:
- "Adam Keech (@smadam813)"
- "George Frank (@georgefrank)"
Expand Down