[th/firewall-cmd-show-overview] show more information with plain firewall-cmd output#1186
Open
thom311 wants to merge 11 commits intofirewalld:mainfrom
Open
[th/firewall-cmd-show-overview] show more information with plain firewall-cmd output#1186thom311 wants to merge 11 commits intofirewalld:mainfrom
firewall-cmd output#1186thom311 wants to merge 11 commits intofirewalld:mainfrom
Conversation
9c73298 to
7018d75
Compare
erig0
requested changes
Oct 10, 2023
Collaborator
erig0
left a comment
There was a problem hiding this comment.
Most of this looks good. I appreciate the clean ups.
7018d75 to
fdda506
Compare
fdda506 to
031d0a2
Compare
031d0a2 to
7ae1774
Compare
7ae1774 to
d4d95e3
Compare
The exit() helper (of course) only wraps sys.exit(). However, it's also *the* blessed way how we can call exit. That means, if you want to add some printf debugging, this is the place. There are still many direct calls to sys.exit(). Maybe at the places where we use FirewallCommand, we should use instead cmd.exit().
d4d95e3 to
b18da6d
Compare
There are various alternative functions for printing. Some are more customizable than others. They also have different defaults or behaviors (e.g. print to stderr instead of stdout). Add a print() functions, which does it all. This is the basis for all convenience wrappers. If you wonder what print_warning() or print_error_msg() does, they all just call print() with different arguments. I find this a useful property. Whatever wrapper for the print function we use, internally they end up at the similar code. The wrappers only exist for selecting different default values (or internal parameters) to the print() function. Also add an "eol" argument to make that configurable. That may be the main reason for this patch. The "eol" argument is a fundamental tweak, that is potentially useful to any of the print variants. I wouldn't want to add the "eol" argument to any convenience wrappers like print_error_msg(). In particular, I wouldn't want to (re) implement the logic differently. A user who needs to use a different "eol", can now call the print() function directly. By choosing the right arguments, they also can be sure that what they do behaves in a similar manner as the wrapper functions. Despite the large number of arguments to print(), they still make sense and have useful default values.
…nnection_established() There is no conceivable reason why the creation of the D-Bus proxy objects should fail, after we successfully got a D-Bus object. Move the code out of the try-except block, which would hide errors. This code should not fail, and if it would, we want to notice.
…tate
Only emit the signals that connection was established/lost, if
there is an actual change. In other words, make (some parts of)
_connection_{established,lost}() idempotent.
Also, drop comments like
# connection established
self._connection_established()
Clearing "dbus_obj" and "fw_policies" was forgotten, and "fw_helper" is unused. Also drop @handle_exceptions. This method is not supposed to throw exceptions, and there is nothing to handle.
dbus.exceptions.DBusException does not always have a valid dbus_name. Check for that, otherwise we get another exception while handling the exception.
… not running
When the daemon is not running, then bus.get_object() in
_connection_established() fails with a D-Bus exception
"org.freedesktop.DBus.Error.ServiceUnknown" and message "The name is not
activatable" (when using d-bus broker).
Consequently, self.dbus_obj and attributes like self.fw_properties are
left at None.
That means, if we call `firewall-cmd`, we get an attribute error and an
ugly backtrace:
$ firewall-cmd
Exception 'NoneType' object has no attribute 'Get'
Error: Traceback (most recent call last):
File "/usr/lib/python3.11/site-packages/firewall/client.py", line 50, in _impl
return func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.11/site-packages/firewall/client.py", line 3150, in get_property
return dbus_to_python(self.fw_properties.Get(
^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'Get'
Try to handle that case better by raising a better exception.
What we instead could do, is calling
self.dbus_obj = self.bus.get_object(config.dbus.DBUS_INTERFACE,
config.dbus.DBUS_PATH,
follow_name_owner_changes=True)
then we would always be able to create D-Bus proxy objects. However,
that affects the tracking of the well-known name, and I think we would
need to adjust our _connection_established() handling. It's not clear to
me, that that would really be preferable, at least not without further
changes.
Instead, add for attributes like `self.fw_properties` a getter
`self._get_fw_properties()`, which will raise a DBusException when the
proxy is None. Update most places that accessed the attribute to use the
new getter functions.
This gives:
$ firewall-cmd
Error: org.freedesktop.DBus.Error.NameHasNoOwner: firewalld is not running
Another benefit is, that you can catch DBusException when calling those
D-Bus methods, and don't need to consider that they might fail with an
AttributeError (which would indicate some internal bug).
This essentially allows to assert that what we request, has the expected type.
The methods like FirewallClient.get_property() are decorated by @handle_exceptions. Users (like `firewall-cmd`) hook into those exceptions and will abort the process. Add FirewallClient.raw_*() helpers to access the underlying functionality. When calling these, we can handle the exceptions ourselves.
b18da6d to
bf67676
Compare
…ll-cmd`
Make calling `firewall-cmd` without arguments show some more useful information.
Similar to `nmcli`, `networkctl`, and `systemctl`, which give an overview.
The shown data is subject to change and further improvements.
- drop the "No options specified" line, it's not interesting and wastes
space.
- don't exit with error code 2 but with success (zero). Unless firewalld is not
running, in which case exit with 252 (NOT_RUNNING) or 253 (NOT_AUTHORIZED).
- previously, errors we handled by @handle_exceptions decorator. In
particular, that handled the not-running and not-authorized cases.
Now, that handling is bypassed, aiming to do something more useful.
Honors "--verbose" to show more information. It also overrides "--quiet"
handling. Currently passing "--quiet" has no additional effect, but we
could imagine to show even less information (but still more than none).
Example:
$ firewall-cmd -v
State: running
Version: 2.0.999
ActiveZones:
public (default)
Zones:
FedoraServer
FedoraWorkstation
block
dmz
drop
external
home
internal
nm-shared
trusted
work
ActivePolicies:
allow-host-ipv6
ingress-zones: ANY
egress-zones: HOST
usage: 'firewall-cmd --help' for usage information or see firewall-cmd(1) man page
bf67676 to
5989748
Compare
erig0
requested changes
Apr 11, 2024
Collaborator
There was a problem hiding this comment.
I like this idea, but instead of adding things like _get_fw_ipset() I'd rather override __getattribute__(). I think it's more likely that new code written may do self.fw and not realize there are these helper functions. It also avoids changing all these call sites.
def __getattribute__(self, attr):
value = super().__getattribute__(attr)
if attr in ["fw", "fw_ipset" ... ] and value is None:
raise dbus.exceptions.DBusException(
"org.freedesktop.DBus.Error.NameHasNoOwner: firewalld is not running"
)
return value| def getZoneNames(self): | ||
| return self.raw_getZoneNames() | ||
|
|
||
| def raw_getZoneNames(self): |
Collaborator
There was a problem hiding this comment.
These are only used for show_state_and_exit(). If one fails I would expect them all to fail. So in show_state_and_exit() couldn't we have a single failure scenario that prints "unknown" for all things. i.e. fetch all the days in try, and if you get an exception set all the printed info to "unknown".
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Let
firewall-cmd(without command arguments) show an overview of the current configuration.The fields that are shown are subject to change and improvement.
Depending on what exactly is requested, this could fix #1062
Example: