本文介绍了dbus_to_python()只需要1个参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图通过Python dbus 模块控制 firewalld



我想为我的当前运行时以及永久配置添加一个ip地址到信任区。



这里是文档 firewalld 的dbus介面:



有效:运行时配置



我可以将其添加到运行时配置,只需:

  def trustIP(ip):
'''firewalld必须已经运行'''
从dbus import SystemBus
bus = SystemBus()
runtimeProxy = bus.get_object('org.fedoraproject.FirewallD1',
'/ org / fedoraproject / FirewallD1')
runtimeProxy.addSource ip)

很简单。



strong>不起作用:永久配置



将其添加到永久配置已证明更加困难。这里是我到目前为止交互式尝试的:

 >>来自dbus import SystemBus 
>>>> bus = SystemBus()

#首先我需要找出哪个对象是受信任的区域...
>>> config = bus.get_object('org.fedoraproject.FirewallD1',
'/ org / fedoraproject / FirewallD1 / config')
>>>> config.getZoneByName('trusted')
dbus.ObjectPath('/ org / fedoraproject / FirewallD1 / config / zone / 7')

>>> permanentProxy = bus.get_object('org.fedoraproject.FirewallD1',
'/ org / fedoraproject / FirewallD1 / config / zone / 7')

快速检查,正确的对象:
>>>> permanentProxy.getShort()
dbus.String(u'Trusted')

#正好是我的期望,所以移动和...
>>> permanentProxy.addSource('aaa.xxx.yyy.zzz')#实际ip被移除...
回溯(最近一次调用最后):
文件< stdin>,第1行, ;模块>
文件/usr/lib64/python2.7/site-packages/dbus/proxies.py,第145行,在__call__
**关键字中)
文件/ usr / lib64 / python2.7 / site-packages / dbus / connection.py,行651,在call_blocking
消息,超时)
dbus.exceptions.DBusException:
org.freedesktop.DBus.Python。 dbus.exceptions.DBusException:
dbus_to_python()只需要1个参数(给定2个)

我也试过检查 permanentProxy.getDescription(),它返回的描述,因为它应该有,我尝试 permanentProxy.setDescription('test'),它与 permanentProxy.addSource('aaa.xxx.yyy.zzz')完全相同的堆栈跟踪失败。



我会跳转到错误在于python dbus 模块并假设它不正确处理参数的结论,除了事实, runtimeProxy.addSource('trusted',ip)涉及两个参数,并完美地工作。 config.getZoneByName('trusted')甚至有与permanentProxy.addSource('aaa.xxx.yyy.zzz')'相同的签名,只有一个字符串, 。



所以也许有一些奇怪的我错过了?但我不知道会是什么...



更多我没有成功的东西 b $ b

我认为可能 addSource 应该被调用没有字符串参数,也许curry不知何故或什么,所以我试试这个: / p>

 >>> permanentProxy.addSource()
回溯(最近一次调用):
在< module>中的文件< stdin&
文件/usr/lib64/python2.7/site-packages/dbus/proxies.py,第145行,在__call__
**关键字中)
文件/ usr / lib64 / python2.7 / site-packages / dbus / connection.py,行651,在call_blocking
消息,超时)
dbus.exceptions.DBusException:org.freedesktop.DBus.Python.TypeError:Traceback最近最近一次调用:
文件/usr/lib/python2.7/site-packages/slip/dbus/service.py,第123行,在reply_handler
result = method(self,* p,** k)
TypeError:addSource()至少需要2个参数(2给出)

这只是甚至weirder现在...我有一个Traceback在另一个traceback坚持,我需要传入至少2个参数,但也说我给它两个参数(我实际上只给它一个,所以如何)



还有一些我没有成功的事情:

 >>> 
错误:dbus.connection:无法根据签名u的':< type'exceptions.TypeError'>设置参数()。 :在D-Bus签名中找到的更多项目比Python参数
Traceback(最近最后调用):
在< module>中第1行的文件< stdin&
文件/usr/lib64/python2.7/site-packages/dbus/proxies.py,第145行,在__call__
**关键字中)
文件/ usr / lib64 / python2.7 / site-packages / dbus / connection.py,行641,在call_blocking
message.append(signature = signature,* args)
TypeError:在D-Bus签名中找到的项目比在Python参数

>>>
回溯(最近最后一次调用):
文件< stdin>(< stdin> ,行1,在< module>
文件/usr/lib64/python2.7/site-packages/dbus/proxies.py,第145行,在__call__
**关键字中)
文件/ usr / lib64 / python2.7 / site-packages / dbus / connection.py,行651,在call_blocking
消息,超时)
dbus.exceptions.DBusException:
org.freedesktop.DBus.Python。 dbus.exceptions.DBusException:
dbus_to_python()只需要1个参数(给定2个)

>>>从dbus import接口
>>>>接口(permanentProxy,'org.fedoraproject.FirewallD1.config.zone')。addSource('aaa.xxx.yyy.zzz')
回溯(最近最后调用):
文件< stdin> ;,行1,在< module>
文件/usr/lib64/python2.7/site-packages/dbus/proxies.py,第145行,在__call__
**关键字中)
文件/ usr / lib64 / python2.7 / site-packages / dbus / connection.py,行651,在call_blocking
消息,超时)
dbus.exceptions.DBusException:
org.freedesktop.DBus.Python。 dbus.exceptions.DBusException:
dbus_to_python()只需要1个参数(给定2个)

Gah!



这真的像是 dbus 最初解决 addSource 不正确,并认为它需要较少的参数,但如果你给它较少的参数,它想要,它会通过那个错误的检查,然后它会正确解决和失败,因为你的参数不匹配。



这是我的理论。有人看到我不是吗?有没有办法我可以解决这个bug,如果真的有一个? IE ...有一些我可以在dbus上使用的内部方法,这将强制它调用正确的方法?

解决方案

以下适用于我:

 >> import dbus 
>>>> bus = dbus.SystemBus()
>>>> config = bus.get_object('org.fedoraproject.FirewallD1',
...'/ org / fedoraproject / FirewallD1 / config')
>>> path = config.getZoneByName('trusted')
>>>> zone = bus.get_object('org.fedoraproject.FirewallD1',path)
>>>> zone.addSource('192.168.1.0/24')

此时, code> /etc/firewalld/zones/trusted.xml ,我可以看到源地址已按预期添加:

 <?xml version =1.0encoding =utf-8?> 
< zone target =ACCEPT>
< short> Trusted< / short>
< description>接受所有网络连接。< / description>
< interface name =docker0/>
< interface name =virbr0/>
< source address =192.168.1.0/24/>
< / zone>

...表示我已成功更改持久配置。



如果我在第二个 get_object 调用中使用文字路径,而不是 config的返回值,上面的代码也可以工作。 getZoneByName



对于值得的,我正在运行:




  • Fedora 23

  • firewalld-0.3.14.2-4.fc23.noarch

  • dbus-1.10.6-1.fc23 .x86_64

  • dbus-python-1.2.0-12.fc23.x86_64



strong> UPDATE



由于您使用的是CentOS,而不是Fedora,因此您没有看到任何更新的内容。看起来,解决这个特定任务的最简单的方法可能是使用FirewallD附带的 firewall python模块。以下适用于我在CentOS 7上:

 >> from firewall.client import * 
>>>> client = FirewallClient()
>>>> zone = client.config()。getZoneByName('public')
>>> settings = zone.getSettings()
>>>> settings.addSource('192.168.1.0/24')
>>>> zone.update(settings)

其他更新
$ b

通过源码浏览到 firewall.client 模块,你可以通过直接的dbus这样做:

 >>> zone = bus.get_object('org.fedoraproject.FirewallD1',path)
>>>> settings = zone.getSettings()
>>>> settings [11] .append('192.168.20.0/24')
>>> zone.update(settings)

在CentOS下正常工作。 。但是你最好使用 firewall 模块。


I'm attempting to control firewalld via the Python dbus module.

I'd like to add an ip address to the trusted zone for both my current runtime as well as my permanent configuration.

Here's the documentation for firewalld's dbus interface:http://manpages.ubuntu.com/manpages/wily/man5/firewalld.dbus.5.html

What works: The runtime configuration

I'm able to add it to the runtime configuration just fine with this:

def trustIP(ip):
    ''' firewalld must already be running '''
    from dbus import SystemBus
    bus = SystemBus()
    runtimeProxy = bus.get_object('org.fedoraproject.FirewallD1',
                                 '/org/fedoraproject/FirewallD1')
    runtimeProxy.addSource('trusted', ip)

Pretty simple.

What doesn't work: The permanent configuration

Adding it to the permanent configuration has proved to be more difficult. Here's what I've tried so far interactively:

>>> from dbus import SystemBus
>>> bus = SystemBus()

# First I need to find out which object is for the trusted zone...
>>> config = bus.get_object('org.fedoraproject.FirewallD1',
                           '/org/fedoraproject/FirewallD1/config')
>>> config.getZoneByName('trusted')
dbus.ObjectPath('/org/fedoraproject/FirewallD1/config/zone/7')

>>> permanentProxy = bus.get_object('org.fedoraproject.FirewallD1',
                                   '/org/fedoraproject/FirewallD1/config/zone/7')

# A quick check to make sure I have the right object:
>>> permanentProxy.getShort()
dbus.String(u'Trusted')

# Exactly what I expected, so move on and...
>>> permanentProxy.addSource('aaa.xxx.yyy.zzz')  # Actual ip removed...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python2.7/site-packages/dbus/proxies.py", line 145, in __call__
    **keywords)
  File "/usr/lib64/python2.7/site-packages/dbus/connection.py", line 651, in call_blocking
    message, timeout)
dbus.exceptions.DBusException:
    org.freedesktop.DBus.Python.dbus.exceptions.DBusException:
        dbus_to_python() takes exactly 1 argument (2 given)

I also tried checking permanentProxy.getDescription(), which returned the description as it should have, and I tried permanentProxy.setDescription('test') which failed with the exact same stack trace as permanentProxy.addSource('aaa.xxx.yyy.zzz').

I would jump to the conclusion that the bug lies in the python dbus module and assume it somehow doesn't handle arguments properly, except for the fact that runtimeProxy.addSource('trusted', ip) involved two arguments and works perfectly. config.getZoneByName('trusted') even has the same signature as permanentProxy.addSource('aaa.xxx.yyy.zzz')`, exactly one string, and works perfectly.

So maybe there's something weird I'm missing? But I don't know what that would be...

More stuff I tried without success

I considered the possibility that maybe addSource is supposed to be called without the string argument at all and maybe curries somehow or something, so I tried this:

>>> permanentProxy.addSource()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python2.7/site-packages/dbus/proxies.py", line 145, in __call__
    **keywords)
  File "/usr/lib64/python2.7/site-packages/dbus/connection.py", line 651, in call_blocking
    message, timeout)
dbus.exceptions.DBusException: org.freedesktop.DBus.Python.TypeError: Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/slip/dbus/service.py", line 123, in reply_handler
    result = method(self, *p, **k)
TypeError: addSource() takes at least 2 arguments (2 given)

This is just even weirder now... I have one Traceback within another traceback insisting that I need to pass in at least 2 arguments, but also saying I gave it two arguments (and I actually only gave it one, so how'd it come up with two anyways?)

A few more things I tried without success:

>>> permanentProxy.addSource(dbus_interface='org.fedoraproject.FirewallD1.config.zone')
ERROR:dbus.connection:Unable to set arguments () according to signature u's': <type 'exceptions.TypeError'>: More items found in D-Bus signature than in Python arguments
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python2.7/site-packages/dbus/proxies.py", line 145, in __call__
    **keywords)
  File "/usr/lib64/python2.7/site-packages/dbus/connection.py", line 641, in call_blocking
    message.append(signature=signature, *args)
TypeError: More items found in D-Bus signature than in Python arguments

>>> permanentProxy.addSource('aaa.xxx.yyy.zzz', dbus_interface='org.fedoraproject.FirewallD1.config.zone')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python2.7/site-packages/dbus/proxies.py", line 145, in __call__
    **keywords)
  File "/usr/lib64/python2.7/site-packages/dbus/connection.py", line 651, in call_blocking
    message, timeout)
dbus.exceptions.DBusException:
    org.freedesktop.DBus.Python.dbus.exceptions.DBusException:
        dbus_to_python() takes exactly 1 argument (2 given)

>>> from dbus import Interface
>>> Interface(permanentProxy, 'org.fedoraproject.FirewallD1.config.zone').addSource('aaa.xxx.yyy.zzz')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python2.7/site-packages/dbus/proxies.py", line 145, in __call__
    **keywords)
  File "/usr/lib64/python2.7/site-packages/dbus/connection.py", line 651, in call_blocking
    message, timeout)
dbus.exceptions.DBusException:
    org.freedesktop.DBus.Python.dbus.exceptions.DBusException:
        dbus_to_python() takes exactly 1 argument (2 given)

Gah!

This really seems like a bug in dbus... somehow it's initially resolving addSource incorrectly and thinking that it needs fewer arguments, but if you give it fewer arguments like it wants, it'll pass that erroneous check, and then it'll properly resolve and fail because your arguments don't match it.

That's my theory anyways. Is someone seeing something I'm not? Is there some way I can work around this bug, if there really is one? IE... is there some kind of internal method I can use on dbus that will force it to call the proper method?

解决方案

The following works for me:

>>> import dbus
>>> bus = dbus.SystemBus()
>>> config = bus.get_object('org.fedoraproject.FirewallD1',
...                            '/org/fedoraproject/FirewallD1/config')
>>> path = config.getZoneByName('trusted')
>>> zone = bus.get_object('org.fedoraproject.FirewallD1', path)
>>> zone.addSource('192.168.1.0/24')

At this point, if I look in /etc/firewalld/zones/trusted.xml, I can see that the source address has been added as expected:

<?xml version="1.0" encoding="utf-8"?>
<zone target="ACCEPT">
  <short>Trusted</short>
  <description>All network connections are accepted.</description>
  <interface name="docker0"/>
  <interface name="virbr0"/>
  <source address="192.168.1.0/24"/>
</zone>

...indicating that I have successfully changed the persistent configuration.

The above also works if I use a literal path in the second get_object call, instead of the return value from config.getZoneByName.

For what it's worth, I'm running:

  • Fedora 23
  • firewalld-0.3.14.2-4.fc23.noarch
  • dbus-1.10.6-1.fc23.x86_64
  • dbus-python-1.2.0-12.fc23.x86_64

UPDATE

You're not seeing anything newer because you're on CentOS, rather than Fedora. It looks like the easiest way of solving this particular task may be to use the firewall python module that ships with FirewallD. The following works for me on CentOS 7:

>>> from firewall.client import *
>>> client = FirewallClient()
>>> zone = client.config().getZoneByName('public')
>>> settings = zone.getSettings()
>>> settings.addSource('192.168.1.0/24')
>>> zone.update(settings)

ANOTHER UPDATE

Browsing through the source to the firewall.client module, you can do this via straight dbus like this:

>>> zone = bus.get_object('org.fedoraproject.FirewallD1', path)
>>> settings = zone.getSettings()
>>> settings[11].append('192.168.20.0/24')
>>> zone.update(settings)

This also works fine under CentOS...but you're much better off using the firewall module.

这篇关于dbus_to_python()只需要1个参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-18 21:39
查看更多