Skip to content

Commit

Permalink
Service filename bugfix
Browse files Browse the repository at this point in the history
This started out as a fix for the custom service filename but spiraled a
bit further during debugging.

* Auto-correct the filename for firewalld::custom_service
* Add a function `firewalld::safe_filename` for munging filenames to
  safely work with firewalld. The allowed characters were determined by
  experimentation and are not documented.
* Ensure that firewalld_zone resources automatically reload the firewall
* Ensure that firewalld_zone names are no longer than 17 characters per
  the manual
* Create firewalld::reload and firewalld::reload::complete classes to
  allow easier resource chaining
* Fix spacing in init.pp
* Ensure that all of the Execs that call firewall-cmd happen after the
  service is running
* Ensure that all permanent configuration changes happen before the
  firewalld service is started/restarted. This is critical if switching
  from nft to iptables due to the segfault bug in nft
* Ensure that all custom service declarations happen before all
  firewalld_zone resources are triggered. This is automatic in all
  native types
* Updated the service.xml.erb to an EPP file

Closes #265
  • Loading branch information
trevor-vaughan committed Mar 6, 2020
1 parent a4ef580 commit 52327e2
Show file tree
Hide file tree
Showing 13 changed files with 433 additions and 213 deletions.
72 changes: 72 additions & 0 deletions functions/safe_filename.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# @summary Returns a string that is safe for firewalld filenames
#
# @example Regular Filename
# $filename = 'B@d Characters!'
# firewalld::safe_filename($orig_string)
#
# Result => 'B_d_Characters_'
#
# @example Filename with Options
# $filename = 'B@d Characters!.txt'
# firewalld::safe_filename(
# $filename,
# {
# 'replacement_string' => '@@',
# 'file_extension' => '.txt'
# }
# )
#
# Result => 'B@@d@@Characters@@.txt'
#
# @param filename
# The String to process
#
# @param options
# Various processing options
#
# @param options [String[1]] replacement_string
# The String to use when replacing invalid characters
#
# @option options [String[1]] file_extension
# This will be stripped from the end of the string prior to processing and
# re-added afterwards
#
# @return [String]
# Processed string
#
function firewalld::safe_filename(
String[1] $filename,
Struct[
{
'replacement_string' => Pattern[/[\w-]/],
'file_extension' => Optional[String[1]]
}
] $options = { 'replacement_string' => '_'}
) {

$_badchar_regex = '[^\w-]'

# If we have an extension defined
if $options['file_extension'] {

# See if the string ends with the extension
$_extension_length = length($options['file_extension'])
if $filename[-($_extension_length), -1] == $options['file_extension'] {

# And extract the base filename
$_basename = $filename[0, -($_extension_length) - 1]
}
}

# If we extraced a base filename substitute on that and re-add the file extension
if defined('$_basename') {
sprintf('%s%s',
regsubst($_basename, $_badchar_regex, $options['replacement_string'], 'G'),
$options['file_extension']
)
}
# Otherwise, just substitute on the original filename
else {
regsubst($filename, $_badchar_regex, $options['replacement_string'], 'G')
}
}
4 changes: 4 additions & 0 deletions lib/puppet/provider/firewalld_zone/firewall_cmd.rb
Original file line number Diff line number Diff line change
Expand Up @@ -197,4 +197,8 @@ def short
def short=(new_short)
execute_firewall_cmd(['--set-short', new_short], @resource[:name], true, false)
end

def flush
reload_firewall
end
end
9 changes: 9 additions & 0 deletions lib/puppet/type/firewalld_zone.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ def generate

newparam(:name) do
desc 'Name of the rule resource in Puppet'
isnamevar
end

newparam(:zone) do
Expand Down Expand Up @@ -165,6 +166,14 @@ def retrieve
end
end

validate do
[:zone, :name].each do |attr|
if self[attr] && (self[attr]).to_s.length > 17
raise(Puppet::Error, "Zone identifier '#{attr}' must be less than 18 characters long")
end
end
end

autorequire(:service) do
['firewalld']
end
Expand Down
32 changes: 21 additions & 11 deletions manifests/custom_service.pp
Original file line number Diff line number Diff line change
Expand Up @@ -45,18 +45,28 @@
Enum['present','absent'] $ensure = 'present',
) {

file{"${config_dir}/${filename}.xml":
include firewalld::reload

# Service files may only contain alphanumeric characters and underscores.
# This is not documented, but has been experimentally confirmed.
$_safe_filename = firewalld::safe_filename($filename)

$_content = epp(
"${module_name}/service.xml.epp",
'short' => $short,
'description' => $description,
'port' => $port,
'module' => $module,
'destination' => $destination,
'filename' => $filename,
'config_dir' => $config_dir,
'ensure' => $ensure
)

file{ "${config_dir}/${_safe_filename}.xml":
ensure => $ensure,
content => template('firewalld/service.xml.erb'),
content => $_content,
mode => '0644',
notify => Exec["firewalld::custom_service::reload-${name}"],
notify => Class['firewalld::reload'],
}

exec{ "firewalld::custom_service::reload-${name}":
path =>'/usr/bin:/bin',
command => 'firewall-cmd --reload',
onlyif => 'firewall-cmd --state',
refreshonly => true,
}

}
Loading

0 comments on commit 52327e2

Please sign in to comment.