Merge branch 'netbox' into 'master'
__netbox type See merge request ungleich-public/cdist-contrib!12
This commit is contained in:
commit
2e02c413b6
57 changed files with 1956 additions and 0 deletions
8
type/__netbox/explorer/secretkey
Executable file
8
type/__netbox/explorer/secretkey
Executable file
|
@ -0,0 +1,8 @@
|
|||
#!/bin/sh -e
|
||||
|
||||
# Explorer will output the key if he exists.
|
||||
|
||||
secretkey="/opt/netbox/cdist/secretkey"
|
||||
if [ -f "$secretkey" ]; then
|
||||
cat "$secretkey"
|
||||
fi
|
5
type/__netbox/explorer/version
Executable file
5
type/__netbox/explorer/version
Executable file
|
@ -0,0 +1,5 @@
|
|||
#!/bin/sh -e
|
||||
|
||||
# output version if exist
|
||||
version_path="/opt/netbox/cdist/version"
|
||||
if [ -f "$version_path" ]; then cat "$version_path"; fi
|
319
type/__netbox/files/configuration.py.sh
Executable file
319
type/__netbox/files/configuration.py.sh
Executable file
|
@ -0,0 +1,319 @@
|
|||
#!/bin/sh
|
||||
|
||||
cat << EOF
|
||||
#########################
|
||||
# #
|
||||
# Required settings #
|
||||
# #
|
||||
#########################
|
||||
|
||||
# This is a list of valid fully-qualified domain names (FQDNs) for the NetBox server. NetBox will not permit write
|
||||
# access to the server via any other hostnames. The first FQDN in the list will be treated as the preferred name.
|
||||
#
|
||||
# Example: ALLOWED_HOSTS = ['netbox.example.com', 'netbox.internal.local']
|
||||
ALLOWED_HOSTS = [$ALLOWED_HOSTS ]
|
||||
|
||||
# PostgreSQL database configuration. See the Django documentation for a complete list of available parameters:
|
||||
# https://docs.djangoproject.com/en/stable/ref/settings/#databases
|
||||
DATABASE = {
|
||||
'NAME': '$DATABASE_NAME', # Database name
|
||||
'USER': '$DATABASE_USER', # PostgreSQL username
|
||||
'PASSWORD': '$DATABASE_PASSWORD', # PostgreSQL password
|
||||
'HOST': '$DATABASE_HOST', # Database server
|
||||
'PORT': '$DATABASE_PORT', # Database port (leave blank for default)
|
||||
'CONN_MAX_AGE': 300, # Max database connection age
|
||||
}
|
||||
|
||||
# Redis database settings. Redis is used for caching and for queuing background tasks such as webhook events. A separate
|
||||
# configuration exists for each. Full connection details are required in both sections, and it is strongly recommended
|
||||
# to use two separate database IDs.
|
||||
REDIS = {
|
||||
'tasks': {
|
||||
'HOST': '$REDIS_HOST',
|
||||
'PORT': $REDIS_PORT,
|
||||
# Comment out \`HOST\` and \`PORT\` lines and uncomment the following if using Redis Sentinel
|
||||
# 'SENTINELS': [('mysentinel.redis.example.com', 6379)],
|
||||
# 'SENTINEL_SERVICE': 'netbox',
|
||||
'PASSWORD': '$REDIS_PASSWORD',
|
||||
'DATABASE': $((REDIS_DBID_OFFSET + 0)),
|
||||
'SSL': $REDIS_SSL,
|
||||
},
|
||||
'caching': {
|
||||
'HOST': '$REDIS_HOST',
|
||||
'PORT': $REDIS_PORT,
|
||||
# Comment out \`HOST\` and \`PORT\` lines and uncomment the following if using Redis Sentinel
|
||||
# 'SENTINELS': [('mysentinel.redis.example.com', 6379)],
|
||||
# 'SENTINEL_SERVICE': 'netbox',
|
||||
'PASSWORD': '$REDIS_PASSWORD',
|
||||
'DATABASE': $((REDIS_DBID_OFFSET + 1)),
|
||||
'SSL': $REDIS_SSL,
|
||||
}
|
||||
}
|
||||
RQ_DEFAULT_TIMEOUT = 300
|
||||
|
||||
# This key is used for secure generation of random numbers and strings. It must never be exposed outside of this file.
|
||||
# For optimal security, SECRET_KEY should be at least 50 characters in length and contain a mix of letters, numbers, and
|
||||
# symbols. NetBox will not run without this defined. For more information, see
|
||||
# https://docs.djangoproject.com/en/stable/ref/settings/#std:setting-SECRET_KEY
|
||||
SECRET_KEY = '$SECRET_KEY'
|
||||
|
||||
|
||||
#########################
|
||||
# #
|
||||
# Optional settings #
|
||||
# #
|
||||
#########################
|
||||
|
||||
# Specify one or more name and email address tuples representing NetBox administrators. These people will be notified of
|
||||
# application errors (assuming correct email settings are provided).
|
||||
ADMINS = [
|
||||
# ['John Doe', 'jdoe@example.com'],
|
||||
]
|
||||
|
||||
# URL schemes that are allowed within links in NetBox
|
||||
ALLOWED_URL_SCHEMES = (
|
||||
'file', 'ftp', 'ftps', 'http', 'https', 'irc', 'mailto', 'sftp', 'ssh', 'tel', 'telnet', 'tftp', 'vnc', 'xmpp',
|
||||
)
|
||||
|
||||
# Optionally display a persistent banner at the top and/or bottom of every page. HTML is allowed. To display the same
|
||||
# content in both banners, define BANNER_TOP and set BANNER_BOTTOM = BANNER_TOP.
|
||||
BANNER_TOP = ''
|
||||
BANNER_BOTTOM = ''
|
||||
|
||||
# Text to include on the login page above the login form. HTML is allowed.
|
||||
BANNER_LOGIN = ''
|
||||
|
||||
# Base URL path if accessing NetBox within a directory. For example, if installed at http://example.com/netbox/, set:
|
||||
# BASE_PATH = 'netbox/'
|
||||
BASE_PATH = '$BASEPATH'
|
||||
|
||||
# Cache timeout in seconds. Set to 0 to dissable caching. Defaults to 900 (15 minutes)
|
||||
CACHE_TIMEOUT = 900
|
||||
|
||||
# Maximum number of days to retain logged changes. Set to 0 to retain changes indefinitely. (Default: 90)
|
||||
CHANGELOG_RETENTION = 90
|
||||
|
||||
# API Cross-Origin Resource Sharing (CORS) settings. If CORS_ORIGIN_ALLOW_ALL is set to True, all origins will be
|
||||
# allowed. Otherwise, define a list of allowed origins using either CORS_ORIGIN_WHITELIST or
|
||||
# CORS_ORIGIN_REGEX_WHITELIST. For more information, see https://github.com/ottoyiu/django-cors-headers
|
||||
CORS_ORIGIN_ALLOW_ALL = False
|
||||
CORS_ORIGIN_WHITELIST = [
|
||||
# 'https://hostname.example.com',
|
||||
]
|
||||
CORS_ORIGIN_REGEX_WHITELIST = [
|
||||
# r'^(https?://)?(\w+\.)?example\.com$',
|
||||
]
|
||||
|
||||
# Set to True to enable server debugging. WARNING: Debugging introduces a substantial performance penalty and may reveal
|
||||
# sensitive information about your installation. Only enable debugging while performing testing. Never enable debugging
|
||||
# on a production system.
|
||||
DEBUG = False
|
||||
|
||||
# Email settings
|
||||
EMAIL = {
|
||||
'SERVER': '$SMTP_HOST',
|
||||
'PORT': $SMTP_PORT,
|
||||
'USERNAME': '$SMTP_USER',
|
||||
'PASSWORD': '$SMTP_PASSWORD',
|
||||
'USE_SSL': $SMTP_USE_SSL,
|
||||
'USE_TLS': $SMTP_USE_TLS,
|
||||
'TIMEOUT': 10, # seconds
|
||||
'FROM_EMAIL': '$SMTP_FROM_EMAIL',
|
||||
}
|
||||
|
||||
# Enforcement of unique IP space can be toggled on a per-VRF basis. To enforce unique IP space within the global table
|
||||
# (all prefixes and IP addresses not assigned to a VRF), set ENFORCE_GLOBAL_UNIQUE to True.
|
||||
ENFORCE_GLOBAL_UNIQUE = False
|
||||
|
||||
# Exempt certain models from the enforcement of view permissions. Models listed here will be viewable by all users and
|
||||
# by anonymous users. List models in the form \`<app>.<model>\`. Add '*' to this list to exempt all models.
|
||||
EXEMPT_VIEW_PERMISSIONS = [
|
||||
# 'dcim.site',
|
||||
# 'dcim.region',
|
||||
# 'ipam.prefix',
|
||||
]
|
||||
|
||||
EOF
|
||||
|
||||
if [ "$HTTP_PROXY" != "" ] || [ "$HTTPS_PROXY" != "" ]; then
|
||||
cat << EOF
|
||||
# HTTP proxies NetBox should use when sending outbound HTTP requests (e.g. for webhooks).
|
||||
HTTP_PROXIES = {
|
||||
EOF
|
||||
if [ "$HTTP_PROXY" != "" ]; then
|
||||
cat << EOF
|
||||
'http': '$HTTP_PROXY',
|
||||
EOF
|
||||
fi
|
||||
if [ "$HTTPS_PROXY" != "" ]; then
|
||||
cat << EOF
|
||||
'https': '$HTTPS_PROXY',
|
||||
EOF
|
||||
fi
|
||||
cat << EOF
|
||||
}
|
||||
EOF
|
||||
fi
|
||||
|
||||
cat << EOF
|
||||
# IP addresses recognized as internal to the system. The debugging toolbar will be available only to clients accessing
|
||||
# NetBox from an internal IP.
|
||||
INTERNAL_IPS = ('127.0.0.1', '::1')
|
||||
|
||||
# Enable custom logging. Please see the Django documentation for detailed guidance on configuring custom logs:
|
||||
# https://docs.djangoproject.com/en/stable/topics/logging/
|
||||
LOGGING = {}
|
||||
|
||||
# Setting this to True will permit only authenticated users to access any part of NetBox. By default, anonymous users
|
||||
# are permitted to access most data in NetBox (excluding secrets) but not make any changes.
|
||||
LOGIN_REQUIRED = $LOGIN_REQUIRED
|
||||
|
||||
# The length of time (in seconds) for which a user will remain logged into the web UI before being prompted to
|
||||
# re-authenticate. (Default: 1209600 [14 days])
|
||||
LOGIN_TIMEOUT = None
|
||||
|
||||
# Setting this to True will display a "maintenance mode" banner at the top of every page.
|
||||
MAINTENANCE_MODE = False
|
||||
|
||||
# An API consumer can request an arbitrary number of objects =by appending the "limit" parameter to the URL (e.g.
|
||||
# "?limit=1000"). This setting defines the maximum limit. Setting it to 0 or None will allow an API consumer to request
|
||||
# all objects by specifying "?limit=0".
|
||||
MAX_PAGE_SIZE = 1000
|
||||
|
||||
EOF
|
||||
|
||||
if [ "$MEDIA_ROOT" != "" ]; then
|
||||
cat << EOF
|
||||
# The file path where uploaded media such as image attachments are stored. A trailing slash is not needed. Note that
|
||||
# the default value of this setting is derived from the installed location.
|
||||
MEDIA_ROOT = '$MEDIA_ROOT'
|
||||
|
||||
EOF
|
||||
fi
|
||||
|
||||
cat << EOF
|
||||
# By default uploaded media is stored on the local filesystem. Using Django-storages is also supported. Provide the
|
||||
# class path of the storage driver in STORAGE_BACKEND and any configuration options in STORAGE_CONFIG. For example:
|
||||
# STORAGE_BACKEND = 'storages.backends.s3boto3.S3Boto3Storage'
|
||||
# STORAGE_CONFIG = {
|
||||
# 'AWS_ACCESS_KEY_ID': 'Key ID',
|
||||
# 'AWS_SECRET_ACCESS_KEY': 'Secret',
|
||||
# 'AWS_STORAGE_BUCKET_NAME': 'netbox',
|
||||
# 'AWS_S3_REGION_NAME': 'eu-west-1',
|
||||
# }
|
||||
|
||||
# Expose Prometheus monitoring metrics at the HTTP endpoint '/metrics'
|
||||
METRICS_ENABLED = False
|
||||
|
||||
# Credentials that NetBox will uses to authenticate to devices when connecting via NAPALM.
|
||||
NAPALM_USERNAME = ''
|
||||
NAPALM_PASSWORD = ''
|
||||
|
||||
# NAPALM timeout (in seconds). (Default: 30)
|
||||
NAPALM_TIMEOUT = 30
|
||||
|
||||
# NAPALM optional arguments (see http://napalm.readthedocs.io/en/latest/support/#optional-arguments). Arguments must
|
||||
# be provided as a dictionary.
|
||||
NAPALM_ARGS = {}
|
||||
|
||||
# Determine how many objects to display per page within a list. (Default: 50)
|
||||
PAGINATE_COUNT = 50
|
||||
|
||||
# Enable installed plugins. Add the name of each plugin to the list.
|
||||
PLUGINS = []
|
||||
|
||||
# Plugins configuration settings. These settings are used by various plugins that the user may have installed.
|
||||
# Each key in the dictionary is the name of an installed plugin and its value is a dictionary of settings.
|
||||
# PLUGINS_CONFIG = {
|
||||
# 'my_plugin': {
|
||||
# 'foo': 'bar',
|
||||
# 'buzz': 'bazz'
|
||||
# }
|
||||
# }
|
||||
|
||||
# When determining the primary IP address for a device, IPv6 is preferred over IPv4 by default. Set this to True to
|
||||
# prefer IPv4 instead.
|
||||
PREFER_IPV4 = False
|
||||
|
||||
# Rack elevation size defaults, in pixels. For best results, the ratio of width to height should be roughly 10:1.
|
||||
RACK_ELEVATION_DEFAULT_UNIT_HEIGHT = 22
|
||||
RACK_ELEVATION_DEFAULT_UNIT_WIDTH = 220
|
||||
|
||||
EOF
|
||||
|
||||
if [ "$USE_LDAP" ]; then
|
||||
cat << EOF
|
||||
# Remote authentication support with ldap
|
||||
REMOTE_AUTH_ENABLED = True
|
||||
REMOTE_AUTH_BACKEND = 'netbox.authentication.LDAPBackend'
|
||||
EOF
|
||||
else
|
||||
cat << EOF
|
||||
# Remote authentication support
|
||||
REMOTE_AUTH_ENABLED = False
|
||||
REMOTE_AUTH_BACKEND = 'netbox.authentication.RemoteUserBackend'
|
||||
EOF
|
||||
fi
|
||||
|
||||
cat << EOF
|
||||
REMOTE_AUTH_HEADER = 'HTTP_REMOTE_USER'
|
||||
REMOTE_AUTH_AUTO_CREATE_USER = True
|
||||
REMOTE_AUTH_DEFAULT_GROUPS = []
|
||||
REMOTE_AUTH_DEFAULT_PERMISSIONS = {}
|
||||
|
||||
# This determines how often the GitHub API is called to check the latest release of NetBox. Must be at least 1 hour.
|
||||
RELEASE_CHECK_TIMEOUT = 24 * 3600
|
||||
|
||||
# This repository is used to check whether there is a new release of NetBox available. Set to None to disable the
|
||||
# version check or use the URL below to check for release in the official NetBox repository.
|
||||
|
||||
EOF
|
||||
|
||||
if [ "$UPDATE_CHECK" != "" ]; then
|
||||
cat << EOF
|
||||
RELEASE_CHECK_URL = 'https://api.github.com/repos/netbox-community/netbox/releases'
|
||||
|
||||
EOF
|
||||
else
|
||||
cat << EOF
|
||||
RELEASE_CHECK_URL = None
|
||||
|
||||
EOF
|
||||
fi
|
||||
|
||||
if [ "$REPORTS_ROOT" != "" ]; then
|
||||
cat << EOF
|
||||
# The file path where custom reports will be stored. A trailing slash is not needed. Note that the default value of
|
||||
# this setting is derived from the installed location.
|
||||
REPORTS_ROOT = '$REPORTS_ROOT'
|
||||
|
||||
EOF
|
||||
fi
|
||||
|
||||
if [ "$SCRIPTS_ROOT" != "" ]; then
|
||||
cat << EOF
|
||||
# The file path where custom scripts will be stored. A trailing slash is not needed. Note that the default value of
|
||||
# this setting is derived from the installed location.
|
||||
SCRIPTS_ROOT = '$SCRIPTS_ROOT'
|
||||
|
||||
EOF
|
||||
fi
|
||||
|
||||
cat << EOF
|
||||
# By default, NetBox will store session data in the database. Alternatively, a file path can be specified here to use
|
||||
# local file storage instead. (This can be useful for enabling authentication on a standby instance with read-only
|
||||
# database access.) Note that the user as which NetBox runs must have read and write permissions to this path.
|
||||
SESSION_FILE_PATH = None
|
||||
|
||||
# Time zone (default: UTC)
|
||||
TIME_ZONE = 'UTC'
|
||||
|
||||
# Date/time formatting. See the following link for supported formats:
|
||||
# https://docs.djangoproject.com/en/stable/ref/templates/builtins/#date
|
||||
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'
|
||||
EOF
|
82
type/__netbox/files/ldap_config.py.sh
Executable file
82
type/__netbox/files/ldap_config.py.sh
Executable file
|
@ -0,0 +1,82 @@
|
|||
#!/bin/sh
|
||||
|
||||
# no configuration if there are no ldap parameters
|
||||
if [ -z "$USE_LDAP" ]; then
|
||||
# skip
|
||||
cat << EOF
|
||||
##############################
|
||||
# LDAP-backed authentication #
|
||||
##############################
|
||||
|
||||
# no options set
|
||||
EOF
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
||||
cat << EOF
|
||||
##############################
|
||||
# LDAP-backed authentication #
|
||||
##############################
|
||||
|
||||
import ldap
|
||||
from django_auth_ldap.config import LDAPSearch, PosixGroupType
|
||||
|
||||
# Server URI
|
||||
AUTH_LDAP_SERVER_URI = "$LDAP_SERVER"
|
||||
|
||||
# Set the DN and password for the NetBox service account.
|
||||
AUTH_LDAP_BIND_DN = "$LDAP_BIND_DN"
|
||||
AUTH_LDAP_BIND_PASSWORD = "$LDAP_BIND_PASSWORD"
|
||||
|
||||
# Search for user entry.
|
||||
AUTH_LDAP_USER_SEARCH = LDAPSearch("$LDAP_USER_BASE",
|
||||
ldap.SCOPE_SUBTREE,
|
||||
"(uid=%(user)s)")
|
||||
|
||||
# You can map user attributes to Django attributes as so.
|
||||
AUTH_LDAP_USER_ATTR_MAP = {
|
||||
"first_name": "givenName",
|
||||
"last_name": "sn",
|
||||
"email": "mail"
|
||||
}
|
||||
EOF
|
||||
|
||||
if [ "$LDAP_GROUP_BASE" != "" ]; then
|
||||
cat << EOF
|
||||
|
||||
# This search ought to return all groups to which the user belongs. django_auth_ldap uses this to determine group
|
||||
# hierarchy.
|
||||
AUTH_LDAP_GROUP_SEARCH = LDAPSearch("$LDAP_GROUP_BASE", ldap.SCOPE_SUBTREE,
|
||||
"(objectClass=posixGroup)")
|
||||
AUTH_LDAP_GROUP_TYPE = PosixGroupType()
|
||||
|
||||
# Mirror LDAP group assignments.
|
||||
AUTH_LDAP_MIRROR_GROUPS = True
|
||||
# For more granular permissions, map LDAP groups to Django groups.
|
||||
AUTH_LDAP_FIND_GROUP_PERMS = True
|
||||
EOF
|
||||
|
||||
if [ "$LDAP_REQUIRE_GROUP" != "" ]; then
|
||||
cat << EOF
|
||||
|
||||
# Define a group required to login.
|
||||
AUTH_LDAP_REQUIRE_GROUP = "$LDAP_REQUIRE_GROUP"
|
||||
EOF
|
||||
fi
|
||||
|
||||
cat << EOF
|
||||
|
||||
# Define special user types using groups. Exercise great caution when assigning superuser status.
|
||||
AUTH_LDAP_USER_FLAGS_BY_GROUP = {
|
||||
EOF
|
||||
# superuser
|
||||
if [ "$LDAP_SUPERUSER_GROUP" != "" ]; then
|
||||
echo " \"is_superuser\": \"$LDAP_SUPERUSER_GROUP\","
|
||||
fi
|
||||
# staff user
|
||||
if [ "$LDAP_STAFF_GROUP" != "" ]; then
|
||||
echo " \"is_staff\": \"$LDAP_STAFF_GROUP\","
|
||||
fi
|
||||
echo "}"
|
||||
fi
|
24
type/__netbox/files/netbox-rq.service
Normal file
24
type/__netbox/files/netbox-rq.service
Normal file
|
@ -0,0 +1,24 @@
|
|||
[Unit]
|
||||
Description=NetBox Request Queue Worker
|
||||
Documentation=https://netbox.readthedocs.io/en/stable/
|
||||
PartOf=netbox.service
|
||||
Wants=network.target
|
||||
After=netbox.service
|
||||
After=network.target
|
||||
After=redis-server.service postgresql.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
|
||||
User=netbox
|
||||
Group=netbox
|
||||
WorkingDirectory=/opt/netbox
|
||||
|
||||
ExecStart=/opt/netbox/venv/bin/python3 /opt/netbox/netbox/manage.py rqworker
|
||||
|
||||
Restart=on-failure
|
||||
RestartSec=30
|
||||
PrivateTmp=true
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
13
type/__netbox/files/netbox.service
Normal file
13
type/__netbox/files/netbox.service
Normal file
|
@ -0,0 +1,13 @@
|
|||
[Unit]
|
||||
Description=NetBox Service Wrapper
|
||||
Documentation=https://netbox.readthedocs.io/en/stable/
|
||||
Wants=network.target
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/bin/true
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
33
type/__netbox/files/netbox.socket.sh
Executable file
33
type/__netbox/files/netbox.socket.sh
Executable file
|
@ -0,0 +1,33 @@
|
|||
#!/bin/sh -e
|
||||
# __netbox/files/netbox.socket.sh
|
||||
|
||||
# This is shared between all WSGI-server types.
|
||||
|
||||
# Arguments:
|
||||
# 1: File which list all sockets to listen on (sepearated by \n)
|
||||
|
||||
if [ $# -ne 1 ]; then
|
||||
printf "netbox.socket.sh: argument \$1 missing or too much given!\n" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
cat << UNIT
|
||||
[Unit]
|
||||
Description=Socket for NetBox via $TYPE
|
||||
|
||||
[Socket]
|
||||
UNIT
|
||||
|
||||
# read all sockets to listen to
|
||||
while read -r line; do
|
||||
printf "ListenStream=%s\n" "$line"
|
||||
done < "$1"
|
||||
|
||||
cat << UNIT
|
||||
SocketUser=netbox
|
||||
SocketGroup=www-data
|
||||
|
||||
[Install]
|
||||
WantedBy=sockets.target
|
||||
UNIT
|
120
type/__netbox/gencode-remote
Executable file
120
type/__netbox/gencode-remote
Executable file
|
@ -0,0 +1,120 @@
|
|||
#!/bin/sh -e
|
||||
|
||||
old_version="$(cat "$__object/explorer/version")"
|
||||
VERSION=$(cat "$__object/parameter/version")
|
||||
|
||||
src="netbox-$VERSION"
|
||||
archive="v$VERSION.tar.gz"
|
||||
url="https://github.com/netbox-community/netbox/archive/$archive"
|
||||
install_dir=/opt/netbox/netbox
|
||||
|
||||
if [ "$VERSION" != "$old_version" ]; then
|
||||
cat << EOF
|
||||
# Ensure that coreutils is installed.
|
||||
if [ ! -x \$(which mktemp) ]; then
|
||||
echo "mktemp is not available on the remote host." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Create temporary working directory.
|
||||
tmpdir=\$(mktemp -d)
|
||||
cd "\$tmpdir"
|
||||
|
||||
# Download and extract sources.
|
||||
curl -sS -L '$url' > '$archive'
|
||||
tar xf '$archive'
|
||||
|
||||
|
||||
# virtualenv is given already by __pyvenv, just using it
|
||||
|
||||
# backup requirement files
|
||||
if [ -f /opt/netbox/requirements.txt ]; then
|
||||
mv /opt/netbox/requirements.txt /opt/netbox/old-requirements.txt
|
||||
else
|
||||
# preseve file-not-found errors and warnings
|
||||
touch /opt/netbox/old-requirements.txt
|
||||
fi
|
||||
cp '$src/requirements.txt' /opt/netbox/
|
||||
|
||||
# Uninstall packages not required anymore
|
||||
# if versions not be shortend, they will be ignored by pip, but not by comm
|
||||
# all of this could be done with grep, too, but it's still must be shortend with awk
|
||||
awk -F== '{print \$1}' '/opt/netbox/requirements.txt' | sort > "\$tmpdir/curr-reqs.txt"
|
||||
awk -F== '{print \$1}' '/opt/netbox/old-requirements.txt' | sort > "\$tmpdir/old-reqs.txt"
|
||||
comm -23 "\$tmpdir/old-reqs.txt" "\$tmpdir/curr-reqs.txt" > "\$tmpdir/pip-uninstall.txt"
|
||||
|
||||
# only uninstall if something is available (to avoid errors cause of this)
|
||||
if [ -s "\$tmpdir/pip-uninstall.txt" ]; then
|
||||
/opt/netbox/venv/bin/pip3 uninstall -qy -r "\$tmpdir/pip-uninstall.txt"
|
||||
fi
|
||||
|
||||
# Install python dependencies.
|
||||
# avoid gunicorn, because it will be done in an other type
|
||||
grep -v "^gunicorn==" "\$tmpdir/$src/requirements.txt" \
|
||||
| xargs /opt/netbox/venv/bin/pip3 install -q
|
||||
EOF
|
||||
|
||||
if [ -f "$__object/parameter/ldap-server" ]; then
|
||||
echo "/opt/netbox/venv/bin/pip3 install -q django-auth-ldap"
|
||||
else
|
||||
echo "/opt/netbox/venv/bin/pip3 uninstall -qy django-auth-ldap"
|
||||
fi
|
||||
|
||||
cat << EOF
|
||||
|
||||
# Deploy sources and restore configuration.
|
||||
rm -rf '$install_dir'
|
||||
cp -r '$src/netbox' '$install_dir'
|
||||
# force links to the cdist directory
|
||||
ln -fs /opt/netbox/cdist/configuration.py '$install_dir/netbox/configuration.py'
|
||||
ln -fs /opt/netbox/cdist/ldap_config.py '$install_dir/netbox/ldap_config.py'
|
||||
|
||||
# Set final permissions.
|
||||
chown -R netbox /opt/netbox
|
||||
|
||||
|
||||
# NetBox manage scripts
|
||||
# Run database migrations.
|
||||
sudo -u netbox /opt/netbox/venv/bin/python3 /opt/netbox/netbox/manage.py migrate
|
||||
# Generate static assets.
|
||||
sudo -u netbox /opt/netbox/venv/bin/python3 /opt/netbox/netbox/manage.py collectstatic --no-input
|
||||
# Delete any stale content types
|
||||
sudo -u netbox /opt/netbox/venv/bin/python3 /opt/netbox/netbox/manage.py remove_stale_contenttypes --no-input
|
||||
# Delete any expired user sessions
|
||||
sudo -u netbox /opt/netbox/venv/bin/python3 /opt/netbox/netbox/manage.py clearsessions
|
||||
# Clear all cached data
|
||||
sudo -u netbox /opt/netbox/venv/bin/python3 /opt/netbox/netbox/manage.py invalidate all
|
||||
|
||||
# Remove temporary working directory.
|
||||
cd /
|
||||
rm -rf "\$tmpdir"
|
||||
|
||||
# Save version after successful installation
|
||||
printf "%s\\n" "$VERSION" > /opt/netbox/cdist/version
|
||||
|
||||
EOF
|
||||
|
||||
# meta
|
||||
printf "installed %s\n" "$VERSION" >> "$__messages_out"
|
||||
changes=yes
|
||||
fi
|
||||
|
||||
# check if configuration changed
|
||||
if grep -q "^__file/opt/netbox/" "$__messages_in"; then
|
||||
# meta
|
||||
printf "configured\n" >> "$__messages_out"
|
||||
changes=yes
|
||||
fi
|
||||
|
||||
|
||||
# Check for changes
|
||||
if [ "$changes" = "yes" ]; then
|
||||
# After the upstream upgrade.sh script, it's ok to migrate while the
|
||||
# application is running ;)
|
||||
|
||||
# restarting after changes
|
||||
cat << EOF
|
||||
# Restart service. All required services are included with netbox.service.
|
||||
systemctl restart netbox
|
||||
EOF
|
||||
fi
|
275
type/__netbox/man.rst
Normal file
275
type/__netbox/man.rst
Normal file
|
@ -0,0 +1,275 @@
|
|||
cdist-type__netbox(7)
|
||||
=====================
|
||||
|
||||
NAME
|
||||
----
|
||||
cdist-type__netbox - Install and configure NetBox
|
||||
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
This (singleton) type installs and configures a NetBox instance, a web
|
||||
application to help manage and document computer networks.
|
||||
|
||||
It installs it with the user ``netbox`` at ``/opt/netbox`` with `python-venv`.
|
||||
It setup systemd unit files for the services `netbox` and `netbox-rq`. The
|
||||
`netbox` service only wrap all netbox related services, e.g. restarting and
|
||||
so one will be delegated to all related services.
|
||||
|
||||
The application is still not accessable because a WSGI server is required. To
|
||||
access the application through WSGI, uWSGI or Gunicorn can be used. The setup
|
||||
can be done via there own types `__netbox_gunicorn` and `__netbox_uwsgi`.
|
||||
|
||||
The Gunicorn setup is recommended from the NetBox documentation. Consult each
|
||||
manual page to decide. The types must be called after the `__netbox` type.
|
||||
|
||||
|
||||
REQUIRED PARAMETERS
|
||||
-------------------
|
||||
version
|
||||
NetBox version to be installed. You can find the correct and newest version
|
||||
on GitHub at the NetBox project page under
|
||||
"`Releases <https://github.com/netbox-community/netbox/releases>`_".
|
||||
|
||||
database
|
||||
PostgreSQL database name.
|
||||
|
||||
database-user
|
||||
PostgreSQL database user.
|
||||
|
||||
database-password
|
||||
PostgreSQL database password.
|
||||
|
||||
host
|
||||
Hostname (domain or IP address) on which the application is served.
|
||||
Multiple hostnames are possible; given as multiple arguments.
|
||||
|
||||
|
||||
OPTIONAL PARAMETERS
|
||||
-------------------
|
||||
secret-key
|
||||
Random secret key of at least 50 alphanumeric characters and symbols. This
|
||||
key must be unique to this installation and must not be shared outside the
|
||||
local system. If no secret key is given, the type generates an own 50 chars
|
||||
long key and saves it on the remote host to remember it for the next run.
|
||||
|
||||
The secret, random string is used to assist in the creation new
|
||||
cryptographic hashes for passwords and HTTP cookies. It is not directly
|
||||
used for hasing user passwords or for encrpted storage. It can be changed
|
||||
at any time, but will invalidate all existing sessions.
|
||||
|
||||
database-host
|
||||
PostgreSQL database hostname. Defaults to ``localhost``.
|
||||
|
||||
database-port
|
||||
PostgreSQL database port. Defaults to empty (uses the default port).
|
||||
|
||||
ldap-server
|
||||
LDAP server URI. Enables LDAP-backed authentication if specified.
|
||||
|
||||
ldap-bind-dn
|
||||
DN for the NetBox service account. Required for LDAP authentication.
|
||||
|
||||
ldap-bind-password
|
||||
Password for the NetBox service account. Required for LDAP authentication.
|
||||
|
||||
ldap-user-base
|
||||
Base used for searching user entries. Required for LDAP authentication.
|
||||
|
||||
ldap-group-base
|
||||
Base used for searching group entries.
|
||||
|
||||
ldap-require-group
|
||||
Group required to login.
|
||||
|
||||
ldap-staff-group
|
||||
Make members of this group to "staff". This gives the users "Admin Access",
|
||||
which means access to the "NetBox Administration" site.
|
||||
|
||||
ldap-superuser-group
|
||||
Make members of this groups superusers.
|
||||
|
||||
redis-host
|
||||
Redis database hostname. Defaults to ``localhost``.
|
||||
|
||||
redis-port
|
||||
Redis database port. Defaults to ``6379``.
|
||||
|
||||
redis-password
|
||||
Redis password. Defaults to empty password.
|
||||
|
||||
redis-dbid-offset
|
||||
Offset to set the redis database id's. The `tasks` database id is
|
||||
`offset + 0` and `caching` is `offset + 1`. The offset defaults to ``0``.
|
||||
|
||||
smtp-host
|
||||
Host of the SMTP email server. Defaults to ``localhost``.
|
||||
|
||||
smtp-port
|
||||
Port of the SMTP email server. Defaults to ``25``.
|
||||
|
||||
smtp-user
|
||||
Username to access the SMTP email server. Defaults to empty.
|
||||
|
||||
smtp-password
|
||||
Password to access the SMTP email server. Defaults to empty.
|
||||
|
||||
smtp-from-email
|
||||
Email from which NetBox will be sent of. Defaults to empty.
|
||||
|
||||
basepath
|
||||
Base URL path if accessing netbox within a directory instead of directly the
|
||||
webroot ``/``. For example, if installed at https://example.com/netbox/, set
|
||||
the value ``netbox/``.
|
||||
|
||||
http-proxy
|
||||
https-proxy
|
||||
Proxy which will be used with any HTTP request like webhooks.
|
||||
|
||||
data-root
|
||||
This parameter set's the media, reports and scripts root to subdirectories
|
||||
of the given directory. Values can be overwritten by special parameters like
|
||||
`--media-root` for example. Use this option if you want to store persistant
|
||||
data of netbox on an other partition. A trailing slash is not needed.
|
||||
|
||||
The data directories have following predefined sub-directory names:
|
||||
|
||||
media root:
|
||||
``$data_root/media``
|
||||
reports root:
|
||||
``$data_root/reports``
|
||||
scripts root:
|
||||
``$data_root/scripts``
|
||||
|
||||
To preserve all data from installation upgrades - which just replace the
|
||||
installation directory - the data will be kept in the netbox home directory
|
||||
rather than the installation directory by default (``/opt/netbox/data/``).
|
||||
This way, no data will be deleted after the installation directory
|
||||
replacement because it remains outside of the installation directory.
|
||||
|
||||
media-root
|
||||
The file path to where media files (like image attachments) are stored.
|
||||
Change this path if you require to store data on an other partiotion.
|
||||
A trailing slash is not needed. Defaults to ``$data_root/media``.
|
||||
|
||||
reports-root
|
||||
The file path of where custom reports are kept. Change this path if you
|
||||
require to store data on an other partition. A trailing slash is not
|
||||
needed. Defaults to ``$data_root/reports``.
|
||||
|
||||
scripts-root
|
||||
The file path of where custom scripts are kept. Change this path if you
|
||||
require to store data on an other partition. A trailing slash is not
|
||||
needed. Defaults to ``$data_root/scripts``.
|
||||
|
||||
|
||||
BOOLEAN PARAMETERS
|
||||
------------------
|
||||
redis-ssl
|
||||
Enables a secure TLS/SSL connection to the redis database. By default, ssl
|
||||
is disabled.
|
||||
|
||||
smtp-use-tls
|
||||
Uses TLS to connect to the SMTP email server. `See documentation
|
||||
<https://docs.djangoproject.com/en/3.1/ref/settings/#email-use-tls>`_
|
||||
for more information.
|
||||
|
||||
smtp-use-ssl
|
||||
Uses implicit TLS with the SMTP email server. `See documentation
|
||||
<https://docs.djangoproject.com/en/3.1/ref/settings/#email-use-ssl>`_
|
||||
for more information.
|
||||
|
||||
login-required
|
||||
Sets if a login is required to access all sites. By default, anonymous
|
||||
users can see most data (excluding secrets) but not make any changes.
|
||||
|
||||
update-notify
|
||||
Enables the NetBox version check for new upstream updates. It checks every
|
||||
24 hours for new releases and notify the admin users in the gui if any.
|
||||
|
||||
|
||||
MESSAGES
|
||||
--------
|
||||
installed $VERSION
|
||||
Netbox was fresh installed or updated. The new version number is appended.
|
||||
|
||||
configured
|
||||
Some configuration files got updated and therefore the service was
|
||||
restarted. This message will not be echoed if configuration got updated due
|
||||
a standard installation.
|
||||
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
__netbox --version 2.8.7 --database netbox \
|
||||
--database-password "secretsecretsecret" \
|
||||
--secret-key "secretsecretsecret" \
|
||||
--host "${__target_host:?}" \
|
||||
--host "cool-netbox.xyz" \
|
||||
--ldap-server "ldaps://ldap.domain.tld" \
|
||||
--ldap-bind-dn "uid=netbox,ou=services,dc=domain,dc=tld" \
|
||||
--ldap-bind-password "secretsecretsecret" \
|
||||
--ldap-user-base "ou=users,dc=domain,dc=tld" \
|
||||
--ldap-group-base "ou=groups,dc=domain,dc=tld" \
|
||||
--ldap-require-group "cn=netbox-login,ou=groups,dc=domain,dc=tld" \
|
||||
--ldap-superuser-group "cn=netbox-admin,ou=groups,dc=domain,dc=tld"
|
||||
# using recommended gunicorn setup
|
||||
require="__netbox" __netbox_gunicorn
|
||||
|
||||
|
||||
NOTES
|
||||
-----
|
||||
The configuration of NetBox contains more optional settings than that what can
|
||||
be set with this type. If you think an important setting is missing or there
|
||||
is a more good way to inject python code for dynamic configuration variables,
|
||||
you are welcome to contribute!
|
||||
|
||||
- `Possible optional settings
|
||||
<https://netbox.readthedocs.io/en/stable/configuration/optional-settings/>`_
|
||||
|
||||
If you not setup ldap authentification, you may be interested into how to
|
||||
`setting up a super user
|
||||
<https://netbox.readthedocs.io/en/stable/installation/3-netbox/#create-a-super-user>`_
|
||||
directly on the machine to be able to access and use NetBox.
|
||||
|
||||
You may also be interested of writing a own type which handles the creation of
|
||||
the super user. To do this non-interactivly, see the ansible role as `reference
|
||||
<https://github.com/lae/ansible-role-netbox/blob/18f46a3345f100936c5116abe716c480e1886676/vars/main.yml#L15>`_.
|
||||
|
||||
If you change the secret key while the netbox instance is running, there is a
|
||||
time frame where the access to the application corrupts the whole database.
|
||||
Then, you need to restore a backup or wipe the database.
|
||||
|
||||
Currently, the cause is not clear, but it should work if you do not touch
|
||||
netbox while the configuration is done (do not shut it down, too). It only
|
||||
applies for changes of the secret key, which not happen normally.
|
||||
|
||||
Maybe the `--restart` flag for the `__systemd_unit` types is not the best idea,
|
||||
but avoids that the changes will not be applied. It could be solved if the type
|
||||
would send messages from his actions.
|
||||
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
`NetBox documentation <https://netbox.readthedocs.io/en/stable/>`_
|
||||
|
||||
:strong:`cdist-type__netbox_gunicorn`\ (7)
|
||||
:strong:`cdist-type__netbox_uwsgi`\ (7)
|
||||
|
||||
|
||||
AUTHORS
|
||||
-------
|
||||
Timothée Floure <t.floure@e-durable.ch>
|
||||
Matthias Stecher <matthiasstecher@gmx.de>
|
||||
|
||||
|
||||
COPYING
|
||||
-------
|
||||
Copyright \(C) 2020 Timothée Floure.
|
||||
Copyright \(C) 2020 Matthias Stecher.
|
||||
You can redistribute it and/or modify it under the terms of the GNU
|
||||
General Public License as published by the Free Software Foundation,
|
||||
either version 3 of the License, or (at your option) any later version.
|
226
type/__netbox/manifest
Executable file
226
type/__netbox/manifest
Executable file
|
@ -0,0 +1,226 @@
|
|||
#!/bin/sh -e
|
||||
|
||||
os=$(cat "$__global/explorer/os")
|
||||
|
||||
case "$os" in
|
||||
debian|ubuntu)
|
||||
# Install netbox dependencies.
|
||||
for pkg in python3-pip python3-venv python3-dev build-essential libxml2-dev \
|
||||
libxslt1-dev libffi-dev libpq-dev libssl-dev zlib1g-dev curl sudo; do
|
||||
__package $pkg
|
||||
done
|
||||
|
||||
if [ -f "$__object/parameter/ldap-server" ]; then
|
||||
for pkg in libldap2-dev libsasl2-dev libssl-dev; do
|
||||
__package $pkg
|
||||
done
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
printf "Your operating system (%s) is currently not supported by this type (%s)\n" "$os" "${__type##*/}" >&2
|
||||
printf "Please contribute an implementation for it if you can.\n" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
DATABASE_NAME=$(cat "$__object/parameter/database")
|
||||
export DATABASE_NAME
|
||||
DATABASE_USER="$(cat "$__object/parameter/database-user")"
|
||||
export DATABASE_USER
|
||||
DATABASE_PASSWORD=$(cat "$__object/parameter/database-password")
|
||||
export DATABASE_PASSWORD
|
||||
DATABASE_HOST="$(cat "$__object/parameter/database-host")"
|
||||
export DATABASE_HOST
|
||||
DATABASE_PORT="$(cat "$__object/parameter/database-port")"
|
||||
export DATABASE_PORT
|
||||
|
||||
# list of hosts
|
||||
ALLOWED_HOSTS=""
|
||||
while read -r hostname; do
|
||||
# shellcheck disable=SC2089
|
||||
ALLOWED_HOSTS="$ALLOWED_HOSTS '$hostname',"
|
||||
done < "$__object/parameter/host"
|
||||
# shellcheck disable=SC2090
|
||||
export ALLOWED_HOSTS
|
||||
|
||||
if [ -f "$__object/parameter/secret-key" ]; then
|
||||
SECRET_KEY=$(cat "$__object/parameter/secret-key")
|
||||
elif [ -s "$__object/explorer/secretkey" ]; then
|
||||
# take the key that is already used
|
||||
SECRET_KEY="$(cat "$__object/explorer/secretkey")"
|
||||
else
|
||||
# Can be done over netbox/generate_secret_key.py too, but it can't be
|
||||
# generated right now where it's required (only if it's preloaded for
|
||||
# this type to execute it now).
|
||||
# Generates a 50-character long key with the same character set like
|
||||
# the helper script. Must escape the '-' to be no character range.
|
||||
SECRET_KEY="$(tr -cd '!@#$%^&*(\-_=+)[:alnum:]' < /dev/urandom | head -c50)"
|
||||
fi
|
||||
export SECRET_KEY
|
||||
|
||||
if [ -f "$__object/parameter/ldap-server" ]; then
|
||||
LDAP_SERVER=$(cat "$__object/parameter/ldap-server")
|
||||
USE_LDAP=yes
|
||||
export LDAP_SERVER
|
||||
fi
|
||||
if [ -f "$__object/parameter/ldap-bind-dn" ]; then
|
||||
LDAP_BIND_DN=$(cat "$__object/parameter/ldap-bind-dn")
|
||||
USE_LDAP=yes
|
||||
export LDAP_BIND_DN
|
||||
fi
|
||||
if [ -f "$__object/parameter/ldap-bind-password" ]; then
|
||||
LDAP_BIND_PASSWORD=$(cat "$__object/parameter/ldap-bind-password")
|
||||
USE_LDAP=yes
|
||||
export LDAP_BIND_PASSWORD
|
||||
fi
|
||||
if [ -f "$__object/parameter/ldap-user-base" ]; then
|
||||
LDAP_USER_BASE=$(cat "$__object/parameter/ldap-user-base")
|
||||
USE_LDAP=yes
|
||||
export LDAP_USER_BASE
|
||||
fi
|
||||
if [ -f "$__object/parameter/ldap-group-base" ]; then
|
||||
LDAP_GROUP_BASE=$(cat "$__object/parameter/ldap-group-base")
|
||||
export LDAP_GROUP_BASE
|
||||
fi
|
||||
if [ -f "$__object/parameter/ldap-require-group" ]; then
|
||||
LDAP_REQUIRE_GROUP=$(cat "$__object/parameter/ldap-require-group")
|
||||
export LDAP_REQUIRE_GROUP
|
||||
fi
|
||||
if [ -f "$__object/parameter/ldap-superuser-group" ]; then
|
||||
LDAP_SUPERUSER_GROUP=$(cat "$__object/parameter/ldap-superuser-group")
|
||||
export LDAP_SUPERUSER_GROUP
|
||||
fi
|
||||
if [ -f "$__object/parameter/ldap-staff-group" ]; then
|
||||
LDAP_STAFF_GROUP="$(cat "$__object/parameter/ldap-staff-group")"
|
||||
export LDAP_STAFF_GROUP
|
||||
fi
|
||||
# export if base ldap parameters are used
|
||||
export USE_LDAP
|
||||
|
||||
# have default values
|
||||
REDIS_HOST="$(cat "$__object/parameter/redis-host")"
|
||||
export REDIS_HOST
|
||||
REDIS_PORT="$(cat "$__object/parameter/redis-port")"
|
||||
export REDIS_PORT
|
||||
REDIS_PASSWORD="$(cat "$__object/parameter/redis-password")"
|
||||
export REDIS_PASSWORD
|
||||
REDIS_DBID_OFFSET="$(cat "$__object/parameter/redis-dbid-offset")"
|
||||
export REDIS_DBID_OFFSET
|
||||
if [ -f "$__object/parameter/redis-ssl" ]; then
|
||||
REDIS_SSL="True"
|
||||
else
|
||||
REDIS_SSL="False"
|
||||
fi
|
||||
export REDIS_SSL
|
||||
|
||||
SMTP_HOST="$(cat "$__object/parameter/smtp-host")"
|
||||
export SMTP_HOST
|
||||
SMTP_PORT="$(cat "$__object/parameter/smtp-port")"
|
||||
export SMTP_PORT
|
||||
SMTP_USER="$(cat "$__object/parameter/smtp-user")"
|
||||
export SMTP_USER
|
||||
SMTP_PASSWORD="$(cat "$__object/parameter/smtp-password")"
|
||||
export SMTP_PASSWORD
|
||||
SMTP_FROM_EMAIL="$(cat "$__object/parameter/smtp-from-email")"
|
||||
export SMTP_FROM_EMAIL
|
||||
|
||||
if [ -f "$__object/parameter/smtp-use-ssl" ]; then
|
||||
SMTP_USE_SSL="True"
|
||||
else
|
||||
SMTP_USE_SSL="False"
|
||||
fi
|
||||
export SMTP_USE_SSL
|
||||
if [ -f "$__object/parameter/smtp-use-tls" ]; then
|
||||
if [ "$SMTP_USE_SSL" = "True" ]; then
|
||||
echo "options --smtp-use-ssl and --smtp-use-tls are not compatible" >&2
|
||||
exit 2
|
||||
fi
|
||||
SMTP_USE_TLS="True"
|
||||
else
|
||||
SMTP_USE_TLS="False"
|
||||
fi
|
||||
export SMTP_USE_TLS
|
||||
|
||||
BASEPATH="$(cat "$__object/parameter/basepath")"
|
||||
export BASEPATH
|
||||
|
||||
if [ -f "$__object/parameter/http-proxy" ]; then
|
||||
HTTP_PROXY=$(cat "$__object/parameter/http-proxy")
|
||||
export HTTP_PROXY
|
||||
fi
|
||||
if [ -f "$__object/parameter/https-proxy" ]; then
|
||||
HTTPS_PROXY=$(cat "$__object/parameter/https-proxy")
|
||||
export HTTPS_PROXY
|
||||
fi
|
||||
|
||||
if [ -f "$__object/parameter/login-required" ]; then
|
||||
LOGIN_REQUIRED="True"
|
||||
else
|
||||
LOGIN_REQUIRED="False"
|
||||
fi
|
||||
export LOGIN_REQUIRED
|
||||
|
||||
data_root="$(cat "$__object/parameter/data-root")"
|
||||
MEDIA_ROOT="$data_root/media"
|
||||
REPORTS_ROOT="$data_root/reports"
|
||||
SCRIPTS_ROOT="$data_root/scripts"
|
||||
|
||||
if [ -f "$__object/parameter/media-root" ]; then
|
||||
MEDIA_ROOT="$(cat "$__object/parameter/media-root")"
|
||||
fi
|
||||
export MEDIA_ROOT
|
||||
if [ -f "$__object/parameter/reports-root" ]; then
|
||||
REPORTS_ROOT="$(cat "$__object/parameter/reports-root")"
|
||||
fi
|
||||
export REPORTS_ROOT
|
||||
if [ -f "$__object/parameter/scripts-root" ]; then
|
||||
SCRIPTS_ROOT="$(cat "$__object/parameter/scripts-root")"
|
||||
fi
|
||||
export SCRIPTS_ROOT
|
||||
|
||||
if [ -f "$__object/parameter/update-notify" ]; then
|
||||
UPDATE_CHECK="yes"
|
||||
export UPDATE_CHECK
|
||||
fi
|
||||
|
||||
|
||||
# Create system user used to run netbox.
|
||||
__user netbox --system --home /opt/netbox --create-home
|
||||
# Generate python environment (user will be set by gencode-remote)
|
||||
require="__user/netbox" __pyvenv /opt/netbox/venv/
|
||||
|
||||
# Generate and upload netbox configuration.
|
||||
mkdir -p "$__object/files"
|
||||
"$__type/files/configuration.py.sh" > "$__object/files/configuration.py"
|
||||
"$__type/files/ldap_config.py.sh" > "$__object/files/ldap_config.py"
|
||||
|
||||
require="__user/netbox" __directory /opt/netbox/cdist
|
||||
require="__directory/opt/netbox/cdist" __file \
|
||||
/opt/netbox/cdist/configuration.py --mode 640 --owner netbox \
|
||||
--source "$__object/files/configuration.py"
|
||||
|
||||
if [ -f "$__object/parameter/ldap-server" ]; then
|
||||
require="__directory/opt/netbox/cdist" __file \
|
||||
/opt/netbox/cdist/ldap_config.py --mode 640 --owner netbox \
|
||||
--source "$__object/files/ldap_config.py"
|
||||
else
|
||||
require="__directory/opt/netbox/cdist" __file \
|
||||
/opt/netbox/cdist/ldap_config.py --state absent
|
||||
fi
|
||||
|
||||
# save secret
|
||||
require="__directory/opt/netbox/cdist" __file /opt/netbox/cdist/secretkey \
|
||||
--mode 400 --owner netbox --source - << SECRET
|
||||
$SECRET_KEY
|
||||
SECRET
|
||||
|
||||
|
||||
# Upload systemd unit for worker and wsgi service
|
||||
# does not restart netbox on change cause it only restart all other services
|
||||
__systemd_unit netbox.service \
|
||||
--source "$__type/files/netbox.service" \
|
||||
--enablement-state enabled
|
||||
__systemd_unit netbox-rq.service \
|
||||
--source "$__type/files/netbox-rq.service" \
|
||||
--enablement-state enabled --restart
|
5
type/__netbox/parameter/boolean
Normal file
5
type/__netbox/parameter/boolean
Normal file
|
@ -0,0 +1,5 @@
|
|||
redis-ssl
|
||||
smtp-use-ssl
|
||||
smtp-use-tls
|
||||
login-required
|
||||
update-notify
|
1
type/__netbox/parameter/default/basepath
Normal file
1
type/__netbox/parameter/default/basepath
Normal file
|
@ -0,0 +1 @@
|
|||
|
1
type/__netbox/parameter/default/data-root
Normal file
1
type/__netbox/parameter/default/data-root
Normal file
|
@ -0,0 +1 @@
|
|||
/opt/netbox/data
|
1
type/__netbox/parameter/default/database-host
Normal file
1
type/__netbox/parameter/default/database-host
Normal file
|
@ -0,0 +1 @@
|
|||
localhost
|
1
type/__netbox/parameter/default/database-port
Normal file
1
type/__netbox/parameter/default/database-port
Normal file
|
@ -0,0 +1 @@
|
|||
|
1
type/__netbox/parameter/default/redis-dbid-offset
Normal file
1
type/__netbox/parameter/default/redis-dbid-offset
Normal file
|
@ -0,0 +1 @@
|
|||
0
|
1
type/__netbox/parameter/default/redis-host
Normal file
1
type/__netbox/parameter/default/redis-host
Normal file
|
@ -0,0 +1 @@
|
|||
localhost
|
1
type/__netbox/parameter/default/redis-password
Normal file
1
type/__netbox/parameter/default/redis-password
Normal file
|
@ -0,0 +1 @@
|
|||
|
1
type/__netbox/parameter/default/redis-port
Normal file
1
type/__netbox/parameter/default/redis-port
Normal file
|
@ -0,0 +1 @@
|
|||
6379
|
1
type/__netbox/parameter/default/smtp-from-email
Normal file
1
type/__netbox/parameter/default/smtp-from-email
Normal file
|
@ -0,0 +1 @@
|
|||
|
1
type/__netbox/parameter/default/smtp-host
Normal file
1
type/__netbox/parameter/default/smtp-host
Normal file
|
@ -0,0 +1 @@
|
|||
localhost
|
1
type/__netbox/parameter/default/smtp-password
Normal file
1
type/__netbox/parameter/default/smtp-password
Normal file
|
@ -0,0 +1 @@
|
|||
|
1
type/__netbox/parameter/default/smtp-port
Normal file
1
type/__netbox/parameter/default/smtp-port
Normal file
|
@ -0,0 +1 @@
|
|||
25
|
1
type/__netbox/parameter/default/smtp-user
Normal file
1
type/__netbox/parameter/default/smtp-user
Normal file
|
@ -0,0 +1 @@
|
|||
|
27
type/__netbox/parameter/optional
Normal file
27
type/__netbox/parameter/optional
Normal file
|
@ -0,0 +1,27 @@
|
|||
secret-key
|
||||
database-host
|
||||
database-port
|
||||
ldap-server
|
||||
ldap-bind-dn
|
||||
ldap-bind-password
|
||||
ldap-user-base
|
||||
ldap-group-base
|
||||
ldap-require-group
|
||||
ldap-staff-group
|
||||
ldap-superuser-group
|
||||
redis-host
|
||||
redis-port
|
||||
redis-password
|
||||
redis-dbid-offset
|
||||
smtp-host
|
||||
smtp-port
|
||||
smtp-user
|
||||
smtp-password
|
||||
smtp-from-email
|
||||
basepath
|
||||
http-proxy
|
||||
https-proxy
|
||||
data-root
|
||||
media-root
|
||||
reports-root
|
||||
scripts-root
|
4
type/__netbox/parameter/required
Normal file
4
type/__netbox/parameter/required
Normal file
|
@ -0,0 +1,4 @@
|
|||
version
|
||||
database
|
||||
database-user
|
||||
database-password
|
1
type/__netbox/parameter/required_multiple
Normal file
1
type/__netbox/parameter/required_multiple
Normal file
|
@ -0,0 +1 @@
|
|||
host
|
0
type/__netbox/singleton
Normal file
0
type/__netbox/singleton
Normal file
4
type/__netbox_gunicorn/explorer/installed
Executable file
4
type/__netbox_gunicorn/explorer/installed
Executable file
|
@ -0,0 +1,4 @@
|
|||
#!/bin/sh -e
|
||||
|
||||
# print version if available
|
||||
/opt/netbox/venv/bin/pip3 show gunicorn | awk '/Version:/{print $2}'
|
3
type/__netbox_gunicorn/explorer/should_installed
Executable file
3
type/__netbox_gunicorn/explorer/should_installed
Executable file
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh -e
|
||||
|
||||
awk -v FS="==" '$1 ~ /gunicorn/{print $2}' /opt/netbox/requirements.txt
|
31
type/__netbox_gunicorn/files/gunicorn.py.sh
Executable file
31
type/__netbox_gunicorn/files/gunicorn.py.sh
Executable file
|
@ -0,0 +1,31 @@
|
|||
#!/bin/sh -e
|
||||
|
||||
# Generates gunicorn config
|
||||
# see https://docs.gunicorn.org/en/stable/settings.html
|
||||
|
||||
# fix missing $__explorer
|
||||
# see https://code.ungleich.ch/ungleich-public/cdist/-/issues/834
|
||||
__explorer="$__global/explorer"
|
||||
|
||||
# size workes by cpu
|
||||
cores="$(cat "$__explorer/cpu_cores")"
|
||||
|
||||
|
||||
cat << EOF
|
||||
# The IP address (typically localhost) and port that the Netbox WSGI process should listen on
|
||||
#bind = done via systemd socket 'gunicorn-netbox.socket'
|
||||
|
||||
# Number of gunicorn workers to spawn. This should typically be 2n+1, where
|
||||
# n is the number of CPU cores present.
|
||||
workers = $(( 2*cores + 1 ))
|
||||
|
||||
# Number of threads per worker process
|
||||
threads = 3
|
||||
|
||||
# Timeout (in seconds) for a request to complete
|
||||
timeout = 120
|
||||
|
||||
# The maximum number of requests a worker can handle before being respawned
|
||||
max_requests = 5000
|
||||
max_requests_jitter = 500
|
||||
EOF
|
29
type/__netbox_gunicorn/files/netbox.service
Normal file
29
type/__netbox_gunicorn/files/netbox.service
Normal file
|
@ -0,0 +1,29 @@
|
|||
[Unit]
|
||||
Description=NetBox Gunicorn WSGI Service
|
||||
Documentation=https://netbox.readthedocs.io/en/stable/
|
||||
PartOf=netbox.service
|
||||
Requires=netbox-rq.service
|
||||
Requires=gunicorn-netbox.socket
|
||||
Wants=network.target
|
||||
After=netbox.service
|
||||
After=network.target
|
||||
After=redis-server.service postgresql.service
|
||||
|
||||
[Service]
|
||||
Type=notify
|
||||
|
||||
User=netbox
|
||||
Group=netbox
|
||||
WorkingDirectory=/opt/netbox
|
||||
|
||||
ExecStart=/opt/netbox/venv/bin/gunicorn --pythonpath /opt/netbox/netbox --config /opt/netbox/gunicorn.py netbox.wsgi
|
||||
# signals: https://docs.gunicorn.org/en/stable/signals.html
|
||||
ExecReload=kill -HUP $MAINPID
|
||||
ExecStop=kill -TERM $MAINPID
|
||||
KillSignal=SIGQUIT
|
||||
|
||||
Restart=on-failure
|
||||
RestartSec=30
|
||||
|
||||
[Install]
|
||||
WantedBy=netbox.service
|
1
type/__netbox_gunicorn/files/netbox.socket.sh
Symbolic link
1
type/__netbox_gunicorn/files/netbox.socket.sh
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../__netbox/files/netbox.socket.sh
|
50
type/__netbox_gunicorn/gencode-remote
Executable file
50
type/__netbox_gunicorn/gencode-remote
Executable file
|
@ -0,0 +1,50 @@
|
|||
#!/bin/sh -e
|
||||
|
||||
# control state
|
||||
state="$(cat "$__object/parameter/state")"
|
||||
|
||||
case "$state" in
|
||||
# install gunicorn
|
||||
enabled|disabled)
|
||||
curr_installed="$(cat "$__object/explorer/installed")"
|
||||
should_installed="$(cat "$__object/explorer/should_installed")"
|
||||
|
||||
# gunicorn version change
|
||||
if [ "$curr_installed" != "$should_installed" ]; then
|
||||
# (re)installing gunicorn
|
||||
echo "/opt/netbox/venv/bin/pip3 install 'gunicorn==$should_installed'"
|
||||
|
||||
if [ "$curr_installed" != "" ]; then
|
||||
printf "updated %s to %s\n" "$curr_installed" "$should_installed" \
|
||||
>> "$__messages_out"
|
||||
else
|
||||
printf "installed\n" >> "$__messages_out"
|
||||
fi
|
||||
do_restart=yes
|
||||
fi
|
||||
|
||||
# configuration changes
|
||||
if grep -q "^__file/opt/netbox/gunicorn.py:" "$__messages_in"; then
|
||||
do_restart=yes
|
||||
printf "configured\n" >> "$__messages_out"
|
||||
fi
|
||||
|
||||
|
||||
# restart gunicorn
|
||||
if [ "$do_restart" ] && [ "$state" != "disabled" ]; then
|
||||
cat << EOF
|
||||
# Restart service
|
||||
systemctl restart gunicorn-netbox
|
||||
EOF
|
||||
fi
|
||||
;;
|
||||
|
||||
# uninstall
|
||||
absent)
|
||||
# check if installed
|
||||
if [ -s "$__object/explorer/installed" ]; then
|
||||
# service already disabled
|
||||
echo "/opt/netbox/venv/bin/pip3 uninstall -y gunicorn"
|
||||
printf "uninstalled\n" >> "$__messages_out"
|
||||
fi
|
||||
esac
|
117
type/__netbox_gunicorn/man.rst
Normal file
117
type/__netbox_gunicorn/man.rst
Normal file
|
@ -0,0 +1,117 @@
|
|||
cdist-type__netbox_gunicorn(7)
|
||||
==============================
|
||||
|
||||
NAME
|
||||
----
|
||||
cdist-type__netbox_gunicorn - Run NetBox with Gunicorn
|
||||
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
This (singleton) type installs Gunicorn into the NetBox `python-venv` to host
|
||||
the NetBox WSGI application. It provides the application as HTTP over the given
|
||||
sockets. Static content must be served independent of Gunicorn. The Gunicorn
|
||||
daemon is available as the `gunicorn-netbox` systemd service, but also
|
||||
available via the `netbox` wrapper service.
|
||||
|
||||
It will use systemd socket activation to listen to the given sockets. This
|
||||
should allow to bind to privileaged ports (all below 1024) and hot reloads.
|
||||
|
||||
|
||||
REQUIRED PARAMETERS
|
||||
-------------------
|
||||
None.
|
||||
|
||||
|
||||
OPTIONAL PARAMETERS
|
||||
-------------------
|
||||
state
|
||||
Represents the state of the Gunciron application. Defaults to ``enabled``.
|
||||
|
||||
enabled
|
||||
The Gunicorn service is enabled and running.
|
||||
disabled
|
||||
The Gunicorn service is installed, but disabled.
|
||||
absent
|
||||
The uWSGI service is not installed and all configuration removed.
|
||||
|
||||
This type does not guarantee anything about the running state of the
|
||||
service. To be sure about the service is stopped or not, use the type
|
||||
:strong:`cdist-type__systemd_service`\ (7) after this execution.
|
||||
|
||||
bind-to
|
||||
The hosts the gunicorn socket should be bind to. Formats are `IP`,
|
||||
`IP:PORT`, `PATH` or anything other that systemd socket units will
|
||||
understand as stream. Parameter can be set multiple times. Defaults
|
||||
to ``127.0.0.1:8001``.
|
||||
|
||||
|
||||
BOOLEAN PARAMETERS
|
||||
------------------
|
||||
None.
|
||||
|
||||
|
||||
MESSAGES
|
||||
--------
|
||||
installed
|
||||
The software was installed.
|
||||
|
||||
upgraded $old to $new
|
||||
The version of the gunicorn software was updated from `$old` to `$new`.
|
||||
|
||||
configured
|
||||
Configuration for gunicorn changed.
|
||||
|
||||
uninstalled
|
||||
The Gunicorn application was removed.
|
||||
|
||||
In all cases where the application is still present, it restarts the service to
|
||||
use the up-to-date version.
|
||||
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
# simple
|
||||
__netbox $args
|
||||
require="__netbox" __netbox_gunicorn
|
||||
|
||||
# with arguments
|
||||
__netbox $args
|
||||
require="__netbox" __netbox_gunicorn \
|
||||
--bind-to 0.0.0.0:8001 \
|
||||
--bind-to 1.2.3.4:5678
|
||||
|
||||
# replace uwsgi with gunicorn
|
||||
__netbox $args
|
||||
require="__netbox" __netbox_uwsgi --state absent
|
||||
# it should depend on __netbox_uwsgi if they use the same socket
|
||||
require="__netbox_uwsgi" __netbox_gunicorn --state enabled
|
||||
|
||||
# be sure the service is disabled
|
||||
__netbox $args
|
||||
require="__netbox" __netbox_gunicorn --state disabled
|
||||
require="__netbox_gunicorn" __systemd_service gunicorn-netbox --state stopped
|
||||
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
`Gunicorn Documentation <https://docs.gunicorn.org/en/stable/>`_
|
||||
|
||||
:strong:`cdist-type__netbox`\ (7)
|
||||
:strong:`cdist-type__netbox_uwsgi`\ (7)
|
||||
|
||||
|
||||
AUTHORS
|
||||
-------
|
||||
Matthias Stecher <matthiasstecher@gmx.de>
|
||||
|
||||
|
||||
COPYING
|
||||
-------
|
||||
Copyright \(C) 2020 Matthias Stecher. You can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
57
type/__netbox_gunicorn/manifest
Executable file
57
type/__netbox_gunicorn/manifest
Executable file
|
@ -0,0 +1,57 @@
|
|||
#!/bin/sh -e
|
||||
# __netbox_gunicorn/manifest
|
||||
|
||||
# Check states
|
||||
state=""
|
||||
unit_state=""
|
||||
param_state="$(cat "$__object/parameter/state")"
|
||||
|
||||
case "$param_state" in
|
||||
enabled|disabled)
|
||||
state="present"
|
||||
unit_state="$param_state"
|
||||
;;
|
||||
|
||||
absent)
|
||||
state="absent"
|
||||
unit_state="disabled"
|
||||
;;
|
||||
|
||||
*)
|
||||
# does not exist
|
||||
printf "The state '%s' does not exist, can't continue!\n" "$param_state" >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
mkdir "$__object/files"
|
||||
|
||||
if [ "$state" = "present" ]; then
|
||||
# process template
|
||||
"$__type/files/gunicorn.py.sh" > "$__object/files/gunicorn.py"
|
||||
|
||||
# gunicorn config file
|
||||
__file /opt/netbox/gunicorn.py \
|
||||
--mode 644 --owner netbox \
|
||||
--source "$__object/files/gunicorn.py"
|
||||
|
||||
else
|
||||
# absent config file
|
||||
__file /opt/netbox/gunicorn.py --state absent
|
||||
fi
|
||||
|
||||
|
||||
TYPE="Gunicorn"
|
||||
export TYPE
|
||||
|
||||
"$__type/files/netbox.socket.sh" "$__object/parameter/bind-to" \
|
||||
> "$__object/files/netbox.socket"
|
||||
|
||||
# install systemd files
|
||||
__systemd_unit gunicorn-netbox.socket \
|
||||
--state "$state" --enablement-state "$unit_state" \
|
||||
--source "$__object/files/netbox.socket" --restart
|
||||
__systemd_unit gunicorn-netbox.service \
|
||||
--state "$state" --enablement-state "$unit_state" \
|
||||
--source "$__type/files/netbox.service" --restart
|
1
type/__netbox_gunicorn/parameter/default/bind-to
Normal file
1
type/__netbox_gunicorn/parameter/default/bind-to
Normal file
|
@ -0,0 +1 @@
|
|||
127.0.0.1:8001
|
1
type/__netbox_gunicorn/parameter/default/state
Normal file
1
type/__netbox_gunicorn/parameter/default/state
Normal file
|
@ -0,0 +1 @@
|
|||
enabled
|
1
type/__netbox_gunicorn/parameter/optional
Normal file
1
type/__netbox_gunicorn/parameter/optional
Normal file
|
@ -0,0 +1 @@
|
|||
state
|
1
type/__netbox_gunicorn/parameter/optional_multiple
Normal file
1
type/__netbox_gunicorn/parameter/optional_multiple
Normal file
|
@ -0,0 +1 @@
|
|||
bind-to
|
0
type/__netbox_gunicorn/singleton
Normal file
0
type/__netbox_gunicorn/singleton
Normal file
12
type/__netbox_uwsgi/explorer/bind-capability
Executable file
12
type/__netbox_uwsgi/explorer/bind-capability
Executable file
|
@ -0,0 +1,12 @@
|
|||
#!/bin/sh -e
|
||||
# explorer/bind-capablility
|
||||
|
||||
# Checks if the uWSGI binary have the capability to bind to privileaged ports
|
||||
# as a non-root user. It's required if no systemd sockets are used (cause of
|
||||
# the use of multiple protocols etc.)
|
||||
|
||||
binary="/opt/netbox/venv/bin/uwsgi"
|
||||
# -v verifies if capability is set
|
||||
if setcap -q -v CAP_NET_BIND_SERVICE+ep "$binary"; then
|
||||
echo set
|
||||
fi
|
4
type/__netbox_uwsgi/explorer/installed
Executable file
4
type/__netbox_uwsgi/explorer/installed
Executable file
|
@ -0,0 +1,4 @@
|
|||
#!/bin/sh -e
|
||||
|
||||
# print version if available
|
||||
/opt/netbox/venv/bin/pip3 show uwsgi | awk '/Version:/{print $2}'
|
4
type/__netbox_uwsgi/explorer/upgradeable
Executable file
4
type/__netbox_uwsgi/explorer/upgradeable
Executable file
|
@ -0,0 +1,4 @@
|
|||
#!/bin/sh -e
|
||||
|
||||
# print latest version if availble
|
||||
/opt/netbox/venv/bin/pip3 list --outdated | awk '$1 == "uwsgi" {print $3}'
|
40
type/__netbox_uwsgi/files/netbox.service.sh
Executable file
40
type/__netbox_uwsgi/files/netbox.service.sh
Executable file
|
@ -0,0 +1,40 @@
|
|||
#!/bin/sh -e
|
||||
|
||||
cat << EOF
|
||||
[Unit]
|
||||
Description=Netbox uWSGI WSGI Service
|
||||
Documentation=https://netbox.readthedocs.io/en/stable/
|
||||
PartOf=netbox.service
|
||||
Requires=netbox-rq.service
|
||||
EOF
|
||||
|
||||
# Add dependency to own socket
|
||||
if [ "$(cat "$__object/files/systemd_socket")" = "yes" ]; then
|
||||
echo "Requires=uwsgi-netbox.socket"
|
||||
fi
|
||||
|
||||
cat << EOF
|
||||
Wants=network.target
|
||||
After=netbox.service
|
||||
After=network.target
|
||||
After=redis-server.service postgresql.service
|
||||
|
||||
[Service]
|
||||
Type=notify
|
||||
|
||||
User=netbox
|
||||
Group=netbox
|
||||
WorkingDirectory=/opt/netbox
|
||||
|
||||
ExecStart=/opt/netbox/venv/bin/uwsgi --master --chdir /opt/netbox/netbox --module netbox.wsgi uwsgi.ini
|
||||
# signals: https://uwsgi-docs.readthedocs.io/en/latest/Management.html#signals-for-controlling-uwsgi
|
||||
ExecReload=kill -HUP \$MAINPID
|
||||
ExecStop=kill -INT \$MAINPID
|
||||
KillSignal=SIGQUIT
|
||||
|
||||
Restart=on-failure
|
||||
RestartSec=30
|
||||
|
||||
[Install]
|
||||
WantedBy=netbox.service
|
||||
EOF
|
1
type/__netbox_uwsgi/files/netbox.socket.sh
Symbolic link
1
type/__netbox_uwsgi/files/netbox.socket.sh
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../__netbox/files/netbox.socket.sh
|
60
type/__netbox_uwsgi/files/uwsgi.ini.sh
Executable file
60
type/__netbox_uwsgi/files/uwsgi.ini.sh
Executable file
|
@ -0,0 +1,60 @@
|
|||
#!/bin/sh -e
|
||||
|
||||
# Generates uwsgi config
|
||||
# see https://uwsgi-docs.readthedocs.io/en/latest/Options.html
|
||||
# or https://uwsgi-docs-additions.readthedocs.io/en/latest/Options.html
|
||||
|
||||
# params:
|
||||
# 1: parameter name
|
||||
# 2: parameter value file
|
||||
#
|
||||
# output: the lines for the configuration option
|
||||
multi_options() {
|
||||
while read -r line; do
|
||||
printf "%s = %s\n" "$1" "$line"
|
||||
done < "$2"
|
||||
}
|
||||
|
||||
# fix missing $__explorer
|
||||
# see https://code.ungleich.ch/ungleich-public/cdist/-/issues/834
|
||||
__explorer="$__global/explorer"
|
||||
|
||||
# size workes by cpu
|
||||
cores="$(cat "$__explorer/cpu_cores")"
|
||||
|
||||
|
||||
cat << EOF
|
||||
[uwsgi]
|
||||
; socket(s) to bind
|
||||
EOF
|
||||
|
||||
if [ "$SYSTEMD_SOCKET" != "yes" ]; then
|
||||
# special protocol to bind
|
||||
find "$__object/parameter/" -maxdepth 1 -name "*-bind" -print \
|
||||
| while read -r param; do
|
||||
multi_options "$(basename "$param" | awk -F'-' '{print $1}')-socket" "$param"
|
||||
done
|
||||
else
|
||||
# else, systemd will offer socket
|
||||
echo "; sockets managed via 'uwsgi-netbox.socket'"
|
||||
printf "protocol = %s\n" "$PROTOCOL"
|
||||
fi
|
||||
|
||||
|
||||
# multi-process settings
|
||||
cat << EOF
|
||||
|
||||
; processes and threads
|
||||
processes = $(( 2*cores + 1 ))
|
||||
threads = 2
|
||||
EOF
|
||||
|
||||
|
||||
# optional mapping of static content
|
||||
if [ "$STATIC_MAP" != "" ]; then
|
||||
cat << EOF
|
||||
|
||||
; map static content
|
||||
static-map = /static=/opt/netbox/netbox/static
|
||||
EOF
|
||||
fi
|
101
type/__netbox_uwsgi/gencode-remote
Executable file
101
type/__netbox_uwsgi/gencode-remote
Executable file
|
@ -0,0 +1,101 @@
|
|||
#!/bin/sh -e
|
||||
|
||||
# control state
|
||||
state="$(cat "$__object/parameter/state")"
|
||||
|
||||
# Set capabilities to aquire privileaged ports as netbox user. Two modes are
|
||||
# available to efficiently set capabilites. Assumes libcap-bin is installed as
|
||||
# default on debian systems.
|
||||
#
|
||||
# Arguments:
|
||||
# 1: mode to detect if capabilites are required to set ('set' or 'correct')
|
||||
set_bind_cap() {
|
||||
cap_mode="" # reset variable from the execution before
|
||||
|
||||
# check if capabilites are required after given mode
|
||||
case "$1" in
|
||||
# assumes capabilites are not set (cause of new binaries)
|
||||
set)
|
||||
if [ "$SYSTEMD_SOCKET" != "yes" ]; then
|
||||
cap_mode="+ep"
|
||||
fi
|
||||
;;
|
||||
|
||||
# check if capabilities have changed
|
||||
correct)
|
||||
if [ -s "$__object/explorer/bind-capability" ]; then
|
||||
# capabilites are set
|
||||
if [ "$SYSTEMD_SOCKET" = "yes" ]; then
|
||||
cap_mode="-ep" # unset
|
||||
fi
|
||||
else
|
||||
# capabilities are unset
|
||||
if [ "$SYSTEMD_SOCKET" != "yes" ]; then
|
||||
cap_mode="+ep" # set
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
|
||||
# faulty mode
|
||||
*)
|
||||
echo "called set_bind_cap incorrect (\$1 missing)" >&2
|
||||
;;
|
||||
esac
|
||||
|
||||
# set capabilities if any
|
||||
if [ "$cap_mode" ]; then
|
||||
printf "setcap -q CAP_NET_BIND_SERVICE%s /opt/netbox/venv/bin/uwsgi\n" "$cap_mode"
|
||||
fi
|
||||
}
|
||||
SYSTEMD_SOCKET="$(cat "$__object/files/systemd_socket")"
|
||||
|
||||
|
||||
case "$state" in
|
||||
# install uwsgi
|
||||
enabled|disabled)
|
||||
# not installed
|
||||
if ! [ -s "$__object/explorer/installed" ]; then
|
||||
echo "/opt/netbox/venv/bin/pip3 install -q uwsgi"
|
||||
set_bind_cap set
|
||||
do_restart=yes
|
||||
printf "installed\n" >> "$__messages_out"
|
||||
|
||||
# updates available
|
||||
elif [ -s "$__object/explorer/upgradeable" ]; then
|
||||
echo "/opt/netbox/venv/bin/pip3 install -q --upgrade uwsgi"
|
||||
set_bind_cap set
|
||||
do_restart=yes
|
||||
printf "upgraded\n" >> "$__messages_out"
|
||||
fi
|
||||
|
||||
# changed configuration
|
||||
if grep -q "^__file/opt/netbox/uwsgi.ini:" "$__messages_in"; then
|
||||
do_restart=yes
|
||||
printf "configured\n" >> "$__messages_out"
|
||||
fi
|
||||
|
||||
# if no capabilities were set yet, check if any are required
|
||||
if [ -z "$cap_mode" ]; then
|
||||
set_bind_cap correct
|
||||
fi
|
||||
|
||||
|
||||
# restart uwsgi
|
||||
if [ "$do_restart" ] && [ "$state" != "disabled" ]; then
|
||||
cat << EOF
|
||||
# Restart service
|
||||
systemctl restart uwsgi-netbox
|
||||
EOF
|
||||
fi
|
||||
;;
|
||||
|
||||
# uninstall
|
||||
absent)
|
||||
# check if installed
|
||||
if [ -s "$__object/explorer/installed" ]; then
|
||||
# service already disabled
|
||||
echo "/opt/netbox/venv/bin/pip3 uninstall -qy uwsgi"
|
||||
printf "uninstalled\n" >> "$__messages_out"
|
||||
fi
|
||||
;;
|
||||
esac
|
186
type/__netbox_uwsgi/man.rst
Normal file
186
type/__netbox_uwsgi/man.rst
Normal file
|
@ -0,0 +1,186 @@
|
|||
cdist-type__netbox_uwsgi(7)
|
||||
===========================
|
||||
|
||||
NAME
|
||||
----
|
||||
cdist-type__netbox_uwsgi - Run NetBox with uWSGI
|
||||
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
This (singleton) type installs uWSGI into the NetBox `python-venv`. It hosts
|
||||
the NetBox WSGI application via the WSGI protocol. A further server must be
|
||||
installed to provide it as HTTP and serve static content. It supports multiple
|
||||
protocols like uwsgi, fastcgi or HTTP to comunicate with the proxy server. This
|
||||
application is available via the `uwsgi-netbox` systemd service. It is
|
||||
controllable via the `netbox` wrapper service, too.
|
||||
|
||||
**As uWSGI will be started as netbox user, it does not have privileges to
|
||||
bind to a privileaged port (all ports below 1024).** Because uWSGI will
|
||||
drop privileages anyway before binding to a port, solutions are to use
|
||||
the systemd sockets to activate the ports as root or set linux kernel
|
||||
capabilites to bind to such a privileaged port.
|
||||
|
||||
As systemd sockets (or uwsgi itself) do not allow to distinguish multiple
|
||||
sockets if different protocols are used for different sockets, this type does
|
||||
not use systemd sockets if it is requested from the user. Using the
|
||||
``--bind-to`` and ``--protocol`` parameters, it uses the systemd socket
|
||||
activation. Else, it set the different sockets and protocols natively to uwsgi
|
||||
and add kernel capabilities to be able to listen to privileaged ports.
|
||||
|
||||
|
||||
REQUIRED PARAMETERS
|
||||
-------------------
|
||||
None.
|
||||
|
||||
|
||||
OPTIONAL PARAMETERS
|
||||
-------------------
|
||||
state
|
||||
Represents the state of the uWSGI application. Defaults to ``enabled``.
|
||||
|
||||
enabled
|
||||
The uWSGI service is enabled and running.
|
||||
disabled
|
||||
The uWSGI service is installed, but disabled.
|
||||
absent
|
||||
The uWSGI service is not installed and all configuration removed.
|
||||
|
||||
This type does not guarantee anything about the running state of the
|
||||
service. To be sure about the service is stopped or not, use the type
|
||||
:strong:`cdist-type__systemd_service`\ (7) after this execution.
|
||||
|
||||
|
||||
bind-to
|
||||
The socket uwsgi should bind to. Must be UNIX/TCP (or anything that
|
||||
systemd sockets accept as stream). Defaults to ``127.0.0.1:3031``. Can be
|
||||
set multiple times. The used protocol is defined by ``--protocol``.
|
||||
|
||||
**By setting up the socket via this parameter, it uses systemd sockets to
|
||||
handle these.** This parameter will be ignored if a more detailed paramter
|
||||
is given (``--$proto-bind``).
|
||||
|
||||
protocol
|
||||
The protocol which should be used for the socket given by the ``--bind-to``
|
||||
parameter. Possible values are ``uwsgi``, ``http``, ``fastcgi`` and
|
||||
``scgi``. If nothing given, it defaults to ``uwsgi``.
|
||||
|
||||
uwsgi-bind
|
||||
http-bind
|
||||
fastcgi-bind
|
||||
scgi-bind
|
||||
Bind the application to a specific protocol instead of implicit uwsgi via
|
||||
``--bind-to``. If such parameter given, ``--bind-to`` will be ignored. Must
|
||||
be a UNIX/TCP socket. Can be set multiple times.
|
||||
|
||||
**By using such parameters instead of ``--bind-to``, no systemd sockets
|
||||
will be used because it can not handle sockets for multiple protocols.**
|
||||
Instead, the native socket binding will be used. It will add kernel
|
||||
capabilites to bind to privileaged ports, too. This allow binds to ports
|
||||
like 80 as netbox user.
|
||||
|
||||
|
||||
BOOLEAN PARAMETERS
|
||||
------------------
|
||||
serve-static
|
||||
Setup uWSGI to serve the static content, too. This is generally not
|
||||
recommended for real production setups, as it is the job of the reverse
|
||||
proxy server, who will thread it as static cachable content. This option
|
||||
is only recommended for small setups or direct usage of the uWSGI socket
|
||||
like using it as standalone HTTP server for NetBox.
|
||||
|
||||
**Hint**: This parameter does not work in junction with the `__netbox`
|
||||
parameter ``--basepath``. It is because this type does not know the
|
||||
parameter value and this case is very unlikly to happen; although an
|
||||
implementation is not difficult.
|
||||
|
||||
|
||||
MESSAGES
|
||||
--------
|
||||
installed
|
||||
The uwsgi service was installed.
|
||||
|
||||
upgraded
|
||||
The uwsgi service was upgraded.
|
||||
|
||||
configured
|
||||
The uwsgi configuration got updated.
|
||||
|
||||
uninstalled
|
||||
The uWSGI application was removed.
|
||||
|
||||
In all cases where the application is still present, it restarts the service to
|
||||
use the up-to-date version.
|
||||
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
# simple
|
||||
__netbox $args
|
||||
require="__netbox" __netbox_uwsgi
|
||||
|
||||
# with multiple binds
|
||||
__netbox $args
|
||||
require="__netbox" __netbox_uwsgi --bind-to 0.0.0.0:3032 \
|
||||
--bind-to 0.0.0.0:3033
|
||||
|
||||
# with multiple protocols
|
||||
# parameter `--bind-to` will be ignored
|
||||
# avoids systemd sockets, but can handle multiple protocols
|
||||
__netbox $args
|
||||
require="__netbox" __netbox_uwsgi --uwsgi-bind 0.0.0.0:3031 \
|
||||
--http-bind 0.0.0.0:8080 \
|
||||
--fastcgi-bind 1.2.3.4:5678
|
||||
|
||||
# as standalone server
|
||||
__netbox $args
|
||||
require="__netbox" __netbox_uwsgi --serve-static --http-bind 0.0.0.0:80
|
||||
|
||||
# replace gunicorn with uwsgi
|
||||
__netbox $args
|
||||
require="__netbox" __netbox_gunicorn --state absent
|
||||
# it should depend on __netbox_gunicorn if they use the same socket
|
||||
require="__netbox_gunicorn" __netbox_uwsgi --state enabled
|
||||
|
||||
# be sure the service is disabled
|
||||
__netbox $args
|
||||
require="__netbox" __netbox_uwsgi --state disabled
|
||||
require="__netbox_uwsgi" __systemd_service uwsgi-netbox --state stopped
|
||||
|
||||
|
||||
NOTES
|
||||
-----
|
||||
If systemd sockets are used, uwsgi can not be reloaded because it does not
|
||||
handle the socket correctly. It works by completly restarting uwsgi (because
|
||||
it is near the same cause of the systemd socket) or tweaking the service unit
|
||||
with the line ``StandardInput=socket``, which limits you to only one address
|
||||
to bind to (else, the service will not start).
|
||||
|
||||
Maybe someone is interested in enabling log files, because the "log to stdout"
|
||||
is not the fanciest approach (because it is shown in the journal). See the
|
||||
`uwsgi documentation <https://uwsgi.readthedocs.io/en/latest/Logging.html>` for
|
||||
reference.
|
||||
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
`uWSGI Documentation <https://uwsgi-docs.readthedocs.io/en/latest/>`_
|
||||
|
||||
:strong:`cdist-type__netbox`\ (7)
|
||||
:strong:`cdist-type__netbox_gunicorn`\ (7)
|
||||
|
||||
|
||||
AUTHORS
|
||||
-------
|
||||
Matthias Stecher <matthiasstecher@gmx.de>
|
||||
|
||||
|
||||
COPYING
|
||||
-------
|
||||
Copyright \(C) 2020 Matthias Stecher. You can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
86
type/__netbox_uwsgi/manifest
Executable file
86
type/__netbox_uwsgi/manifest
Executable file
|
@ -0,0 +1,86 @@
|
|||
#!/bin/sh -e
|
||||
# __netbox_uwsgi/manifest
|
||||
|
||||
# Check states
|
||||
state=""
|
||||
unit_state=""
|
||||
param_state="$(cat "$__object/parameter/state")"
|
||||
|
||||
case "$param_state" in
|
||||
enabled|disabled)
|
||||
state="present"
|
||||
unit_state="$param_state"
|
||||
;;
|
||||
|
||||
absent)
|
||||
state="absent"
|
||||
unit_state="disabled"
|
||||
;;
|
||||
|
||||
*)
|
||||
# does not exist
|
||||
printf "The state '%s' does not exist, can't continue!\n" "$param_state" >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
mkdir "$__object/files"
|
||||
|
||||
# check if systemd sockets will be used
|
||||
if [ -f "$__object/parameter/bind-to" ]; then
|
||||
SYSTEMD_SOCKET="yes"
|
||||
fi
|
||||
if find "$__object/parameter/" -maxdepth 1 -name "*-bind" -print -quit | grep -q .; then
|
||||
SYSTEMD_SOCKET="no"
|
||||
fi
|
||||
echo "$SYSTEMD_SOCKET" > "$__object/files/systemd_socket"
|
||||
|
||||
if [ "$state" = "present" ]; then
|
||||
# already checked outside this if-clause
|
||||
export SYSTEMD_SOCKET
|
||||
|
||||
PROTOCOL="$(cat "$__object/parameter/protocol")"
|
||||
export PROTOCOL
|
||||
|
||||
if [ -f "$__object/parameter/serve-static" ]; then
|
||||
STATIC_MAP="yes"
|
||||
export STATIC_MAP
|
||||
fi
|
||||
|
||||
# process template
|
||||
"$__type/files/uwsgi.ini.sh" > "$__object/files/uwsgi.ini"
|
||||
|
||||
# uwsgi config file
|
||||
# TODO maybe patching with __key_value cause of .ini ?
|
||||
__file /opt/netbox/uwsgi.ini \
|
||||
--mode 644 --owner netbox \
|
||||
--source "$__object/files/uwsgi.ini"
|
||||
|
||||
else
|
||||
# absent config file
|
||||
__file /opt/netbox/uwsgi.ini --state absent
|
||||
fi
|
||||
|
||||
|
||||
# handle the systemd socket
|
||||
if [ "$SYSTEMD_SOCKET" = "yes" ]; then
|
||||
TYPE="uWSGI"
|
||||
export TYPE
|
||||
|
||||
# generate and set the socket unit
|
||||
"$__type/files/netbox.socket.sh" "$__object/parameter/bind-to" \
|
||||
> "$__object/files/netbox.socket"
|
||||
__systemd_unit uwsgi-netbox.socket \
|
||||
--state "$state" --enablement-state "$unit_state" \
|
||||
--source "$__object/files/netbox.socket" --restart
|
||||
else
|
||||
# remove the systemd socket unit
|
||||
__systemd_unit uwsgi-netbox.socket --state absent
|
||||
fi
|
||||
|
||||
# install service file
|
||||
"$__type/files/netbox.service.sh" > "$__object/files/netbox.service"
|
||||
__systemd_unit uwsgi-netbox.service \
|
||||
--state "$state" --enablement-state "$unit_state" \
|
||||
--source "$__object/files/netbox.service" --restart
|
1
type/__netbox_uwsgi/parameter/boolean
Normal file
1
type/__netbox_uwsgi/parameter/boolean
Normal file
|
@ -0,0 +1 @@
|
|||
serve-static
|
1
type/__netbox_uwsgi/parameter/default/bind-to
Normal file
1
type/__netbox_uwsgi/parameter/default/bind-to
Normal file
|
@ -0,0 +1 @@
|
|||
127.0.0.1:3031
|
1
type/__netbox_uwsgi/parameter/default/protocol
Normal file
1
type/__netbox_uwsgi/parameter/default/protocol
Normal file
|
@ -0,0 +1 @@
|
|||
uwsgi
|
1
type/__netbox_uwsgi/parameter/default/state
Normal file
1
type/__netbox_uwsgi/parameter/default/state
Normal file
|
@ -0,0 +1 @@
|
|||
enabled
|
2
type/__netbox_uwsgi/parameter/optional
Normal file
2
type/__netbox_uwsgi/parameter/optional
Normal file
|
@ -0,0 +1,2 @@
|
|||
state
|
||||
protocol
|
5
type/__netbox_uwsgi/parameter/optional_multiple
Normal file
5
type/__netbox_uwsgi/parameter/optional_multiple
Normal file
|
@ -0,0 +1,5 @@
|
|||
bind-to
|
||||
uwsgi-bind
|
||||
http-bind
|
||||
fastcgi-bind
|
||||
scgi-bind
|
0
type/__netbox_uwsgi/singleton
Normal file
0
type/__netbox_uwsgi/singleton
Normal file
Loading…
Reference in a new issue