Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AttributeError: module 'netbox_dns' has no attribute 'config' #104

Closed
andyfsimon opened this issue Dec 12, 2023 · 16 comments
Closed

AttributeError: module 'netbox_dns' has no attribute 'config' #104

andyfsimon opened this issue Dec 12, 2023 · 16 comments
Labels
faq FAQ

Comments

@andyfsimon
Copy link

andyfsimon commented Dec 12, 2023

Versions
NetBox Version: 3.6.4
NetBox DNS Version: 0.21.3 (latest)
Python Version: 3.9.18

Describe the bug
When I run the migrate script I get this error:

(venv) [root@netbox netbox]# ./manage.py migrate
Traceback (most recent call last):
  File "/opt/netbox-3.6.4/netbox/netbox/settings.py", line 749, in <module>
    plugin_config: PluginConfig = plugin.config
AttributeError: module 'netbox_dns' has no attribute 'config'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/opt/netbox-3.6.4/netbox/./manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/opt/netbox-3.6.4/venv/lib64/python3.9/site-packages/django/core/management/__init__.py", line 442, in execute_from_command_line
    utility.execute()
  File "/opt/netbox-3.6.4/venv/lib64/python3.9/site-packages/django/core/management/__init__.py", line 436, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/opt/netbox-3.6.4/venv/lib64/python3.9/site-packages/django/core/management/base.py", line 412, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/opt/netbox-3.6.4/venv/lib64/python3.9/site-packages/django/core/management/base.py", line 458, in execute
    output = self.handle(*args, **options)
  File "/opt/netbox-3.6.4/venv/lib64/python3.9/site-packages/django/core/management/base.py", line 103, in wrapper
    saved_locale = translation.get_language()
  File "/opt/netbox-3.6.4/venv/lib64/python3.9/site-packages/django/utils/translation/__init__.py", line 210, in get_language
    return _trans.get_language()
  File "/opt/netbox-3.6.4/venv/lib64/python3.9/site-packages/django/utils/translation/__init__.py", line 65, in __getattr__
    if settings.USE_I18N:
  File "/opt/netbox-3.6.4/venv/lib64/python3.9/site-packages/django/conf/__init__.py", line 102, in __getattr__
    self._setup(name)
  File "/opt/netbox-3.6.4/venv/lib64/python3.9/site-packages/django/conf/__init__.py", line 89, in _setup
    self._wrapped = Settings(settings_module)
  File "/opt/netbox-3.6.4/venv/lib64/python3.9/site-packages/django/conf/__init__.py", line 217, in __init__
    mod = importlib.import_module(self.SETTINGS_MODULE)
  File "/usr/lib64/python3.9/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 850, in exec_module
  File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
  File "/opt/netbox-3.6.4/netbox/netbox/settings.py", line 751, in <module>
    raise ImproperlyConfigured(
django.core.exceptions.ImproperlyConfigured: Plugin netbox_dns does not provide a 'config' variable. This should be defined in the plugin's __init__.py file and point to the PluginConfig subclass.

To Reproduce
Follow installation procedure.

Expected result
Expect it to work.

Actual result
Netbox doesn't load unless I remove the plugin from the list

@peteeckel
Copy link
Owner

peteeckel commented Dec 12, 2023

Hi @andyfsimon, I can't reproduce this.

I've seen similar errors however, most of them occurring when something is not correct about the permissions in the NetBox directory tree. Could you please check and, to be on the safe side, fix permissions for all files under /opt/netbox-3.6.4?

@andyfsimon
Copy link
Author

You were correct @peteeckel ! I indeed had some folders not owned by user "netbox".
Changing ownership wasn't sufficient though, I also had to uninstall the plugin and reinstall it.

Once I did that, migration worked.

Thank you for your responsiveness! And for the excellent job too!

@peteeckel
Copy link
Owner

peteeckel commented Dec 12, 2023

You're welcome! Glad that it worked.

@MalteKiefer
Copy link

I apologize for posting to this issue again.
I have the same error and my permissions are correct.
However, I have netbox 3.7.0, could that be the problem.
I have implemented these folder permissions:

sudo chown --recursive netbox /opt/netbox/netbox/media/
sudo chown --recursive netbox /opt/netbox/netbox/reports/
sudo chown --recursive netbox /opt/netbox/netbox/scripts/

@peteeckel
Copy link
Owner

Hi @MalteKiefer, no need to apoligise!

NetBox 3.7.0 is probably not the problem, I have some working installations (freshly installed ones and upgraded ones) with NetBox DNS.

Could you please post:

  • The exact error message from the startup log (e.g. journalctl -u netbox)
  • The contents of the configuration.py file (redacted for privacy, of course)
  • The output of pip freeze in your NetBox venv

I'm sure we will find out what's wrong.

@MalteKiefer
Copy link

Thanks for your help:

journalctl -u netbox

Dec 24 06:04:25 netbox-nms systemd[1]: Started NetBox WSGI Service.
Dec 24 06:04:25 netbox-nms gunicorn[195]: [2023-12-24 06:04:25 +0000] [195] [INFO] Starting gunicorn 21.2.0
Dec 24 06:04:25 netbox-nms gunicorn[195]: [2023-12-24 06:04:25 +0000] [195] [INFO] Listening at: http://127.0.0.1:8001 (195)
Dec 24 06:04:25 netbox-nms gunicorn[195]: [2023-12-24 06:04:25 +0000] [195] [INFO] Using worker: gthread
Dec 24 06:04:25 netbox-nms gunicorn[258]: [2023-12-24 06:04:25 +0000] [258] [INFO] Booting worker with pid: 258
Dec 24 06:04:25 netbox-nms gunicorn[267]: [2023-12-24 06:04:25 +0000] [267] [INFO] Booting worker with pid: 267
Dec 24 06:04:25 netbox-nms gunicorn[286]: [2023-12-24 06:04:25 +0000] [286] [INFO] Booting worker with pid: 286
Dec 24 06:04:25 netbox-nms gunicorn[297]: [2023-12-24 06:04:25 +0000] [297] [INFO] Booting worker with pid: 297
Dec 24 06:04:25 netbox-nms gunicorn[298]: [2023-12-24 06:04:25 +0000] [298] [INFO] Booting worker with pid: 298
Jan 03 10:05:30 netbox-nms systemd[1]: Stopping NetBox WSGI Service...
Jan 03 10:05:30 netbox-nms gunicorn[195]: [2024-01-03 10:05:30 +0000] [195] [INFO] Handling signal: term
Jan 03 10:05:31 netbox-nms gunicorn[286]: [2024-01-03 10:05:31 +0000] [286] [INFO] Worker exiting (pid: 286)
Jan 03 10:05:31 netbox-nms gunicorn[267]: [2024-01-03 10:05:31 +0000] [267] [INFO] Worker exiting (pid: 267)
Jan 03 10:05:31 netbox-nms gunicorn[297]: [2024-01-03 10:05:31 +0000] [297] [INFO] Worker exiting (pid: 297)
Jan 03 10:05:31 netbox-nms gunicorn[298]: [2024-01-03 10:05:31 +0000] [298] [INFO] Worker exiting (pid: 298)
Jan 03 10:05:31 netbox-nms gunicorn[258]: [2024-01-03 10:05:31 +0000] [258] [INFO] Worker exiting (pid: 258)
Jan 03 10:05:32 netbox-nms gunicorn[195]: [2024-01-03 10:05:32 +0000] [195] [INFO] Shutting down: Master
Jan 03 10:05:32 netbox-nms systemd[1]: netbox.service: Succeeded.
Jan 03 10:05:32 netbox-nms systemd[1]: Stopped NetBox WSGI Service.
Jan 03 10:05:32 netbox-nms systemd[1]: netbox.service: Consumed 19min 37.499s CPU time.
Jan 03 10:05:32 netbox-nms systemd[1]: Started NetBox WSGI Service.
Jan 03 10:05:32 netbox-nms gunicorn[281913]: [2024-01-03 10:05:32 +0000] [281913] [INFO] Starting gunicorn 21.2.0
Jan 03 10:05:32 netbox-nms gunicorn[281913]: [2024-01-03 10:05:32 +0000] [281913] [INFO] Listening at: http://127.0.0.1:8001 (281913)
Jan 03 10:05:32 netbox-nms gunicorn[281913]: [2024-01-03 10:05:32 +0000] [281913] [INFO] Using worker: gthread
Jan 03 10:05:32 netbox-nms gunicorn[281915]: [2024-01-03 10:05:32 +0000] [281915] [INFO] Booting worker with pid: 281915
Jan 03 10:05:32 netbox-nms gunicorn[281916]: [2024-01-03 10:05:32 +0000] [281916] [INFO] Booting worker with pid: 281916
Jan 03 10:05:32 netbox-nms gunicorn[281917]: [2024-01-03 10:05:32 +0000] [281917] [INFO] Booting worker with pid: 281917
Jan 03 10:05:32 netbox-nms gunicorn[281918]: [2024-01-03 10:05:32 +0000] [281918] [INFO] Booting worker with pid: 281918
Jan 03 10:05:32 netbox-nms gunicorn[281919]: [2024-01-03 10:05:32 +0000] [281919] [INFO] Booting worker with pid: 281919
Jan 03 10:08:06 netbox-nms systemd[1]: Stopping NetBox WSGI Service...
Jan 03 10:08:06 netbox-nms gunicorn[281913]: [2024-01-03 10:08:06 +0000] [281913] [INFO] Handling signal: term
Jan 03 10:08:07 netbox-nms gunicorn[281918]: [2024-01-03 10:08:07 +0000] [281918] [INFO] Worker exiting (pid: 281918)
Jan 03 10:08:07 netbox-nms gunicorn[281917]: [2024-01-03 10:08:07 +0000] [281917] [INFO] Worker exiting (pid: 281917)
Jan 03 10:08:07 netbox-nms gunicorn[281916]: [2024-01-03 10:08:07 +0000] [281916] [INFO] Worker exiting (pid: 281916)
Jan 03 10:08:07 netbox-nms gunicorn[281915]: [2024-01-03 10:08:07 +0000] [281915] [INFO] Worker exiting (pid: 281915)
Jan 03 10:08:07 netbox-nms gunicorn[281919]: [2024-01-03 10:08:07 +0000] [281919] [INFO] Worker exiting (pid: 281919)
Jan 03 10:08:08 netbox-nms gunicorn[281913]: [2024-01-03 10:08:08 +0000] [281913] [INFO] Shutting down: Master
Jan 03 10:08:08 netbox-nms systemd[1]: netbox.service: Succeeded.
Jan 03 10:08:08 netbox-nms systemd[1]: Stopped NetBox WSGI Service.
Jan 03 10:08:08 netbox-nms systemd[1]: netbox.service: Consumed 13.412s CPU time.
Jan 03 10:08:08 netbox-nms systemd[1]: Started NetBox WSGI Service.
Jan 03 10:08:08 netbox-nms gunicorn[282039]: [2024-01-03 10:08:08 +0000] [282039] [INFO] Starting gunicorn 21.2.0
Jan 03 10:08:08 netbox-nms gunicorn[282039]: [2024-01-03 10:08:08 +0000] [282039] [INFO] Listening at: http://127.0.0.1:8001 (282039)
Jan 03 10:08:08 netbox-nms gunicorn[282039]: [2024-01-03 10:08:08 +0000] [282039] [INFO] Using worker: gthread
Jan 03 10:08:08 netbox-nms gunicorn[282041]: [2024-01-03 10:08:08 +0000] [282041] [INFO] Booting worker with pid: 282041
Jan 03 10:08:08 netbox-nms gunicorn[282042]: [2024-01-03 10:08:08 +0000] [282042] [INFO] Booting worker with pid: 282042
Jan 03 10:08:09 netbox-nms gunicorn[282044]: [2024-01-03 10:08:09 +0000] [282044] [INFO] Booting worker with pid: 282044
Jan 03 10:08:09 netbox-nms gunicorn[282045]: [2024-01-03 10:08:09 +0000] [282045] [INFO] Booting worker with pid: 282045
Jan 03 10:08:09 netbox-nms gunicorn[282046]: [2024-01-03 10:08:09 +0000] [282046] [INFO] Booting worker with pid: 282046
Jan 03 10:12:33 netbox-nms systemd[1]: Stopping NetBox WSGI Service...
Jan 03 10:12:33 netbox-nms gunicorn[282039]: [2024-01-03 10:12:33 +0000] [282039] [INFO] Handling signal: term
Jan 03 10:12:33 netbox-nms gunicorn[282041]: [2024-01-03 10:12:33 +0000] [282041] [INFO] Worker exiting (pid: 282041)
Jan 03 10:12:33 netbox-nms gunicorn[282042]: [2024-01-03 10:12:33 +0000] [282042] [INFO] Worker exiting (pid: 282042)
Jan 03 10:12:34 netbox-nms gunicorn[282045]: [2024-01-03 10:12:34 +0000] [282045] [INFO] Worker exiting (pid: 282045)
Jan 03 10:12:34 netbox-nms gunicorn[282044]: [2024-01-03 10:12:34 +0000] [282044] [INFO] Worker exiting (pid: 282044)
Jan 03 10:12:34 netbox-nms gunicorn[282046]: [2024-01-03 10:12:34 +0000] [282046] [INFO] Worker exiting (pid: 282046)
Jan 03 10:12:34 netbox-nms gunicorn[282039]: [2024-01-03 10:12:34 +0000] [282039] [INFO] Shutting down: Master
Jan 03 10:12:34 netbox-nms systemd[1]: netbox.service: Succeeded.
Jan 03 10:12:34 netbox-nms systemd[1]: Stopped NetBox WSGI Service.
Jan 03 10:12:34 netbox-nms systemd[1]: netbox.service: Consumed 9.872s CPU time.
Jan 03 10:12:34 netbox-nms systemd[1]: Started NetBox WSGI Service.
Jan 03 10:12:35 netbox-nms gunicorn[282265]: [2024-01-03 10:12:35 +0000] [282265] [INFO] Starting gunicorn 21.2.0
Jan 03 10:12:35 netbox-nms gunicorn[282265]: [2024-01-03 10:12:35 +0000] [282265] [INFO] Listening at: http://127.0.0.1:8001 (282265)
Jan 03 10:12:35 netbox-nms gunicorn[282265]: [2024-01-03 10:12:35 +0000] [282265] [INFO] Using worker: gthread
Jan 03 10:12:35 netbox-nms gunicorn[282270]: [2024-01-03 10:12:35 +0000] [282270] [INFO] Booting worker with pid: 282270
Jan 03 10:12:35 netbox-nms gunicorn[282271]: [2024-01-03 10:12:35 +0000] [282271] [INFO] Booting worker with pid: 282271
Jan 03 10:12:35 netbox-nms gunicorn[282272]: [2024-01-03 10:12:35 +0000] [282272] [INFO] Booting worker with pid: 282272
Jan 03 10:12:35 netbox-nms gunicorn[282273]: [2024-01-03 10:12:35 +0000] [282273] [INFO] Booting worker with pid: 282273
Jan 03 10:12:35 netbox-nms gunicorn[282274]: [2024-01-03 10:12:35 +0000] [282274] [INFO] Booting worker with pid: 282274

configuration.py

#########################
#                       #
#   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 = ['XXX', '10.11.20.29', '*']
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 = {
    'ENGINE': 'django.db.backends.postgresql',  # Database engine
    'NAME': 'netbox',         # Database name
    'USER': 'netbox',               # PostgreSQL username
    'PASSWORD': 'XXX',           # PostgreSQL password
    'HOST': 'localhost',      # Database server
    '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': 'localhost',
        'PORT': 6379,
        # Comment out `HOST` and `PORT` lines and uncomment the following if using Redis Sentinel
        # 'SENTINELS': [('mysentinel.redis.example.com', 6379)],
        # 'SENTINEL_SERVICE': 'netbox',
        'USERNAME': '',
        'PASSWORD': '',
        'DATABASE': 0,
        'SSL': False,
        # Set this to True to skip TLS certificate verification
        # This can expose the connection to attacks, be careful
        # 'INSECURE_SKIP_TLS_VERIFY': False,
        # Set a path to a certificate authority, typically used with a self signed certificate.
        # 'CA_CERT_PATH': '/etc/ssl/certs/ca.crt',
    },
    'caching': {
        'HOST': 'localhost',
        'PORT': 6379,
        # Comment out `HOST` and `PORT` lines and uncomment the following if using Redis Sentinel
        # 'SENTINELS': [('mysentinel.redis.example.com', 6379)],
        # 'SENTINEL_SERVICE': 'netbox',
        'USERNAME': '',
        'PASSWORD': '',
        'DATABASE': 1,
        'SSL': False,
        # Set this to True to skip TLS certificate verification
        # This can expose the connection to attacks, be careful
        # 'INSECURE_SKIP_TLS_VERIFY': False,
        # Set a path to a certificate authority, typically used with a self signed certificate.
        # 'CA_CERT_PATH': '/etc/ssl/certs/ca.crt',
    }
}

# 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 = 'XXX'


#########################
#                       #
#   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'),
]

# Permit the retrieval of API tokens after their creation.
ALLOW_TOKEN_RETRIEVAL = 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,
    #     }
    # },
]

# Base URL path if accessing NetBox within a directory. For example, if installed at https://example.com/netbox/, set:
# BASE_PATH = 'netbox/'
BASE_PATH = ''

# 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$',
]

# 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.
DEBUG = False

# Set the default preferred language/locale
DEFAULT_LANGUAGE = 'en-us'

# Email settings
EMAIL = {
    'SERVER': 'localhost',
    'PORT': 25,
    'USERNAME': '',
    'PASSWORD': '',
    'USE_SSL': False,
    'USE_TLS': False,
    'TIMEOUT': 10,  # seconds
    'FROM_EMAIL': '',
}

# Localization
ENABLE_LOCALIZATION = 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',
]

# HTTP proxies NetBox should use when sending outbound HTTP requests (e.g. for webhooks).
# HTTP_PROXIES = {
#     'http': 'http://10.10.1.10:3128',
#     'https': 'http://10.10.1.10:1080',
# }

# 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 but not make any changes.
LOGIN_REQUIRED = False

# 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

# The view name or URL to which users are redirected after logging out.
LOGOUT_REDIRECT_URL = 'home'

# 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 = '/opt/netbox/netbox/media'

# Expose Prometheus monitoring metrics at the HTTP endpoint '/metrics'
METRICS_ENABLED = False

# Enable installed plugins. Add the name of each plugin to the list.
PLUGINS = [
    "netbox_dns",
]

# 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'
#     }
# }

# Remote authentication support
REMOTE_AUTH_ENABLED = False
REMOTE_AUTH_BACKEND = 'netbox.authentication.RemoteUserBackend'
REMOTE_AUTH_HEADER = 'HTTP_REMOTE_USER'
REMOTE_AUTH_USER_FIRST_NAME = 'HTTP_REMOTE_USER_FIRST_NAME'
REMOTE_AUTH_USER_LAST_NAME = 'HTTP_REMOTE_USER_LAST_NAME'
REMOTE_AUTH_USER_EMAIL = 'HTTP_REMOTE_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 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 = '/opt/netbox/netbox/scripts'

# The name to use for the session cookie.
SESSION_COOKIE_NAME = 'sessionid'

# 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

# 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',
# }

# Time zone (default: UTC)
TIME_ZONE = 'Europe/Berlin'

# 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'

pip freeze

aniso8601==9.0.1
asgiref==3.7.2
astunparse==1.6.3
async-timeout==4.0.3
attrs==23.2.0
Babel==2.14.0
backports.zoneinfo==0.2.1
bleach==6.1.0
certifi==2023.11.17
cffi==1.16.0
charset-normalizer==3.3.2
click==8.1.7
colorama==0.4.6
cryptography==41.0.7
defusedxml==0.8.0rc2
Django==4.2.8
django-auth-ldap==4.6.0
django-cors-headers==4.3.1
django-debug-toolbar==4.2.0
django-filter==23.5
django-graphiql-debug-toolbar==0.2.0
django-js-asset==2.2.0
django-mptt==0.14.0
django-pglocks==1.0.4
django-prometheus==2.3.1
django-redis==5.4.0
django-rich==1.8.0
django-rq==2.10.1
django-tables2==2.7.0
django-taggit==5.0.1
django-timezone-field==6.1.0
djangorestframework==3.14.0
dnspython==2.4.2
drf-spectacular==0.27.0
drf-spectacular-sidecar==2023.12.1
feedparser==6.0.11
ghp-import==2.1.0
graphene==3.3
graphene-django==3.0.0
graphql-core==3.2.3
graphql-relay==3.2.0
gunicorn==21.2.0
idna==3.6
importlib-metadata==7.0.1
importlib-resources==6.1.1
inflection==0.5.1
Jinja2==3.1.2
jsonschema==4.20.0
jsonschema-specifications==2023.12.1
Markdown==3.5.1
markdown-it-py==3.0.0
MarkupSafe==2.1.3
mdurl==0.1.2
mergedeep==1.3.4
mkdocs==1.5.3
mkdocs-autorefs==0.5.0
mkdocs-material==9.5.3
mkdocs-material-extensions==1.3.1
mkdocstrings==0.24.0
mkdocstrings-python-legacy==0.2.3
netaddr==0.9.0
netbox-plugin-dns==0.21.11
oauthlib==3.2.2
packaging==23.2
paginate==0.5.6
pathspec==0.12.1
Pillow==10.1.0
pkg_resources==0.0.0
pkgutil_resolve_name==1.3.10
platformdirs==4.1.0
prometheus-client==0.19.0
promise==2.3
psycopg==3.1.16
psycopg-binary==3.1.16
psycopg-pool==3.2.0
pyasn1==0.5.1
pyasn1-modules==0.3.0
pycparser==2.21
Pygments==2.17.2
PyJWT==2.8.0
pymdown-extensions==10.7
python-dateutil==2.8.2
python-ldap==3.4.4
python3-openid==3.2.0
pytkdocs==0.16.1
pytz==2023.3.post1
PyYAML==6.0.1
pyyaml_env_tag==0.1
redis==5.0.1
referencing==0.32.0
regex==2023.12.25
requests==2.31.0
requests-oauthlib==1.3.1
rich==13.7.0
rpds-py==0.16.2
rq==1.15.1
sgmllib3k==1.0.0
six==1.16.0
social-auth-app-django==5.4.0
social-auth-core==4.5.1
sqlparse==0.4.4
svgwrite==1.4.3
tablib==3.5.0
text-unidecode==1.3
typing_extensions==4.9.0
tzdata==2023.3
uritemplate==4.1.1
urllib3==2.1.0
watchdog==3.0.0
webencodings==0.5.1
zipp==3.17.0

@peteeckel
Copy link
Owner

Thanks, that all looks OK.

Do you get exactly the same error as the OP when you run manage.py migrate?

And do you run manage.py from within the venv (just asking to make sure we're not looking in the wrong place)?

@MalteKiefer
Copy link

Yes, take a look:

(venv) root@netbox-nms:/opt/netbox/netbox# ./manage.py migrate
Traceback (most recent call last):
  File "/opt/netbox-3.7.0/netbox/netbox/settings.py", line 759, in <module>
    plugin_config: PluginConfig = plugin.config
AttributeError: module 'netbox_dns' has no attribute 'config'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "./manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/opt/netbox-3.7.0/venv/lib/python3.8/site-packages/django/core/management/__init__.py", line 442, in execute_from_command_line
    utility.execute()
  File "/opt/netbox-3.7.0/venv/lib/python3.8/site-packages/django/core/management/__init__.py", line 436, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/opt/netbox-3.7.0/venv/lib/python3.8/site-packages/django/core/management/base.py", line 412, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/opt/netbox-3.7.0/venv/lib/python3.8/site-packages/django/core/management/base.py", line 458, in execute
    output = self.handle(*args, **options)
  File "/opt/netbox-3.7.0/venv/lib/python3.8/site-packages/django/core/management/base.py", line 103, in wrapper
    saved_locale = translation.get_language()
  File "/opt/netbox-3.7.0/venv/lib/python3.8/site-packages/django/utils/translation/__init__.py", line 210, in get_language
    return _trans.get_language()
  File "/opt/netbox-3.7.0/venv/lib/python3.8/site-packages/django/utils/translation/__init__.py", line 65, in __getattr__
    if settings.USE_I18N:
  File "/opt/netbox-3.7.0/venv/lib/python3.8/site-packages/django/conf/__init__.py", line 102, in __getattr__
    self._setup(name)
  File "/opt/netbox-3.7.0/venv/lib/python3.8/site-packages/django/conf/__init__.py", line 89, in _setup
    self._wrapped = Settings(settings_module)
  File "/opt/netbox-3.7.0/venv/lib/python3.8/site-packages/django/conf/__init__.py", line 217, in __init__
    mod = importlib.import_module(self.SETTINGS_MODULE)
  File "/usr/lib/python3.8/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 848, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/opt/netbox-3.7.0/netbox/netbox/settings.py", line 761, in <module>
    raise ImproperlyConfigured(
django.core.exceptions.ImproperlyConfigured: Plugin netbox_dns does not provide a 'config' variable. This should be defined in the plugin's __init__.py file and point to the PluginConfig subclass.
(venv) root@netbox-nms:/opt/netbox/netbox# 

@peteeckel
Copy link
Owner

peteeckel commented Jan 3, 2024

If all of that looks good we're going to run some tests ... I'm still fairly sure that it is a permission issue. Let's try to fix the permissions and not only the ownership first - there could be an unexpected umask messing things up:

[root@dns ~]# chmod -R u=rwX,g=rX,o=rX /opt/netbox/

(note the uppercase Xes!)

Then try the migration again:

[root@dns ~]# sudo -su netbox 
[netbox@dns root]$ . /opt/netbox/venv/bin/activate
(netbox) [netbox@dns root]$ /opt/netbox/netbox/manage.py migrate 
Operations to perform:
  Apply all migrations: account, admin, auth, circuits, contenttypes, core, dcim, django_rq, extras, ipam, netbox_dns, sessions, social_django, taggit, tenancy, users, virtualization, vpn, wireless
Running migrations:
  No migrations to apply.

If that works, you're fine (and we know what went wrong). If it doesn't, we need to find out why.

(netbox) [netbox@dns root]$ /opt/netbox/netbox/manage.py nbshell
### NetBox interactive shell (dns.example.com)
### Python 3.11.5 | Django 4.2.8 | NetBox 3.7.0
### lsmodels() will show available models. Use help(<model>) for more info.
>>> from netbox_dns import config
>>> config.version
'0.21.12'

And again I would like to see the system output if anything looks differently from the above.

@peteeckel
Copy link
Owner

Yes, take a look:

...

You were quicker than me :-)

The pip output and config all look well, so Django should be able to import anything from netbox_dns it wants. The error message in the migration, however, says it can't. What we need to figure out is why.

@MalteKiefer
Copy link

(venv) netbox@netbox-nms:/opt/netbox-3.7.0/netbox$ /opt/netbox/netbox/manage.py nbshell
Traceback (most recent call last):
  File "/opt/netbox-3.7.0/venv/lib/python3.8/site-packages/django/core/management/__init__.py", line 255, in fetch_command
    app_name = commands[subcommand]
KeyError: 'nbshell'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/opt/netbox-3.7.0/netbox/netbox/settings.py", line 759, in <module>
    plugin_config: PluginConfig = plugin.config
AttributeError: module 'netbox_dns' has no attribute 'config'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/opt/netbox/netbox/manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/opt/netbox-3.7.0/venv/lib/python3.8/site-packages/django/core/management/__init__.py", line 442, in execute_from_command_line
    utility.execute()
  File "/opt/netbox-3.7.0/venv/lib/python3.8/site-packages/django/core/management/__init__.py", line 436, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/opt/netbox-3.7.0/venv/lib/python3.8/site-packages/django/core/management/__init__.py", line 262, in fetch_command
    settings.INSTALLED_APPS
  File "/opt/netbox-3.7.0/venv/lib/python3.8/site-packages/django/conf/__init__.py", line 102, in __getattr__
    self._setup(name)
  File "/opt/netbox-3.7.0/venv/lib/python3.8/site-packages/django/conf/__init__.py", line 89, in _setup
    self._wrapped = Settings(settings_module)
  File "/opt/netbox-3.7.0/venv/lib/python3.8/site-packages/django/conf/__init__.py", line 217, in __init__
    mod = importlib.import_module(self.SETTINGS_MODULE)
  File "/usr/lib/python3.8/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 848, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/opt/netbox-3.7.0/netbox/netbox/settings.py", line 761, in <module>
    raise ImproperlyConfigured(
django.core.exceptions.ImproperlyConfigured: Plugi

@peteeckel
Copy link
Owner

peteeckel commented Jan 3, 2024

Did you change the permissions before trying that?

Let's try something else.

  1. Disable the netbox_dns plugin in configuration.py.
  2. Now run the following code (as the NetBox user):
(netbox) [netbox@dns netbox]$ PYTHONPATH=/opt/netbox/netbox python3
Python 3.11.5 (main, Sep  7 2023, 00:00:00) [GCC 11.4.1 20230605 (Red Hat 11.4.1-2)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from netbox_dns import config 
>>> config.version
'0.21.12'

Does that work?

@peteeckel
Copy link
Owner

peteeckel commented Jan 3, 2024

If it does, next we try to do that from the nbshell (netbox_dns still disabled):

(netbox) [netbox@dns netbox]$ /opt/netbox/netbox/manage.py nbshell 
### NetBox interactive shell (dns.example.com)
### Python 3.11.5 | Django 4.2.8 | NetBox 3.7.0
### lsmodels() will show available models. Use help(<model>) for more info.
>>> from netbox_dns import config 
>>> config.version
'0.21.12'

@MalteKiefer
Copy link

(venv) netbox@netbox-nms:/opt/netbox-3.7.0$ PYTHONPATH=/opt/netbox/netbox python3
Python 3.8.10 (default, Nov 22 2023, 10:22:35) 
[GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from netbox_dns import config
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: cannot import name 'config' from 'netbox_dns' (unknown location)
>>> 

But maybe I have an idea.
I have installed the old netbox_dns plugin before.
But I removed it because it didn't work.
Maybe that is the problem-

@peteeckel
Copy link
Owner

peteeckel commented Jan 3, 2024

That could very well be ... how did you remove it? pip uninstall, I assume, since the pip freeze looks good.

I'll try to find out if that's the root cause and how it can be remedied. If you find something, please update this ticket.

I'm so sorry that this still happens, I already wrote a discussion article and opened an issue in the old repo, but it still gets installed by too many people and I can't do anything about it :-/

@peteeckel
Copy link
Owner

peteeckel commented Jan 3, 2024

I got it - I can reproduce the problem.

  • install netbox-dns
  • realise that it doesn't work anymore :-(
  • install netbox-plugin-dns
  • realise that you now have two plugins installed
  • uninstall netbox-dns

Bingo:

(netbox) [root@dns netbox]# /opt/netbox/netbox/manage.py migrate 
Traceback (most recent call last):
  File "/opt/netbox/netbox/netbox/settings.py", line 759, in <module>
    plugin_config: PluginConfig = plugin.config
                                  ^^^^^^^^^^^^^
AttributeError: module 'netbox_dns' has no attribute 'config'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/opt/netbox/netbox/manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/opt/netbox/lib64/python3.11/site-packages/django/core/management/__init__.py", line 442, in execute_from_command_line
    utility.execute()
  File "/opt/netbox/lib64/python3.11/site-packages/django/core/management/__init__.py", line 436, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/opt/netbox/lib64/python3.11/site-packages/django/core/management/base.py", line 412, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/opt/netbox/lib64/python3.11/site-packages/django/core/management/base.py", line 458, in execute
    output = self.handle(*args, **options)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/lib64/python3.11/site-packages/django/core/management/base.py", line 103, in wrapper
    saved_locale = translation.get_language()
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/lib64/python3.11/site-packages/django/utils/translation/__init__.py", line 210, in get_language
    return _trans.get_language()
           ^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/lib64/python3.11/site-packages/django/utils/translation/__init__.py", line 65, in __getattr__
    if settings.USE_I18N:
       ^^^^^^^^^^^^^^^^^
  File "/opt/netbox/lib64/python3.11/site-packages/django/conf/__init__.py", line 102, in __getattr__
    self._setup(name)
  File "/opt/netbox/lib64/python3.11/site-packages/django/conf/__init__.py", line 89, in _setup
    self._wrapped = Settings(settings_module)
                    ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/lib64/python3.11/site-packages/django/conf/__init__.py", line 217, in __init__
    mod = importlib.import_module(self.SETTINGS_MODULE)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.11/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen importlib._bootstrap>", line 1204, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 940, in exec_module
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "/opt/netbox/netbox/netbox/settings.py", line 761, in <module>
    raise ImproperlyConfigured(
django.core.exceptions.ImproperlyConfigured: Plugin netbox_dns does not provide a 'config' variable. This should be defined in the plugin's __init__.py file and point to the PluginConfig subclass.

The reason is that uninstalling netbox-dns also uninstalls parts of netbox-plugin-dns, which leaves it in a pretty useless state. The remedy is simple: First uninstall netbox-dns, then install netbox-plugin-dns.

Or in your case, as the brown mass has already hit the fan:

(netbox) [root@dns netbox]# pip install --force-reinstall netbox-plugin-dns
Collecting netbox-plugin-dns
  Using cached netbox_plugin_dns-0.21.12-py3-none-any.whl.metadata (3.9 kB)
Collecting dnspython<3.0.0,>=2.2.1 (from netbox-plugin-dns)
  Using cached dnspython-2.4.2-py3-none-any.whl.metadata (4.9 kB)
Using cached netbox_plugin_dns-0.21.12-py3-none-any.whl (83 kB)
Using cached dnspython-2.4.2-py3-none-any.whl (300 kB)
Installing collected packages: dnspython, netbox-plugin-dns
  Attempting uninstall: dnspython
    Found existing installation: dnspython 2.4.2
    Uninstalling dnspython-2.4.2:
      Successfully uninstalled dnspython-2.4.2
  Attempting uninstall: netbox-plugin-dns
    Found existing installation: netbox-plugin-dns 0.21.12
    Uninstalling netbox-plugin-dns-0.21.12:
      Successfully uninstalled netbox-plugin-dns-0.21.12
Successfully installed dnspython-2.4.2 netbox-plugin-dns-0.21.12

(netbox) [root@dns netbox]# /opt/netbox/netbox/manage.py migrate 
Operations to perform:
  Apply all migrations: account, admin, auth, circuits, contenttypes, core, dcim, django_rq, extras, ipam, netbox_dns, sessions, social_django, taggit, tenancy, users, virtualization, vpn, wireless
Running migrations:
  No migrations to apply.

A big thank you to you for re-raising this, as this time I got so unnerved that I really wanted to get to the core of it.

@peteeckel peteeckel added the faq FAQ label Jan 3, 2024
@peteeckel peteeckel pinned this issue Jan 3, 2024
@peteeckel peteeckel changed the title module 'netbox_dns' has no attribute 'config' AttributeError: module 'netbox_dns' has no attribute 'config' Jan 3, 2024
@peteeckel peteeckel unpinned this issue May 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
faq FAQ
Projects
None yet
Development

No branches or pull requests

3 participants