Skip to content

Quick Start Guide#

Installation#

In most cases installation via pip is the simplest and best way to install pyfortinet. See here for advanced installation details.

pip install pyfortinet

A Simple Example (get object)#

from pyfortinet import FMG
from pyfortinet.fmg_api.firewall import Address
from pyfortinet.fmg_api.common import F

config = {
    "base_url": "https://myfmg.com",
    "username": "myuser",
    "password": "verysecret",
    "adom": "root",
    "verify": False
}
with FMG(**config) as fmg:
    # get exact address object from FMG
    server2 = fmg.get(Address, F(name="server2")).first()
    print(server2.name)

Updating existing object#

from pyfortinet import FMG
from pyfortinet.fmg_api.firewall import Address
from pyfortinet.fmg_api.common import F

config = {
    "base_url": "https://myfmg.com",
    "username": "myuser",
    "password": "verysecret",
    "adom": "root",
    "verify": False
}
with FMG(**config) as fmg:
    # get exact address object from FMG
    server = fmg.get(Address, F(name="server1")).first()
    server.subnet = "10.1.1.1/24"
    server.update()

Filtering#

F filter function can be used to compile complex search filters. More examples can be found in the respective testing functions:

F filter examples
"""Test offline classes and functions"""

import pytest

from pyfortinet import FMGResponse, AsyncFMGResponse
from pyfortinet.fmg_api.common import F, text_to_filter


class TestFilters:
    def test_simple_filter(self):
        f = F(name="test_address").generate()
        assert f == ["name", "==", "test_address"]

    def test_negate_filter(self):
        f = (~F(name="test_address")).generate()
        assert f == ["!", "name", "==", "test_address"]

    def test_filter_with_more_values(self):
        f = F(member__in=["abc", "def", "ghi"]).generate()
        assert f == ["member", "in", "abc", "def", "ghi"]

    def test_filter_with_implicit_or(self):
        f = (F(name="test_address") + F(name="test2_address")).generate()
        assert f == [["name", "==", "test_address"], ["name", "==", "test2_address"]]

    def test_explicit_or_filters(self):
        f = (F(name="test_address") | F(name="prod_address")).generate()
        assert f == [["name", "==", "test_address"], "||", ["name", "==", "prod_address"]]

    def test_multiple_filters(self):
        f = (F(name="acceptance_address") | F(name="test_address") | F(name="prod_address")).generate()
        assert f == [
            [["name", "==", "acceptance_address"], "||", ["name", "==", "test_address"]],
            "||",
            ["name", "==", "prod_address"],
        ]

    def test_filters_with_parentheses(self):
        f = (F(name="acceptance_address") | (F(name="test_address") | F(name="prod_address"))).generate()
        assert f == [
            ["name", "==", "acceptance_address"],
            "||",
            [["name", "==", "test_address"], "||", ["name", "==", "prod_address"]],
        ]

    def test_filters_with_parentheses2(self):
        f = ((F(name="acceptance_address") | F(name="test_address")) & F(state=1)).generate()
        assert f == [
            [["name", "==", "acceptance_address"], "||", ["name", "==", "test_address"]],
            "&&",
            ["state", "==", 1],
        ]

    def test_and_filters(self):
        f = (F(name__like="test%") & F(interface="port1")).generate()
        assert f == [["name", "like", "test%"], "&&", ["interface", "==", "port1"]]

    def test_complex_filter(self):
        f = ((F(name="root") + F(name="rootp")) & (F(status=1) + F(status=2))).generate()
        assert f == [
            [["name", "==", "root"], ["name", "==", "rootp"]],
            "&&",
            [["status", "==", 1], ["status", "==", 2]],
        ]

    def test_first_good(self):
        response = FMGResponse(data={"data": ["response1", "response2"]})
        assert response.first() == "response1"

    def test_first_empty(self):
        response = FMGResponse()
        assert response.first() is None

    def test_first_good_async(self):
        response = AsyncFMGResponse(data={"data": ["response1", "response2"]})
        assert response.first() == "response1"

    def test_first_empty_async(self):
        response = AsyncFMGResponse()
        assert response.first() is None

    def test_text_to_filter(self):
        assert text_to_filter("name like test%").generate() == ["name", "like", "test%"]
        assert text_to_filter("~name like host_%").generate() == ["!", "name", "like", "host_%"]
        assert text_to_filter("name eq host_1 and conf_status eq insync").generate() == [
            ["name", "==", "host_1"],
            "&&",
            ["conf_status", "==", "insync"],
        ]
Short examples
from pyfortinet import FMG
from pyfortinet.fmg_api.firewall import Address
from pyfortinet.fmg_api.dvmdb import Device
from pyfortinet.fmg_api.common import F

config = {
    "base_url": "https://myfmg.com",
    "username": "myuser",
    "password": "verysecret",
    "adom": "root",
    "verify": False
}
with FMG(**config) as fmg:
    # simple 'or'
    server1_and_2 = fmg.get(Address, F(name="server1") + F(name="server2")).data
    # list devices with name dc-fw-* which connection status is not up
    firewalls = fmg.get(Device, F(name__like="dc-fw-%") & ~F(conn_status="up")).data

Task run#

Exec objects are called Tasks. These have extra functionality like waiting. This is an example of running device settings installation on devices with modified config status:

from pyfortinet import FMG
from pyfortinet.fmg_api.common import Scope
from pyfortinet.fmg_api.dvmdb import Device
from pyfortinet.fmg_api.common import F

config = {
    "base_url": "https://myfmg.com",
    "username": "myuser",
    "password": "verysecret",
    "adom": "root",
    "verify": False
}
with FMG(**config) as fmg:
    devices: List[Device] = fmg.get(Device, conf_status="mod").data
    # for simplicity, assume all device is single mode
    task: InstallDeviceTask = fmg.get_obj(
        InstallDeviceTask, adom=fmg.adom, scope=[Scope(name=test_device.name, vdom="root")], flags=["auto_lock_ws"]
    )
    result: FMGResponse = task.exec()
    # block here until task is done. Print task percentage and log in the meanwhile
    result.wait_for_task(callback=lambda percent, log: print(f"Task at {percent}%: {log}"))