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 c9a0b04..85f3071 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 aee139d..0753deb 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 029d3e3..37236b5 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 0000000..79c8e85 --- /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 0000000..b1cea08 --- /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 -%>