def test_config_set(mock_requests_post): fauxapi = PfsenseFauxapi(host=None, apikey=None, apisecret=None) mock_requests_post.return_value.status_code = 200 mock_requests_post.return_value.text = '{"callid": "5c8db8b4efb90", "action": "config_set", "message": "ok", "data": {"do_backup": true, "do_reload": true, "previous_config_file": "/cf/conf/backup/config-1552791732.xml"}}' response = fauxapi.config_set(config={}) assert response['action'] == 'config_set' assert response['message'] == 'ok' assert response['data'] is not None
def set_rule_state(self, action): """Setup the pfSense Rules platform.""" import pprint, sys from PfsenseFauxapi.PfsenseFauxapi import PfsenseFauxapi _LOGGER.debug("Connecting to pfSense firewall to change rule states.") try: # Setup connection with devices/cloud FauxapiLib = PfsenseFauxapi(self._host, self._api_key, self._access_token, debug=True) # Get the current set of filters filters = FauxapiLib.config_get('filter') except: _LOGGER.error( "Problem retrieving rule set from pfSense host: %s. Likely due to API key or secret.", self._host) i = 0 for rule in filters['rule']: if (rule.get('tracker') == self._tracker_id): _LOGGER.info("Found rule changing state rule: %s", self._rule_name) if (action == True): if ('disabled' in rule): del filters['rule'][i]['disabled'] _LOGGER.debug( "Rule %s enabled in config (this has not been pushed back to firewall yet!)", self._rule_name) elif (action == False): filters['rule'][i]['disabled'] = "" _LOGGER.debug( "Rule %s disabled in config (this has not been pushed back to firewall yet!)", self._rule_name) i = i + 1 try: _LOGGER.debug("Sending updated rule set to pfSense firewall") # Push the config back to pfSense filters = FauxapiLib.config_set(filters, 'filter') _LOGGER.debug( "Reloading the config on pfSense firewall to accept rule changes" ) # Reload the config FauxapiLib.send_event("filter reload") except: _LOGGER.error( "Problem sending & reloading rule set from pfSense host: %s. Likely due to API key or secret.", self._host)
class UpdateAwsAliasesFauxapi(): fauxapi_host = None fauxapi_apikey = None fauxapi_apisecret = None system_config = None aws_ipranges_uri = 'https://ip-ranges.amazonaws.com/ip-ranges.json' FauxapiLib = None def __init__(self, fauxapi_host, fauxapi_apikey, fauxapi_apisecret, debug=False): self.FauxapiLib = PfsenseFauxapi(fauxapi_host, fauxapi_apikey, fauxapi_apisecret, debug) def update(self, regions_match='*', services_match='*', ipv4=True, ipv6=True): # Use FauxapiLib to load the remote system config into memory self.system_config = self.FauxapiLib.config_get() # download ip-ranges.json parse and iterate for name, data in sorted(self.get_aws_ipranges().items()): if regions_match == '*' or regions_match.replace('*', '').replace( '-', '').lower() in name: if services_match == '*' or services_match.replace( '*', '').replace('_', '').lower() in name: addresses = [] if ipv4 is True and len(data['ipv4']) > 0: addresses += data['ipv4'] if ipv6 is True and len(data['ipv6']) > 0: addresses += data['ipv6'] self.update_alias_in_config( name=name, description=data['description'], addresses=addresses, aws_create_date=data['aws_create_date']) # Use FauxapiLib to save to the remote system the new edited config result = self.FauxapiLib.config_set(self.system_config) print(json.dumps(result)) def update_alias_in_config(self, name, description, addresses, aws_create_date): addresses.sort() # candidate alias to apply alias_data = { 'name': name, 'type': 'network', 'address': ' '.join(addresses), 'descr': description, 'detail': '||'.join( ['ip-ranges.json createDate: {}'.format(aws_create_date)] * len(addresses)) } if 'aliases' not in self.system_config or type( self.system_config['aliases']) is not dict: self.system_config['aliases'] = {} if 'alias' not in self.system_config['aliases'] or type( self.system_config['aliases']['alias']) is not list: self.system_config['aliases']['alias'] = [] alias_found = False for index, alias in enumerate(self.system_config['aliases']['alias']): if alias['name'] == name: alias_found = True if alias['address'] != alias_data['address']: self.system_config['aliases']['alias'][index] = alias_data if alias_found is False: self.system_config['aliases']['alias'].append(alias_data) def get_aws_ipranges(self): with urllib.request.urlopen(self.aws_ipranges_uri) as response: aws_ipranges_data = json.loads(response.read()) ipranges = {} for prefix in aws_ipranges_data['prefixes'] + aws_ipranges_data[ 'ipv6_prefixes']: name = 'aws_{}_{}'.format( prefix['region'].replace('-', '').lower(), prefix['service'].replace('_', '').lower())[:32] if name not in ipranges: ipranges[name] = { 'ipv4': [], 'ipv6': [], 'description': 'AWS {region} {service}'.format(region=prefix['region'], service=prefix['service']), 'aws_create_date': aws_ipranges_data['createDate'] } if 'ip_prefix' in prefix and len(prefix['ip_prefix']) > 0: ipranges[name]['ipv4'].append(prefix['ip_prefix']) if 'ipv6_prefix' in prefix and len(prefix['ipv6_prefix']) > 0: ipranges[name]['ipv6'].append(prefix['ipv6_prefix']) return ipranges
FauxapiLib = PfsenseFauxapi(fauxapi_host, fauxapi_apikey, fauxapi_apisecret, debug=False) # config get the full configuration and simply print to console # ============================================================================= config = FauxapiLib.config_get() print(json.dumps( config )) # config set the full configuration # ============================================================================= # NB: nothing amazing is happening here, we are simply writing back the same (full) configuration again, the developer # most likely wants to make changes to `config` before calling the config_set function again here print(json.dumps( FauxapiLib.config_set(config) )) # config_get, config_set by section # ============================================================================= # perform a second config_get > config_set this time within the 'aliases' section only # NB: again, nothing amazing happening in this example, we are are again only writing back the same (section) # configuration, the developer more likely wants to perform some kind of operation on `config_aliases` before calling # the config_set function again. config_aliases = FauxapiLib.config_get('aliases') print(json.dumps( FauxapiLib.config_set(config_aliases, 'aliases')) ) # config_patch # =============================================================================
class PfSense: """ PfSense Thingy... ... Methods ------- get_openvpn_settings(self) -> dict: set_pfsense_config(self, data: dict, vpnid: list, refresh: bool = None) -> dict: get_pf_openvpn_clients(self) -> dict: get_pf_openvpn_locations(self, vpn_clients: dict) -> set: """ def __init__(self): self.host = getenv("HOST_ADDRESS") self.port = 443 self.key = getenv("FAUXAPI_KEY") self.secret = getenv("FAUXAPI_SECRET") try: PfsenseFauxapi(f"{self.host}:{self.port}", self.key, self.secret) except PfsenseFauxapiException as e: print(f"error: {str(e)}") else: self.pfapi = PfsenseFauxapi(f"{self.host}:{self.port}", self.key, self.secret) def get_openvpn_settings(self) -> dict: try: pf_openvpn_settings = self.pfapi.config_get('openvpn') except PfsenseFauxapiException as e: return {"error": str(e)} else: return pf_openvpn_settings def set_pfsense_config(self, data: dict, vpnid: list, refresh: bool = None) -> dict: """ Parameters ---------- data : dict . vpnid : list . refresh : bool . """ try: resp = self.pfapi.config_set(data, 'openvpn') except PfsenseFauxapiException as e: return {"error": str(e)} else: if refresh: self.pfapi.config_reload() if len(vpnid): for vid in vpnid: data = self.pfapi.function_call({ "function": "openvpn_restart_by_vpnid", "args": ["client", f"{vid}"] }) return resp def get_pf_openvpn_clients(self) -> dict: clients: list = [] vpn_clients = self.get_openvpn_settings() if "error" in vpn_clients.keys(): return vpn_clients locations: set = self.get_pf_openvpn_locations(vpn_clients) for vpnclient in vpn_clients["openvpn-client"]: clients.append(vpnclient["server_addr"]) return {"clients": clients, "locations": list(locations)} def get_pf_openvpn_locations(self, vpn_clients: dict) -> set: """ Parameters ---------- vpn_clients : dict . """ locations = set() for client in vpn_clients["openvpn-client"]: loc = is_vpn_address(client["server_addr"]) if loc is not None: locations.add(loc[1].lower()) return locations
FauxapiLib = PfsenseFauxapi(fauxapi_host, fauxapi_apikey, fauxapi_apisecret, debug=False) # config get the full configuration and simply print to console # ============================================================================= config = FauxapiLib.config_get() print(json.dumps(config)) # config set the full configuration # ============================================================================= # NB: nothing amazing is happening here, we are simply writing back the same (full) configuration again, the developer # most likely wants to make changes to `config` before calling the config_set function again here print(json.dumps(FauxapiLib.config_set(config))) # config_get, config_set by section # ============================================================================= # perform a second config_get > config_set this time within the 'aliases' section only # NB: again, nothing amazing happening in this example, we are are again only writing back the same (section) # configuration, the developer more likely wants to perform some kind of operation on `config_aliases` before calling # the config_set function again. config_aliases = FauxapiLib.config_get('aliases') print(json.dumps(FauxapiLib.config_set(config_aliases, 'aliases'))) # config_patch # ============================================================================= # in this example we patch a specific set of configuration parameters and then revert them back to what they were config_patch = { 'system': {