GithubHelp home page GithubHelp logo

vladimirs-git / fortigate-api Goto Github PK

View Code? Open in Web Editor NEW
58.0 58.0 18.0 3.64 MB

Python package for configuring Fortigate (Fortios) devices using REST API

License: Apache License 2.0

Python 99.53% Jinja 0.47%
api firewall fortigate fortigate-api fortigate-automation fortigate-firewall fortinet fortios python

fortigate-api's People

Contributors

vladimirs-git avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

fortigate-api's Issues

Incorrect token validation link

In the token check the URL that is checked is .../cmdb/system/status. However this is an undocumented endpoint and might not be supported in future FortiOS versions. I propose that that the following endpoint be used instead: .../monitor/system/status

help on filtering policies

Hi,
Regarding the policy filters how can I try to get all policies filtered by destination address?
For example to extract all policies that allora traffic to a specific il say 192.168.1.2?

Thanks in advance for your help

Copying Policy

Hi I'm trying to user the API to read policies from one firewall and create the very same on another.
reading work perfectly but when I create the policy i get error 500.

I read all policies
for policy in oldfgt.policy.get():
if policy["status"] == "enable":
policies.append(policy)

the filter on which i want i my array then:

for policy in policies:
print("create "+policy['name']);
if confirm_choice() == 'c':
try:
response = newfgt.policy.create(data=policy)
print("policy.create", response)
except:
print("exception "+policy['name'])
else:
print("skip "+policy['name'])

Should I remove some filed on the object?
policyid and uuid ar e then as read from the source, mut I remove those fields?

Thanks in advance

python 3.10.5 pip install fails on not installing 'requests' before usage with poetry

When installing the fortigate-api using pip, it crashes and fails on 'requests' not being present.

    × Getting requirements to build wheel did not run successfully.
    │ exit code: 1
    ╰─> [21 lines of output]
        Traceback (most recent call last):
          File "/tmp/tmp9j5_wgaq_in_process.py", line 363, in <module>
            main()
          File "/tmp/tmp9j5_wgaq_in_process.py", line 345, in main
            json_out['return_val'] = hook(**hook_input['kwargs'])
          File "/tmp/tmp9j5_wgaq_in_process.py", line 130, in get_requires_for_build_wheel
            return hook(config_settings)
          File "/tmp/pip-build-env-6rdrkzvm/overlay/lib/python3.10/site-packages/setuptools/build_meta.py", line 177, in get_requires_for_build_wheel
            return self._get_build_requires(
          File "/tmp/pip-build-env-6rdrkzvm/overlay/lib/python3.10/site-packages/setuptools/build_meta.py", line 159, in _get_build_requires
            self.run_setup()
          File "/tmp/pip-build-env-6rdrkzvm/overlay/lib/python3.10/site-packages/setuptools/build_meta.py", line 281, in run_setup
            super(_BuildMetaLegacyBackend,
          File "/tmp/pip-build-env-6rdrkzvm/overlay/lib/python3.10/site-packages/setuptools/build_meta.py", line 174, in run_setup
            exec(code, locals())
          File "<string>", line 7, in <module>
          File "/tmp/pip-req-build-psl84rhi/fortigate_api/__init__.py", line 3, in <module>
            from fortigate_api.fortigate import Fortigate
          File "/tmp/pip-req-build-psl84rhi/fortigate_api/fortigate.py", line 12, in <module>
            import requests
        ModuleNotFoundError: No module named 'requests'
        [end of output]

Using a fresh virtualenv the following can be seen. I'm not able to understand yet, why pypi wouldn't honor the "install_requires" argument (or so it seems).

hostname ~/tmp
$ venvcreate
Requirement already satisfied: pip in ./venv/lib/python3.10/site-packages (22.0.4)
Collecting pip
  Using cached pip-22.2.1-py3-none-any.whl (2.0 MB)
Requirement already satisfied: setuptools in ./venv/lib/python3.10/site-packages (58.1.0)
Collecting setuptools
  Using cached setuptools-63.3.0-py3-none-any.whl (1.2 MB)
Installing collected packages: setuptools, pip
  Attempting uninstall: setuptools
    Found existing installation: setuptools 58.1.0
    Uninstalling setuptools-58.1.0:
      Successfully uninstalled setuptools-58.1.0
  Attempting uninstall: pip
    Found existing installation: pip 22.0.4
    Uninstalling pip-22.0.4:
      Successfully uninstalled pip-22.0.4
Successfully installed pip-22.2.1 setuptools-63.3.0
(venv) hostname ~/tmp
$ pip install fortigate-api
Collecting fortigate-api
  Using cached fortigate_api-0.2.5.tar.gz (30 kB)
  Preparing metadata (setup.py) ... error
  error: subprocess-exited-with-error

  × python setup.py egg_info did not run successfully.
  │ exit code: 1
  ╰─> [10 lines of output]
      Traceback (most recent call last):
        File "<string>", line 2, in <module>
        File "<pip-setuptools-caller>", line 34, in <module>
        File "/tmp/pip-install-dsvb5kv5/fortigate-api_01b828e11cff462d9af5d9c172bd885d/setup.py", line 7, in <module>
          import fortigate_api as package
        File "/tmp/pip-install-dsvb5kv5/fortigate-api_01b828e11cff462d9af5d9c172bd885d/fortigate_api/__init__.py", line 3, in <module>
          from fortigate_api.fortigate import Fortigate
        File "/tmp/pip-install-dsvb5kv5/fortigate-api_01b828e11cff462d9af5d9c172bd885d/fortigate_api/fortigate.py", line 12, in <module>
          import requests
      ModuleNotFoundError: No module named 'requests'
      [end of output]

  note: This error originates from a subprocess, and is likely not a problem with pip.
error: metadata-generation-failed

× Encountered error while generating package metadata.
╰─> See above for output.

note: This is an issue with the package mentioned above, not pip.
hint: See above for details.

python version: 3.10.5

prior versions don't seem to have this issue.

New future

Hello. Is it possible to add execution of execute commands and wake-on-lan command?

Unable to use Query Params with Fortigate.get()

Hi,

I am trying to access a REST endpoint that needs to be supplied a query parameter, but due the the URL formatting I am not able to do this.

Example:

from fortigate_api import Fortigate

fgt = Fortigate(host='127.0.0.1', username='user', password='password')
fgt.get('api/v2/monitor/router/lookup?destination=0.0.0.0')

Will return an error "{'error_message': 'Failed to resolve FQDN'}" because the URL is formatted to be: api/v2/monitor/router/lookup?destination=0.0.0.0/

The _valid_url function does this:

return f"{self.url}/{url}/"

Will probably either need to remove the trailing / from the url, or may extend the get function to also accept parameters.
Happy to raise a PR for this, just not sure which solution you would have preferred.

A hacky workaround I've found is to add an additional query parameter to the URL so that the / ends up as part of that:

fgt.get('api/v2/monitor/router/lookup?destination=0.0.0.0&ignore')

Thanks,
Aaron

Logic simplification and unnecessary loop elimination for csrf token

Currently the get token from cookies function has the following loop:

Current code
while True:
    # fortios < v7
    cookie_name = "ccsrftoken"
    if cookies := [o for o in session.cookies if o and o.name == cookie_name]:
        break

    # fortios >= v7
    cookie_name += "_"
    if cookies := [o for o in session.cookies if o and o.name.startswith(cookie_name)]:
        break

    raise ValueError("Invalid login credentials. Cookie 'ccsrftoken' is missing.")

token = str(cookies[0].value).strip('"')
return token

In my opinion the logic could be significantly simplified and the loop removed. I've tested it on 7.2.8 and it works flawlessly :)
Let me know what you think!
(Of course the tests would need to be adjusted as they currently check for the underscore as well)

My suggestion
cookie_prefix = "ccsrftoken"
if cookies := [o for o in session.cookies if o and o.name.startswith(cookie_prefix)]:
    token = str(cookies[0].value).strip('"')
    return token
else:
    raise ValueError("Invalid login credentials. Cookie 'ccsrftoken' is missing.")

Logic simplification for login with user/pw

Inside the login function the logic for user/password authentication seems flawed.

  • The response to the post is not raised.
  • The request to /system/vdom seems unnecessary as the existence of an authenticated session is provided by the existence of the CSRF token
Current code
try:
    session.post(
        url=f"{self.url}/logincheck",
        data=urlencode([("username", self.username), ("secretkey", self.password)]),
        timeout=self.timeout,
        verify=self.verify,
    )
except Exception as ex:
    raise self._hide_secret_ex(ex)

token = self._get_token_from_cookies(session)
session.headers.update({"X-CSRFTOKEN": token})

response = session.get(url=f"{self.url}/api/v2/cmdb/system/vdom")
response.raise_for_status()
self._session = session

Let me know what you think about my suggestion!

My suggestion
# password
try:
    response: Response = session.post(
        url=f"{self.url}/logincheck",
        data=urlencode([("username", self.username), ("secretkey", self.password)]),
        timeout=self.timeout,
        verify=self.verify,
    )
except Exception as ex:
    raise self._hide_secret_ex(ex)
response.raise_for_status()
token = self._get_token_from_cookies(session)
session.headers.update({"X-CSRFTOKEN": token})
self._session = session

How do i fetch fortigate Serial number?

Because the output is already filtered with results dictionary , there is no api call to fetch fortigate serial number can anyone provide me with the url

Can't delete objects with '/' in their name

Hi,
This is a bug in the native Fortigate API (tested on 6.2.0), but if you have a workaround to delete objects, here is the sample code.

from fortigate_api import FortigateAPI

fgt = FortigateAPI(
    host="XXX",
    username="XXX",
    password="XXX",
)

subnet = "42.42.42.42/32"
subnet_name = f"my_vip_{subnet}"

data = {
    "name": subnet_name,
    "obj-type": "ip",
    "subnet": subnet,
    "type": "ipmask",
}
print(fgt.address.create(data)) # This works

print(fgt.address.get(uid=subnet_name)) # KO
print(fgt.address.get(filter=f"name=@{subnet_name}")) # This works

print(fgt.address.delete(uid=subnet_name)) # KO
print(fgt.address.delete(filter=f"name=@{subnet_name}")) # KO

ValueError: invalid login credentials, absent cookie ccsrftoken

Hi,
after having upgraded the fortigate to version 7.2.4 I get this error
ValueError: invalid login credentials, absent cookie ccsrftoken

I double checked the credentials and the login still work on an old version of fortigate
Ho can I debug this further?

thanks in advance

DC

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.