diff --git a/manifests/config.pp b/manifests/config.pp index e9ce50e..338b737 100644 --- a/manifests/config.pp +++ b/manifests/config.pp @@ -17,6 +17,9 @@ # Array 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. # +# @param allow_token_retrieval +# Permit the retrieval of API tokens after their creation. +# # @param database_name # Name of the PostgreSQL database. If handle_database is true, then this database # gets created as well. If not, then it is only used by the application, and needs to exist. @@ -132,6 +135,36 @@ # Date/time formatting. See the following link for supported formats: # https://docs.djangoproject.com/en/stable/ref/templates/builtins/#date # +# @param remote_auth_enabled +# boolean that enables the remote authentication for netbox. +# This must be set to True in order for remote_auth_* settings to take effect. +# +# @param remote_auth_backend +# This is the Python path to the custom Django authentication backend to use for external +# user authentication. NetBox provides two built-in backends (listed below), though custom +# authentication backends may also be provided by other packages or plugins. Provide a string +# for a single backend, or an iterable for multiple backends, which will be attempted in the order given. +# +# @param remote_auth_header +# When remote user authentication is in use, this is the name of the HTTP header which informs +# NetBox of the currently authenticated user. For example, to use the request header X-Remote-User +# it needs to be set to HTTP_X_REMOTE_USER +# +# @param remote_auth_first_name +# When remote user authentication is in use, this is the name of the HTTP header which informs +# NetBox of the first name of the currently authenticated user. For example, to use the request +# header X-Remote-User-First-Name it needs to be set to HTTP_X_REMOTE_USER_FIRST_NAME. +# +# @param remote_auth_last_name +# When remote user authentication is in use, this is the name of the HTTP header which informs +# NetBox of the last name of the currently authenticated user. For example, to use the request +# header X-Remote-User-Last-Name it needs to be set to HTTP_X_REMOTE_USER_LAST_NAME. +# +# @param remote_auth_user_email +# When remote user authentication is in use, this is the name of the HTTP header which informs +# NetBox of the email address of the currently authenticated user. For example, to use the request +# header X-Remote-User-Email it needs to be set to HTTP_X_REMOTE_USER_EMAIL. +# # @example # include netbox::config class netbox::config ( @@ -139,6 +172,7 @@ String $group, Stdlib::Absolutepath $install_root, Array[Stdlib::Host] $allowed_hosts, + Boolean $allow_api_token_retrieval, String $database_name, String $database_user, String $database_password, @@ -169,6 +203,21 @@ String $short_time_format, String $datetime_format, String $short_datetime_format, + Boolean $remote_auth_enabled, + String $remote_auth_backend, + String $remote_auth_header, + String $remote_auth_first_name, + String $remote_auth_last_name, + String $remote_auth_user_email, + String $ldap_sever_uri, + String $ad_ou, + String $ad_bind_dn, + String $ad_require_dn, + String $ad_admin_dn, + String $ad_superuser_dn, + String $ldap_bind_password, + Boolean $ldap_ignore_cert_errors, + Boolean $ldap_mirror_groups, ) { $should_create_superuser = false; $software_directory = "${install_root}/netbox" @@ -195,37 +244,44 @@ file { $config_file: content => epp('netbox/configuration.py.epp', { - 'allowed_hosts' => $allowed_hosts, - 'database_name' => $database_name, - 'database_user' => $database_user, - 'database_password' => $database_password, - 'database_host' => $database_host, - 'database_port' => $database_port, - 'database_conn_max_age' => $database_conn_max_age, - 'redis_options' => $redis_options, - 'email_options' => $email_options, - 'secret_key' => $secret_key, - 'admins' => $admins, - 'banner_top' => $banner_top, - 'banner_bottom' => $banner_bottom, - 'banner_login' => $banner_login, - 'base_path' => $base_path, - 'debug' => $debug, - 'enforce_global_unique' => $enforce_global_unique, - 'exempt_view_permissions' => $exempt_view_permissions, - 'login_required' => $login_required, - 'metrics_enabled' => $metrics_enabled, - 'prefer_ipv4' => $prefer_ipv4, - 'napalm_username' => $napalm_username, - 'napalm_password' => $napalm_password, - 'napalm_timeout' => $napalm_timeout, - 'time_zone' => $time_zone, - 'date_format' => $date_format, - 'short_date_format' => $short_date_format, - 'time_format' => $time_format, - 'short_time_format' => $short_time_format, - 'datetime_format' => $datetime_format, - 'short_datetime_format' => $short_datetime_format, + 'allowed_hosts' => $allowed_hosts, + 'allow_api_token_retrieval' => $allow_api_token_retrieval, + 'database_name' => $database_name, + 'database_user' => $database_user, + 'database_password' => $database_password, + 'database_host' => $database_host, + 'database_port' => $database_port, + 'database_conn_max_age' => $database_conn_max_age, + 'redis_options' => $redis_options, + 'email_options' => $email_options, + 'secret_key' => $secret_key, + 'admins' => $admins, + 'banner_top' => $banner_top, + 'banner_bottom' => $banner_bottom, + 'banner_login' => $banner_login, + 'base_path' => $base_path, + 'debug' => $debug, + 'enforce_global_unique' => $enforce_global_unique, + 'exempt_view_permissions' => $exempt_view_permissions, + 'login_required' => $login_required, + 'metrics_enabled' => $metrics_enabled, + 'prefer_ipv4' => $prefer_ipv4, + 'napalm_username' => $napalm_username, + 'napalm_password' => $napalm_password, + 'napalm_timeout' => $napalm_timeout, + 'time_zone' => $time_zone, + 'date_format' => $date_format, + 'short_date_format' => $short_date_format, + 'time_format' => $time_format, + 'short_time_format' => $short_time_format, + 'datetime_format' => $datetime_format, + 'short_datetime_format' => $short_datetime_format, + 'remote_auth_enabled' => $remote_auth_enabled, + 'remote_auth_backend' => $remote_auth_backend, + 'remote_auth_header' => $remote_auth_header, + 'remote_auth_first_name' => $remote_auth_first_name, + 'remote_auth_last_name' => $remote_auth_last_name, + 'remote_auth_user_email' => $remote_auth_user_email, }), owner => $user, group => $group, @@ -234,6 +290,30 @@ notify => Exec['collect static files'], } + if $remote_auth_enabled { + + $ldap_config_file = "${software_directory}/netbox/netbox/ldap_config.py" + + file { $ldap_config_file: + content => epp('netbox/ldap_config.py.epp', { + 'ldap_sever_uri' => $ldap_sever_uri, + 'ad_ou' => $ad_ou, + 'ad_bind_dn' => $ad_bind_dn, + 'ad_require_dn' => $ad_require_dn, + 'ad_admin_dn' => $ad_admin_dn, + 'ad_superuser_dn' => $ad_superuser_dn, + 'ldap_bind_password' => $ldap_bind_password, + 'ldap_ignore_cert_errors' => $ldap_ignore_cert_errors, + 'ldap_mirror_groups' => $ldap_mirror_groups, + }), + owner => $user, + group => $group, + mode => '0644', + validate_cmd => "${venv_dir}/bin/python -m py_compile %", + notify => Exec['collect static files'], + } + } + Exec { cwd => $software_directory, path => [ "${venv_dir}/bin", '/usr/bin', '/usr/sbin' ], diff --git a/manifests/database.pp b/manifests/database.pp index 4725b51..a20089c 100644 --- a/manifests/database.pp +++ b/manifests/database.pp @@ -28,16 +28,12 @@ String $database_locale, ){ - class { 'postgresql::globals': - encoding => $database_encoding, - locale => $database_locale, - } - ->class { 'postgresql::server': - } - +include postgresql::server postgresql::server::db { $database_name: user => $database_user, - password => postgresql_password($database_name, $database_password), + password => postgresql::postgresql_password($database_name, $database_password), + encoding => $database_encoding, + locale => $database_locale, } postgresql::server::database_grant { 'user_ALL_on_database': diff --git a/manifests/init.pp b/manifests/init.pp index 633c5c7..48d7977 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -226,9 +226,9 @@ # class netbox ( String $secret_key, - String $version = '2.10.1', - String $download_url = 'https://github.com/netbox-community/netbox/archive/v2.10.1.tar.gz', - String $download_checksum = 'b827c520e4c82842e426a5f9ad2d914d1728a3671e304d5f25eb06392c24866c', + String $version = '4.3.4', + String $download_url = 'https://github.com/netbox-community/netbox/archive/v4.3.4.tar.gz', + String $download_checksum = 'c96c6708ecdba84f1b8952151dd5760ae4ddc51c7770ea9734218b21038a230c', Stdlib::Absolutepath $download_tmp_dir = '/var/tmp', String $user = 'netbox', String $group = 'netbox', @@ -236,6 +236,17 @@ Stdlib::Absolutepath $install_root = '/opt', Boolean $handle_database = true, Boolean $handle_redis = true, + Boolean $handle_python = true, + String $redis_host = 'localhost', + Integer $redis_port = 6379, + String $redis_password = '', + Integer $redis_database = 0, + String $redis_ssl = 'False', + String $redis_cache_host = 'localhost', + Integer $redis_cache_port = 6379, + String $redis_cache_password = '', + Integer $redis_cache_database = 1, + String $redis_cache_ssl = 'False', Boolean $install_dependencies_from_filesystem = false, Stdlib::Absolutepath $python_dependency_path = '/srv/python_dependencies', Boolean $include_napalm = true, @@ -270,6 +281,8 @@ String $email_username = '', String $email_password = '', String $email_from_email = '', + Boolean $email_ssl = false, + Boolean $email_tls = false, String $time_zone = 'UTC', String $date_format = 'N j, Y', String $short_date_format = 'Y-m-d', @@ -277,10 +290,35 @@ String $short_time_format = 'H:i:s', String $datetime_format = 'N j, Y g:i a', String $short_datetime_format = 'Y-m-d H:i', + Boolean $allow_api_token_retrieval = false, + Boolean $remote_auth_enabled = false, + String $remote_auth_backend = '', + String $remote_auth_header = '', + String $remote_auth_first_name = '', + String $remote_auth_last_name = '', + String $remote_auth_user_email = '', + String $ldap_sever_uri = '', + String $ad_ou = '', + String $ad_bind_dn = '', + String $ad_require_dn = '', + String $ad_admin_dn = '', + String $ad_superuser_dn = '', + String $ldap_bind_password = '', + Boolean $ldap_ignore_cert_errors = false, + Boolean $ldap_mirror_groups = true, ) { Class['netbox::install'] -> Class['netbox::config'] ~> Class['netbox::service'] + if $handle_python { + class { 'python': + version => '3', + pip => 'present', + dev => 'present', + venv => 'present', + } + } + if $handle_database { class { 'netbox::database': database_name => $database_name, @@ -316,24 +354,25 @@ include_ldap => $include_ldap, install_dependencies_from_filesystem => $install_dependencies_from_filesystem, python_dependency_path => $python_dependency_path, + } $redis_options = { 'tasks' => { - host => 'localhost', - port => 6379, - password => '', - database => 0, + host => $redis_host, + port => $redis_port, + password => $redis_password, + database => $redis_database, default_timeout => 300, - ssl => 'False', + ssl => $redis_ssl, }, 'caching' => { - host => 'localhost', - port => 6379, - password => '', - database => 1, + host => $redis_cache_host, + port => $redis_cache_port, + password => $redis_cache_password, + database => $redis_cache_database, default_timeout => 300, - ssl => 'False', + ssl => $redis_cache_ssl, }, } @@ -344,43 +383,61 @@ password => $email_password, timeout => $email_timeout, from_email => $email_from_email, + ssl => $email_ssl, + tls => $email_tls, } class { 'netbox::config': - user => $user, - group => $group, - install_root => $install_root, - allowed_hosts => $allowed_hosts, - database_name => $database_name, - database_user => $database_user, - database_password => $database_password, - database_host => $database_host, - database_port => $database_port, - database_conn_max_age => $database_conn_max_age, - redis_options => $redis_options, - email_options => $email_options, - secret_key => $secret_key, - admins => $admins, - banner_top => $banner_top, - banner_bottom => $banner_bottom, - banner_login => $banner_login, - base_path => $base_path, - debug => $debug, - enforce_global_unique => $enforce_global_unique, - login_required => $login_required, - metrics_enabled => $metrics_enabled, - prefer_ipv4 => $prefer_ipv4, - exempt_view_permissions => $exempt_view_permissions, - napalm_username => $napalm_username, - napalm_password => $napalm_password, - napalm_timeout => $napalm_timeout, - time_zone => $time_zone, - date_format => $date_format, - short_date_format => $short_date_format, - time_format => $time_format, - short_time_format => $short_time_format, - datetime_format => $datetime_format, - short_datetime_format => $short_datetime_format, + user => $user, + group => $group, + install_root => $install_root, + allowed_hosts => $allowed_hosts, + database_name => $database_name, + database_user => $database_user, + database_password => $database_password, + database_host => $database_host, + database_port => $database_port, + database_conn_max_age => $database_conn_max_age, + redis_options => $redis_options, + email_options => $email_options, + secret_key => $secret_key, + admins => $admins, + banner_top => $banner_top, + banner_bottom => $banner_bottom, + banner_login => $banner_login, + base_path => $base_path, + debug => $debug, + enforce_global_unique => $enforce_global_unique, + login_required => $login_required, + metrics_enabled => $metrics_enabled, + prefer_ipv4 => $prefer_ipv4, + exempt_view_permissions => $exempt_view_permissions, + napalm_username => $napalm_username, + napalm_password => $napalm_password, + napalm_timeout => $napalm_timeout, + time_zone => $time_zone, + date_format => $date_format, + short_date_format => $short_date_format, + time_format => $time_format, + short_time_format => $short_time_format, + datetime_format => $datetime_format, + short_datetime_format => $short_datetime_format, + allow_api_token_retrieval => $allow_api_token_retrieval, + remote_auth_enabled => $remote_auth_enabled, + remote_auth_backend => $remote_auth_backend, + remote_auth_header => $remote_auth_header, + remote_auth_first_name => $remote_auth_first_name, + remote_auth_last_name => $remote_auth_last_name, + remote_auth_user_email => $remote_auth_user_email, + ldap_sever_uri => $ldap_sever_uri, + ad_ou => $ad_ou, + ad_bind_dn => $ad_bind_dn, + ad_require_dn => $ad_require_dn, + ad_admin_dn => $ad_admin_dn, + ad_superuser_dn => $ad_superuser_dn, + ldap_bind_password => $ldap_bind_password, + ldap_ignore_cert_errors => $ldap_ignore_cert_errors, + ldap_mirror_groups => $ldap_mirror_groups, } class {'netbox::service': diff --git a/manifests/install.pp b/manifests/install.pp index 5ed143e..e9fa1e1 100644 --- a/manifests/install.pp +++ b/manifests/install.pp @@ -79,24 +79,46 @@ Enum['tarball', 'git_clone'] $install_method = 'tarball', ) { - $packages =[ - gcc, - python36, - python36-devel, - libxml2-devel, - libxslt-devel, - libffi-devel, - openssl-devel, - redhat-rpm-config - ] + case $facts['os']['family'] { + 'Redhat': { + $packages = [ + gcc, + libxml2-devel, + libxslt-devel, + libffi-devel, + openssl-devel, + redhat-rpm-config + ] + $ldap_packages = [ + openldap-devel + ] + } + /^(Debian|Ubuntu)$/:{ + $packages = [ + build-essential, + libxml2-dev, + libxslt1-dev, + libffi-dev, + libpq-dev, + libssl-dev, + zlib1g-dev + ] + $ldap_packages = [ + libldap2-dev, + libsasl2-dev, + libssl-dev + ] + } + default: { + fail('Unknown OS family.') + } + } $local_tarball = "${download_tmp_dir}/netbox-${version}.tar.gz" $software_directory_with_version = "${install_root}/netbox-${version}" $software_directory = "${install_root}/netbox" $venv_dir = "${software_directory}/venv" - $ldap_packages = [openldap-devel] - ensure_packages($packages) if $include_ldap { @@ -113,14 +135,6 @@ system => true, } - if $install_dependencies_from_filesystem { - $install_requirements_command = "${venv_dir}/bin/pip3 install -r requirements.txt --no-index --find-links ${python_dependency_path}" - $install_local_requirements_command = "${venv_dir}/bin/pip3 install -r local_requirements.txt --no-index --find-links ${python_dependency_path}" - } else { - $install_requirements_command = "${venv_dir}/bin/pip3 install -r requirements.txt" - $install_local_requirements_command = "${venv_dir}/bin/pip3 install -r local_requirements.txt" - } - archive { $local_tarball: source => $download_url, checksum => $download_checksum, @@ -129,7 +143,6 @@ extract_path => $install_root, creates => $software_directory_with_version, cleanup => true, - notify => Exec['install python requirements'], } exec { 'netbox permission': @@ -154,7 +167,6 @@ file_line { 'napalm': path => "${software_directory}/local_requirements.txt", line => 'napalm', - notify => Exec['install local python requirements'], require => File['local_requirements'] } } @@ -163,7 +175,6 @@ file_line { 'django_storages': path => "${software_directory}/local_requirements.txt", line => 'django-storages', - notify => Exec['install local python requirements'], require => File['local_requirements'] } } @@ -172,36 +183,43 @@ file_line { 'ldap': path => "${software_directory}/local_requirements.txt", line => 'django-auth-ldap', - notify => Exec['install local python requirements'], require => File['local_requirements'] } } - exec { "python_venv_${venv_dir}": - command => "/usr/bin/python3 -m venv ${venv_dir}", - user => $user, - creates => "${venv_dir}/bin/activate", - cwd => '/tmp', - unless => "/usr/bin/grep '^[\\t ]*VIRTUAL_ENV=[\\\\'\\\"]*${venv_dir}[\\\"\\\\'][\\t ]*$' ${venv_dir}/bin/activate", - } - ~>exec { 'install python requirements': - cwd => $software_directory, - path => [ "${venv_dir}/bin", '/usr/bin', '/usr/sbin' ], - environment => ["VIRTUAL_ENV=${venv_dir}"], - provider => shell, - user => $user, - command => $install_requirements_command, - onlyif => "/usr/bin/grep '^[\\t ]*VIRTUAL_ENV=[\\\\'\\\"]*${venv_dir}[\\\"\\\\'][\\t ]*$' ${venv_dir}/bin/activate", - refreshonly => true, + python::pyvenv { 'netbox_venv': + ensure => present, + owner => $user, + group => $group, + systempkgs => false, + venv_dir => $venv_dir, } - ~>exec { 'install local python requirements': - cwd => $software_directory, - path => [ "${venv_dir}/bin", '/usr/bin', '/usr/sbin' ], - environment => ["VIRTUAL_ENV=${venv_dir}"], - provider => shell, - user => $user, - command => $install_local_requirements_command, - onlyif => "/usr/bin/grep '^[\\t ]*VIRTUAL_ENV=[\\\\'\\\"]*${venv_dir}[\\\"\\\\'][\\t ]*$' ${venv_dir}/bin/activate", - refreshonly => true, + +if $install_dependencies_from_filesystem { + python::requirements { "${install_root}/netbox/requirements.txt" : + virtualenv => $venv_dir, + owner => $user, + group => $group, + extra_pip_args => ['--no-index','--find-links', $python_dependency_path], + } + + python::requirements { "${install_root}/netbox/local_requirements.txt" : + virtualenv => $venv_dir, + owner => $user, + group => $group, + extra_pip_args => ['--no-index','--find-links', $python_dependency_path], + } + } else { + python::requirements { "${install_root}/netbox/requirements.txt" : + virtualenv => $venv_dir, + owner => $user, + group => $group, + } + + python::requirements { "${install_root}/netbox/local_requirements.txt" : + virtualenv => $venv_dir, + owner => $user, + group => $group, + } } } diff --git a/metadata.json b/metadata.json index ef39965..2c9514a 100644 --- a/metadata.json +++ b/metadata.json @@ -11,6 +11,10 @@ { "name": "puppetlabs-stdlib", "version_requirement": ">= 1.0.0" + }, + { + "name": "puppet-python", + "version_requirement": ">= 2.0.0" } ], "operatingsystem_support": [ @@ -25,6 +29,12 @@ "operatingsystemrelease": [ "8" ] + }, + { + "operatingsystem": "Ubuntu", + "operatingsystemrelease": [ + "22.04" + ] } ], "requirements": [ diff --git a/templates/configuration.py.epp b/templates/configuration.py.epp index dbf3c47..2babfe5 100644 --- a/templates/configuration.py.epp +++ b/templates/configuration.py.epp @@ -1,5 +1,6 @@ <% | Array[Stdlib::Host] $allowed_hosts, + Boolean $allow_api_token_retrieval, String $database_name, String $database_user, String $database_password, @@ -30,6 +31,12 @@ String $short_time_format, String $datetime_format, String $short_datetime_format, + Boolean $remote_auth_enabled, + String $remote_auth_backend, + String $remote_auth_header, + String $remote_auth_first_name, + String $remote_auth_last_name, + String $remote_auth_user_email, | -%> ######################### @@ -46,13 +53,16 @@ ALLOWED_HOSTS = ['<%=$allowed_hosts.join("\',\'")%>'] # 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': <%=$database_conn_max_age%>, # Max database connection age +DATABASES = { + 'default':{ + 'ENGINE': 'django.db.backends.postgresql', # Database engine + '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': <%=$database_conn_max_age%>, # Max database connection age + } } # Redis database settings. The Redis database is used for caching and background processing such as webhooks @@ -103,6 +113,20 @@ ADMINS = [ <%= $admins.map |$v| { String([$v['name'], $v['email']])}.join(",\n ") %> ] +# Permit the retrieval of API tokens after their creation. +ALLOW_TOKEN_RETRIEVAL = <%=if $allow_api_token_retrieval {'True'} else {'False'} %> + +# Enable any desired validators for local account passwords below. For a list of included validators, please see the +# Django documentation at https://docs.djangoproject.com/en/stable/topics/auth/passwords/#password-validation. +AUTH_PASSWORD_VALIDATORS = [ + # { + # 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + # 'OPTIONS': { + # 'min_length': 10, + # } + # }, +] + # 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_top %>' @@ -132,6 +156,9 @@ CORS_ORIGIN_REGEX_WHITELIST = [ # r'^(https?://)?(\w+\.)?example\.com$', ] +# The name to use for the CSRF token cookie. +CSRF_COOKIE_NAME = 'csrftoken' + # 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. @@ -141,6 +168,9 @@ DEBUG = True DEBUG = False <% } -%> +# Set the default preferred language/locale +DEFAULT_LANGUAGE = 'en-us' + # Email settings # https://netbox.readthedocs.io/en/stable/configuration/optional-settings/#email EMAIL = { @@ -148,6 +178,8 @@ EMAIL = { 'PORT': <%=$email_options['port']%>, 'USERNAME': '<%=$email_options['username']%>', 'PASSWORD': '<%=$email_options['password']%>', + 'USE_SSL': <%= if $email_options['ssl'] {'True'} else {'False'} %>, + 'USE_TLS': <%=if $email_options['tls'] {'True'} else {'False'} %>, 'TIMEOUT': <%=$email_options['timeout']%>, # seconds 'FROM_EMAIL': '<%=$email_options['from_email']%>', } @@ -166,10 +198,18 @@ EXEMPT_VIEW_PERMISSIONS = [ <%= $exempt_view_permissions.join(",\n ") %> ] +# 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 = {} +# Automatically reset the lifetime of a valid session upon each authenticated request. Enables users to remain +# authenticated to NetBox indefinitely. +LOGIN_PERSISTENCE = False + # 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. <% if $login_required { -%> @@ -182,6 +222,12 @@ LOGIN_REQUIRED = False # re-authenticate. (Default: 1209600 [14 days]) LOGIN_TIMEOUT = None +# Hide the login form. Useful when only allowing SSO authentication. +LOGIN_FORM_HIDDEN = False + +# The view name or URL to which users are redirected after logging out. +LOGOUT_REDIRECT_URL = 'home' + # Setting this to True will display a "maintenance mode" banner at the top of every page. MAINTENANCE_MODE = False @@ -225,6 +271,18 @@ 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. <% if $prefer_ipv4 { -%> @@ -233,6 +291,29 @@ PREFER_IPV4 = True PREFER_IPV4 = False <% } -%> +# Remote authentication support +REMOTE_AUTH_ENABLED = <%=if $remote_auth_enabled {'True'} else {'False'} %> +REMOTE_AUTH_BACKEND = '<%=$remote_auth_backend%>' +REMOTE_AUTH_HEADER = '<%=$remote_auth_header%>' +REMOTE_AUTH_USER_FIRST_NAME = '<%=$remote_auth_first_name%>' +REMOTE_AUTH_USER_LAST_NAME = '<%=$remote_auth_last_name%>' +REMOTE_AUTH_USER_EMAIL = '<%=$remote_auth_user_email%>' +REMOTE_AUTH_AUTO_CREATE_USER = True +REMOTE_AUTH_DEFAULT_GROUPS = [] +REMOTE_AUTH_DEFAULT_PERMISSIONS = {} + +# 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. +RELEASE_CHECK_URL = None +# RELEASE_CHECK_URL = 'https://api.github.com/repos/netbox-community/netbox/releases' + +# 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 = '/opt/netbox/netbox/reports' + +# Maximum execution time for background tasks, in seconds. +RQ_DEFAULT_TIMEOUT = 300 + # 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 = '/opt/netbox/netbox/reports' diff --git a/templates/ldap_config.py.epp b/templates/ldap_config.py.epp index 5726d0b..55edf40 100644 --- a/templates/ldap_config.py.epp +++ b/templates/ldap_config.py.epp @@ -1,10 +1,19 @@ <% | + String $ldap_sever_uri, + String $ad_ou, + String $ad_bind_dn, + String $ad_require_dn, + String $ad_admin_dn, + String $ad_superuser_dn, + String $ldap_bind_password, + Boolean $ldap_ignore_cert_errors, + Boolean $ldap_mirror_groups, | -%> import ldap -from django_auth_ldap.config import LDAPSearch, GroupOfNamesType +from django_auth_ldap.config import LDAPSearch, GroupOfNamesType, NestedActiveDirectoryGroupType # Server URI -AUTH_LDAP_SERVER_URI = "ldaps://ad.example.com" +AUTH_LDAP_SERVER_URI = '<%=$ldap_sever_uri%>' # The following may be needed if you are binding to Active Directory. AUTH_LDAP_CONNECTION_OPTIONS = { @@ -12,47 +21,53 @@ AUTH_LDAP_CONNECTION_OPTIONS = { } # Set the DN and password for the NetBox service account. -AUTH_LDAP_BIND_DN = "CN=NETBOXSA, OU=Service Accounts,DC=example,DC=com" -AUTH_LDAP_BIND_PASSWORD = "demo" +AUTH_LDAP_BIND_DN = "<%=$ad_bind_dn%>,<%=$ad_ou%>" +AUTH_LDAP_BIND_PASSWORD = "<%=$ldap_bind_password%>" # Include this setting if you want to ignore certificate errors. This might be needed to accept a self-signed cert. # Note that this is a NetBox-specific setting which sets: # ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER) -LDAP_IGNORE_CERT_ERRORS = True +LDAP_IGNORE_CERT_ERRORS = <%=if $ldap_ignore_cert_errors {'True'} else {'False'}%> # This search matches users with the sAMAccountName equal to the provided username. This is required if the user's # username is not in their DN (Active Directory). -AUTH_LDAP_USER_SEARCH = LDAPSearch("ou=Users,dc=example,dc=com", +AUTH_LDAP_USER_SEARCH = LDAPSearch("<%=$ad_ou%>", ldap.SCOPE_SUBTREE, - "(sAMAccountName=%(user)s)") + "(|(userPrincipalName=%(user)s)(sAMAccountName=%(user)s))") +AUTH_LDAP_USER_SEARCH_BASEDN = "<%=$ad_ou%>" +AUTH_LDAP_USER_SEARCH_ATTR = "sAMAccountName" +AUTH_LDAP_USER_SEARCH_FILTER = "(|(userPrincipalName=%(user)s)(sAMAccountName=%(user)s))" # If a user's DN is producible from their username, we don't need to search. -AUTH_LDAP_USER_DN_TEMPLATE = "uid=%(user)s,ou=users,dc=example,dc=com" +AUTH_LDAP_USER_DN_TEMPLATE = None # You can map user attributes to Django attributes as so. AUTH_LDAP_USER_ATTR_MAP = { + "username": "sAMAccountName", "first_name": "givenName", "last_name": "sn", "email": "mail" } +AUTH_LDAP_USER_QUERY_FIELD = "username" + # 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("dc=example,dc=com", ldap.SCOPE_SUBTREE, +AUTH_LDAP_GROUP_SEARCH = LDAPSearch("<%=$ad_ou%>", ldap.SCOPE_SUBTREE, "(objectClass=group)") -AUTH_LDAP_GROUP_TYPE = GroupOfNamesType() +AUTH_LDAP_GROUP_TYPE = NestedActiveDirectoryGroupType() # Define a group required to login. -AUTH_LDAP_REQUIRE_GROUP = "CN=NETBOX_USERS,DC=example,DC=com" +AUTH_LDAP_REQUIRE_GROUP = "<%=$ad_require_dn%>,<%=$ad_ou%>" # Mirror LDAP group assignments. -AUTH_LDAP_MIRROR_GROUPS = True +AUTH_LDAP_MIRROR_GROUPS = <%=if $ldap_mirror_groups {'True'} else {'False'}%> # Define special user types using groups. Exercise great caution when assigning superuser status. AUTH_LDAP_USER_FLAGS_BY_GROUP = { - "is_active": "cn=active,ou=groups,dc=example,dc=com", - "is_staff": "cn=staff,ou=groups,dc=example,dc=com", - "is_superuser": "cn=superuser,ou=groups,dc=example,dc=com" + "is_active": "<%=$ad_require_dn%>,<%=$ad_ou%>", + "is_staff": "<%=$ad_admin_dn%>,<%=$ad_ou%>", + "is_superuser": "<%=$ad_superuser_dn%>,<%=$ad_ou%>" } # For more granular permissions, we can map LDAP groups to Django groups.