From 2decd1c765200344ab0d30c8f4274f23262cba07 Mon Sep 17 00:00:00 2001 From: Patrick Emery Date: Mon, 1 Apr 2024 05:47:23 -0400 Subject: [PATCH] Add support for epp templates with params --- README.md | 42 +++++++++++++++++++++++++++- REFERENCE.md | 11 +++++++- manifests/conf.pp | 27 ++++++++++++++++-- templates/multi_line_allocation.epp | 23 +++++++++++++++ templates/single_line_allocation.epp | 20 +++++++++++++ 5 files changed, 119 insertions(+), 4 deletions(-) create mode 100644 templates/multi_line_allocation.epp create mode 100644 templates/single_line_allocation.epp diff --git a/README.md b/README.md index c9a0b045..85f3071a 100644 --- a/README.md +++ b/README.md @@ -194,6 +194,45 @@ sudo::configs: 'template' : "mymodule/bill.erb" ``` +##### Using templates for sudo allocations +The `template` meta-parameter supports both erb and epp templates. If the filename specified as the template ends with ".epp" then the puppet `epp` function will be used to interpret the template. If the filename specified as the template does not end with ".epp" then the puppet `template` function will be used to interpret the template. This means that template names do not have to have an extension. If one does not it will be treated as an erb template. + +```yaml +sudo::configs: + 'elizabeth': + 'template': "mymodule/webserver_administrator" + 'mohammed': + 'template': "mymodule/databaseadministrator.erb" + 'jose': + 'template': "mymodule/appserver_administrator.epp" +``` + +The `template_epp` meta-parameter expects a hash with two elements; `filename` and `params`. `filename` is a string containing a path to a puppet epp template. `params` is a hash containing data elements to be passed to the corresponding epp template parameters. + +```yaml +sudo::configs: + 'george': + 'template_epp': + 'filename': 'sudo/single_line_allocation.epp' + 'params': + 'user_spec': + - '%dbas' + 'run_as': + - 'root' + 'commands': + - '/usr/bin/startdb' + 'srini': + 'template_epp': + 'filename': 'sudo/single_line_allocation.epp' + 'params': + 'user_spec': + - 'srini' + 'run_as': + - 'ALL' + 'commands': + - 'ALL' +``` + ##### Set a custom name for the sudoers file In some edge cases, the automatically generated sudoers file name is insufficient. For example, when an application generates a sudoers file with a fixed file name, using this class with the purge option enabled will always delete the custom file and adding it manually will generate a file with the right content, but the wrong name. To solve this, you can use the ```sudo_file_name``` option to manually set the desired file name. @@ -238,5 +277,6 @@ sudo::conf { "foreman-proxy": | content | string | undef | content of configuration snippet | | source | string | undef | source of configuration snippet | | template | string | undef | template of configuration snippet | +| template_epp | hash | undef | template and parameters for an epp configuration snippet | | sudo_config_dir | string | OS Specific | configuration snippet directory _(for unsupported platforms)_ | -| sudo_file_name | string | undef | custom file name for sudo file in sudoers directory | +| sudo_file_name | string | undef | custom file name for sudo file in sudoers directory | diff --git a/REFERENCE.md b/REFERENCE.md index aee139d5..0753debd 100644 --- a/REFERENCE.md +++ b/REFERENCE.md @@ -427,6 +427,7 @@ The following parameters are available in the `sudo::conf` defined type: * [`content`](#-sudo--conf--content) * [`source`](#-sudo--conf--source) * [`template`](#-sudo--conf--template) +* [`template_epp`](#-sudo--conf--template_epp) * [`sudo_config_dir`](#-sudo--conf--sudo_config_dir) * [`sudo_file_name`](#-sudo--conf--sudo_file_name) * [`sudo_syntax_path`](#-sudo--conf--sudo_syntax_path) @@ -467,7 +468,15 @@ Default value: `undef` Data type: `Any` -Path of a template file +Path of a erb template file or epp template file without parameters + +Default value: `undef` + +##### `template_epp` + +Data type: `Any` + +Path of an epp template and associated template parameters Default value: `undef` diff --git a/manifests/conf.pp b/manifests/conf.pp index 029d3e38..37236b5f 100644 --- a/manifests/conf.pp +++ b/manifests/conf.pp @@ -16,7 +16,10 @@ # Source of configuration snippet # # @param template -# Path of a template file +# Path of a erb template file or epp template file without parameters +# +# @param template_epp +# Path of an epp template and associated template parameters # # @param sudo_config_dir # Where to place configuration snippets. @@ -40,6 +43,7 @@ $content = undef, $source = undef, $template = undef, + $template_epp = undef, $sudo_config_dir = undef, $sudo_file_name = undef, $sudo_syntax_path = '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' @@ -94,6 +98,10 @@ } } + if $template and $template_epp { + fail("'template' and 'template_epp' are mutually exclusive") + } + if $content != undef { if $content =~ Array { $lines = join($content, "\n") @@ -102,7 +110,22 @@ $content_real = "# This file is managed by Puppet; changes may be overwritten\n${content}\n" } } elsif $template != undef { - $content_real = template($template) + if $template =~ /\.epp$/ { + $lines = epp($template) + } else { + $lines = template($template) + } + $content_real = "# This file is managed by Puppet; changes may be overwritten\n${lines}\n" + } elsif $template_epp != undef { + $missing_data_error = "'template_epp' must be a hash containing two elements; filename(string) and params(hash)" + if $template_epp[filename] == undef { + fail("template_epp hash missing filename element: ${missing_data_error}") + } + if $template_epp[params] == undef { + fail("template_epp hash missing params element: ${missing_data_error}") + } + $lines = epp($template_epp[filename], $template_epp[params]) + $content_real = "# This file is managed by Puppet; changes may be overwritten\n${lines}\n" } else { $content_real = undef } diff --git a/templates/multi_line_allocation.epp b/templates/multi_line_allocation.epp new file mode 100644 index 00000000..79c8e85d --- /dev/null +++ b/templates/multi_line_allocation.epp @@ -0,0 +1,23 @@ +<%- | Array[String] $user_spec, + Optional[Array[String]] $run_as = ['root'], + Optional[Boolean] $req_passwd = true, + Optional[Array[String]] $commands = ['ALL'] +| -%> +<% + if $req_passwd == true { + $req_passwd_final = 'PASSWD' + } + else { + $req_passwd_final = 'NOPASSWD' + } + + $user_spec.each |String $one_user_spec| { + $run_as.each |String $one_run_as| { + $commands.each |String $one_command| { +-%> +<%= $one_user_spec %> <%= $facts['hostname'] %> = (<%= $one_run_as %>) <%= $req_passwd_final %>: <%= $one_command %> +<% + } + } + } +-%> diff --git a/templates/single_line_allocation.epp b/templates/single_line_allocation.epp new file mode 100644 index 00000000..b1cea088 --- /dev/null +++ b/templates/single_line_allocation.epp @@ -0,0 +1,20 @@ +<%- | Array[String] $user_spec, + Optional[Array[String]] $run_as = ['root'], + Optional[Boolean] $req_passwd = true, + Optional[Array[String]] $commands = ['ALL'] +| -%> +<% + $user_spec_final = $user_spec.join(',') + + $run_as_final = $run_as.join(',') + + if $req_passwd == true { + $req_passwd_final = 'PASSWD' + } + else { + $req_passwd_final = 'NOPASSWD' + } + + $commands_final = $commands.join(',') +-%> +<%= $user_spec_final %> <%= $facts['hostname'] %> = (<%= $run_as_final %>) <%= $req_passwd_final %>: <%= $commands_final -%>