From 660226cf9d34150a0abc59a19dc14c80e83d8909 Mon Sep 17 00:00:00 2001 From: Ben Ford Date: Sat, 4 Jan 2020 15:01:07 -0800 Subject: [PATCH] Porting functions to the modern Puppet 4.x API --- .../functions/iptables/format_action.rb | 64 ++++++ lib/puppet/functions/iptables/format_chain.rb | 64 ++++++ .../functions/iptables/format_interface.rb | 67 ++++++ lib/puppet/functions/iptables/format_log.rb | 122 +++++++++++ lib/puppet/functions/iptables/format_port.rb | 116 +++++++++++ .../functions/iptables/format_protocol.rb | 113 +++++++++++ .../functions/iptables/format_reject.rb | 80 ++++++++ lib/puppet/functions/iptables/format_state.rb | 92 +++++++++ .../iptables/iptables_format_limit.rb | 53 +++++ .../iptables/iptables_format_to_port.rb | 58 ++++++ .../iptables/iptables_generate_rule.rb | 190 ++++++++++++++++++ .../iptables/iptables_parse_options.rb | 185 +++++++++++++++++ .../iptables/iptables_prep_option.rb | 73 +++++++ spec/functions/iptables_format_action_spec.rb | 41 ++++ spec/functions/iptables_format_chain_spec.rb | 41 ++++ .../iptables_format_interface_spec.rb | 41 ++++ spec/functions/iptables_format_log_spec.rb | 41 ++++ spec/functions/iptables_format_port_spec.rb | 41 ++++ .../iptables_format_protocol_spec.rb | 41 ++++ spec/functions/iptables_format_reject_spec.rb | 41 ++++ spec/functions/iptables_format_state_spec.rb | 41 ++++ .../iptables_iptables_format_limit_spec.rb | 41 ++++ .../iptables_iptables_format_to_port_spec.rb | 41 ++++ .../iptables_iptables_generate_rule_spec.rb | 41 ++++ .../iptables_iptables_parse_options_spec.rb | 41 ++++ .../iptables_iptables_prep_option_spec.rb | 41 ++++ 26 files changed, 1810 insertions(+) create mode 100644 lib/puppet/functions/iptables/format_action.rb create mode 100644 lib/puppet/functions/iptables/format_chain.rb create mode 100644 lib/puppet/functions/iptables/format_interface.rb create mode 100644 lib/puppet/functions/iptables/format_log.rb create mode 100644 lib/puppet/functions/iptables/format_port.rb create mode 100644 lib/puppet/functions/iptables/format_protocol.rb create mode 100644 lib/puppet/functions/iptables/format_reject.rb create mode 100644 lib/puppet/functions/iptables/format_state.rb create mode 100644 lib/puppet/functions/iptables/iptables_format_limit.rb create mode 100644 lib/puppet/functions/iptables/iptables_format_to_port.rb create mode 100644 lib/puppet/functions/iptables/iptables_generate_rule.rb create mode 100644 lib/puppet/functions/iptables/iptables_parse_options.rb create mode 100644 lib/puppet/functions/iptables/iptables_prep_option.rb create mode 100644 spec/functions/iptables_format_action_spec.rb create mode 100644 spec/functions/iptables_format_chain_spec.rb create mode 100644 spec/functions/iptables_format_interface_spec.rb create mode 100644 spec/functions/iptables_format_log_spec.rb create mode 100644 spec/functions/iptables_format_port_spec.rb create mode 100644 spec/functions/iptables_format_protocol_spec.rb create mode 100644 spec/functions/iptables_format_reject_spec.rb create mode 100644 spec/functions/iptables_format_state_spec.rb create mode 100644 spec/functions/iptables_iptables_format_limit_spec.rb create mode 100644 spec/functions/iptables_iptables_format_to_port_spec.rb create mode 100644 spec/functions/iptables_iptables_generate_rule_spec.rb create mode 100644 spec/functions/iptables_iptables_parse_options_spec.rb create mode 100644 spec/functions/iptables_iptables_prep_option_spec.rb diff --git a/lib/puppet/functions/iptables/format_action.rb b/lib/puppet/functions/iptables/format_action.rb new file mode 100644 index 0000000..e0e718c --- /dev/null +++ b/lib/puppet/functions/iptables/format_action.rb @@ -0,0 +1,64 @@ +# This is an autogenerated function, ported from the original legacy version. +# It /should work/ as is, but will not have all the benefits of the modern +# function API. You should see the function docs to learn how to add function +# signatures for type safety and to document this function using puppet-strings. +# +# https://puppet.com/docs/puppet/latest/custom_functions_ruby.html +# +# ---- original file header ---- + +# ---- original file header ---- +# +# @summary +# Given an action, ie. ACCEPT/REJECT or a chain name, returns the partial iptables +#rule to facilitate taking the appropriate action. +# +#Examples: +# +# # returns "-j ACCEPT' +# format_action('ACCEPT') +# format_action(nil) +# +# # returns '-j LOG' +# format_action('LOG') +# +# # Parse Error +# format_action('') +# format_action('SOME CHAIN') +# +# +Puppet::Functions.create_function(:'iptables::format_action') do + # @param args + # The original array of arguments. Port this to individually managed params + # to get the full benefit of the modern function API. + # + # @return [Data type] + # Describe what the function returns here + # + dispatch :default_impl do + # Call the method named 'default_impl' when this is matched + # Port this to match individual params for better type safety + repeated_param 'Any', :args + end + + + def default_impl(*args) + + action = 'ACCEPT' + action = args[0] unless args[0] == nil or args[0] == 'UNSET' + + if action == :undef or action == '' + raise Puppet::ParseError, \ + "action not specified" + end + + # do some basic validation of the action + if action =~ /\s/ + raise Puppet::ParseError, \ + "action cannot contain whitespace - \"#{action}\"" + end + + return "-j #{action}" + + end +end diff --git a/lib/puppet/functions/iptables/format_chain.rb b/lib/puppet/functions/iptables/format_chain.rb new file mode 100644 index 0000000..7066a66 --- /dev/null +++ b/lib/puppet/functions/iptables/format_chain.rb @@ -0,0 +1,64 @@ +# This is an autogenerated function, ported from the original legacy version. +# It /should work/ as is, but will not have all the benefits of the modern +# function API. You should see the function docs to learn how to add function +# signatures for type safety and to document this function using puppet-strings. +# +# https://puppet.com/docs/puppet/latest/custom_functions_ruby.html +# +# ---- original file header ---- + +# ---- original file header ---- +# +# @summary +# format_chain( name ) +# +#Given an chain name, generates the partial iptables rule to faciliate appending +#a rule to given chain. +# +#Examples: +# +# # returns '-A INPUT' +# format_chain('INPUT') +# +# # returns '-A LOGNDUMP' +# format_chain('LOGNDUMP') +# +# # throws ParseError +# format_chain('SOME CHAIN') +# +# +Puppet::Functions.create_function(:'iptables::format_chain') do + # @param args + # The original array of arguments. Port this to individually managed params + # to get the full benefit of the modern function API. + # + # @return [Data type] + # Describe what the function returns here + # + dispatch :default_impl do + # Call the method named 'default_impl' when this is matched + # Port this to match individual params for better type safety + repeated_param 'Any', :args + end + + + def default_impl(*args) + + chain = 'INPUT' + chain = args[0] unless args[0] == nil + + if chain == :undef or chain == '' + raise Puppet::ParseError, \ + "chain name cannot be empty" + end + + # Do some validation here + if chain =~ /\s/ + raise Puppet::ParseError, \ + "chain name cannot contain whitespace - \"#{chain}\"" + end + + return "-A #{chain}" + + end +end diff --git a/lib/puppet/functions/iptables/format_interface.rb b/lib/puppet/functions/iptables/format_interface.rb new file mode 100644 index 0000000..165c719 --- /dev/null +++ b/lib/puppet/functions/iptables/format_interface.rb @@ -0,0 +1,67 @@ +# This is an autogenerated function, ported from the original legacy version. +# It /should work/ as is, but will not have all the benefits of the modern +# function API. You should see the function docs to learn how to add function +# signatures for type safety and to document this function using puppet-strings. +# +# https://puppet.com/docs/puppet/latest/custom_functions_ruby.html +# +# ---- original file header ---- + +# ---- original file header ---- +# +# @summary +# +# +Puppet::Functions.create_function(:'iptables::format_interface') do + # @param args + # The original array of arguments. Port this to individually managed params + # to get the full benefit of the modern function API. + # + # @return [Data type] + # Describe what the function returns here + # + dispatch :default_impl do + # Call the method named 'default_impl' when this is matched + # Port this to match individual params for better type safety + repeated_param 'Any', :args + end + + + def default_impl(*args) + + + # setup some objects to hold our regexes + out_rx = /^out(going)?$/i + in_rx = /^in(coming)?$/i + int_rx = /^[a-z0-9\.\-_]+\+?$/i + + return '' if args == nil or args[0] == :undef + return '' if args[0] == nil + + # make sure we were at least passed a string or nil + raise Puppet::ParseError, "non-string interface passed - #{args[0]}" \ + unless args[0].kind_of?(String) + + interface = '' + interface = String(args[0]).dup + + + # handle cases where we weren't passed an interface + return interface if interface == '' + + direction = 'in' + direction = args[1] unless args[1] == nil + + raise Puppet::ParseError, "invalid direction specified - #{direction}" \ + unless direction =~ /(#{out_rx}|#{in_rx})/i + + # lets assume all interfaces will only have alphanumerics, plus + # '.' and '_' + raise Puppet::ParseError, "bad interface name passed - #{interface}" \ + unless interface =~ int_rx + + return "-o #{interface}" if direction =~ out_rx + return "-i #{interface}" + + end +end diff --git a/lib/puppet/functions/iptables/format_log.rb b/lib/puppet/functions/iptables/format_log.rb new file mode 100644 index 0000000..dc036b6 --- /dev/null +++ b/lib/puppet/functions/iptables/format_log.rb @@ -0,0 +1,122 @@ +# This is an autogenerated function, ported from the original legacy version. +# It /should work/ as is, but will not have all the benefits of the modern +# function API. You should see the function docs to learn how to add function +# signatures for type safety and to document this function using puppet-strings. +# +# https://puppet.com/docs/puppet/latest/custom_functions_ruby.html +# +# ---- original file header ---- + +# ---- original file header ---- +# +# @summary +# format_log( options ): +# +# +# +Puppet::Functions.create_function(:'iptables::format_log') do + # @param args + # The original array of arguments. Port this to individually managed params + # to get the full benefit of the modern function API. + # + # @return [Data type] + # Describe what the function returns here + # + dispatch :default_impl do + # Call the method named 'default_impl' when this is matched + # Port this to match individual params for better type safety + repeated_param 'Any', :args + end + + + def default_impl(*args) + + syslog_priorities = { + 'emerg' => '0', + 'panic' => '0', + 'alert' => '1', + 'crit' => '2', + 'err' => '3', + 'error' => '3', + 'warn' => '4', + 'warning' => '4', + 'notice' => '5', + 'info' => '6', + 'debug' => '7', + } + + raise Puppet::ParseError, "input must be an anonymous array" \ + unless args.is_a?(Array) + + return '' unless args[0] != nil + + raise Puppet::ParseError, "input must be hash table" \ + unless args[0].is_a?(Hash) + + opts = args[0] unless args[0] == nil + + log_opts = Array.new + + # + ## log_level option + # + loglevel = [] + loglevel = opts['log_level'].split('.') unless opts['log_level'] == nil + + if loglevel.size == 1 + # we were just passed the log level, if it's a text version, convert it to + # numeric + loglevel[0] = syslog_priorities[loglevel[0]] \ + if syslog_priorities.has_key?(loglevel[0]) + + # make sure it's a valid syslog priority + raise Puppet::ParseError, "invalid log level passed - #{loglevel[0]}" \ + unless syslog_priorities.has_value?(String(loglevel[0])) + + log_opts.push("--log-level #{loglevel[0]}") + elsif loglevel.size == 0 + # no log_level info was passed, we can move on + else + raise Puppet::ParseError, \ + "invalid log level passed - #{opts['log_level']}" + end + + # + ## log_prefix options + # + logprefix = '' + logprefix = opts['log_prefix'] unless opts['log_prefix'] == nil + + if logprefix.size == 0 + # do nothing + elsif logprefix.size > 0 + # push the first 29 characters, giving a warning if we trimmed some + log_opts.push("--log-prefix \"" + logprefix.scan(/^.{1,29}/)[0] + "\"") + function_warning(["log prefix \"#{logprefix}\" exceeds 29 characters." \ + + " Truncating chars beyond 29"]) if logprefix.size > 29 + end + + # + ## log_tcp_options option + # + log_opts.push('--log-tcp-options') if opts['log_tcp_options'] + + # + ## log_ip_options option + # + log_opts.push('--log-ip-options') if opts['log_ip_options'] + + # + ## log_uid option + # + log_opts.push('--log-uid') if opts['log_uid'] + + # + ## log_tcp_sequence + # + log_opts.push('--log-tcp-sequence') if opts['log_tcp_sequence'] + + return log_opts.join(' ') + + end +end diff --git a/lib/puppet/functions/iptables/format_port.rb b/lib/puppet/functions/iptables/format_port.rb new file mode 100644 index 0000000..5365ab8 --- /dev/null +++ b/lib/puppet/functions/iptables/format_port.rb @@ -0,0 +1,116 @@ +# This is an autogenerated function, ported from the original legacy version. +# It /should work/ as is, but will not have all the benefits of the modern +# function API. You should see the function docs to learn how to add function +# signatures for type safety and to document this function using puppet-strings. +# +# https://puppet.com/docs/puppet/latest/custom_functions_ruby.html +# +# ---- original file header ---- + +# ---- original file header ---- +# +# @summary +# format_port( port, type ): +# +#Provided port(s), as either an array or comma separated list of port numbers, +#and the type of port, either sport (source port) or dport (dest. port), +#generates a partial iptables rule handling the appropriate ports. +# +#Result is returned in a hash, with the flag multiport set to true if more than +#one valid port was passed. False otherwise. +# +#If multiple ports are specified, but some are not legal, they will be skipped +#and a warning will be logged. +# +#If all ports specified are invalid, a ParseError will be thrown. +# +#If no ports are specified, an empty string will be returned. +# +#If not specified, the type defaults to 'dport' +# +#Examples: +# +# # returns { 'port' => '--dport 22', 'multiport' => false } +# format_port('22') +# +# # returns { 'port' => '--dports 22,80', 'multiport' => true } +# format_port('22,80') +# format_port([ '22', '80' ]) +# format_port([ '22', '80', 'ftp' ]) # a warning is also logged for 'ftp' +# +# # returns { 'port' => '', 'multiport' => false } +# format_port('') +# format_port(nil) +# +# # throws ParseError +# format_port('ftp') +# +# +Puppet::Functions.create_function(:'iptables::format_port') do + # @param args + # The original array of arguments. Port this to individually managed params + # to get the full benefit of the modern function API. + # + # @return [Data type] + # Describe what the function returns here + # + dispatch :default_impl do + # Call the method named 'default_impl' when this is matched + # Port this to match individual params for better type safety + repeated_param 'Any', :args + end + + + def default_impl(*args) + + Puppet::Parser::Functions.function('warning') + + ports = [] + ports = args[0] unless args[0] == nil or args[0] == :undef + type = "dport" + type = "sport" if args[1] == "sport" + + + ports = ports.split(',') if ports.kind_of?(String) + ports.uniq! + + # special case -- we weren't given an empty array or string + if ports.size == 0 + return { + 'port' => '', + 'multiport' => false + } + end + + # go through our ports, removing any non numeric ones + # if we've got at least one good one, we'll just skip the bad ones and warn + # the user. otherwise, we'll throw a parse error + to_delete = Array.new + ports.each { |p| to_delete.push(p) unless p =~ /^[0-9]+(:[0-9]+)?$/ } + + # delete ports if they aren't numeric, maybe we'll support well-known ports + # in the future... + ports.delete_if { |port| to_delete.include?(port) } + if ports.size > 0 and to_delete.size > 0 + function_warning(["non-numeric ports \"#{to_delete.join(',')}\" skipped"]) + elsif ports.size == 0 + raise Puppet::ParseError, "no valid ports specified" + end + + # give some indication if they'll want to add the multiport module + multiport = false + multiport = true if ports.size > 1 + + if multiport then port = "--#{type}s" + else port = "--#{type}" end + port = "#{port} #{ports.join(',')}" + + r_h = { + 'multiport' => multiport, + 'port' => port, + } + + return r_h + + end +end diff --git a/lib/puppet/functions/iptables/format_protocol.rb b/lib/puppet/functions/iptables/format_protocol.rb new file mode 100644 index 0000000..5b09c71 --- /dev/null +++ b/lib/puppet/functions/iptables/format_protocol.rb @@ -0,0 +1,113 @@ +# This is an autogenerated function, ported from the original legacy version. +# It /should work/ as is, but will not have all the benefits of the modern +# function API. You should see the function docs to learn how to add function +# signatures for type safety and to document this function using puppet-strings. +# +# https://puppet.com/docs/puppet/latest/custom_functions_ruby.html +# +# ---- original file header ---- + +# ---- original file header ---- +# +# @summary +# format_protocol( protocol [, version ]) +#Formats the protocol portion of an iptable rule. +# +#Takes 3 optional arguments as input: +# String: protocol name, defaults to 'all' +# String: protocol version, default to '4' +# Boolean: strict protocol checking, defaults to 'true' +# +#Beyond formatting the protocol component, this function also does some sanity +#checking to make it difficult to pass a bad protocol value. If strict is left +#set to 'true', this function will verify the protocol is one of the protocols +#baked into iptables/ip6tables. +# +#Valid protocols for each ip version: +# 4: 'tcp', 'udp', 'udplite', 'icmp', 'esp', 'ah', 'sctp', 'all' +# 6: 'tcp', 'udp', 'icmpv6', 'esp', 'all' +# +#Alternatively, you can pass an integer value representing the protocol type. +# +#Passing 'false' as argument 3, will allow you to specify any string/integer +#combination. +# +#Examples: +# +# # returns '-p tcp' +# format_protocol('tcp',4) +# format_protocol('tcp',6) +# +# # returns '-p icmp' +# format_protocol('icmp',4) +# +# # returns '-p icmpv6' +# format_protocol('icmp',6) +# format_protocol('icmpv6',6) +# +# # returns '' +# format_protocol(undef) +# format_protocol('') +# +# # returns '-p eigrp' +# format_protocol('eigrp',4,false) +# format_protocol('eigrp',6,false) +# +# # returns '-p 88' +# format_protocol('88',4) +# format_protocol('88',6) +# +# # parse error +# format_protocol('proto') +# format_protocol('proto',6) +# +# +Puppet::Functions.create_function(:'iptables::format_protocol') do + # @param args + # The original array of arguments. Port this to individually managed params + # to get the full benefit of the modern function API. + # + # @return [Data type] + # Describe what the function returns here + # + dispatch :default_impl do + # Call the method named 'default_impl' when this is matched + # Port this to match individual params for better type safety + repeated_param 'Any', :args + end + + + def default_impl(*args) + + protocols = { + '4' => [ 'tcp', 'udp', 'udplite', 'icmp', 'esp', 'ah', 'sctp', 'all' ], + '6' => [ 'tcp', 'udp', 'icmpv6', 'esp', 'all' ] + } + + return '' if args == nil or args[0] == :undef + + protocol = '' + protocol = args[0].dup unless args[0] == nil + version = '4' + version = '6' if String(args[1]) =~ /(ip(v)?)?6/i + strict = true + strict = false if args[2] == false + + return protocol if protocol == '' + + # we'll be nice and translate icmp to icmpv6 when passed icmp for formatting + # a ipv6 protocol + protocol = 'icmpv6' if version == '6' and protocol == 'icmp' + + # if we disabled strict_protocol_checking, or if we set our protocol to an + # integer, don't worry about verifying the protocol exists in our lists + if strict and not protocol =~ /^[0-9]+$/ + # do some basic validation of the protocol + raise Puppet::ParseError, "invalid protocol - #{protocol}" \ + unless protocols[version].include?(protocol) + end + + return "-p #{protocol}" + + end +end diff --git a/lib/puppet/functions/iptables/format_reject.rb b/lib/puppet/functions/iptables/format_reject.rb new file mode 100644 index 0000000..39b98e4 --- /dev/null +++ b/lib/puppet/functions/iptables/format_reject.rb @@ -0,0 +1,80 @@ +# This is an autogenerated function, ported from the original legacy version. +# It /should work/ as is, but will not have all the benefits of the modern +# function API. You should see the function docs to learn how to add function +# signatures for type safety and to document this function using puppet-strings. +# +# https://puppet.com/docs/puppet/latest/custom_functions_ruby.html +# +# ---- original file header ---- + +# ---- original file header ---- +# +# @summary +# +# +Puppet::Functions.create_function(:'iptables::format_reject') do + # @param args + # The original array of arguments. Port this to individually managed params + # to get the full benefit of the modern function API. + # + # @return [Data type] + # Describe what the function returns here + # + dispatch :default_impl do + # Call the method named 'default_impl' when this is matched + # Port this to match individual params for better type safety + repeated_param 'Any', :args + end + + + def default_impl(*args) + + rej = '' + rej = args[0] if args[0].is_a?(String) + + ver = '4' + ver = args[1][-1].chr if args[1][-1].chr == '6' + + return rej if rej == '' + + # create a translation table so reject types from iptables + # and ip6tables can be used as interchangeably as possible, + # though its not perfect. + translations = { + # v4 to v6 translations + 'icmp-net-unreachable' => 'icmp6-no-route', + 'icmp-host-unreachable' => 'icmp6-addr-unreachable', + 'icmp-port-unreachable' => 'icmp6-port-unreachable', + 'icmp-proto-unreachable' => 'icmp6-port-unreachable', + 'icmp-net-prohibited' => 'icmp6-adm-prohibited', + 'icmp-host-prohibited' => 'icmp6-adm-prohibited', + 'icmp-admin-prohibited' => 'icmp6-adm-prohibited', + # v6 to v4 translations + 'icmp6-no-route' => 'icmp-net-unreachable', + 'no-route' => 'icmp-net-unreachable', + 'icmp6-adm-prohibited' => 'icmp-admin-prohibited', + 'adm-prohibited' => 'icmp-admin-prohibitied', + 'icmp6-addr-unreachable' => 'icmp-host-unreachable', + 'addr-unreach' => 'icmp-addr-unreachable', + 'icmp6-port-unreachable' => 'icmp-port-unreachable', + 'port-unreach' => 'icmp-port-unreachable' + } + + valid_rejects = { + '4' => [ 'icmp-net-unreachable', 'icmp-host-unreachable', + 'icmp-port-unreachable', 'icmp-proto-unreachable', + 'icmp-net-prohibited', 'icmp-host-prohibited', + 'icmp-admin-prohibited' ], + '6' => [ 'icmp6-no-route', 'no-route', 'icmp6-adm-prohibited', + 'adm-prohibited', 'icmp6-addr-unreachable', 'addr-unreach', + 'icmp6-port-unreachable', 'port-unreach' ] + } + + if ( ver == '4' and valid_rejects['6'].include?(rej) ) or + ( ver == '6' and valid_rejects['4'].include?(rej) ) then + rej = translations[rej] + end + return "--reject-with #{rej}" + + end +end diff --git a/lib/puppet/functions/iptables/format_state.rb b/lib/puppet/functions/iptables/format_state.rb new file mode 100644 index 0000000..480b792 --- /dev/null +++ b/lib/puppet/functions/iptables/format_state.rb @@ -0,0 +1,92 @@ +# This is an autogenerated function, ported from the original legacy version. +# It /should work/ as is, but will not have all the benefits of the modern +# function API. You should see the function docs to learn how to add function +# signatures for type safety and to document this function using puppet-strings. +# +# https://puppet.com/docs/puppet/latest/custom_functions_ruby.html +# +# ---- original file header ---- + +# ---- original file header ---- +# +# @summary +# format_state( state ) +# +#Given an array or comma separated list of states, generates the partial iptables +#rule to facilitate matching on specific states. +# +#If no state is specified, an empty string is returned. +# +#If multiple states are specified any invalid states will be skipped, and a +#warning will be logged. +# +#If all passed states are invalid, a ParseError is thrown +# +#Examples: +# +# # returns '-m state --state NEW,REL' +# format_state('NEW,RELATED') +# +# # returns '-m state --state NEW' +# format_state(['NEW','NET']) +# +# # throws parse error +# format_state('NET') +# format_state([ 'NEXT', 'NET' ]) +# +# +Puppet::Functions.create_function(:'iptables::format_state') do + # @param args + # The original array of arguments. Port this to individually managed params + # to get the full benefit of the modern function API. + # + # @return [Data type] + # Describe what the function returns here + # + dispatch :default_impl do + # Call the method named 'default_impl' when this is matched + # Port this to match individual params for better type safety + repeated_param 'Any', :args + end + + + def default_impl(*args) + + Puppet::Parser::Functions.function('warning') + + states = "" + states = args[0].dup unless args[0] == nil or args[0] == :undef + valid = [ 'NEW', 'REL', 'EST', 'INV' ] + + states = states.split(',') unless states.kind_of?(Array) + + # handle if we were not passed any states + return '' if states.size == 0 + + # limit each state to the first 3 letters since we just need to provide + # enough information for iptables such that the state is not ambigous + states.map! { |s| s=s[0,3] } + states.uniq! + + # remove invalid states + to_delete = [ ] + states.each { |s| to_delete.push(s) unless valid.include?(s) } + + if to_delete.size > 0 and states.size > 0 + function_warning(["skipping invalid states -- #{to_delete.join(',')}"]) + to_delete.each { |s| states.delete(s) } + end + + if to_delete.size > 0 and states.size == 0 + raise Puppet::ParseError, "no valid states were passed" + end + + states.compact! + + state = "" + state = "-m state --state #{states.join(',')}" if states.size > 0 + + return state + + end +end diff --git a/lib/puppet/functions/iptables/iptables_format_limit.rb b/lib/puppet/functions/iptables/iptables_format_limit.rb new file mode 100644 index 0000000..126352d --- /dev/null +++ b/lib/puppet/functions/iptables/iptables_format_limit.rb @@ -0,0 +1,53 @@ +# This is an autogenerated function, ported from the original legacy version. +# It /should work/ as is, but will not have all the benefits of the modern +# function API. You should see the function docs to learn how to add function +# signatures for type safety and to document this function using puppet-strings. +# +# https://puppet.com/docs/puppet/latest/custom_functions_ruby.html +# +# ---- original file header ---- + +# ---- original file header ---- +# +# @summary +# +# +Puppet::Functions.create_function(:'iptables::iptables_format_limit') do + # @param args + # The original array of arguments. Port this to individually managed params + # to get the full benefit of the modern function API. + # + # @return [Data type] + # Describe what the function returns here + # + dispatch :default_impl do + # Call the method named 'default_impl' when this is matched + # Port this to match individual params for better type safety + repeated_param 'Any', :args + end + + + def default_impl(*args) + + limit = burst = '' + + limit = args[0].dup if args[0].is_a?(String) + burst = args[1].dup if args[1].is_a?(String) + + return '' if limit == '' + + info = limit.split('/') + value = info[0] + + valid_units = [ 'second', 'minute', 'hour', 'day' ] + + unit = info[1] + unit = valid_units.select { |v| v =~ /^#{unit}/ }[0] unless unit.nil? + unit ||= 'second' + + burst = "--limit-burst #{burst}" unless burst == '' + + return "-m limit --limit #{value}/#{unit} #{burst}".strip + + end +end diff --git a/lib/puppet/functions/iptables/iptables_format_to_port.rb b/lib/puppet/functions/iptables/iptables_format_to_port.rb new file mode 100644 index 0000000..796166a --- /dev/null +++ b/lib/puppet/functions/iptables/iptables_format_to_port.rb @@ -0,0 +1,58 @@ +# This is an autogenerated function, ported from the original legacy version. +# It /should work/ as is, but will not have all the benefits of the modern +# function API. You should see the function docs to learn how to add function +# signatures for type safety and to document this function using puppet-strings. +# +# https://puppet.com/docs/puppet/latest/custom_functions_ruby.html +# +# ---- original file header ---- + +# ---- original file header ---- +# +# @summary +# +# +Puppet::Functions.create_function(:'iptables::iptables_format_to_port') do + # @param args + # The original array of arguments. Port this to individually managed params + # to get the full benefit of the modern function API. + # + # @return [Data type] + # Describe what the function returns here + # + dispatch :default_impl do + # Call the method named 'default_impl' when this is matched + # Port this to match individual params for better type safety + repeated_param 'Any', :args + end + + + def default_impl(*args) + + red = '' + red = args[0] if args[0].is_a?(String) + + return red if red == '' + + nums = red.split(':') + + nums.each do |n| + # if we were given integer ports, do some minor logic on them + if n.is_a? String and n.to_i.to_s == n and n.to_i > 65535 + raise Puppet::ParseError, "invalid port number (max is 65535)" + end + + # if we ever figure out a way to look into the /etc/services file, we can + # try and verify that the ports are valid + end + + if nums.size == 1 + return "--to-port #{nums[0]}" + elsif nums.size == 2 + return "--to-port #{nums[0]}:#{nums[1]}" + else + raise Puppet::ParseError, "invalid range definition '#{red}'" + end + + end +end diff --git a/lib/puppet/functions/iptables/iptables_generate_rule.rb b/lib/puppet/functions/iptables/iptables_generate_rule.rb new file mode 100644 index 0000000..5aafb19 --- /dev/null +++ b/lib/puppet/functions/iptables/iptables_generate_rule.rb @@ -0,0 +1,190 @@ +# This is an autogenerated function, ported from the original legacy version. +# It /should work/ as is, but will not have all the benefits of the modern +# function API. You should see the function docs to learn how to add function +# signatures for type safety and to document this function using puppet-strings. +# +# https://puppet.com/docs/puppet/latest/custom_functions_ruby.html +# +# ---- original file header ---- + +# ---- original file header ---- +# +# @summary +# Provided an array of options, generates iptables rule(s). +# +# +Puppet::Functions.create_function(:'iptables::iptables_generate_rule') do + # @param args + # The original array of arguments. Port this to individually managed params + # to get the full benefit of the modern function API. + # + # @return [Data type] + # Describe what the function returns here + # + dispatch :default_impl do + # Call the method named 'default_impl' when this is matched + # Port this to match individual params for better type safety + repeated_param 'Any', :args + end + + + def default_impl(*args) + + Puppet::Parser::Functions.function('iptables_parse_options') + Puppet::Parser::Functions.function('format_action') + Puppet::Parser::Functions.function('split_ip_by_version') + Puppet::Parser::Functions.function('format_chain') + Puppet::Parser::Functions.function('format_interface') + Puppet::Parser::Functions.function('format_log') + Puppet::Parser::Functions.function('format_port') + Puppet::Parser::Functions.function('format_protocol') + Puppet::Parser::Functions.function('format_reject') + Puppet::Parser::Functions.function('format_state') + Puppet::Parser::Functions.function('iptables_format_to_port') + Puppet::Parser::Functions.function('iptables_format_limit') + + opt = args[0] + + version = '4' + version = String(args[1])[-1].chr \ + if String(args[1]) =~ /(?i-mx:(ip)?(v)?(4|6))/ + + raise Puppet::Error, "invalid version detected - #{version}" \ + unless version =~ /(4|6)/ + + flg = { } + flg = opt['mod_flags'] if opt['mod_flags'].is_a?(Hash) + flg.default=false + + # addresses are arrays that should always have at least one object, even if + # its an empty-string + dst = function_split_ip_by_version( [ opt['destination'] ] )[version] + dst.push('') if dst.size == 0 + src = function_split_ip_by_version( [ opt['source'] ] )[version] + src.push('') if src.size == 0 + + # our ports also require a little logic + dpt_h = function_format_port( [ opt['destination_port'], 'dport' ] ) + dpt = dpt_h['port'] + spt_h = function_format_port( [ opt['source_port'], 'sport' ] ) + spt = spt_h['port'] + flg['multiport'] = true if spt_h['multiport'] or dpt_h['multiport'] + + # the rest are pretty easy + act = function_format_action( [ opt['action'] ] ) + chn = function_format_chain( [ opt['chain'] ] ) + in_int = function_format_interface( [ opt['incoming_interface'], 'in' ] ) + out_int = function_format_interface( [ opt['outgoing_interface'], 'out' ] ) + proto = function_format_protocol( [ opt['protocol'], version, + opt['strict_protocol_checking'] ] ) + ste = function_format_state( [ opt['state'] ] ) + rej = function_format_reject( [ opt['reject_with'], version ] ) if flg['act_REJECT'] + limit = function_iptables_format_limit( [ opt['limit'], opt['limit_burst'] ]) + + # logging options are all formatted in one function, so we'll pass in a + # hash of values. we'll also only format if the act_LOG flag is set, + # otherwise these options are useless + log_opts = { + 'log_ip_opt' => opt['log_ip_opt'], + 'log_level' => opt['log_level'], + 'log_prefix' => opt['log_prefix'], + 'log_tcp_opt' => opt['log_tcp_opt'], + 'log_tcp_sequence' => opt['log_tcp_sequence'], + } + log = function_format_log( [ log_opts ] ) if flg['act_LOG'] + + # redirect's can only happen on the nat table + red = function_iptables_format_to_port( [ opt['to_port'] ] ) \ + if flg['act_REDIRECT'] and opt['table'] == 'nat' + + # throw some errors when appropriate + raise Puppet::ParseError, + "only the FORWARD chain may specify both an in and out interface" \ + + " FWD=#{flg['chn_FORWARD']}, out=#{out_int}, in=#{in_int}" \ + if out_int != '' and in_int != '' and ! flg['chn_FORWARD'] + + raise Puppet::Error, + "something broke. we should have a valid CHAIN by this point" \ + if chn == '' + + raise Puppet::ParseError, + "protocol required if a source or destination port is provided" \ + if ( spt != '' or dpt != '' ) and proto == '' + + raise Puppet::ParseError, + "REDIRECT action is not valid for IPv6 rules" \ + if flg['act_REDIRECT'] and version == '6' + + raise Puppet::ParseError, + "REDIRECT action is only valid on the nat table" \ + if opt['table'] != 'nat' and flg['act_REDIRECT'] + + # + ## begin processing + # + + # we will store our rules and comments in this array and return it when + # we are all done + rules = [ ] + + # lets handle the comments first + comment_line_width = 80 + comment = opt['comment'] + if comment != nil and comment != 'UNSET' + prepend = "# " + comment_width = comment_line_width - prepend.length + comments = [] + if comment.kind_of?(Array) + comment.each do |c| + comments += c.scan(/.{1,#{comment_width}}/) if c.kind_of?(String) + end + else + comments = comment.scan(/.{1,#{comment_width}}/) + end + comments.map! { |c| c = prepend + c } + rules += comments + end + + # allow users to pass rule rule code through, without being + # tampered with + raw = opt['raw'] + raw_after = opt['raw_after'] + + src.each do |s| + # we'll store our pieces here, and join() them later + + @src = "-s #{s}" if s != '' + @src = nil if s == nil or s == '' + dst.each do |d| + @dst = "-d #{d}" if d != '' + @dst = nil if d == nil or d == '' + + rule = [ ] + rule.push(chn) + rule.push(in_int) + rule.push(out_int) + rule.push(@src) + rule.push(@dst) + rule.push(proto) + rule.push('-m multiport') if flg['multiport'] + rule.push(spt) + rule.push(dpt) + rule.push(ste) + rule.push(limit) + rule.push(raw) + rule.push(act) + rule.push(raw_after) + # add our action-specific flags now + rule.push(log) if flg['act_LOG'] + rule.push(rej) if flg['act_REJECT'] + rule.push(red) if flg['act_REDIRECT'] + rule.compact! + rule.delete('') + rule.delete('UNSET') + rules.push(rule.join(' ')) + end + end + return rules + + end +end diff --git a/lib/puppet/functions/iptables/iptables_parse_options.rb b/lib/puppet/functions/iptables/iptables_parse_options.rb new file mode 100644 index 0000000..40506e4 --- /dev/null +++ b/lib/puppet/functions/iptables/iptables_parse_options.rb @@ -0,0 +1,185 @@ +# This is an autogenerated function, ported from the original legacy version. +# It /should work/ as is, but will not have all the benefits of the modern +# function API. You should see the function docs to learn how to add function +# signatures for type safety and to document this function using puppet-strings. +# +# https://puppet.com/docs/puppet/latest/custom_functions_ruby.html +# +# ---- original file header ---- + +# ---- original file header ---- +# +# @summary +# +# +Puppet::Functions.create_function(:'iptables::iptables_parse_options') do + # @param args + # The original array of arguments. Port this to individually managed params + # to get the full benefit of the modern function API. + # + # @return [Data type] + # Describe what the function returns here + # + dispatch :default_impl do + # Call the method named 'default_impl' when this is matched + # Port this to match individual params for better type safety + repeated_param 'Any', :args + end + + + def default_impl(*args) + + Puppet::Parser::Functions.function('iptables_prep_option') + + options = { } + options = args[0].dup if args[0].is_a?(Hash) + options.delete_if { |k,v| v == 'UNSET' } + + defaults = { } + defaults = args[1].dup if args[1].is_a?(Hash) + defaults.delete_if { |k,v| v == 'UNSET' } + + version = '4' + version = args[2][-1].chr if args[2].is_a?(String) \ + and args[2] =~ /(?i-mx:ip(v)?(4|6))/ + + # these are the only static defaults for our module + mod_default = { + 'action' => 'ACCEPT', + 'chain' => 'INPUT', + 'table' => 'filter', + } + + # store any flags we want to pass back out to the calling function. this + # will end up being part of the options hash we return, with key 'mod_flags' + mod_flags = { } + + # + ## 'table' option - tbl_ flags + # + table_input = [ 'table', options, defaults, mod_default['table'] ] + options['table'] = function_iptables_prep_option(table_input) + mod_flags["tbl_#{options['table']}"] = true + + # + ## 'action' option - act_ flags + # + action_input = [ 'action', options, defaults, mod_default['action'] ] + options['action'] = function_iptables_prep_option( action_input ) + mod_flags["act_#{options['action']}"] = true + + # + ## 'chain' option - chn_ flags + # + chain_input = [ 'chain', options, defaults, mod_default['chain'] ] + options['chain'] = function_iptables_prep_option( chain_input ) + mod_flags["chn_#{options['chain']}"] = true + + # + ## 'destination' option + # + dest_input = [ 'destination', options, defaults, + mod_default['destination'] ] + options['destination'] = function_iptables_prep_option( dest_input ) + + # + ## 'destination_port' option + # + dpt_input = [ 'destination_port', options, defaults, + mod_default['destination_port'] ] + options['destination_port'] = function_iptables_prep_option( dpt_input ) + + # + ## 'incoming_interface' option + # + in_input = [ 'incoming_interface', options, defaults, + mod_default['incoming_interface'] ] + options['incoming_interface'] = function_iptables_prep_option( in_input ) + + # + ## 'log_ip_options' option + # + lio_input = [ 'log_ip_options', options, defaults, + mod_default['log_ip_options'] ] + options['log_ip_options']= function_iptables_prep_option( lio_input ) + + # + ## 'log_level' option + # + ll_input = [ 'log_level', options, defaults, mod_default['log_level'] ] + options['log_level'] = function_iptables_prep_option( ll_input ) + + # + ## 'log_prefix' option + # + lp_input = [ 'log_prefix', options, defaults, mod_default['log_prefix'] ] + options['log_prefix'] = function_iptables_prep_option( lp_input ) + + # + ## 'log_tcp_options' option + # + lto_input = [ 'log_tcp_options', options, defaults, + mod_default['log_tcp_options'] ] + options['log_tcp_options'] = function_iptables_prep_option( lto_input ) + + # + ## 'log_tcp_sequence' option + # + lts_input = [ 'log_tcp_sequence', options, defaults, + mod_default['log_tcp_sequence'] ] + options['log_tcp_sequence'] = function_iptables_prep_option( lts_input ) + + # + ## 'outgoing_interface' option + # + out_input = [ 'outgoing_interface', options, defaults, + mod_default['outgoing_interface'] ] + if options['outgoing_interface'] != '' + options['outgoing_interface'] = function_iptables_prep_option( out_input) + end + + # + ## 'protocol' option + # + proto_input = [ 'protocol', options, defaults, mod_default['protocol'] ] + options['protocol'] = function_iptables_prep_option( proto_input ) + mod_flags["proto_#{options['protocol']}"] = true \ + unless options['protocol'] == '' + # + ## 'source' option + # + src_input = [ 'source', options, defaults, mod_default['source'] ] + options['source'] = function_iptables_prep_option( src_input ) + + # + ## 'source_port' option + # + spt_input = [ 'source_port', options, defaults, mod_default['source_port'] ] + options['source_port'] = function_iptables_prep_option( spt_input ) + + # + ## 'state' option + # + ste_input = [ 'state', options, defaults, mod_default['state'] ] + options['state'] = function_iptables_prep_option( ste_input ) + + # + ## 'limit' option + # + lmt_input = [ 'limit', options, defaults, mod_default['limit'] ] + options['limit'] = function_iptables_prep_option( lmt_input ) + + # + ## 'limit_burst' option + # + lmt_burst_input = [ 'limit_burst', options, defaults, mod_default['limit_burst'] ] + options['limit_burst'] = function_iptables_prep_option( lmt_burst_input ) + + # finally, we return our options after pruning empty ones + options.delete_if { |opt,val| val=='' or val == nil or val == :undef } + options['mod_flags'] = mod_flags + + return options + + end +end diff --git a/lib/puppet/functions/iptables/iptables_prep_option.rb b/lib/puppet/functions/iptables/iptables_prep_option.rb new file mode 100644 index 0000000..3a850fc --- /dev/null +++ b/lib/puppet/functions/iptables/iptables_prep_option.rb @@ -0,0 +1,73 @@ +# This is an autogenerated function, ported from the original legacy version. +# It /should work/ as is, but will not have all the benefits of the modern +# function API. You should see the function docs to learn how to add function +# signatures for type safety and to document this function using puppet-strings. +# +# https://puppet.com/docs/puppet/latest/custom_functions_ruby.html +# +# ---- original file header ---- + +# ---- original file header ---- +# +# @summary +# Used internally by the iptables module, handles the determination of the initial +#value of our option by taking the provided name, values hash, defaults hash and +#default value, and returning the appropriate value. +# +#Example: +# +# vals = { 'opt2' => '1', 'opt3' => '2' } +# defs = { 'opt' => '0', 'opt3' => '4' } +# default = '-1' +# +# # returns '0' +# opt_val = iptables_prep_option( 'opt', vals, defs, default ) +# +# # returns '1' +# opt2_val = iptables_prep_option( 'opt2', vals, defs, default ) +# +# # returns '2' +# opt3_val = iptables_prep_option( 'opt3', vals, defs, default ) +# +# # returns -1 +# opt4_val = iptables_prep_option( 'opt4', vals, defs, default ) +# +# +Puppet::Functions.create_function(:'iptables::iptables_prep_option') do + # @param args + # The original array of arguments. Port this to individually managed params + # to get the full benefit of the modern function API. + # + # @return [Data type] + # Describe what the function returns here + # + dispatch :default_impl do + # Call the method named 'default_impl' when this is matched + # Port this to match individual params for better type safety + repeated_param 'Any', :args + end + + + def default_impl(*args) + + name = args[0] + + vals = { } + vals = args[1] if args[1].is_a?(Hash) + + defs = { } + defs = args[2] if args[2].is_a?(Hash) + + + default = '' + default = args[3] unless args[3] == nil or args[3] == :undef + + # just run through the values + ret = default + ret = defs[name] unless defs[name] == nil or defs[name] == :undef or defs[name] == 'UNSET' + ret = vals[name] unless vals[name] == nil or vals[name] == :undef or vals[name] == 'UNSET' + + return ret + + end +end diff --git a/spec/functions/iptables_format_action_spec.rb b/spec/functions/iptables_format_action_spec.rb new file mode 100644 index 0000000..60cbd1c --- /dev/null +++ b/spec/functions/iptables_format_action_spec.rb @@ -0,0 +1,41 @@ +require 'spec_helper' + +describe 'iptables::format_action' do + # without knowing details about the implementation, this is the only test + # case that we can autogenerate. You should add more examples below! + it { is_expected.not_to eq(nil) } + +################################# +# Below are some example test cases. You may uncomment and modify them to match +# your needs. Notice that they all expect the base error class of `StandardError`. +# This is because the autogenerated function uses an untyped array for parameters +# and relies on your implementation to do the validation. As you convert your +# function to proper dispatches and typed signatures, you should change the +# expected error of the argument validation examples to `ArgumentError`. +# +# Other error types you might encounter include +# +# * StandardError +# * ArgumentError +# * Puppet::ParseError +# +# Read more about writing function unit tests at https://rspec-puppet.com/documentation/functions/ +# +# it 'raises an error if called with no argument' do +# is_expected.to run.with_params.and_raise_error(StandardError) +# end +# +# it 'raises an error if there is more than 1 arguments' do +# is_expected.to run.with_params({ 'foo' => 1 }, 'bar' => 2).and_raise_error(StandardError) +# end +# +# it 'raises an error if argument is not the proper type' do +# is_expected.to run.with_params('foo').and_raise_error(StandardError) +# end +# +# it 'returns the proper output' do +# is_expected.to run.with_params(123).and_return('the expected output') +# end +################################# + +end diff --git a/spec/functions/iptables_format_chain_spec.rb b/spec/functions/iptables_format_chain_spec.rb new file mode 100644 index 0000000..e8483e1 --- /dev/null +++ b/spec/functions/iptables_format_chain_spec.rb @@ -0,0 +1,41 @@ +require 'spec_helper' + +describe 'iptables::format_chain' do + # without knowing details about the implementation, this is the only test + # case that we can autogenerate. You should add more examples below! + it { is_expected.not_to eq(nil) } + +################################# +# Below are some example test cases. You may uncomment and modify them to match +# your needs. Notice that they all expect the base error class of `StandardError`. +# This is because the autogenerated function uses an untyped array for parameters +# and relies on your implementation to do the validation. As you convert your +# function to proper dispatches and typed signatures, you should change the +# expected error of the argument validation examples to `ArgumentError`. +# +# Other error types you might encounter include +# +# * StandardError +# * ArgumentError +# * Puppet::ParseError +# +# Read more about writing function unit tests at https://rspec-puppet.com/documentation/functions/ +# +# it 'raises an error if called with no argument' do +# is_expected.to run.with_params.and_raise_error(StandardError) +# end +# +# it 'raises an error if there is more than 1 arguments' do +# is_expected.to run.with_params({ 'foo' => 1 }, 'bar' => 2).and_raise_error(StandardError) +# end +# +# it 'raises an error if argument is not the proper type' do +# is_expected.to run.with_params('foo').and_raise_error(StandardError) +# end +# +# it 'returns the proper output' do +# is_expected.to run.with_params(123).and_return('the expected output') +# end +################################# + +end diff --git a/spec/functions/iptables_format_interface_spec.rb b/spec/functions/iptables_format_interface_spec.rb new file mode 100644 index 0000000..678c7d3 --- /dev/null +++ b/spec/functions/iptables_format_interface_spec.rb @@ -0,0 +1,41 @@ +require 'spec_helper' + +describe 'iptables::format_interface' do + # without knowing details about the implementation, this is the only test + # case that we can autogenerate. You should add more examples below! + it { is_expected.not_to eq(nil) } + +################################# +# Below are some example test cases. You may uncomment and modify them to match +# your needs. Notice that they all expect the base error class of `StandardError`. +# This is because the autogenerated function uses an untyped array for parameters +# and relies on your implementation to do the validation. As you convert your +# function to proper dispatches and typed signatures, you should change the +# expected error of the argument validation examples to `ArgumentError`. +# +# Other error types you might encounter include +# +# * StandardError +# * ArgumentError +# * Puppet::ParseError +# +# Read more about writing function unit tests at https://rspec-puppet.com/documentation/functions/ +# +# it 'raises an error if called with no argument' do +# is_expected.to run.with_params.and_raise_error(StandardError) +# end +# +# it 'raises an error if there is more than 1 arguments' do +# is_expected.to run.with_params({ 'foo' => 1 }, 'bar' => 2).and_raise_error(StandardError) +# end +# +# it 'raises an error if argument is not the proper type' do +# is_expected.to run.with_params('foo').and_raise_error(StandardError) +# end +# +# it 'returns the proper output' do +# is_expected.to run.with_params(123).and_return('the expected output') +# end +################################# + +end diff --git a/spec/functions/iptables_format_log_spec.rb b/spec/functions/iptables_format_log_spec.rb new file mode 100644 index 0000000..4ee82da --- /dev/null +++ b/spec/functions/iptables_format_log_spec.rb @@ -0,0 +1,41 @@ +require 'spec_helper' + +describe 'iptables::format_log' do + # without knowing details about the implementation, this is the only test + # case that we can autogenerate. You should add more examples below! + it { is_expected.not_to eq(nil) } + +################################# +# Below are some example test cases. You may uncomment and modify them to match +# your needs. Notice that they all expect the base error class of `StandardError`. +# This is because the autogenerated function uses an untyped array for parameters +# and relies on your implementation to do the validation. As you convert your +# function to proper dispatches and typed signatures, you should change the +# expected error of the argument validation examples to `ArgumentError`. +# +# Other error types you might encounter include +# +# * StandardError +# * ArgumentError +# * Puppet::ParseError +# +# Read more about writing function unit tests at https://rspec-puppet.com/documentation/functions/ +# +# it 'raises an error if called with no argument' do +# is_expected.to run.with_params.and_raise_error(StandardError) +# end +# +# it 'raises an error if there is more than 1 arguments' do +# is_expected.to run.with_params({ 'foo' => 1 }, 'bar' => 2).and_raise_error(StandardError) +# end +# +# it 'raises an error if argument is not the proper type' do +# is_expected.to run.with_params('foo').and_raise_error(StandardError) +# end +# +# it 'returns the proper output' do +# is_expected.to run.with_params(123).and_return('the expected output') +# end +################################# + +end diff --git a/spec/functions/iptables_format_port_spec.rb b/spec/functions/iptables_format_port_spec.rb new file mode 100644 index 0000000..a2d1ae8 --- /dev/null +++ b/spec/functions/iptables_format_port_spec.rb @@ -0,0 +1,41 @@ +require 'spec_helper' + +describe 'iptables::format_port' do + # without knowing details about the implementation, this is the only test + # case that we can autogenerate. You should add more examples below! + it { is_expected.not_to eq(nil) } + +################################# +# Below are some example test cases. You may uncomment and modify them to match +# your needs. Notice that they all expect the base error class of `StandardError`. +# This is because the autogenerated function uses an untyped array for parameters +# and relies on your implementation to do the validation. As you convert your +# function to proper dispatches and typed signatures, you should change the +# expected error of the argument validation examples to `ArgumentError`. +# +# Other error types you might encounter include +# +# * StandardError +# * ArgumentError +# * Puppet::ParseError +# +# Read more about writing function unit tests at https://rspec-puppet.com/documentation/functions/ +# +# it 'raises an error if called with no argument' do +# is_expected.to run.with_params.and_raise_error(StandardError) +# end +# +# it 'raises an error if there is more than 1 arguments' do +# is_expected.to run.with_params({ 'foo' => 1 }, 'bar' => 2).and_raise_error(StandardError) +# end +# +# it 'raises an error if argument is not the proper type' do +# is_expected.to run.with_params('foo').and_raise_error(StandardError) +# end +# +# it 'returns the proper output' do +# is_expected.to run.with_params(123).and_return('the expected output') +# end +################################# + +end diff --git a/spec/functions/iptables_format_protocol_spec.rb b/spec/functions/iptables_format_protocol_spec.rb new file mode 100644 index 0000000..91a3c20 --- /dev/null +++ b/spec/functions/iptables_format_protocol_spec.rb @@ -0,0 +1,41 @@ +require 'spec_helper' + +describe 'iptables::format_protocol' do + # without knowing details about the implementation, this is the only test + # case that we can autogenerate. You should add more examples below! + it { is_expected.not_to eq(nil) } + +################################# +# Below are some example test cases. You may uncomment and modify them to match +# your needs. Notice that they all expect the base error class of `StandardError`. +# This is because the autogenerated function uses an untyped array for parameters +# and relies on your implementation to do the validation. As you convert your +# function to proper dispatches and typed signatures, you should change the +# expected error of the argument validation examples to `ArgumentError`. +# +# Other error types you might encounter include +# +# * StandardError +# * ArgumentError +# * Puppet::ParseError +# +# Read more about writing function unit tests at https://rspec-puppet.com/documentation/functions/ +# +# it 'raises an error if called with no argument' do +# is_expected.to run.with_params.and_raise_error(StandardError) +# end +# +# it 'raises an error if there is more than 1 arguments' do +# is_expected.to run.with_params({ 'foo' => 1 }, 'bar' => 2).and_raise_error(StandardError) +# end +# +# it 'raises an error if argument is not the proper type' do +# is_expected.to run.with_params('foo').and_raise_error(StandardError) +# end +# +# it 'returns the proper output' do +# is_expected.to run.with_params(123).and_return('the expected output') +# end +################################# + +end diff --git a/spec/functions/iptables_format_reject_spec.rb b/spec/functions/iptables_format_reject_spec.rb new file mode 100644 index 0000000..e416430 --- /dev/null +++ b/spec/functions/iptables_format_reject_spec.rb @@ -0,0 +1,41 @@ +require 'spec_helper' + +describe 'iptables::format_reject' do + # without knowing details about the implementation, this is the only test + # case that we can autogenerate. You should add more examples below! + it { is_expected.not_to eq(nil) } + +################################# +# Below are some example test cases. You may uncomment and modify them to match +# your needs. Notice that they all expect the base error class of `StandardError`. +# This is because the autogenerated function uses an untyped array for parameters +# and relies on your implementation to do the validation. As you convert your +# function to proper dispatches and typed signatures, you should change the +# expected error of the argument validation examples to `ArgumentError`. +# +# Other error types you might encounter include +# +# * StandardError +# * ArgumentError +# * Puppet::ParseError +# +# Read more about writing function unit tests at https://rspec-puppet.com/documentation/functions/ +# +# it 'raises an error if called with no argument' do +# is_expected.to run.with_params.and_raise_error(StandardError) +# end +# +# it 'raises an error if there is more than 1 arguments' do +# is_expected.to run.with_params({ 'foo' => 1 }, 'bar' => 2).and_raise_error(StandardError) +# end +# +# it 'raises an error if argument is not the proper type' do +# is_expected.to run.with_params('foo').and_raise_error(StandardError) +# end +# +# it 'returns the proper output' do +# is_expected.to run.with_params(123).and_return('the expected output') +# end +################################# + +end diff --git a/spec/functions/iptables_format_state_spec.rb b/spec/functions/iptables_format_state_spec.rb new file mode 100644 index 0000000..aeb941d --- /dev/null +++ b/spec/functions/iptables_format_state_spec.rb @@ -0,0 +1,41 @@ +require 'spec_helper' + +describe 'iptables::format_state' do + # without knowing details about the implementation, this is the only test + # case that we can autogenerate. You should add more examples below! + it { is_expected.not_to eq(nil) } + +################################# +# Below are some example test cases. You may uncomment and modify them to match +# your needs. Notice that they all expect the base error class of `StandardError`. +# This is because the autogenerated function uses an untyped array for parameters +# and relies on your implementation to do the validation. As you convert your +# function to proper dispatches and typed signatures, you should change the +# expected error of the argument validation examples to `ArgumentError`. +# +# Other error types you might encounter include +# +# * StandardError +# * ArgumentError +# * Puppet::ParseError +# +# Read more about writing function unit tests at https://rspec-puppet.com/documentation/functions/ +# +# it 'raises an error if called with no argument' do +# is_expected.to run.with_params.and_raise_error(StandardError) +# end +# +# it 'raises an error if there is more than 1 arguments' do +# is_expected.to run.with_params({ 'foo' => 1 }, 'bar' => 2).and_raise_error(StandardError) +# end +# +# it 'raises an error if argument is not the proper type' do +# is_expected.to run.with_params('foo').and_raise_error(StandardError) +# end +# +# it 'returns the proper output' do +# is_expected.to run.with_params(123).and_return('the expected output') +# end +################################# + +end diff --git a/spec/functions/iptables_iptables_format_limit_spec.rb b/spec/functions/iptables_iptables_format_limit_spec.rb new file mode 100644 index 0000000..a189f62 --- /dev/null +++ b/spec/functions/iptables_iptables_format_limit_spec.rb @@ -0,0 +1,41 @@ +require 'spec_helper' + +describe 'iptables::iptables_format_limit' do + # without knowing details about the implementation, this is the only test + # case that we can autogenerate. You should add more examples below! + it { is_expected.not_to eq(nil) } + +################################# +# Below are some example test cases. You may uncomment and modify them to match +# your needs. Notice that they all expect the base error class of `StandardError`. +# This is because the autogenerated function uses an untyped array for parameters +# and relies on your implementation to do the validation. As you convert your +# function to proper dispatches and typed signatures, you should change the +# expected error of the argument validation examples to `ArgumentError`. +# +# Other error types you might encounter include +# +# * StandardError +# * ArgumentError +# * Puppet::ParseError +# +# Read more about writing function unit tests at https://rspec-puppet.com/documentation/functions/ +# +# it 'raises an error if called with no argument' do +# is_expected.to run.with_params.and_raise_error(StandardError) +# end +# +# it 'raises an error if there is more than 1 arguments' do +# is_expected.to run.with_params({ 'foo' => 1 }, 'bar' => 2).and_raise_error(StandardError) +# end +# +# it 'raises an error if argument is not the proper type' do +# is_expected.to run.with_params('foo').and_raise_error(StandardError) +# end +# +# it 'returns the proper output' do +# is_expected.to run.with_params(123).and_return('the expected output') +# end +################################# + +end diff --git a/spec/functions/iptables_iptables_format_to_port_spec.rb b/spec/functions/iptables_iptables_format_to_port_spec.rb new file mode 100644 index 0000000..8b9902f --- /dev/null +++ b/spec/functions/iptables_iptables_format_to_port_spec.rb @@ -0,0 +1,41 @@ +require 'spec_helper' + +describe 'iptables::iptables_format_to_port' do + # without knowing details about the implementation, this is the only test + # case that we can autogenerate. You should add more examples below! + it { is_expected.not_to eq(nil) } + +################################# +# Below are some example test cases. You may uncomment and modify them to match +# your needs. Notice that they all expect the base error class of `StandardError`. +# This is because the autogenerated function uses an untyped array for parameters +# and relies on your implementation to do the validation. As you convert your +# function to proper dispatches and typed signatures, you should change the +# expected error of the argument validation examples to `ArgumentError`. +# +# Other error types you might encounter include +# +# * StandardError +# * ArgumentError +# * Puppet::ParseError +# +# Read more about writing function unit tests at https://rspec-puppet.com/documentation/functions/ +# +# it 'raises an error if called with no argument' do +# is_expected.to run.with_params.and_raise_error(StandardError) +# end +# +# it 'raises an error if there is more than 1 arguments' do +# is_expected.to run.with_params({ 'foo' => 1 }, 'bar' => 2).and_raise_error(StandardError) +# end +# +# it 'raises an error if argument is not the proper type' do +# is_expected.to run.with_params('foo').and_raise_error(StandardError) +# end +# +# it 'returns the proper output' do +# is_expected.to run.with_params(123).and_return('the expected output') +# end +################################# + +end diff --git a/spec/functions/iptables_iptables_generate_rule_spec.rb b/spec/functions/iptables_iptables_generate_rule_spec.rb new file mode 100644 index 0000000..92f477f --- /dev/null +++ b/spec/functions/iptables_iptables_generate_rule_spec.rb @@ -0,0 +1,41 @@ +require 'spec_helper' + +describe 'iptables::iptables_generate_rule' do + # without knowing details about the implementation, this is the only test + # case that we can autogenerate. You should add more examples below! + it { is_expected.not_to eq(nil) } + +################################# +# Below are some example test cases. You may uncomment and modify them to match +# your needs. Notice that they all expect the base error class of `StandardError`. +# This is because the autogenerated function uses an untyped array for parameters +# and relies on your implementation to do the validation. As you convert your +# function to proper dispatches and typed signatures, you should change the +# expected error of the argument validation examples to `ArgumentError`. +# +# Other error types you might encounter include +# +# * StandardError +# * ArgumentError +# * Puppet::ParseError +# +# Read more about writing function unit tests at https://rspec-puppet.com/documentation/functions/ +# +# it 'raises an error if called with no argument' do +# is_expected.to run.with_params.and_raise_error(StandardError) +# end +# +# it 'raises an error if there is more than 1 arguments' do +# is_expected.to run.with_params({ 'foo' => 1 }, 'bar' => 2).and_raise_error(StandardError) +# end +# +# it 'raises an error if argument is not the proper type' do +# is_expected.to run.with_params('foo').and_raise_error(StandardError) +# end +# +# it 'returns the proper output' do +# is_expected.to run.with_params(123).and_return('the expected output') +# end +################################# + +end diff --git a/spec/functions/iptables_iptables_parse_options_spec.rb b/spec/functions/iptables_iptables_parse_options_spec.rb new file mode 100644 index 0000000..b4eda77 --- /dev/null +++ b/spec/functions/iptables_iptables_parse_options_spec.rb @@ -0,0 +1,41 @@ +require 'spec_helper' + +describe 'iptables::iptables_parse_options' do + # without knowing details about the implementation, this is the only test + # case that we can autogenerate. You should add more examples below! + it { is_expected.not_to eq(nil) } + +################################# +# Below are some example test cases. You may uncomment and modify them to match +# your needs. Notice that they all expect the base error class of `StandardError`. +# This is because the autogenerated function uses an untyped array for parameters +# and relies on your implementation to do the validation. As you convert your +# function to proper dispatches and typed signatures, you should change the +# expected error of the argument validation examples to `ArgumentError`. +# +# Other error types you might encounter include +# +# * StandardError +# * ArgumentError +# * Puppet::ParseError +# +# Read more about writing function unit tests at https://rspec-puppet.com/documentation/functions/ +# +# it 'raises an error if called with no argument' do +# is_expected.to run.with_params.and_raise_error(StandardError) +# end +# +# it 'raises an error if there is more than 1 arguments' do +# is_expected.to run.with_params({ 'foo' => 1 }, 'bar' => 2).and_raise_error(StandardError) +# end +# +# it 'raises an error if argument is not the proper type' do +# is_expected.to run.with_params('foo').and_raise_error(StandardError) +# end +# +# it 'returns the proper output' do +# is_expected.to run.with_params(123).and_return('the expected output') +# end +################################# + +end diff --git a/spec/functions/iptables_iptables_prep_option_spec.rb b/spec/functions/iptables_iptables_prep_option_spec.rb new file mode 100644 index 0000000..41b793b --- /dev/null +++ b/spec/functions/iptables_iptables_prep_option_spec.rb @@ -0,0 +1,41 @@ +require 'spec_helper' + +describe 'iptables::iptables_prep_option' do + # without knowing details about the implementation, this is the only test + # case that we can autogenerate. You should add more examples below! + it { is_expected.not_to eq(nil) } + +################################# +# Below are some example test cases. You may uncomment and modify them to match +# your needs. Notice that they all expect the base error class of `StandardError`. +# This is because the autogenerated function uses an untyped array for parameters +# and relies on your implementation to do the validation. As you convert your +# function to proper dispatches and typed signatures, you should change the +# expected error of the argument validation examples to `ArgumentError`. +# +# Other error types you might encounter include +# +# * StandardError +# * ArgumentError +# * Puppet::ParseError +# +# Read more about writing function unit tests at https://rspec-puppet.com/documentation/functions/ +# +# it 'raises an error if called with no argument' do +# is_expected.to run.with_params.and_raise_error(StandardError) +# end +# +# it 'raises an error if there is more than 1 arguments' do +# is_expected.to run.with_params({ 'foo' => 1 }, 'bar' => 2).and_raise_error(StandardError) +# end +# +# it 'raises an error if argument is not the proper type' do +# is_expected.to run.with_params('foo').and_raise_error(StandardError) +# end +# +# it 'returns the proper output' do +# is_expected.to run.with_params(123).and_return('the expected output') +# end +################################# + +end