add bundle:netbox

This commit is contained in:
Franzi 2021-08-17 18:02:15 +02:00
parent f077346930
commit b0d2503f08
Signed by: kunsi
GPG Key ID: 12E3D2136B818350
8 changed files with 416 additions and 0 deletions

View File

@ -44,6 +44,7 @@ Rule of thumb: keep ports below 10000 free for stuff that reserves ports.
| 22050 | radicale | radicale carddav and caldav server |
| 22060 | pretalx | gunicorn |
| 22070 | paperless-ng | gunicorn |
| 22080 | netbox | gunicorn |
| 22999 | nginx | stub_status |
## UDP

21
bundles/netbox/README.md Normal file
View File

@ -0,0 +1,21 @@
netbox
------
IP address management (IPAM) and data center infrastructure management (DCIM) tool.
https://github.com/digitalocean/netbox
Metadata:
'netbox': {
'hostname': 'netbox.smedia.tools',
'version': '2.0.8',
},
'nginx': {
'vhosts': {
'netbox': {
'generics': {'netbox.conf'},
},
},
}

View File

@ -0,0 +1,117 @@
ALLOWED_HOSTS = [
'${node.metadata.get('netbox/domain')}'
]
DATABASE = {
'NAME': 'netbox',
'USER': 'netbox',
'PASSWORD': '${repo.vault.password_for("netbox postgresql " + node.name)}',
'HOST': 'localhost',
'PORT': '',
}
REDIS = {
'tasks': {
'HOST': 'localhost',
'PORT': 6379,
'PASSWORD': '',
'DATABASE': 0,
'DEFAULT_TIMEOUT': 300,
'SSL': False,
},
'caching': {
'HOST': 'localhost',
'PORT': 6379,
'PASSWORD': '',
'DATABASE': 1,
'DEFAULT_TIMEOUT': 300,
'SSL': False,
}
}
SECRET_KEY = '${repo.vault.password_for('django secret netbox ' + node.name, length=50)}'
ADMINS = [
% for name, email in sorted(node.metadata.get('netbox/admins', {})):
['${name}', '${email}'],
% endfor
]
BANNER_TOP = ''
BANNER_BOTTOM = ''
BASE_PATH = ''
CACHE_TIMEOUT = 0
CHANGELOG_RETENTION = ${node.metadata.get('netbox/changelog_retention_days', 90)}
CORS_ORIGIN_ALLOW_ALL = False
CORS_ORIGIN_WHITELIST = [
% for hostname in sorted(node.metadata.get('netbox/cors_allowlist', set())):
'${hostname}',
% endfor
]
CORS_ORIGIN_REGEX_WHITELIST = []
DEBUG = False
EMAIL = {
'SERVER': 'localhost',
'PORT': 25,
'USERNAME': '',
'PASSWORD': '',
'TIMEOUT': 10, # seconds
'FROM_EMAIL': '',
}
ENFORCE_GLOBAL_UNIQUE = True
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console': {
'class': 'logging.StreamHandler',
},
},
'root': {
'handlers': ['console'],
'level': 'WARNING',
},
}
LOGIN_REQUIRED = False
MAINTENANCE_MODE = False
MAX_PAGE_SIZE = 1000
MEDIA_ROOT = '/opt/netbox/media'
NAPALM_USERNAME = ''
NAPALM_PASSWORD = ''
NAPALM_TIMEOUT = 30
NAPALM_ARGS = {}
PAGINATE_COUNT = 100
PLUGINS = {}
PREFER_IPV4 = False
# We use icinga for that.
RELEASE_CHECK_URL = None
REMOTE_AUTH_BACKEND = 'netbox.authentication.RemoteUserBackend'
SCRIPTS_ROOT = '/opt/netbox/scripts'
TIME_ZONE = 'UTC'
DATE_FORMAT = 'N j, Y'
SHORT_DATE_FORMAT = 'Y-m-d'
TIME_FORMAT = 'g:i a'
SHORT_TIME_FORMAT = 'H:i:s'
DATETIME_FORMAT = 'N j, Y g:i a'
SHORT_DATETIME_FORMAT = 'Y-m-d H:i'

View File

@ -0,0 +1,7 @@
command = '/opt/netbox/venv/bin/gunicorn'
pythonpath = '/opt/netbox/src/netbox'
bind = '127.0.0.1:22080'
workers = ${min(node.metadata.get('vm/cpu', 1), 6)*2+1}
threads = 1
max_requests = 5000
max_requests_jitter = 500

View File

@ -0,0 +1,20 @@
[Unit]
Description=NetBox WSGI Service
Documentation=https://netbox.readthedocs.io/en/stable/
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=netbox
Group=netbox
PIDFile=/var/tmp/netbox.pid
WorkingDirectory=/opt/netbox/src
ExecStart=/opt/netbox/venv/bin/gunicorn --pid /var/tmp/netbox.pid --config /opt/netbox/gunicorn_config.py netbox.wsgi
Restart=on-failure
RestartSec=30
PrivateTmp=true
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,20 @@
[Unit]
Description=NetBox Request Queue Worker
Documentation=https://netbox.readthedocs.io/en/stable/
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=netbox
Group=netbox
WorkingDirectory=/opt/netbox/src
ExecStart=/opt/netbox/venv/bin/python /opt/netbox/src/netbox/manage.py rqworker
Restart=on-failure
RestartSec=30
PrivateTmp=true
[Install]
WantedBy=multi-user.target

124
bundles/netbox/items.py Normal file
View File

@ -0,0 +1,124 @@
users = {
'netbox': {
'home': '/opt/netbox',
},
}
directories = {
'/opt/netbox/src': {},
'/opt/netbox/media': {
'owner': 'netbox',
},
'/opt/netbox/scripts': {
'owner': 'netbox',
},
}
git_deploy = {
'/opt/netbox/src': {
'repo': 'https://github.com/netbox-community/netbox.git',
'rev': node.metadata.get('netbox/version'),
'triggers': {
'action:netbox_install',
'action:netbox_upgrade',
'svc_systemd:netbox-web:restart',
'svc_systemd:netbox-worker:restart',
},
},
}
# This is a recreation of https://github.com/netbox-community/netbox/blob/develop/upgrade.sh
actions = {
'netbox_create_virtualenv': {
'command': '/usr/bin/python3 -m virtualenv -p python3 /opt/netbox/venv',
'unless': 'test -d /opt/netbox/venv/',
'needed_by': {
'action:netbox_install',
},
},
'netbox_install': {
'triggered': True,
'command': ' && '.join([
'cd /opt/netbox/src',
'/opt/netbox/venv/bin/pip install --upgrade pip wheel setuptools django-auth-ldap gunicorn',
'/opt/netbox/venv/bin/pip install --upgrade -r requirements.txt',
]),
'needs': {
'pkg_apt:build-essential',
'pkg_apt:graphviz',
'pkg_apt:libffi-dev',
'pkg_apt:libldap2-dev',
'pkg_apt:libpq-dev',
'pkg_apt:libsasl2-dev',
'pkg_apt:libssl-dev',
'pkg_apt:libxml2-dev',
'pkg_apt:libxslt1-dev',
'pkg_apt:python3-dev',
'pkg_apt:zlib1g-dev',
}
},
'netbox_upgrade': {
'triggered': True,
'command': ' && '.join([
'/opt/netbox/venv/bin/python /opt/netbox/src/netbox/manage.py migrate',
'/opt/netbox/venv/bin/python /opt/netbox/src/netbox/manage.py collectstatic --no-input',
'/opt/netbox/venv/bin/python /opt/netbox/src/netbox/manage.py remove_stale_contenttypes --no-input',
'/opt/netbox/venv/bin/python /opt/netbox/src/netbox/manage.py invalidate all', # clear cached data
]),
'needs': {
'action:netbox_install',
'file:/opt/netbox/src/netbox/netbox/configuration.py',
},
},
}
files = {
'/etc/systemd/system/netbox-web.service': {
'triggers': {
'action:systemd-reload',
'svc_systemd:netbox-web:restart',
},
},
'/etc/systemd/system/netbox-worker.service': {
'triggers': {
'action:systemd-reload',
'svc_systemd:netbox-worker:restart',
},
},
'/opt/netbox/src/netbox/netbox/configuration.py': {
'content_type': 'mako',
'triggers': {
'svc_systemd:netbox-web:restart',
'svc_systemd:netbox-worker:restart',
},
'needs': {
'git_deploy:/opt/netbox/src',
},
},
'/opt/netbox/gunicorn_config.py': {
'content_type': 'mako',
'triggers': {
'svc_systemd:netbox-web:restart',
},
},
}
svc_systemd = {
'netbox-web': {
'needs': {
'action:netbox_install',
'action:netbox_upgrade',
'file:/etc/systemd/system/netbox-web.service',
'file:/opt/netbox/gunicorn_config.py',
'file:/opt/netbox/src/netbox/netbox/configuration.py',
},
},
'netbox-worker': {
'needs': {
'action:netbox_install',
'action:netbox_upgrade',
'file:/etc/systemd/system/netbox-worker.service',
'file:/opt/netbox/src/netbox/netbox/configuration.py',
},
},
}

106
bundles/netbox/metadata.py Normal file
View File

@ -0,0 +1,106 @@
defaults = {
'apt': {
'packages': {
'build-essential': {},
'graphviz': {},
'libffi-dev': {},
'libldap2-dev': {},
'libpq-dev': {},
'libsasl2-dev': {},
'libssl-dev': {},
'libxml2-dev': {},
'libxslt1-dev': {},
'python3-dev': {},
'zlib1g-dev': {},
},
},
'backups': {
'paths': {
'/opt/netbox/media',
'/opt/netbox/scripts',
# and database
},
},
'postgresql': {
'databases': {
'netbox': {
'owner': 'netbox',
},
},
'roles': {
'netbox': {
'password': repo.vault.password_for('netbox postgresql ' + node.name),
},
},
},
'zfs': {
'datasets': {
'tank/netbox': {},
'tank/netbox/install': {
'mountpoint': '/opt/netbox/src',
'needed_by': {
'directory:/opt/netbox/src',
},
},
'tank/netbox/media': {
'mountpoint': '/opt/netbox/media',
'needed_by': {
'directory:/opt/netbox/media',
},
},
'tank/netbox/scripts': {
'mountpoint': '/opt/netbox/scripts',
'needed_by': {
'directory:/opt/netbox/scripts',
},
},
},
},
}
@metadata_reactor.provides(
'icinga2_api/netbox/services/NETBOX UPDATE',
)
def icinga_check_for_new_release(metadata):
return {
'icinga2_api': {
'netbox': {
'services': {
'NETBOX UPDATE': {
'command_on_monitored_host': '/usr/local/share/icinga/plugins/check_github_for_new_release netbox-community/netbox {}'.format(metadata.get('netbox/version')),
'check_interval': '60m',
},
},
},
},
}
@metadata_reactor.provides(
'nginx/vhosts/netbox',
)
def nginx(metadata):
if not node.has_bundle('nginx'):
raise DoNotRunAgain
return {
'nginx': {
'vhosts': {
'netbox': {
'domain': metadata.get('netbox/domain'),
'website_check_path': '/',
'website_check_string': 'NetBox',
'locations': {
'/': {
'target': 'http://127.0.0.1:22080',
},
'/static/': {
'alias': '/opt/netbox/src/netbox/static/',
},
},
},
},
},
}