0

我有这个 Python 脚本来通过 FauxAPI 控制 PfSense 路由器。问题是当我调用一个函数时它会出错。我想我调用函数是错误的。有谁知道怎么称呼他们?这是我正在使用的 API 的链接:https ://github.com/ndejong/pfsense_fauxapi 我尝试调用 config_get(self, section=none) 但这似乎不起作用。

import os
import json
import base64
import urllib
import requests
import datetime
import hashlib


class PfsenseFauxapiException(Exception):
    pass


class PfsenseFauxapi:

    host = '172.16.1.1'
    proto = None
    debug = None
    version = None
    apikey = 'key'
    apisecret = 'secret'
    use_verified_https = None

    def __init__(self, host, apikey, apisecret, use_verified_https=False, debug=False):
        self.proto = 'https'
        self.base_url = 'fauxapi/v1'
        self.version = __version__
        self.host = host
        self.apikey = apikey
        self.apisecret = apisecret
        self.use_verified_https = use_verified_https
        self.debug = debug
        if self.use_verified_https is False:
            requests.packages.urllib3.disable_warnings(requests.packages.urllib3.exceptions.InsecureRequestWarning)

    def config_get(self, section=None):
        config = self._api_request('GET', 'config_get')
        if section is None:
            return config['data']['config']
        elif section in config['data']['config']:
            return config['data']['config'][section]
        raise PfsenseFauxapiException('Unable to complete config_get request, section is unknown', section)

    def config_set(self, config, section=None):
        if section is None:
            config_new = config
        else:
            config_new = self.config_get(section=None)
            config_new[section] = config
        return self._api_request('POST', 'config_set', data=config_new)

    def config_patch(self, config):
        return self._api_request('POST', 'config_patch', data=config)

    def config_reload(self):
        return self._api_request('GET', 'config_reload')

    def config_backup(self):
        return self._api_request('GET', 'config_backup')

    def config_backup_list(self):
        return self._api_request('GET', 'config_backup_list')

    def config_restore(self, config_file):
        return self._api_request('GET', 'config_restore', params={'config_file': config_file})

    def send_event(self, command):
        return self._api_request('POST', 'send_event', data=[command])

    def system_reboot(self):
        return self._api_request('GET', 'system_reboot')

    def system_stats(self):
        return self._api_request('GET', 'system_stats')

    def interface_stats(self, interface):
        return self._api_request('GET', 'interface_stats', params={'interface': interface})

    def gateway_status(self):
        return self._api_request('GET', 'gateway_status')

    def rule_get(self, rule_number=None):
        return self._api_request('GET', 'rule_get', params={'rule_number': rule_number})

    def alias_update_urltables(self, table=None):
        if table is not None:
            return self._api_request('GET', 'alias_update_urltables', params={'table': table})
        return self._api_request('GET', 'alias_update_urltables')

    def function_call(self, data):
        return self._api_request('POST', 'function_call', data=data)

    def system_info(self):
        return self._api_request('GET', 'system_info')

    def _api_request(self, method, action, params=None, data=None):

        if params is None:
            params = {}

        if self.debug:
            params['__debug'] = 'true'

        url = '{proto}://{host}/{base_url}/?action={action}&{params}'.format(
            proto=self.proto, host=self.host, base_url=self.base_url, action=action, params=urllib.parse.urlencode(params))

        if method.upper() == 'GET':
            res = requests.get(
                url,
                headers={'fauxapi-auth': self._generate_auth()},
                verify=self.use_verified_https
            )
        elif method.upper() == 'POST':
            res = requests.post(
                url,
                headers={'fauxapi-auth': self._generate_auth()},
                verify=self.use_verified_https,
                data=json.dumps(data)
            )
        else:
            raise PfsenseFauxapiException('Request method not supported!', method)

        if res.status_code == 404:
            raise PfsenseFauxapiException('Unable to find FauxAPI on target host, is it installed?')
        elif res.status_code != 200:
            raise PfsenseFauxapiException('Unable to complete {}() request'.format(action), json.loads(res.text))

        return self._json_parse(res.text)

    def _generate_auth(self):
        # auth = apikey:timestamp:nonce:HASH(apisecret:timestamp:nonce)
        nonce = base64.b64encode(os.urandom(40)).decode('utf-8').replace('=', '').replace('/', '').replace('+', '')[0:8]
        timestamp = datetime.datetime.utcnow().strftime('%Y%m%dZ%H%M%S')
        hash = hashlib.sha256('{}{}{}'.format(self.apisecret, timestamp, nonce).encode('utf-8')).hexdigest()
        return '{}:{}:{}:{}'.format(self.apikey, timestamp, nonce, hash)

    def _json_parse(self, data):
        try:
            return json.loads(data)
        except json.JSONDecodeError:
            pass
        raise PfsenseFauxapiException('Unable to parse response data!', data)
4

2 回答 2

1

您需要创建该类的对象才能调用该类的功能。例如 x = PfsenseFauxapi()(在构造对象期间调用 init 方法)然后通过x.'any function'. 也许命名变量不是 x 以获得良好的命名质量。

于 2020-10-22T09:49:38.470 回答
1

在没有自己测试过上述脚本的情况下,我可以得出结论,是的,您调用了错误的函数。上面的脚本是一个类,必须先实例化,然后才能使用内部的任何函数。

例如,您可以首先创建一个对象:

pfsense = PfsenseFauxapi(host='<host>', apikey='<API key>', apisecret='<API secret>')

用所需的值替换<host>,<API key><API secret>

然后调用函数:

pfsense.config_get() # self is not passed

whereconfig_get可以用任何函数替换

另请注意

  • 一旦你调用pfsense = PfsenseFauxapi(...)__init__函数中的所有代码也会运行,因为它是构造函数(用于初始化类的所有属性)。
  • 当一个函数有一个参数时parameter=somethingsomething即为该参数没有传递任何内容时的默认值。因此,为什么use_verified_httpsdebug并且section不需要通过(除非您当然想更改它们)

如果您需要,这里有更多关于课程的信息。

于 2020-10-22T10:02:04.797 回答