<commit_before># FauxAPI - v1.3
A REST API interface for pfSense 2.3.x and 2.4.x to facilitate devops:-
 - https://github.com/ndejong/pfsense_fauxapi

Additionally available are a set of [client libraries](#client-libraries) 
that hence make programmatic access and management of pfSense hosts for devops 
tasks feasible.


## API Action Summary
 - [alias_update_urltables](#user-content-alias_update_urltables) - Causes the pfSense host to immediately update any urltable alias entries from their (remote) source URLs.
 - [config_backup](#user-content-config_backup) - Causes the system to take a configuration backup and add it to the regular set of system change backups.
 - [config_backup_list](#user-content-config_backup_list) - Returns a list of the currently available system configuration backups.
 - [config_get](#user-content-config_get) - Returns the full system configuration as a JSON formatted string.
 - [config_patch](#user-content-config_patch) - Patch the system config with a granular piece of new configuration.
 - [config_reload](#user-content-config_reload) - Causes the pfSense system to perform an internal reload of the `config.xml` file.
 - [config_restore](#user-content-config_restore) - Restores the pfSense system to the named backup configuration.
 - [config_set](#user-content-config_set) - Sets a full system configuration and (by default) reloads once successfully written and tested.
 - [function_call](#user-content-function_call) - Call directly a pfSense PHP function with API user supplied parameters.
 - [gateway_status](#user-content-gateway_status) - Returns gateway status data.
 - [interface_stats](#user-content-interface_stats) - Returns statistics and information about an interface.
 - [rule_get](#user-content-rule_get) - Returns the numbered list of loaded pf rules from a `pfctl -sr -vv` command on the pfSense host.
 - [send_event](#user-content-send_event) - Performs a pfSense "send_event" command to cause various pfSense system actions.
 - [system_reboot](#user-content-system_reboot) - Reboots the pfSense system.
 - [system_stats](#user-content-system_stats) - Returns various useful system stats.


## Approach
At its core FauxAPI simply reads the core pfSense `config.xml` file, converts it 
to JSON and returns to the API caller.  Similarly it can take a JSON formatted 
configuration and write it to the pfSense `config.xml` and handles the required 
reload operations.  The ability to programmatically interface with a running 
pfSense host(s) is enormously useful however it should also be obvious that this 
provides the API user the ability to create configurations that can break your 
pfSense system.

FauxAPI provides easy backup and restore API interfaces that by default store
configuration backups on all configuration write operations thus it is very easy 
to roll-back even if the API user manages to deploy a "very broken" configuration.

Multiple sanity checks take place to make sure a user provided JSON config will 
correctly convert into the (slightly quirky) pfSense XML `config.xml` format and 
then reload as expected in the same way.  However, because it is not a real 
per-action application-layer interface it is still possible for the API caller 
to create configuration changes that make no sense and can potentially disrupt 
your pfSense system - as the package name states, it is a "Faux" API to pfSense
filling a gap in functionality with the current pfSense product.

Because FauxAPI is a utility that interfaces with the pfSense `config.xml` there
are some cases where reloading the configuration file is not enough and you 
may need to "tickle" pfSense a little more to do what you want.  This is not 
common however a good example is getting newly defined network interfaces or 
VLANs to be recognized.  These situations are easily handled by calling the
**send_event** action with the payload **interface reload all** - see the example 
included below and refer to a the resolution to [Issue #10](https://github.com/ndejong/pfsense_fauxapi/issues/10)

__NB:__ *As at FauxAPI v1.2 the **function_call** action has been introduced that 
now provides the ability to issue function calls directly into pfSense.*


## Installation
Until the FauxAPI is added to the pfSense FreeBSD-ports tree you will need to 
install manually from **root** as shown:-
```bash
set fauxapi_base_package_url='https://raw.githubusercontent.com/ndejong/pfsense_fauxapi_packages/master'
set fauxapi_latest=`fetch -qo - ${fauxapi_base_package_url}/LATEST`
fetch ${fauxapi_base_package_url}/${fauxapi_latest}
pkg-static install ${fauxapi_latest}
```

Installation and de-installation is quite straight forward, further examples can 
be found in the `README.md` located [here](https://github.com/ndejong/pfsense_fauxapi_packages).

Refer to the published package [`SHA256SUMS`](https://github.com/ndejong/pfsense_fauxapi_packages/blob/master/SHA256SUMS)

**Hint:** if not already, consider installing the `jq` tool on your local machine (not 
pfSense host) to pipe and manage JSON outputs from FauxAPI - https://stedolan.github.io/jq/

**NB:** you MUST at least setup your `/etc/fauxapi/credentials.ini` file on the 
pfSense host before you continue, see the API Authentication section below.

## Client libraries

#### Python
A [Python interface](https://github.com/ndejong/pfsense_fauxapi_client_python) 
to pfSense was perhaps the most desired end-goal at the onset of the FauxAPI 
package project.  Anyone that has tried to parse the pfSense `config.xml` files 
using a Python based library will understand that things don't quite work out as 
expected or desired.

The Python client-library can be easily installed from PyPi as such
```bash
pip3 install pfsense-fauxapi
```

Package Status: [![PyPi](https://img.shields.io/pypi/v/pfsense-fauxapi.svg)](https://pypi.org/project/pfsense-fauxapi/) [![Build Status](https://travis-ci.org/ndejong/pfsense_fauxapi_client_python.svg?branch=master)](https://travis-ci.org/ndejong/pfsense_fauxapi_client_python)

Use of the package should be easy enough as shown
```python
import pprint, sys
from PfsenseFauxapi.PfsenseFauxapi import PfsenseFauxapi
PfsenseFauxapi = FauxapiLib('<host-address>', '<fauxapi-key>', '<fauxapi-secret>')

aliases = FauxapiLib.config_get('aliases')
## perform some kind of manipulation to `aliases` here ##
pprint.pprint(FauxapiLib.config_set(aliases, 'aliases'))
```

It is recommended to review the [Python code examples](https://github.com/ndejong/pfsense_fauxapi_client_python/tree/master/examples)
to observe worked examples with the client library.  Of small note is that the 
Python library supports the ability to get and set single sections of the pfSense 
system, not just the entire system configuration as with the Bash library.

**Python examples**
 - `usergroup-management.py` - example code that provides the ability to `get_users`, 
   `add_user`, `manage_user`, `remove_user` and perform the same functions on groups.
 - `update-aws-aliases.py` - example code that pulls in the latest AWS `ip-ranges.json` 
   data, parses it and injects them into the pfSense aliases section if required.
 - `function-iterate.py` - iterates (almost) all the FauxAPI functions to 
   confirm operation.  

#### Command Line
As distinct from the Bash library as described below the Python pip also introduces
a command-line tool to interact with the API, which makes a wide range of actions
possible directly from the command line, for example
```bash
fauxapi --host 192.168.1.200 gateway_status | jq .
```

#### Bash
The [Bash client library](https://github.com/ndejong/pfsense_fauxapi_client_bash) 
makes it possible to add a line with `source pfsense-fauxapi.sh` to your bash script 
and then access a pfSense host configuration directly as a JSON string
```bash
source pfsense-fauxapi.sh<commit_msg>omit "FauxapiLib" from the sample code<commit_after># FauxAPI - v1.3
A REST API interface for pfSense 2.3.x and 2.4.x to facilitate devops:-
 - https://github.com/ndejong/pfsense_fauxapi

Additionally available are a set of [client libraries](#client-libraries) 
that hence make programmatic access and management of pfSense hosts for devops 
tasks feasible.


## API Action Summary
 - [alias_update_urltables](#user-content-alias_update_urltables) - Causes the pfSense host to immediately update any urltable alias entries from their (remote) source URLs.
 - [config_backup](#user-content-config_backup) - Causes the system to take a configuration backup and add it to the regular set of system change backups.
 - [config_backup_list](#user-content-config_backup_list) - Returns a list of the currently available system configuration backups.
 - [config_get](#user-content-config_get) - Returns the full system configuration as a JSON formatted string.
 - [config_patch](#user-content-config_patch) - Patch the system config with a granular piece of new configuration.
 - [config_reload](#user-content-config_reload) - Causes the pfSense system to perform an internal reload of the `config.xml` file.
 - [config_restore](#user-content-config_restore) - Restores the pfSense system to the named backup configuration.
 - [config_set](#user-content-config_set) - Sets a full system configuration and (by default) reloads once successfully written and tested.
 - [function_call](#user-content-function_call) - Call directly a pfSense PHP function with API user supplied parameters.
 - [gateway_status](#user-content-gateway_status) - Returns gateway status data.
 - [interface_stats](#user-content-interface_stats) - Returns statistics and information about an interface.
 - [rule_get](#user-content-rule_get) - Returns the numbered list of loaded pf rules from a `pfctl -sr -vv` command on the pfSense host.
 - [send_event](#user-content-send_event) - Performs a pfSense "send_event" command to cause various pfSense system actions.
 - [system_reboot](#user-content-system_reboot) - Reboots the pfSense system.
 - [system_stats](#user-content-system_stats) - Returns various useful system stats.


## Approach
At its core FauxAPI simply reads the core pfSense `config.xml` file, converts it 
to JSON and returns to the API caller.  Similarly it can take a JSON formatted 
configuration and write it to the pfSense `config.xml` and handles the required 
reload operations.  The ability to programmatically interface with a running 
pfSense host(s) is enormously useful however it should also be obvious that this 
provides the API user the ability to create configurations that can break your 
pfSense system.

FauxAPI provides easy backup and restore API interfaces that by default store
configuration backups on all configuration write operations thus it is very easy 
to roll-back even if the API user manages to deploy a "very broken" configuration.

Multiple sanity checks take place to make sure a user provided JSON config will 
correctly convert into the (slightly quirky) pfSense XML `config.xml` format and 
then reload as expected in the same way.  However, because it is not a real 
per-action application-layer interface it is still possible for the API caller 
to create configuration changes that make no sense and can potentially disrupt 
your pfSense system - as the package name states, it is a "Faux" API to pfSense
filling a gap in functionality with the current pfSense product.

Because FauxAPI is a utility that interfaces with the pfSense `config.xml` there
are some cases where reloading the configuration file is not enough and you 
may need to "tickle" pfSense a little more to do what you want.  This is not 
common however a good example is getting newly defined network interfaces or 
VLANs to be recognized.  These situations are easily handled by calling the
**send_event** action with the payload **interface reload all** - see the example 
included below and refer to a the resolution to [Issue #10](https://github.com/ndejong/pfsense_fauxapi/issues/10)

__NB:__ *As at FauxAPI v1.2 the **function_call** action has been introduced that 
now provides the ability to issue function calls directly into pfSense.*


## Installation
Until the FauxAPI is added to the pfSense FreeBSD-ports tree you will need to 
install manually from **root** as shown:-
```bash
set fauxapi_base_package_url='https://raw.githubusercontent.com/ndejong/pfsense_fauxapi_packages/master'
set fauxapi_latest=`fetch -qo - ${fauxapi_base_package_url}/LATEST`
fetch ${fauxapi_base_package_url}/${fauxapi_latest}
pkg-static install ${fauxapi_latest}
```

Installation and de-installation is quite straight forward, further examples can 
be found in the `README.md` located [here](https://github.com/ndejong/pfsense_fauxapi_packages).

Refer to the published package [`SHA256SUMS`](https://github.com/ndejong/pfsense_fauxapi_packages/blob/master/SHA256SUMS)

**Hint:** if not already, consider installing the `jq` tool on your local machine (not 
pfSense host) to pipe and manage JSON outputs from FauxAPI - https://stedolan.github.io/jq/

**NB:** you MUST at least setup your `/etc/fauxapi/credentials.ini` file on the 
pfSense host before you continue, see the API Authentication section below.

## Client libraries

#### Python
A [Python interface](https://github.com/ndejong/pfsense_fauxapi_client_python) 
to pfSense was perhaps the most desired end-goal at the onset of the FauxAPI 
package project.  Anyone that has tried to parse the pfSense `config.xml` files 
using a Python based library will understand that things don't quite work out as 
expected or desired.

The Python client-library can be easily installed from PyPi as such
```bash
pip3 install pfsense-fauxapi
```

Package Status: [![PyPi](https://img.shields.io/pypi/v/pfsense-fauxapi.svg)](https://pypi.org/project/pfsense-fauxapi/) [![Build Status](https://travis-ci.org/ndejong/pfsense_fauxapi_client_python.svg?branch=master)](https://travis-ci.org/ndejong/pfsense_fauxapi_client_python)

Use of the package should be easy enough as shown
```python
import pprint, sys
from PfsenseFauxapi.PfsenseFauxapi import PfsenseFauxapi
PfsenseFauxapi = PfsenseFauxapi('<host-address>', '<fauxapi-key>', '<fauxapi-secret>')

aliases = PfsenseFauxapi.config_get('aliases')
## perform some kind of manipulation to `aliases` here ##
pprint.pprint(PfsenseFauxapi.config_set(aliases, 'aliases'))
```

It is recommended to review the [Python code examples](https://github.com/ndejong/pfsense_fauxapi_client_python/tree/master/examples)
to observe worked examples with the client library.  Of small note is that the 
Python library supports the ability to get and set single sections of the pfSense 
system, not just the entire system configuration as with the Bash library.

**Python examples**
 - `usergroup-management.py` - example code that provides the ability to `get_users`, 
   `add_user`, `manage_user`, `remove_user` and perform the same functions on groups.
 - `update-aws-aliases.py` - example code that pulls in the latest AWS `ip-ranges.json` 
   data, parses it and injects them into the pfSense aliases section if required.
 - `function-iterate.py` - iterates (almost) all the FauxAPI functions to 
   confirm operation.  

#### Command Line
As distinct from the Bash library as described below the Python pip also introduces
a command-line tool to interact with the API, which makes a wide range of actions
possible directly from the command line, for example
```bash
fauxapi --host 192.168.1.200 gateway_status | jq .
```

#### Bash
The [Bash client library](https://github.com/ndejong/pfsense_fauxapi_client_bash) 
makes it possible to add a line with `source pfsense-fauxapi.sh` to your bash script 
and then access a pfSense host configuration directly as a JSON string
```bash
source pfsense-fauxapi.sh
{'fraction_non_alphanumeric': 0.07722155079193435, 'fraction_numerical': 0.003689332739647605, 'mean_word_length': 4.910526315789474, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 26, 'lorem ipsum': 0, 'www.': 0, 'xml': 12}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1906197', 'n_tokens_mistral': 4664, 'n_tokens_neox': 4474, 'n_words': 1846}