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

(MODULES-8543) Remove nftables' backend warning from iptables_save outtput #911

Merged
merged 2 commits into from Apr 22, 2020

Conversation

NITEMAN
Copy link
Contributor

@NITEMAN NITEMAN commented Apr 1, 2020

@NITEMAN NITEMAN requested a review from a team as a code owner April 1, 2020 10:54
Copy link

@rayderua rayderua left a comment

Choose a reason for hiding this comment

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

Work only on ipv4 iptables :(
ipv6 warning is: # Warning: ip6tables-legacy tables present, use ip6tables-legacy-save to see them\n

@NITEMAN
Copy link
Contributor Author

NITEMAN commented Apr 14, 2020

@rayderua extended to support ip6tables. It should work but testing is always appreciated

@rayderua
Copy link

Thanks!
Waiting for release

@david22swan
Copy link
Member

@NITEMAN Apologies but I don't think this is something that I can merge. While I can see why you wish this change made, the suppression and removal of warnings is not something that we would like within our code. Rather than simply removing the warns outright if you could instead in turn throw a puppet warn when they are detected I think that that would be more beneficial overall.

@cFire
Copy link

cFire commented Apr 15, 2020

Just my 2 cents:
It looks like it isn't so much an issue of having to suppress the the warning. From the errors we see (and as they are shown in the issue linked earlier) it looks like it's a problem with STDERR and STDOUT getting mixed together.

The STDERR output (ie. the warnings about iptables-legacy) are spliced into STDOUT by whatever random timing it happens to produce the warning at, causing them to show up halfway into an iptables rule. After all, these warnings start with a #, which would mean they'd normally get ignored by the rule parser if they started at the start of the line like they should.

I suspect if we properly split out STDOUT and STDERR (maybe concat STDERR to the end of STDOUT if we care about parsing it) that the problem should go away.

disclaimer: I've not yet tested ANY of this. It's just what it looks like to me from experience.

@NITEMAN
Copy link
Contributor Author

NITEMAN commented Apr 17, 2020

@david22swan the problem is exactly what @cFire points (and that's also mentioned on the original issue with links tu Puppet's core code) .

I might try to raise a puppet warning when ip6?tables-save output contains the warning but:

  • If we want different warnings for iptables-save / ip6tables-save, detection logic will complicate.
  • IMHO the warning will be useless for the user, since the module doesn't support ip6?tables-legacy-save
  • We'll need to strip the warning from the output anyway to make the parser work.

@NITEMAN
Copy link
Contributor Author

NITEMAN commented Apr 17, 2020

Also, this code gets called a bunch of times, causing in one test machine the warning to be printed more than 20 times if introduced

@NITEMAN NITEMAN removed the request for review from a team April 17, 2020 15:37
@NITEMAN
Copy link
Contributor Author

NITEMAN commented Apr 17, 2020

FTR, my warning try consisted on inserting this block between the two lines:

    if iptables_save =~ %r{#{nf_warning_msg}}
      warning "Sripping '#{nf_warning_msg}' form ip6?tables-save combined output"
    end 

@cFire
Copy link

cFire commented Apr 21, 2020

How about something like this?

--- a/lib/puppet/provider/firewall/iptables.rb
+++ b/lib/puppet/provider/firewall/iptables.rb
@@ -406,7 +406,7 @@ Puppet::Type.type(:firewall).provide :iptables, parent: Puppet::Provider::Firewa
     counter = 1
 
     # String#lines would be nice, but we need to support Ruby 1.8.5
-    iptables_save.split("\n").each do |line|
+    self.execute('iptables-save', { :combine => false }).split("\n").each do |line|
       unless line =~ %r{^\#\s+|^\:\S+|^COMMIT|^FATAL}
         if line =~ %r{^\*}
           table = line.sub(%r{\*}, '')

The way the exec is done here is not very pretty, but I've not found another way to tell Puppet::Provider to drop the stderr output.

I've not seen any way to make it behave cleaner either as it calls Puppet::Util::Execution under the hood and this uses IO.select to read 4096 bytes from whichever IO buffer is ready to provide and appends it to an output variable. which assigns stdout and stderr to the same IO.pipe causing them to get mixed by the timing the with which the process outputs to either pipe.
(See https://github.com/puppetlabs/puppet/blob/master/lib/puppet/util/execution.rb#L212 for implementation.)

This is a long winded way of saying "I don't think we can keep stderr and not have this problem."

@NITEMAN
Copy link
Contributor Author

NITEMAN commented Apr 21, 2020

@cFire honestly I don't know what would be better... in one hand your fix is future proof and output agnostic but in the other hand it might lead to other issues going unnoticed.

Anyway, I will welcome any solution that fix the module

@cFire
Copy link

cFire commented Apr 21, 2020

Also, let me be perfectly clear that this is something that should be fixed in puppet (and time permitting, I may give that a shot). The best we can do here is a workaround that's not too ugly.

As for the concerns @david22swan expressed about suppressing warnings; I don't think it's something this change would affect. Since iptables-save is in the habit of prefixing any warnings with a # so they don't break anything when you iptables-restore it, and since the line parser already completely ignores any lines starting with #, all errors are already silently ignored as it is.

Now you might argue that this is bad, and you may be right. But I think that discussion is academic here since we would not be changing the current behavior by dropping stderr.

If the solution I proposed in my diff is found to be acceptable, I'll create a new PR for it. (Since if it's not found to be acceptable I'm not going to put time into fixing the spec tests of course.)

@david22swan david22swan merged commit 233f841 into puppetlabs:master Apr 22, 2020
@david22swan
Copy link
Member

@NITEMAN After some discussion with the team we have decided to merge this as it is. Thank you for the work you have put in.

@cFire
Copy link

cFire commented Apr 22, 2020

@NITEMAN After some discussion with the team we have decided to merge this as it is.

I would recommend against this, as it is not technically correct. The fix as-is discards any lines of output that happens to get corrupted by the error, masking its effects. But I suspect this may lead to duplicate rules getting inserted and/or partially parsed rules getting incorrectly purged.

@NITEMAN
Copy link
Contributor Author

NITEMAN commented Apr 23, 2020

@cFire my fix doesn't discard the line but strips the string from the output (before splitting). If it worths anything my fix is already production tested without issues for nearly a month in ~10 different servers.

@david22swan thank you very much for your continued work.

@cFire
Copy link

cFire commented Apr 23, 2020

@cFire my fix doesn't discard the line but strips the string from the output (before splitting).

Apologies. I apparently miss-remembered what your patch did exactly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants