diff options
Diffstat (limited to 'net-mgmt')
-rw-r--r-- | net-mgmt/Makefile | 2 | ||||
-rw-r--r-- | net-mgmt/peering-manager/Makefile | 93 | ||||
-rw-r--r-- | net-mgmt/peering-manager/distinfo | 3 | ||||
-rwxr-xr-x | net-mgmt/peering-manager/files/850.peeringmanager-housekeeping.in | 32 | ||||
-rw-r--r-- | net-mgmt/peering-manager/files/gunicorn.conf.py.in | 245 | ||||
-rw-r--r-- | net-mgmt/peering-manager/files/patch-peering__manager_configuration.example.py | 11 | ||||
-rwxr-xr-x | net-mgmt/peering-manager/files/peering_manager_rq.in | 50 | ||||
-rw-r--r-- | net-mgmt/peering-manager/files/pkg-message.in | 9 | ||||
-rw-r--r-- | net-mgmt/peering-manager/pkg-descr | 24 | ||||
-rw-r--r-- | net-mgmt/py-pyixapi/Makefile | 23 | ||||
-rw-r--r-- | net-mgmt/py-pyixapi/distinfo | 3 | ||||
-rw-r--r-- | net-mgmt/py-pyixapi/pkg-descr | 3 |
12 files changed, 498 insertions, 0 deletions
diff --git a/net-mgmt/Makefile b/net-mgmt/Makefile index a7e943abb5f7..5aebf555281d 100644 --- a/net-mgmt/Makefile +++ b/net-mgmt/Makefile @@ -296,6 +296,7 @@ SUBDIR += pandorafms_agent SUBDIR += pandorafms_console SUBDIR += pandorafms_server + SUBDIR += peering-manager SUBDIR += pftabled SUBDIR += php-fpm_exporter SUBDIR += php81-snmp @@ -343,6 +344,7 @@ SUBDIR += py-pyIOSXR SUBDIR += py-pyang SUBDIR += py-pyeapi + SUBDIR += py-pyixapi SUBDIR += py-pynetbox SUBDIR += py-pynxos SUBDIR += py-pypowerwall diff --git a/net-mgmt/peering-manager/Makefile b/net-mgmt/peering-manager/Makefile new file mode 100644 index 000000000000..527e3d99d9dd --- /dev/null +++ b/net-mgmt/peering-manager/Makefile @@ -0,0 +1,93 @@ +PORTNAME= peering-manager +DISTVERSIONPREFIX= v +DISTVERSION= 1.9.7 +CATEGORIES= net-mgmt python + +MAINTAINER= bofh@FreeBSD.org +COMMENT= BGP sessions management tool +WWW= https://peering-manager.net/ + +LICENSE= APACHE20 +LICENSE_FILE= ${WRKSRC}/LICENSE + +RUN_DEPENDS= \ + ${PYTHON_PKGNAMEPREFIX}Jinja2>=3.1:devel/py-Jinja2@${PY_FLAVOR} \ + bgpq4>0:net-mgmt/bgpq4 \ + ${PYTHON_PKGNAMEPREFIX}django51>=5.1<5.2:www/py-django51@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}dj51-djangorestframework>=3.15:www/py-dj51-djangorestframework@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}dj51-django-debug-toolbar>=5.0:www/py-dj51-django-debug-toolbar@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}dj51-django-filter>=25.1:www/py-dj51-django-filter@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}dj51-django-netfields>=1.3:www/py-dj51-django-netfields@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}dj51-django-prometheus>=2.3:www/py-dj51-django-prometheus@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}dj51-django-redis>=5.4:www/py-dj51-django-redis@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}dj51-django-rq>=2.10:devel/py-dj51-django-rq@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}dj51-django-tables2>=2.7:www/py-dj51-django-tables2@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}dj51-django-taggit>=6.1:www/py-dj51-django-taggit@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}dj51-drf-spectacular>=0.28:www/py-dj51-drf-spectacular@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}dj51-drf-spectacular-sidecar>=2025:www/py-dj51-drf-spectacular-sidecar@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}dj51-social-auth-app-django>=5.4:www/py-dj51-social-auth-app-django@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}dulwich>=0.22:devel/py-dulwich@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}gunicorn>=23.0.0:www/py-gunicorn@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}markdown>=3.7:textproc/py-markdown@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}napalm>=5.0:net-mgmt/py-napalm@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}packaging>=23.2:devel/py-packaging@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}psycopg>=3.1:databases/py-psycopg@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}psycopg-pool>=3.1:databases/py-psycopg-pool@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}pyixapi>=0.2:net-mgmt/py-pyixapi@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}pynetbox>=7.3:net-mgmt/py-pynetbox@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}pyyaml>=6.0:devel/py-pyyaml@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}requests>=2.32:www/py-requests@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}social-auth-core>=4.5.4:security/py-social-auth-core@${PY_FLAVOR} + +USES= cpe pgsql:13+ python:3.10-3.12 +CPE_VENDOR= ${PORTNAME} +CPE_PRODUCT= ${PORTNAME:S/-/_/} +USE_GITHUB= yes +USE_RC_SUBR= peering_manager_rq + +NO_ARCH= yes +NO_BUILD= yes +SUB_FILES= gunicorn.conf.py 850.peeringmanager-housekeeping +SUB_LIST= WWWDIR=${WWWDIR} PORTNAME=${PORTNAME} WSGI_APP=peering_manager.wsgi PYTHON_CMD=${PYTHON_CMD} PYTHON_VER=${PYTHON_VER} + +PORTDOCS= * + +OPTIONS_DEFINE= DOCS +OPTIONS_DEFAULT=REDIS +OPTIONS_RADIO= KVBACKENDS +OPTIONS_RADIO_KVBACKENDS= REDIS VALKEY + +KVBACKENDS_DESC=Key Value Storage Backends +REDIS_DESC= Redis Key Value Backend support +VALKEY_DESC= Valkey Key Value Backend support + +REDIS_RUN_DEPENDS= redis>=8.2.1:databases/redis +VALKEY_RUN_DEPENDS= valkey>=1.0:databases/valkey + +FIND_EXPR= "! -name *.orig ! -name .gitattributes ! -name .gitignore ! -name .gitattributes ! -name .isort.cfg ! -name .pre-commit-config.yaml ! -name .readthedocs.yaml ! -name CHANGELOG.md ! -name LICENSE ! -name README.md ! -name mkdocs.yaml ! -name poetry.lock ! -name pyproject.toml ! -name requirements.txt ! -name configuration.example.py ! -path */.github ! -path */.github/* ! -path */docs ! -path */docs/* -prune" + +do-install: + ${MKDIR} ${STAGEDIR}${WWWDIR} + ${MKDIR} ${STAGEDIR}${PREFIX}/etc/periodic/daily + ${ECHO} "@owner www" >> ${TMPPLIST} + ${ECHO} "@group www" >> ${TMPPLIST} + (cd ${WRKSRC} && ${COPYTREE_SHARE} . ${STAGEDIR}${WWWDIR} ${FIND_EXPR}) + ${FIND} -s ${STAGEDIR}${PREFIX}/www/${PORTNAME} -not -type d | ${SORT} | \ + ${SED} -e 's|^${STAGEDIR}${PREFIX}/||' >> ${TMPPLIST} + ${FIND} -s ${STAGEDIR}${PREFIX}/www/${PORTNAME} -type d -empty | ${SORT} -r | \ + ${SED} -e 's|^${STAGEDIR}${PREFIX}/|@dir |' >> ${TMPPLIST} + ${INSTALL_DATA} ${WRKDIR}/gunicorn.conf.py ${STAGEDIR}${WWWDIR}/gunicorn.conf.py.sample + ${INSTALL_DATA} ${WRKSRC}/peering_manager/configuration.example.py ${STAGEDIR}${WWWDIR}/peering_manager/configuration.py.sample + ${INSTALL_DATA} ${WRKDIR}/850.peeringmanager-housekeeping ${STAGEDIR}${PREFIX}/etc/periodic/daily/850.peeringmanager-housekeeping + ${ECHO} "@sample ${WWWDIR}/gunicorn.conf.py.sample" >> ${TMPPLIST} + ${ECHO} "@sample ${WWWDIR}/peering_manager/configuration.py.sample" >> ${TMPPLIST} + ${ECHO} "etc/periodic/daily/850.peeringmanager-housekeeping" >> ${TMPPLIST} + +do-install-DOCS-on: + @${MKDIR} ${STAGEDIR}${DOCSDIR} + cd ${WRKSRC}/docs && ${COPYTREE_SHARE} . ${STAGEDIR}${DOCSDIR} +.for f in CHANGELOG.md README.md + ${INSTALL_DATA} ${WRKSRC}/${f} ${STAGEDIR}${DOCSDIR} +.endfor + +.include <bsd.port.mk> diff --git a/net-mgmt/peering-manager/distinfo b/net-mgmt/peering-manager/distinfo new file mode 100644 index 000000000000..95bbe9b48822 --- /dev/null +++ b/net-mgmt/peering-manager/distinfo @@ -0,0 +1,3 @@ +TIMESTAMP = 1756827986 +SHA256 (peering-manager-peering-manager-v1.9.7_GH0.tar.gz) = fa272abe40fec06d3f0c541d771d560f9a93f8940dea96b8538785a9cef32afd +SIZE (peering-manager-peering-manager-v1.9.7_GH0.tar.gz) = 8349343 diff --git a/net-mgmt/peering-manager/files/850.peeringmanager-housekeeping.in b/net-mgmt/peering-manager/files/850.peeringmanager-housekeeping.in new file mode 100755 index 000000000000..675f0f2aef63 --- /dev/null +++ b/net-mgmt/peering-manager/files/850.peeringmanager-housekeeping.in @@ -0,0 +1,32 @@ +#!/bin/sh +# This shell script invokes Peering Manager's housekeeping management command, +# which intended to be run nightly. +# +# If you want to enable this script, copy it to %%PREFIX%%/etc/periodic/daily +# and place the following into /etc/periodic.conf: +# +# daily_peeringmanager_housekeeping_enable="YES" +# +# If Peering Manager has been installed into a nonstandard location, update the +# paths below. +command="%%PYTHON_CMD%%" +peeringmanager_root="%%WWWDIR%%" + +# If there is a global system configuration file, suck it in. +# +if [ -r /etc/defaults/periodic.conf ]; then + . /etc/defaults/periodic.conf + source_periodic_confs +fi + +rc=0 + +case "$daily_peeringmanager_housekeeping_enable" in + [Yy][Ee][Ss]) + echo "" + echo "Running Peering Manager housekeeping:" + $command "$peeringmanager_root/manage.py" housekeeping + rc=$? +esac + +exit $rc diff --git a/net-mgmt/peering-manager/files/gunicorn.conf.py.in b/net-mgmt/peering-manager/files/gunicorn.conf.py.in new file mode 100644 index 000000000000..0477e5bf9f64 --- /dev/null +++ b/net-mgmt/peering-manager/files/gunicorn.conf.py.in @@ -0,0 +1,245 @@ +# Sample Gunicorn configuration file. +import multiprocessing +# +# Server socket +# +# bind - The socket to bind. +# +# A string of the form: 'HOST', 'HOST:PORT', 'unix:PATH'. +# An IP is a valid HOST. +# +# backlog - The number of pending connections. This refers +# to the number of clients that can be waiting to be +# served. Exceeding this number results in the client +# getting an error when attempting to connect. It should +# only affect servers under significant load. +# +# Must be a positive integer. Generally set in the 64-2048 +# range. +# + +bind = ['127.0.0.1:8001','[::1]:8001'] +backlog = 2048 + +# +# Worker processes +# +# workers - The number of worker processes that this server +# should keep alive for handling requests. +# +# A positive integer generally in the 2-4 x $(NUM_CORES) +# range. You'll want to vary this a bit to find the best +# for your particular application's work load. +# +# worker_class - The type of workers to use. The default +# sync class should handle most 'normal' types of work +# loads. You'll want to read +# http://docs.gunicorn.org/en/latest/design.html#choosing-a-worker-type +# for information on when you might want to choose one +# of the other worker classes. +# +# A string referring to a Python path to a subclass of +# gunicorn.workers.base.Worker. The default provided values +# can be seen at +# http://docs.gunicorn.org/en/latest/settings.html#worker-class +# +# worker_connections - For the eventlet and gevent worker classes +# this limits the maximum number of simultaneous clients that +# a single process can handle. +# +# A positive integer generally set to around 1000. +# +# timeout - If a worker does not notify the master process in this +# number of seconds it is killed and a new worker is spawned +# to replace it. +# +# Generally set to thirty seconds. Only set this noticeably +# higher if you're sure of the repercussions for sync workers. +# For the non sync workers it just means that the worker +# process is still communicating and is not tied to the length +# of time required to handle a single request. +# +# keepalive - The number of seconds to wait for the next request +# on a Keep-Alive HTTP connection. +# +# A positive integer. Generally set in the 1-5 seconds range. +# + +#workers = 5 +workers = multiprocessing.cpu_count() * 2 + 1 +worker_class = 'sync' +worker_connections = 1000 +timeout = 300 +keepalive = 2 +threads = 3 +max_requests = 5000 +max_requests_jitter = 500 + +# +# spew - Install a trace function that spews every line of Python +# that is executed when running the server. This is the +# nuclear option. +# +# True or False +# + +spew = False + +# +# Server mechanics +# +# daemon - Detach the main Gunicorn process from the controlling +# terminal with a standard fork/fork sequence. +# +# True or False +# +# raw_env - Pass environment variables to the execution environment. +# +# pidfile - The path to a pid file to write +# +# A path string or None to not write a pid file. +# +# user - Switch worker processes to run as this user. +# +# A valid user id (as an integer) or the name of a user that +# can be retrieved with a call to pwd.getpwnam(value) or None +# to not change the worker process user. +# +# group - Switch worker process to run as this group. +# +# A valid group id (as an integer) or the name of a user that +# can be retrieved with a call to pwd.getgrnam(value) or None +# to change the worker processes group. +# +# umask - A mask for file permissions written by Gunicorn. Note that +# this affects unix socket permissions. +# +# A valid value for the os.umask(mode) call or a string +# compatible with int(value, 0) (0 means Python guesses +# the base, so values like "0", "0xFF", "0022" are valid +# for decimal, hex, and octal representations) +# +# tmp_upload_dir - A directory to store temporary request data when +# requests are read. This will most likely be disappearing soon. +# +# A path to a directory where the process owner can write. Or +# None to signal that Python should choose one on its own. +# + +daemon = False +umask = 0 +user = None +tmp_upload_dir = None +pythonpath = '%%WWWDIR%%' +chdir = '%%WWWDIR%%' +wsgi_app = '%%WSGI_APP%%' + +# +# Logging +# +# logfile - The path to a log file to write to. +# +# A path string. "-" means log to stdout. +# +# loglevel - The granularity of log output +# +# A string of "debug", "info", "warning", "error", "critical" +# + +syslog = True +syslog_prefix = '%%PORTNAME%%' +syslog_addr = 'unix:///var/run/log#dgram' +disable_redirect_access_to_syslog = True +errorlog = '-' +loglevel = 'info' +accesslog = '-' +access_log_format = '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"' + +# +# Process naming +# +# proc_name - A base to use with setproctitle to change the way +# that Gunicorn processes are reported in the system process +# table. This affects things like 'ps' and 'top'. If you're +# going to be running more than one instance of Gunicorn you'll +# probably want to set a name to tell them apart. This requires +# that you install the setproctitle module. +# +# A string or None to choose a default of something like 'gunicorn'. +# + +proc_name = '%%PORTNAME%%' + +# +# Server hooks +# +# post_fork - Called just after a worker has been forked. +# +# A callable that takes a server and worker instance +# as arguments. +# +# pre_fork - Called just prior to forking the worker subprocess. +# +# A callable that accepts the same arguments as post_fork +# +# pre_exec - Called just prior to forking off a secondary +# master process during things like config reloading. +# +# A callable that takes a server instance as the sole argument. +# + +def post_fork(server, worker): + server.log.info("Worker spawned (pid: %s)", worker.pid) + +def pre_fork(server, worker): + pass + +def pre_exec(server): + server.log.info("Forked child, re-executing.") + +def when_ready(server): + server.log.info("Server is ready. Spawning workers") + +def worker_int(worker): + worker.log.info("worker received INT or QUIT signal") + + ## get traceback info + import threading, sys, traceback + id2name = {th.ident: th.name for th in threading.enumerate()} + code = [] + for threadId, stack in sys._current_frames().items(): + code.append("\n# Thread: %s(%d)" % (id2name.get(threadId,""), + threadId)) + for filename, lineno, name, line in traceback.extract_stack(stack): + code.append('File: "%s", line %d, in %s' % (filename, + lineno, name)) + if line: + code.append(" %s" % (line.strip())) + worker.log.debug("\n".join(code)) + +def worker_abort(worker): + worker.log.info("worker received SIGABRT signal") + +def ssl_context(conf, default_ssl_context_factory): + import ssl + + # The default SSLContext returned by the factory function is initialized + # with the TLS parameters from config, including TLS certificates and other + # parameters. + context = default_ssl_context_factory() + + # The SSLContext can be further customized, for example by enforcing + # minimum TLS version. + context.minimum_version = ssl.TLSVersion.TLSv1_3 + + # Server can also return different server certificate depending which + # hostname the client uses. Requires Python 3.7 or later. + def sni_callback(socket, server_hostname, context): + if server_hostname == "foo.127.0.0.1.nip.io": + new_context = default_ssl_context_factory() + new_context.load_cert_chain(certfile="foo.pem", keyfile="foo-key.pem") + socket.context = new_context + + context.sni_callback = sni_callback + + return context diff --git a/net-mgmt/peering-manager/files/patch-peering__manager_configuration.example.py b/net-mgmt/peering-manager/files/patch-peering__manager_configuration.example.py new file mode 100644 index 000000000000..1865973e0e30 --- /dev/null +++ b/net-mgmt/peering-manager/files/patch-peering__manager_configuration.example.py @@ -0,0 +1,11 @@ +--- peering_manager/configuration.example.py.orig 2025-09-05 10:59:41 UTC ++++ peering_manager/configuration.example.py +@@ -9,7 +9,7 @@ ALLOWED_HOSTS = ["*"] + # A random one can be generated with Python in the Peering Manager venv with + # from django.core.management.utils import get_random_secret_key + # get_random_secret_key() +-SECRET_KEY = "ef7npku*djrj_r4jt4cojo8^j@2($$@05e(eq_mn!ywx*jg0vy" ++#SECRET_KEY = "<GENERATE A KEY>" + + # Base URL path if accessing Peering Manager within a directory. + BASE_PATH = "" diff --git a/net-mgmt/peering-manager/files/peering_manager_rq.in b/net-mgmt/peering-manager/files/peering_manager_rq.in new file mode 100755 index 000000000000..6b12856dfa9b --- /dev/null +++ b/net-mgmt/peering-manager/files/peering_manager_rq.in @@ -0,0 +1,50 @@ +#!/bin/sh + +# This sample rc script starts the RQ worker background service which is +# required for Webhooks and various automation tasks. + +# +# PROVIDE: peering_manager_rq +# REQUIRE: DAEMON +# KEYWORD: shutdown +# +# Add the following line to /etc/rc.conf.local or /etc/rc.conf +# to enable peering_manager-rq: +# +# peering_manager_rq_enable (bool): Set to NO by default. +# Set it to YES to enable peering_manager_rq. +# +# peering_manager_rq_user (str): User to run worker as. +# Defaults to www. + +. /etc/rc.subr + +name=peering_manager_rq +rcvar=peering_manager_rq_enable + +load_rc_config $name + +: ${peering_manager_rq_enable:=NO} +: ${peering_manager_rq_user:=www} +: ${peering_manager_rq_workers:=1} + +start_cmd="peering_manager_rq_start" +start_precmd="peering_manager_rq_precmd" +command="%%PYTHON_CMD%%" +command_args="%%WWWDIR%%/manage.py rqworker" +_pidprefix="/var/run/%%PORTNAME%%" + +peering_manager_rq_precmd() +{ + install -d -o ${peering_manager_rq_user} ${_pidprefix} +} + +peering_manager_rq_start() +{ + echo "Starting peering_manager_rq." + for i in `jot - 1 $peering_manager_rq_workers`; do + /usr/sbin/daemon -cf -p ${_pidprefix}/${name}-${i}.pid -u ${peering_manager_rq_user} ${command} ${command_args} --name peering-manager@${i} + done +} + +run_rc_command "$1" diff --git a/net-mgmt/peering-manager/files/pkg-message.in b/net-mgmt/peering-manager/files/pkg-message.in new file mode 100644 index 000000000000..13913edb961b --- /dev/null +++ b/net-mgmt/peering-manager/files/pkg-message.in @@ -0,0 +1,9 @@ +[ +{ type: install + message: <<EOD +For installation instructions please refer to the related wiki page: + +- https://wiki.freebsd.org/Ports/net-mgmt/peering-manager +EOD +} +] diff --git a/net-mgmt/peering-manager/pkg-descr b/net-mgmt/peering-manager/pkg-descr new file mode 100644 index 000000000000..ae00708cbbd6 --- /dev/null +++ b/net-mgmt/peering-manager/pkg-descr @@ -0,0 +1,24 @@ +Peering Manager was originally and still is developed by its lead + maintainer, Guillaume Mazoyer in 2017 as part of an effort to automate + BGP peering provisionning. + +Since then, many organisations around the world have used Peering + Manager as their central network source of truth to empower both + network operators and automation. + +Key Features +Peering Manager was built specifically to serve the needs of network + engineers and operators operating BGP networks. Below is a very brief + overview of the core features it provides. + +- Autonomous system management +- BGP groups +- Internet Exchange Points +- BGP sessions with with differences between classic ones and IXP ones +- BGP communities and routing policies +- Devices and configuration rendering leveraging Jinja2 +- Configuration installation for NAPALM supported platforms +- Detailed, automatic change logging +- Global search engine +- Event-driven webhooks +- Interoperability with other tools such as PeeringDB, IX-API, and more diff --git a/net-mgmt/py-pyixapi/Makefile b/net-mgmt/py-pyixapi/Makefile new file mode 100644 index 000000000000..b1c57adfe523 --- /dev/null +++ b/net-mgmt/py-pyixapi/Makefile @@ -0,0 +1,23 @@ +PORTNAME= pyixapi +DISTVERSION= 0.2.6 +CATEGORIES= net-mgmt python +MASTER_SITES= PYPI +PKGNAMEPREFIX= ${PYTHON_PKGNAMEPREFIX} + +MAINTAINER= bofh@FreeBSD.org +COMMENT= Python API client library for IX-API +WWW= https://ix-api.net/ + +LICENSE= APACHE20 +LICENSE_FILE= ${WRKSRC}/LICENSE + +BUILD_DEPENDS= ${PYTHON_PKGNAMEPREFIX}poetry-core>0:devel/py-poetry-core@${PY_FLAVOR} +RUN_DEPENDS= ${PYTHON_PKGNAMEPREFIX}pyjwt>=2.4.0:www/py-pyjwt@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}requests>=2.20.0:www/py-requests@${PY_FLAVOR} + +USES= python +USE_PYTHON= autoplist pep517 + +NO_ARCH= yes + +.include <bsd.port.mk> diff --git a/net-mgmt/py-pyixapi/distinfo b/net-mgmt/py-pyixapi/distinfo new file mode 100644 index 000000000000..108271427920 --- /dev/null +++ b/net-mgmt/py-pyixapi/distinfo @@ -0,0 +1,3 @@ +TIMESTAMP = 1756893360 +SHA256 (pyixapi-0.2.6.tar.gz) = 864ef41255f62613db3161127b4c7c7bb36c776fb675cb3cdea3f7deee8a9732 +SIZE (pyixapi-0.2.6.tar.gz) = 14614 diff --git a/net-mgmt/py-pyixapi/pkg-descr b/net-mgmt/py-pyixapi/pkg-descr new file mode 100644 index 000000000000..41fcb40e2774 --- /dev/null +++ b/net-mgmt/py-pyixapi/pkg-descr @@ -0,0 +1,3 @@ +Python API client library for IX-API. + +Currently Supported API versions are version 1 and version 2. |