API call to create new prefix fails #3423

Closed
opened 2025-12-29 18:28:59 +01:00 by adam · 3 comments
Owner

Originally created by @ross-alexander on GitHub (Feb 27, 2020).

Environment

  • Python version: 3.6.8
  • NetBox version: 2.7.8

Steps to Reproduce

  1. Using shell script wrapper to call curl to create new prefix using POST to /api/ipam/prefixes/ with data '{"prefix":"10.147.8.0/22", "status":"container"}'
KEY="REDACTED"
BASE="http://agp-sog-p-nbox1.agp.local:8001/api"

curl --resolve agp-sog-p-nbox1.agp.local:8001:127.0.0.1 -v -H "Authorization: Token $KEY" -H "Accept: application/json" -X POST --data '{"prefix":"10.147.8.0/22", "status":"container"}' $BASE/ipam/prefixes/
  1. Run script with output from curl
* Added agp-sog-p-nbox1.agp.local:8001:127.0.0.1 to DNS cache
* Hostname agp-sog-p-nbox1.agp.local was found in DNS cache
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to agp-sog-p-nbox1.agp.local (127.0.0.1) port 8001 (#0)
> POST /api/ipam/prefixes/ HTTP/1.1
> Host: agp-sog-p-nbox1.agp.local:8001
> User-Agent: curl/7.61.1
> Authorization: Token dd05f773146fcedcf1083afdc524793f07a28460
> Accept: application/json
> Content-Length: 48
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 48 out of 48 bytes
< HTTP/1.1 400 Bad Request
< Server: gunicorn/20.0.4
< Date: Thu, 27 Feb 2020 11:52:45 GMT
< Connection: keep-alive
< Content-Type: application/json
< Vary: Accept, Cookie, Origin
< Allow: GET, POST, HEAD, OPTIONS
< API-Version: 2.7
< X-Frame-Options: SAMEORIGIN
< Content-Length: 38
<
* Connection #0 to host agp-sog-p-nbox1.agp.local left intact
{"prefix":["This field is required."]}

Expected Behavior

Create new prefix (from the API documentation only the field "prefix" is required.

Observed Behavior

{"prefix":["This field is required."]}

I have a separate 2.7.8 with python 3.8.1 I get the following debug.

+ curl --resolve exile.hepazulian.net:8001:127.0.0.1 -v -H 'Authorization: Token ceda9bc3a5d14bf8df32f4eb6a94a96d7b38753a' -H 'Accept: application/json' -X POST --data @post.js http://exile.hepazulian.net:8001/api/ipam/prefixes/
Note: Unnecessary use of -X or --request, POST is already inferred.
* Added exile.hepazulian.net:8001:127.0.0.1 to DNS cache
* Hostname exile.hepazulian.net was found in DNS cache
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to exile.hepazulian.net (127.0.0.1) port 8001 (#0)
> POST /api/ipam/prefixes/ HTTP/1.1
> Host: exile.hepazulian.net:8001
> User-Agent: curl/7.63.0
> Authorization: Token ceda9bc3a5d14bf8df32f4eb6a94a96d7b38753a
> Accept: application/json
> Content-Length: 57
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 57 out of 57 bytes
< HTTP/1.1 500 Internal Server Error
< Server: gunicorn/20.0.4
< Date: Thu, 27 Feb 2020 12:43:57 GMT
< Connection: keep-alive
< Content-Type: text/plain; charset=utf-8
< API-Version: 2.7
< X-Frame-Options: SAMEORIGIN
< Content-Length: 20663
< Vary: Cookie, Origin
<
AttributeError at /api/ipam/prefixes/
This QueryDict instance is immutable

Request Method: POST
Request URL: http://exile.hepazulian.net:8001/api/ipam/prefixes/
Django Version: 2.2.10
Python Executable: /usr/bin/python3
Python Version: 3.8.1
Python Path: ['/opt/netbox/netbox', '/opt/netbox-2.7.8', '/usr/bin', '/usr/lib/python38.zip', '/usr/lib/python3.8', '/usr/lib/python3.8/lib-dynload', '/usr/lib/python3.8/site-packages', '/usr/lib/python3.8/site-packages/http_parser-0.8.3-py3.8-linux-x86_64.egg']
Server time: Thu, 27 Feb 2020 12:43:57 +0000
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'django.contrib.humanize',
 'cacheops',
 'corsheaders',
 'debug_toolbar',
 'django_filters',
 'django_rq',
 'django_tables2',
 'django_prometheus',
 'mptt',
 'rest_framework',
 'taggit',
 'taggit_serializer',
 'timezone_field',
 'circuits',
 'dcim',
 'ipam',
 'extras',
 'secrets',
 'tenancy',
 'users',
 'utilities',
 'virtualization',
 'drf_yasg']
Installed Middleware:
('debug_toolbar.middleware.DebugToolbarMiddleware',
 'django_prometheus.middleware.PrometheusBeforeMiddleware',
 'corsheaders.middleware.CorsMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware',
 'django.middleware.security.SecurityMiddleware',
 'utilities.middleware.ExceptionHandlingMiddleware',
 'utilities.middleware.LoginRequiredMiddleware',
 'utilities.middleware.APIVersionMiddleware',
 'extras.middleware.ObjectChangeMiddleware',
 'django_prometheus.middleware.PrometheusAfterMiddleware')


Traceback:

File "/usr/lib/python3.8/site-packages/django/core/handlers/exception.py" in inner
  34.             response = get_response(request)

File "/usr/lib/python3.8/site-packages/django/core/handlers/base.py" in _get_response
  115.                 response = self.process_exception_by_middleware(e, request)

File "/usr/lib/python3.8/site-packages/django/core/handlers/base.py" in _get_response
  113.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/usr/lib/python3.8/site-packages/django/views/decorators/csrf.py" in wrapped_view
  54.         return view_func(*args, **kwargs)

File "/usr/lib/python3.8/site-packages/rest_framework/viewsets.py" in view
  114.             return self.dispatch(request, *args, **kwargs)

File "/opt/netbox/netbox/utilities/api.py" in dispatch
  321.             return super().dispatch(request, *args, **kwargs)

File "/usr/lib/python3.8/site-packages/rest_framework/views.py" in dispatch
  505.             response = self.handle_exception(exc)

File "/usr/lib/python3.8/site-packages/rest_framework/views.py" in handle_exception
  465.             self.raise_uncaught_exception(exc)

File "/usr/lib/python3.8/site-packages/rest_framework/views.py" in raise_uncaught_exception
  476.         raise exc

File "/usr/lib/python3.8/site-packages/rest_framework/views.py" in dispatch
  502.             response = handler(request, *args, **kwargs)

File "/usr/lib/python3.8/site-packages/rest_framework/mixins.py" in create
  17.         serializer = self.get_serializer(data=request.data)

File "/opt/netbox/netbox/utilities/api.py" in get_serializer
  303.         return super().get_serializer(*args, **kwargs)

File "/usr/lib/python3.8/site-packages/rest_framework/generics.py" in get_serializer
  110.         return serializer_class(*args, **kwargs)

File "/opt/netbox/netbox/extras/api/customfields.py" in __init__
  132.                 self.initial_data['custom_fields'] = {}

File "/usr/lib/python3.8/site-packages/django/http/request.py" in __setitem__
  459.         self._assert_mutable()

File "/usr/lib/python3.8/site-packages/django/http/request.py" in _assert_mutable
  456.             raise AttributeError("This QueryDict instance is immutable")

Exception Type: AttributeError at /api/ipam/prefixes/
Exception Value: This QueryDict instance is immutable
Request information:
USER: admin

GET: No GET data

POST:
{   "prefix" : "10.147.8.0/22",   "status" : "container"} = ''

FILES: No FILES data

COOKIES: No cookie data

META:
CONTENT_LENGTH = '57'
CONTENT_TYPE = 'application/x-www-form-urlencoded'
HTTP_ACCEPT = 'application/json'
HTTP_AUTHORIZATION = 'Token ceda9bc3a5d14bf8df32f4eb6a94a96d7b38753a'
HTTP_HOST = 'exile.hepazulian.net:8001'
HTTP_USER_AGENT = 'curl/7.63.0'
PATH_INFO = '/api/ipam/prefixes/'
QUERY_STRING = ''
RAW_URI = '/api/ipam/prefixes/'
REMOTE_ADDR = '127.0.0.1'
REMOTE_PORT = '43564'
REQUEST_METHOD = 'POST'
SCRIPT_NAME = ''
SERVER_NAME = '127.0.0.1'
SERVER_PORT = '8001'
SERVER_PROTOCOL = 'HTTP/1.1'
SERVER_SOFTWARE = 'gunicorn/20.0.4'
gunicorn.socket = <socket.socket fd=11, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8001), raddr=('127.0.0.1', 43564)>
wsgi.errors = <gunicorn.http.wsgi.WSGIErrorsWrapper object at 0x7f2225ced0a0>
wsgi.file_wrapper = ''
wsgi.input = <gunicorn.http.body.Body object at 0x7f22261f2700>
wsgi.input_terminated = True
wsgi.multiprocess = True
wsgi.multithread = True
wsgi.run_once = False
wsgi.url_scheme = 'http'
wsgi.version = '(1, 0)'

Settings:
Using settings module netbox.settings
ABSOLUTE_URL_OVERRIDES = {}
ADMINS = []
ALLOWED_HOSTS = ['mojo.hepazulian.net', 'wormhole.hepazulian.net', 'exile.hepazulian.net']
APPEND_SLASH = True
AUTHENTICATION_BACKENDS = ['utilities.auth_backends.ViewExemptModelBackend']
AUTH_PASSWORD_VALIDATORS = '********************'
AUTH_USER_MODEL = 'auth.User'
BANNER_BOTTOM = ''
BANNER_LOGIN = ''
BANNER_TOP = ''
BASE_DIR = '/opt/netbox/netbox'
BASE_PATH = ''
CACHEOPS = {'auth.user': {'ops': 'get', 'timeout': 900}, 'auth.*': {'ops': ('fetch', 'get')}, 'auth.permission': {'ops': 'all'}, 'circuits.*': {'ops': 'all'}, 'dcim.*': {'ops': 'all'}, 'ipam.*': {'ops': 'all'}, 'extras.*': {'ops': 'all'}, 'secrets.*': '********************', 'users.*': {'ops': 'all'}, 'tenancy.*': {'ops': 'all'}, 'virtualization.*': {'ops': 'all'}}
CACHEOPS_DEFAULTS = {'timeout': 900}
CACHEOPS_DEGRADE_ON_FAILURE = True
CACHEOPS_ENABLED = True
CACHEOPS_REDIS = 'redis://localhost:6379/0'
CACHES = {'default': {'BACKEND': 'django.core.cache.backends.locmem.LocMemCache'}}
CACHE_MIDDLEWARE_ALIAS = 'default'
CACHE_MIDDLEWARE_KEY_PREFIX = '********************'
CACHE_MIDDLEWARE_SECONDS = 600
CACHE_TIMEOUT = 900
CACHING_REDIS = {'HOST': 'localhost', 'PORT': 6379, 'PASSWORD': '********************', 'DATABASE': 0, 'DEFAULT_TIMEOUT': 300, 'SSL': False}
CACHING_REDIS_DATABASE = 0
CACHING_REDIS_DEFAULT_TIMEOUT = 300
CACHING_REDIS_HOST = 'localhost'
CACHING_REDIS_PASSWORD = '********************'
CACHING_REDIS_PORT = 6379
CACHING_REDIS_SENTINELS = []
CACHING_REDIS_SENTINEL_SERVICE = 'default'
CACHING_REDIS_SSL = False
CACHING_REDIS_USING_SENTINEL = False
CHANGELOG_RETENTION = 90
CORS_ORIGIN_ALLOW_ALL = False
CORS_ORIGIN_REGEX_WHITELIST = []
CORS_ORIGIN_WHITELIST = []
CSRF_COOKIE_AGE = 31449600
CSRF_COOKIE_DOMAIN = None
CSRF_COOKIE_HTTPONLY = False
CSRF_COOKIE_NAME = 'csrftoken'
CSRF_COOKIE_PATH = '/'
CSRF_COOKIE_SAMESITE = 'Lax'
CSRF_COOKIE_SECURE = False
CSRF_FAILURE_VIEW = 'django.views.csrf.csrf_failure'
CSRF_HEADER_NAME = 'HTTP_X_CSRFTOKEN'
CSRF_TRUSTED_ORIGINS = ['mojo.hepazulian.net', 'wormhole.hepazulian.net', 'exile.hepazulian.net']
CSRF_USE_SESSIONS = False
DATABASE = {'NAME': 'netbox', 'USER': 'netbox', 'PASSWORD': '********************', 'HOST': 'localhost', 'PORT': '', 'ENGINE': 'django.db.backends.postgresql', 'ATOMIC_REQUESTS': False, 'AUTOCOMMIT': True, 'CONN_MAX_AGE': 0, 'OPTIONS': {}, 'TIME_ZONE': None, 'TEST': {'CHARSET': None, 'COLLATION': None, 'NAME': None, 'MIRROR': None}}
DATABASES = {'default': {'NAME': 'netbox', 'USER': 'netbox', 'PASSWORD': '********************', 'HOST': 'localhost', 'PORT': '', 'ENGINE': 'django.db.backends.postgresql', 'ATOMIC_REQUESTS': False, 'AUTOCOMMIT': True, 'CONN_MAX_AGE': 0, 'OPTIONS': {}, 'TIME_ZONE': None, 'TEST': {'CHARSET': None, 'COLLATION': None, 'NAME': None, 'MIRROR': None}}}
DATABASE_ROUTERS = []
DATA_UPLOAD_MAX_MEMORY_SIZE = 2621440
DATA_UPLOAD_MAX_NUMBER_FIELDS = None
DATETIME_FORMAT = 'N j, Y g:i a'
DATETIME_INPUT_FORMATS = ['%Y-%m-%d %H:%M:%S', '%Y-%m-%d %H:%M:%S.%f', '%Y-%m-%d %H:%M', '%Y-%m-%d', '%m/%d/%Y %H:%M:%S', '%m/%d/%Y %H:%M:%S.%f', '%m/%d/%Y %H:%M', '%m/%d/%Y', '%m/%d/%y %H:%M:%S', '%m/%d/%y %H:%M:%S.%f', '%m/%d/%y %H:%M', '%m/%d/%y']
DATE_FORMAT = 'N j, Y'
DATE_INPUT_FORMATS = ['%Y-%m-%d', '%m/%d/%Y', '%m/%d/%y', '%b %d %Y', '%b %d, %Y', '%d %b %Y', '%d %b, %Y', '%B %d %Y', '%B %d, %Y', '%d %B %Y', '%d %B, %Y']
DEBUG = True
DEBUG_PROPAGATE_EXCEPTIONS = False
DECIMAL_SEPARATOR = '.'
DEFAULT_CHARSET = 'utf-8'
DEFAULT_CONTENT_TYPE = 'text/html'
DEFAULT_EXCEPTION_REPORTER_FILTER = 'django.views.debug.SafeExceptionReporterFilter'
DEFAULT_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage'
DEFAULT_FROM_EMAIL = 'webmaster@localhost'
DEFAULT_INDEX_TABLESPACE = ''
DEFAULT_TABLESPACE = ''
DEVELOPER = False
DISALLOWED_USER_AGENTS = []
EMAIL = {'SERVER': 'localhost', 'PORT': 25, 'USERNAME': '', 'PASSWORD': '********************', 'TIMEOUT': 10, 'FROM_EMAIL': ''}
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'localhost'
EMAIL_HOST_PASSWORD = '********************'
EMAIL_HOST_USER = ''
EMAIL_PORT = 25
EMAIL_SSL_CERTFILE = None
EMAIL_SSL_KEYFILE = '********************'
EMAIL_SUBJECT_PREFIX = '[NetBox] '
EMAIL_TIMEOUT = 10
EMAIL_USE_LOCALTIME = False
EMAIL_USE_SSL = False
EMAIL_USE_TLS = False
ENFORCE_GLOBAL_UNIQUE = False
EXEMPT_VIEW_PERMISSIONS = []
FILE_CHARSET = 'utf-8'
FILE_UPLOAD_DIRECTORY_PERMISSIONS = None
FILE_UPLOAD_HANDLERS = ['django.core.files.uploadhandler.MemoryFileUploadHandler', 'django.core.files.uploadhandler.TemporaryFileUploadHandler']
FILE_UPLOAD_MAX_MEMORY_SIZE = 2621440
FILE_UPLOAD_PERMISSIONS = None
FILE_UPLOAD_TEMP_DIR = None
FILTERS_NULL_CHOICE_LABEL = 'None'
FILTERS_NULL_CHOICE_VALUE = 'null'
FIRST_DAY_OF_WEEK = 0
FIXTURE_DIRS = []
FORCE_SCRIPT_NAME = None
FORMAT_MODULE_PATH = None
FORM_RENDERER = 'django.forms.renderers.DjangoTemplates'
HOSTNAME = 'mojo.hepazulian.net'
IGNORABLE_404_URLS = []
INSTALLED_APPS = ['django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'django.contrib.humanize', 'cacheops', 'corsheaders', 'debug_toolbar', 'django_filters', 'django_rq', 'django_tables2', 'django_prometheus', 'mptt', 'rest_framework', 'taggit', 'taggit_serializer', 'timezone_field', 'circuits', 'dcim', 'ipam', 'extras', 'secrets', 'tenancy', 'users', 'utilities', 'virtualization', 'drf_yasg']
INTERNAL_IPS = "('127.0.0.1', '::1')"
LANGUAGES = [('af', 'Afrikaans'), ('ar', 'Arabic'), ('ast', 'Asturian'), ('az', 'Azerbaijani'), ('bg', 'Bulgarian'), ('be', 'Belarusian'), ('bn', 'Bengali'), ('br', 'Breton'), ('bs', 'Bosnian'), ('ca', 'Catalan'), ('cs', 'Czech'), ('cy', 'Welsh'), ('da', 'Danish'), ('de', 'German'), ('dsb', 'Lower Sorbian'), ('el', 'Greek'), ('en', 'English'), ('en-au', 'Australian English'), ('en-gb', 'British English'), ('eo', 'Esperanto'), ('es', 'Spanish'), ('es-ar', 'Argentinian Spanish'), ('es-co', 'Colombian Spanish'), ('es-mx', 'Mexican Spanish'), ('es-ni', 'Nicaraguan Spanish'), ('es-ve', 'Venezuelan Spanish'), ('et', 'Estonian'), ('eu', 'Basque'), ('fa', 'Persian'), ('fi', 'Finnish'), ('fr', 'French'), ('fy', 'Frisian'), ('ga', 'Irish'), ('gd', 'Scottish Gaelic'), ('gl', 'Galician'), ('he', 'Hebrew'), ('hi', 'Hindi'), ('hr', 'Croatian'), ('hsb', 'Upper Sorbian'), ('hu', 'Hungarian'), ('hy', 'Armenian'), ('ia', 'Interlingua'), ('id', 'Indonesian'), ('io', 'Ido'), ('is', 'Icelandic'), ('it', 'Italian'), ('ja', 'Japanese'), ('ka', 'Georgian'), ('kab', 'Kabyle'), ('kk', 'Kazakh'), ('km', 'Khmer'), ('kn', 'Kannada'), ('ko', 'Korean'), ('lb', 'Luxembourgish'), ('lt', 'Lithuanian'), ('lv', 'Latvian'), ('mk', 'Macedonian'), ('ml', 'Malayalam'), ('mn', 'Mongolian'), ('mr', 'Marathi'), ('my', 'Burmese'), ('nb', 'Norwegian Bokmål'), ('ne', 'Nepali'), ('nl', 'Dutch'), ('nn', 'Norwegian Nynorsk'), ('os', 'Ossetic'), ('pa', 'Punjabi'), ('pl', 'Polish'), ('pt', 'Portuguese'), ('pt-br', 'Brazilian Portuguese'), ('ro', 'Romanian'), ('ru', 'Russian'), ('sk', 'Slovak'), ('sl', 'Slovenian'), ('sq', 'Albanian'), ('sr', 'Serbian'), ('sr-latn', 'Serbian Latin'), ('sv', 'Swedish'), ('sw', 'Swahili'), ('ta', 'Tamil'), ('te', 'Telugu'), ('th', 'Thai'), ('tr', 'Turkish'), ('tt', 'Tatar'), ('udm', 'Udmurt'), ('uk', 'Ukrainian'), ('ur', 'Urdu'), ('vi', 'Vietnamese'), ('zh-hans', 'Simplified Chinese'), ('zh-hant', 'Traditional Chinese')]
LANGUAGES_BIDI = ['he', 'ar', 'fa', 'ur']
LANGUAGE_CODE = 'en-us'
LANGUAGE_COOKIE_AGE = None
LANGUAGE_COOKIE_DOMAIN = None
LANGUAGE_COOKIE_NAME = 'django_language'
LANGUAGE_COOKIE_PATH = '/'
LDAP_CONFIG = None
LOCALE_PATHS = []
LOGGING = {'version': 1, 'disable_existing_loggers': False, 'handlers': {'file': {'level': 'DEBUG', 'class': 'logging.FileHandler', 'filename': '/var/log/netbox.log'}}, 'loggers': {'django': {'handlers': ['file'], 'level': 'DEBUG'}}}
LOGGING_CONFIG = 'logging.config.dictConfig'
LOGIN_REDIRECT_URL = '/accounts/profile/'
LOGIN_REQUIRED = True
LOGIN_TIMEOUT = None
LOGIN_URL = '/login/'
LOGOUT_REDIRECT_URL = None
MAINTENANCE_MODE = False
MANAGERS = []
MAX_PAGE_SIZE = 1000
MEDIA_ROOT = '/opt/netbox/netbox/media'
MEDIA_URL = '/media/'
MESSAGE_STORAGE = 'django.contrib.messages.storage.fallback.FallbackStorage'
MESSAGE_TAGS = {40: 'danger'}
METRICS_ENABLED = False
MIDDLEWARE = "('debug_toolbar.middleware.DebugToolbarMiddleware', 'django_prometheus.middleware.PrometheusBeforeMiddleware', 'corsheaders.middleware.CorsMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.security.SecurityMiddleware', 'utilities.middleware.ExceptionHandlingMiddleware', 'utilities.middleware.LoginRequiredMiddleware', 'utilities.middleware.APIVersionMiddleware', 'extras.middleware.ObjectChangeMiddleware', 'django_prometheus.middleware.PrometheusAfterMiddleware')"
MIGRATION_MODULES = {}
MONTH_DAY_FORMAT = 'F j'
NAPALM_ARGS = {}
NAPALM_PASSWORD = '********************'
NAPALM_TIMEOUT = 30
NAPALM_USERNAME = ''
NUMBER_GROUPING = 0
PAGINATE_COUNT = 50
PASSWORD_HASHERS = '********************'
PASSWORD_RESET_TIMEOUT_DAYS = '********************'
PER_PAGE_DEFAULTS = [25, 50, 100, 250, 500, 1000]
PREFER_IPV4 = False
PREPEND_WWW = False
PROMETHEUS_EXPORT_MIGRATIONS = False
REDIS = {'webhooks': {'HOST': 'localhost', 'PORT': 6379, 'PASSWORD': '********************', 'DATABASE': 0, 'DEFAULT_TIMEOUT': 300, 'SSL': False}, 'caching': {'HOST': 'localhost', 'PORT': 6379, 'PASSWORD': '********************', 'DATABASE': 0, 'DEFAULT_TIMEOUT': 300, 'SSL': False}}
REDIS_CACHE_CON_STRING = 'redis://localhost:6379/0'
REPORTS_ROOT = '/opt/netbox/netbox/reports'
REST_FRAMEWORK = {'ALLOWED_VERSIONS': ['2.7'], 'DEFAULT_AUTHENTICATION_CLASSES': ('rest_framework.authentication.SessionAuthentication', 'netbox.api.TokenAuthentication'), 'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',), 'DEFAULT_PAGINATION_CLASS': 'netbox.api.OptionalLimitOffsetPagination', 'DEFAULT_PERMISSION_CLASSES': ('netbox.api.TokenPermissions',), 'DEFAULT_RENDERER_CLASSES': ('rest_framework.renderers.JSONRenderer', 'netbox.api.FormlessBrowsableAPIRenderer'), 'DEFAULT_VERSION': '2.7', 'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.AcceptHeaderVersioning', 'PAGE_SIZE': 50, 'VIEW_NAME_FUNCTION': 'netbox.api.get_view_name'}
REST_FRAMEWORK_VERSION = '2.7'
ROOT_URLCONF = 'netbox.urls'
RQ_QUEUES = {'default': {'HOST': 'localhost', 'PORT': 6379, 'DB': 0, 'PASSWORD': '********************', 'DEFAULT_TIMEOUT': 300, 'SSL': False}}
SCRIPTS_ROOT = '/opt/netbox/netbox/scripts'
SECRETS_MIN_PUBKEY_SIZE = '********************'
SECRET_KEY = '********************'
SECURE_BROWSER_XSS_FILTER = False
SECURE_CONTENT_TYPE_NOSNIFF = False
SECURE_HSTS_INCLUDE_SUBDOMAINS = False
SECURE_HSTS_PRELOAD = False
SECURE_HSTS_SECONDS = 0
SECURE_PROXY_SSL_HEADER = "('HTTP_X_FORWARDED_PROTO', 'https')"
SECURE_REDIRECT_EXEMPT = []
SECURE_SSL_HOST = None
SECURE_SSL_REDIRECT = False
SERVER_EMAIL = ''
SESSION_CACHE_ALIAS = 'default'
SESSION_COOKIE_AGE = 1209600
SESSION_COOKIE_DOMAIN = None
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_NAME = 'sessionid'
SESSION_COOKIE_PATH = '/'
SESSION_COOKIE_SAMESITE = 'Lax'
SESSION_COOKIE_SECURE = False
SESSION_ENGINE = 'django.contrib.sessions.backends.db'
SESSION_EXPIRE_AT_BROWSER_CLOSE = False
SESSION_FILE_PATH = None
SESSION_SAVE_EVERY_REQUEST = False
SESSION_SERIALIZER = 'django.contrib.sessions.serializers.JSONSerializer'
SETTINGS_MODULE = 'netbox.settings'
SHORT_DATETIME_FORMAT = 'Y-m-d H:i'
SHORT_DATE_FORMAT = 'Y-m-d'
SHORT_TIME_FORMAT = 'H:i:s'
SIGNING_BACKEND = 'django.core.signing.TimestampSigner'
SILENCED_SYSTEM_CHECKS = []
STATICFILES_DIRS = "('/opt/netbox/netbox/project-static',)"
STATICFILES_FINDERS = ['django.contrib.staticfiles.finders.FileSystemFinder', 'django.contrib.staticfiles.finders.AppDirectoriesFinder']
STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.StaticFilesStorage'
STATIC_ROOT = '/opt/netbox/netbox/static'
STATIC_URL = '/static/'
STORAGE_BACKEND = None
STORAGE_CONFIG = {}
SWAGGER_SETTINGS = {'DEFAULT_AUTO_SCHEMA_CLASS': 'utilities.custom_inspectors.NetBoxSwaggerAutoSchema', 'DEFAULT_FIELD_INSPECTORS': ['utilities.custom_inspectors.NullableBooleanFieldInspector', 'utilities.custom_inspectors.CustomChoiceFieldInspector', 'utilities.custom_inspectors.TagListFieldInspector', 'utilities.custom_inspectors.SerializedPKRelatedFieldInspector', 'drf_yasg.inspectors.CamelCaseJSONFilter', 'drf_yasg.inspectors.ReferencingSerializerInspector', 'drf_yasg.inspectors.RelatedFieldInspector', 'drf_yasg.inspectors.ChoiceFieldInspector', 'drf_yasg.inspectors.FileFieldInspector', 'drf_yasg.inspectors.DictFieldInspector', 'drf_yasg.inspectors.SerializerMethodFieldInspector', 'drf_yasg.inspectors.SimpleFieldInspector', 'drf_yasg.inspectors.StringDefaultFieldInspector'], 'DEFAULT_FILTER_INSPECTORS': ['utilities.custom_inspectors.IdInFilterInspector', 'drf_yasg.inspectors.CoreAPICompatInspector'], 'DEFAULT_INFO': 'netbox.urls.openapi_info', 'DEFAULT_MODEL_DEPTH': 1, 'DEFAULT_PAGINATOR_INSPECTORS': ['utilities.custom_inspectors.NullablePaginatorInspector', 'drf_yasg.inspectors.DjangoRestResponsePagination', 'drf_yasg.inspectors.CoreAPICompatInspector'], 'SECURITY_DEFINITIONS': {'Bearer': {'type': 'apiKey', 'name': 'Authorization', 'in': 'header'}}, 'VALIDATOR_URL': None}
TEMPLATES = [{'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': ['/opt/netbox/netbox/templates'], 'APP_DIRS': True, 'OPTIONS': {'context_processors': ['django.template.context_processors.debug', 'django.template.context_processors.request', 'django.template.context_processors.media', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', 'utilities.context_processors.settings']}}]
TEMPLATES_DIR = '/opt/netbox/netbox/templates'
TEST_NON_SERIALIZED_APPS = []
TEST_RUNNER = 'django.test.runner.DiscoverRunner'
THOUSAND_SEPARATOR = ','
TIME_FORMAT = 'g:i a'
TIME_INPUT_FORMATS = ['%H:%M:%S', '%H:%M:%S.%f', '%H:%M']
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = False
USE_THOUSAND_SEPARATOR = False
USE_TZ = True
USE_X_FORWARDED_HOST = True
USE_X_FORWARDED_PORT = False
VERSION = '2.7.8'
WEBHOOKS_REDIS = {'HOST': 'localhost', 'PORT': 6379, 'PASSWORD': '********************', 'DATABASE': 0, 'DEFAULT_TIMEOUT': 300, 'SSL': False}
WEBHOOKS_REDIS_DATABASE = 0
WEBHOOKS_REDIS_DEFAULT_TIMEOUT = 300
WEBHOOKS_REDIS_HOST = 'localhost'
WEBHOOKS_REDIS_PASSWORD = '********************'
WEBHOOKS_REDIS_PORT = 6379
WEBHOOKS_REDIS_SENTINELS = []
WEBHOOKS_REDIS_SENTINEL_SERVICE = 'default'
WEBHOOKS_REDIS_SSL = False
WEBHOOKS_REDIS_USING_SENTINEL = False
WSGI_APPLICATION = 'netbox.wsgi.application'
X_FRAME_OPTIONS = 'SAMEORIGIN'
YEAR_MONTH_FORMAT = 'F Y'
Originally created by @ross-alexander on GitHub (Feb 27, 2020). ### Environment * Python version: 3.6.8 * NetBox version: 2.7.8 ### Steps to Reproduce 1. Using shell script wrapper to call curl to create new prefix using POST to /api/ipam/prefixes/ with data '{"prefix":"10.147.8.0/22", "status":"container"}' ``` KEY="REDACTED" BASE="http://agp-sog-p-nbox1.agp.local:8001/api" curl --resolve agp-sog-p-nbox1.agp.local:8001:127.0.0.1 -v -H "Authorization: Token $KEY" -H "Accept: application/json" -X POST --data '{"prefix":"10.147.8.0/22", "status":"container"}' $BASE/ipam/prefixes/ ``` 2. Run script with output from curl ``` * Added agp-sog-p-nbox1.agp.local:8001:127.0.0.1 to DNS cache * Hostname agp-sog-p-nbox1.agp.local was found in DNS cache * Trying 127.0.0.1... * TCP_NODELAY set * Connected to agp-sog-p-nbox1.agp.local (127.0.0.1) port 8001 (#0) > POST /api/ipam/prefixes/ HTTP/1.1 > Host: agp-sog-p-nbox1.agp.local:8001 > User-Agent: curl/7.61.1 > Authorization: Token dd05f773146fcedcf1083afdc524793f07a28460 > Accept: application/json > Content-Length: 48 > Content-Type: application/x-www-form-urlencoded > * upload completely sent off: 48 out of 48 bytes < HTTP/1.1 400 Bad Request < Server: gunicorn/20.0.4 < Date: Thu, 27 Feb 2020 11:52:45 GMT < Connection: keep-alive < Content-Type: application/json < Vary: Accept, Cookie, Origin < Allow: GET, POST, HEAD, OPTIONS < API-Version: 2.7 < X-Frame-Options: SAMEORIGIN < Content-Length: 38 < * Connection #0 to host agp-sog-p-nbox1.agp.local left intact {"prefix":["This field is required."]} ``` <!-- What did you expect to happen? --> ### Expected Behavior Create new prefix (from the API documentation only the field "prefix" is required. <!-- What happened instead? --> ### Observed Behavior {"prefix":["This field is required."]} I have a separate 2.7.8 with python 3.8.1 I get the following debug. ``` + curl --resolve exile.hepazulian.net:8001:127.0.0.1 -v -H 'Authorization: Token ceda9bc3a5d14bf8df32f4eb6a94a96d7b38753a' -H 'Accept: application/json' -X POST --data @post.js http://exile.hepazulian.net:8001/api/ipam/prefixes/ Note: Unnecessary use of -X or --request, POST is already inferred. * Added exile.hepazulian.net:8001:127.0.0.1 to DNS cache * Hostname exile.hepazulian.net was found in DNS cache * Trying 127.0.0.1... * TCP_NODELAY set * Connected to exile.hepazulian.net (127.0.0.1) port 8001 (#0) > POST /api/ipam/prefixes/ HTTP/1.1 > Host: exile.hepazulian.net:8001 > User-Agent: curl/7.63.0 > Authorization: Token ceda9bc3a5d14bf8df32f4eb6a94a96d7b38753a > Accept: application/json > Content-Length: 57 > Content-Type: application/x-www-form-urlencoded > * upload completely sent off: 57 out of 57 bytes < HTTP/1.1 500 Internal Server Error < Server: gunicorn/20.0.4 < Date: Thu, 27 Feb 2020 12:43:57 GMT < Connection: keep-alive < Content-Type: text/plain; charset=utf-8 < API-Version: 2.7 < X-Frame-Options: SAMEORIGIN < Content-Length: 20663 < Vary: Cookie, Origin < AttributeError at /api/ipam/prefixes/ This QueryDict instance is immutable Request Method: POST Request URL: http://exile.hepazulian.net:8001/api/ipam/prefixes/ Django Version: 2.2.10 Python Executable: /usr/bin/python3 Python Version: 3.8.1 Python Path: ['/opt/netbox/netbox', '/opt/netbox-2.7.8', '/usr/bin', '/usr/lib/python38.zip', '/usr/lib/python3.8', '/usr/lib/python3.8/lib-dynload', '/usr/lib/python3.8/site-packages', '/usr/lib/python3.8/site-packages/http_parser-0.8.3-py3.8-linux-x86_64.egg'] Server time: Thu, 27 Feb 2020 12:43:57 +0000 Installed Applications: ['django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'django.contrib.humanize', 'cacheops', 'corsheaders', 'debug_toolbar', 'django_filters', 'django_rq', 'django_tables2', 'django_prometheus', 'mptt', 'rest_framework', 'taggit', 'taggit_serializer', 'timezone_field', 'circuits', 'dcim', 'ipam', 'extras', 'secrets', 'tenancy', 'users', 'utilities', 'virtualization', 'drf_yasg'] Installed Middleware: ('debug_toolbar.middleware.DebugToolbarMiddleware', 'django_prometheus.middleware.PrometheusBeforeMiddleware', 'corsheaders.middleware.CorsMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.security.SecurityMiddleware', 'utilities.middleware.ExceptionHandlingMiddleware', 'utilities.middleware.LoginRequiredMiddleware', 'utilities.middleware.APIVersionMiddleware', 'extras.middleware.ObjectChangeMiddleware', 'django_prometheus.middleware.PrometheusAfterMiddleware') Traceback: File "/usr/lib/python3.8/site-packages/django/core/handlers/exception.py" in inner 34. response = get_response(request) File "/usr/lib/python3.8/site-packages/django/core/handlers/base.py" in _get_response 115. response = self.process_exception_by_middleware(e, request) File "/usr/lib/python3.8/site-packages/django/core/handlers/base.py" in _get_response 113. response = wrapped_callback(request, *callback_args, **callback_kwargs) File "/usr/lib/python3.8/site-packages/django/views/decorators/csrf.py" in wrapped_view 54. return view_func(*args, **kwargs) File "/usr/lib/python3.8/site-packages/rest_framework/viewsets.py" in view 114. return self.dispatch(request, *args, **kwargs) File "/opt/netbox/netbox/utilities/api.py" in dispatch 321. return super().dispatch(request, *args, **kwargs) File "/usr/lib/python3.8/site-packages/rest_framework/views.py" in dispatch 505. response = self.handle_exception(exc) File "/usr/lib/python3.8/site-packages/rest_framework/views.py" in handle_exception 465. self.raise_uncaught_exception(exc) File "/usr/lib/python3.8/site-packages/rest_framework/views.py" in raise_uncaught_exception 476. raise exc File "/usr/lib/python3.8/site-packages/rest_framework/views.py" in dispatch 502. response = handler(request, *args, **kwargs) File "/usr/lib/python3.8/site-packages/rest_framework/mixins.py" in create 17. serializer = self.get_serializer(data=request.data) File "/opt/netbox/netbox/utilities/api.py" in get_serializer 303. return super().get_serializer(*args, **kwargs) File "/usr/lib/python3.8/site-packages/rest_framework/generics.py" in get_serializer 110. return serializer_class(*args, **kwargs) File "/opt/netbox/netbox/extras/api/customfields.py" in __init__ 132. self.initial_data['custom_fields'] = {} File "/usr/lib/python3.8/site-packages/django/http/request.py" in __setitem__ 459. self._assert_mutable() File "/usr/lib/python3.8/site-packages/django/http/request.py" in _assert_mutable 456. raise AttributeError("This QueryDict instance is immutable") Exception Type: AttributeError at /api/ipam/prefixes/ Exception Value: This QueryDict instance is immutable Request information: USER: admin GET: No GET data POST: { "prefix" : "10.147.8.0/22", "status" : "container"} = '' FILES: No FILES data COOKIES: No cookie data META: CONTENT_LENGTH = '57' CONTENT_TYPE = 'application/x-www-form-urlencoded' HTTP_ACCEPT = 'application/json' HTTP_AUTHORIZATION = 'Token ceda9bc3a5d14bf8df32f4eb6a94a96d7b38753a' HTTP_HOST = 'exile.hepazulian.net:8001' HTTP_USER_AGENT = 'curl/7.63.0' PATH_INFO = '/api/ipam/prefixes/' QUERY_STRING = '' RAW_URI = '/api/ipam/prefixes/' REMOTE_ADDR = '127.0.0.1' REMOTE_PORT = '43564' REQUEST_METHOD = 'POST' SCRIPT_NAME = '' SERVER_NAME = '127.0.0.1' SERVER_PORT = '8001' SERVER_PROTOCOL = 'HTTP/1.1' SERVER_SOFTWARE = 'gunicorn/20.0.4' gunicorn.socket = <socket.socket fd=11, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8001), raddr=('127.0.0.1', 43564)> wsgi.errors = <gunicorn.http.wsgi.WSGIErrorsWrapper object at 0x7f2225ced0a0> wsgi.file_wrapper = '' wsgi.input = <gunicorn.http.body.Body object at 0x7f22261f2700> wsgi.input_terminated = True wsgi.multiprocess = True wsgi.multithread = True wsgi.run_once = False wsgi.url_scheme = 'http' wsgi.version = '(1, 0)' Settings: Using settings module netbox.settings ABSOLUTE_URL_OVERRIDES = {} ADMINS = [] ALLOWED_HOSTS = ['mojo.hepazulian.net', 'wormhole.hepazulian.net', 'exile.hepazulian.net'] APPEND_SLASH = True AUTHENTICATION_BACKENDS = ['utilities.auth_backends.ViewExemptModelBackend'] AUTH_PASSWORD_VALIDATORS = '********************' AUTH_USER_MODEL = 'auth.User' BANNER_BOTTOM = '' BANNER_LOGIN = '' BANNER_TOP = '' BASE_DIR = '/opt/netbox/netbox' BASE_PATH = '' CACHEOPS = {'auth.user': {'ops': 'get', 'timeout': 900}, 'auth.*': {'ops': ('fetch', 'get')}, 'auth.permission': {'ops': 'all'}, 'circuits.*': {'ops': 'all'}, 'dcim.*': {'ops': 'all'}, 'ipam.*': {'ops': 'all'}, 'extras.*': {'ops': 'all'}, 'secrets.*': '********************', 'users.*': {'ops': 'all'}, 'tenancy.*': {'ops': 'all'}, 'virtualization.*': {'ops': 'all'}} CACHEOPS_DEFAULTS = {'timeout': 900} CACHEOPS_DEGRADE_ON_FAILURE = True CACHEOPS_ENABLED = True CACHEOPS_REDIS = 'redis://localhost:6379/0' CACHES = {'default': {'BACKEND': 'django.core.cache.backends.locmem.LocMemCache'}} CACHE_MIDDLEWARE_ALIAS = 'default' CACHE_MIDDLEWARE_KEY_PREFIX = '********************' CACHE_MIDDLEWARE_SECONDS = 600 CACHE_TIMEOUT = 900 CACHING_REDIS = {'HOST': 'localhost', 'PORT': 6379, 'PASSWORD': '********************', 'DATABASE': 0, 'DEFAULT_TIMEOUT': 300, 'SSL': False} CACHING_REDIS_DATABASE = 0 CACHING_REDIS_DEFAULT_TIMEOUT = 300 CACHING_REDIS_HOST = 'localhost' CACHING_REDIS_PASSWORD = '********************' CACHING_REDIS_PORT = 6379 CACHING_REDIS_SENTINELS = [] CACHING_REDIS_SENTINEL_SERVICE = 'default' CACHING_REDIS_SSL = False CACHING_REDIS_USING_SENTINEL = False CHANGELOG_RETENTION = 90 CORS_ORIGIN_ALLOW_ALL = False CORS_ORIGIN_REGEX_WHITELIST = [] CORS_ORIGIN_WHITELIST = [] CSRF_COOKIE_AGE = 31449600 CSRF_COOKIE_DOMAIN = None CSRF_COOKIE_HTTPONLY = False CSRF_COOKIE_NAME = 'csrftoken' CSRF_COOKIE_PATH = '/' CSRF_COOKIE_SAMESITE = 'Lax' CSRF_COOKIE_SECURE = False CSRF_FAILURE_VIEW = 'django.views.csrf.csrf_failure' CSRF_HEADER_NAME = 'HTTP_X_CSRFTOKEN' CSRF_TRUSTED_ORIGINS = ['mojo.hepazulian.net', 'wormhole.hepazulian.net', 'exile.hepazulian.net'] CSRF_USE_SESSIONS = False DATABASE = {'NAME': 'netbox', 'USER': 'netbox', 'PASSWORD': '********************', 'HOST': 'localhost', 'PORT': '', 'ENGINE': 'django.db.backends.postgresql', 'ATOMIC_REQUESTS': False, 'AUTOCOMMIT': True, 'CONN_MAX_AGE': 0, 'OPTIONS': {}, 'TIME_ZONE': None, 'TEST': {'CHARSET': None, 'COLLATION': None, 'NAME': None, 'MIRROR': None}} DATABASES = {'default': {'NAME': 'netbox', 'USER': 'netbox', 'PASSWORD': '********************', 'HOST': 'localhost', 'PORT': '', 'ENGINE': 'django.db.backends.postgresql', 'ATOMIC_REQUESTS': False, 'AUTOCOMMIT': True, 'CONN_MAX_AGE': 0, 'OPTIONS': {}, 'TIME_ZONE': None, 'TEST': {'CHARSET': None, 'COLLATION': None, 'NAME': None, 'MIRROR': None}}} DATABASE_ROUTERS = [] DATA_UPLOAD_MAX_MEMORY_SIZE = 2621440 DATA_UPLOAD_MAX_NUMBER_FIELDS = None DATETIME_FORMAT = 'N j, Y g:i a' DATETIME_INPUT_FORMATS = ['%Y-%m-%d %H:%M:%S', '%Y-%m-%d %H:%M:%S.%f', '%Y-%m-%d %H:%M', '%Y-%m-%d', '%m/%d/%Y %H:%M:%S', '%m/%d/%Y %H:%M:%S.%f', '%m/%d/%Y %H:%M', '%m/%d/%Y', '%m/%d/%y %H:%M:%S', '%m/%d/%y %H:%M:%S.%f', '%m/%d/%y %H:%M', '%m/%d/%y'] DATE_FORMAT = 'N j, Y' DATE_INPUT_FORMATS = ['%Y-%m-%d', '%m/%d/%Y', '%m/%d/%y', '%b %d %Y', '%b %d, %Y', '%d %b %Y', '%d %b, %Y', '%B %d %Y', '%B %d, %Y', '%d %B %Y', '%d %B, %Y'] DEBUG = True DEBUG_PROPAGATE_EXCEPTIONS = False DECIMAL_SEPARATOR = '.' DEFAULT_CHARSET = 'utf-8' DEFAULT_CONTENT_TYPE = 'text/html' DEFAULT_EXCEPTION_REPORTER_FILTER = 'django.views.debug.SafeExceptionReporterFilter' DEFAULT_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage' DEFAULT_FROM_EMAIL = 'webmaster@localhost' DEFAULT_INDEX_TABLESPACE = '' DEFAULT_TABLESPACE = '' DEVELOPER = False DISALLOWED_USER_AGENTS = [] EMAIL = {'SERVER': 'localhost', 'PORT': 25, 'USERNAME': '', 'PASSWORD': '********************', 'TIMEOUT': 10, 'FROM_EMAIL': ''} EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_HOST = 'localhost' EMAIL_HOST_PASSWORD = '********************' EMAIL_HOST_USER = '' EMAIL_PORT = 25 EMAIL_SSL_CERTFILE = None EMAIL_SSL_KEYFILE = '********************' EMAIL_SUBJECT_PREFIX = '[NetBox] ' EMAIL_TIMEOUT = 10 EMAIL_USE_LOCALTIME = False EMAIL_USE_SSL = False EMAIL_USE_TLS = False ENFORCE_GLOBAL_UNIQUE = False EXEMPT_VIEW_PERMISSIONS = [] FILE_CHARSET = 'utf-8' FILE_UPLOAD_DIRECTORY_PERMISSIONS = None FILE_UPLOAD_HANDLERS = ['django.core.files.uploadhandler.MemoryFileUploadHandler', 'django.core.files.uploadhandler.TemporaryFileUploadHandler'] FILE_UPLOAD_MAX_MEMORY_SIZE = 2621440 FILE_UPLOAD_PERMISSIONS = None FILE_UPLOAD_TEMP_DIR = None FILTERS_NULL_CHOICE_LABEL = 'None' FILTERS_NULL_CHOICE_VALUE = 'null' FIRST_DAY_OF_WEEK = 0 FIXTURE_DIRS = [] FORCE_SCRIPT_NAME = None FORMAT_MODULE_PATH = None FORM_RENDERER = 'django.forms.renderers.DjangoTemplates' HOSTNAME = 'mojo.hepazulian.net' IGNORABLE_404_URLS = [] INSTALLED_APPS = ['django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'django.contrib.humanize', 'cacheops', 'corsheaders', 'debug_toolbar', 'django_filters', 'django_rq', 'django_tables2', 'django_prometheus', 'mptt', 'rest_framework', 'taggit', 'taggit_serializer', 'timezone_field', 'circuits', 'dcim', 'ipam', 'extras', 'secrets', 'tenancy', 'users', 'utilities', 'virtualization', 'drf_yasg'] INTERNAL_IPS = "('127.0.0.1', '::1')" LANGUAGES = [('af', 'Afrikaans'), ('ar', 'Arabic'), ('ast', 'Asturian'), ('az', 'Azerbaijani'), ('bg', 'Bulgarian'), ('be', 'Belarusian'), ('bn', 'Bengali'), ('br', 'Breton'), ('bs', 'Bosnian'), ('ca', 'Catalan'), ('cs', 'Czech'), ('cy', 'Welsh'), ('da', 'Danish'), ('de', 'German'), ('dsb', 'Lower Sorbian'), ('el', 'Greek'), ('en', 'English'), ('en-au', 'Australian English'), ('en-gb', 'British English'), ('eo', 'Esperanto'), ('es', 'Spanish'), ('es-ar', 'Argentinian Spanish'), ('es-co', 'Colombian Spanish'), ('es-mx', 'Mexican Spanish'), ('es-ni', 'Nicaraguan Spanish'), ('es-ve', 'Venezuelan Spanish'), ('et', 'Estonian'), ('eu', 'Basque'), ('fa', 'Persian'), ('fi', 'Finnish'), ('fr', 'French'), ('fy', 'Frisian'), ('ga', 'Irish'), ('gd', 'Scottish Gaelic'), ('gl', 'Galician'), ('he', 'Hebrew'), ('hi', 'Hindi'), ('hr', 'Croatian'), ('hsb', 'Upper Sorbian'), ('hu', 'Hungarian'), ('hy', 'Armenian'), ('ia', 'Interlingua'), ('id', 'Indonesian'), ('io', 'Ido'), ('is', 'Icelandic'), ('it', 'Italian'), ('ja', 'Japanese'), ('ka', 'Georgian'), ('kab', 'Kabyle'), ('kk', 'Kazakh'), ('km', 'Khmer'), ('kn', 'Kannada'), ('ko', 'Korean'), ('lb', 'Luxembourgish'), ('lt', 'Lithuanian'), ('lv', 'Latvian'), ('mk', 'Macedonian'), ('ml', 'Malayalam'), ('mn', 'Mongolian'), ('mr', 'Marathi'), ('my', 'Burmese'), ('nb', 'Norwegian Bokmål'), ('ne', 'Nepali'), ('nl', 'Dutch'), ('nn', 'Norwegian Nynorsk'), ('os', 'Ossetic'), ('pa', 'Punjabi'), ('pl', 'Polish'), ('pt', 'Portuguese'), ('pt-br', 'Brazilian Portuguese'), ('ro', 'Romanian'), ('ru', 'Russian'), ('sk', 'Slovak'), ('sl', 'Slovenian'), ('sq', 'Albanian'), ('sr', 'Serbian'), ('sr-latn', 'Serbian Latin'), ('sv', 'Swedish'), ('sw', 'Swahili'), ('ta', 'Tamil'), ('te', 'Telugu'), ('th', 'Thai'), ('tr', 'Turkish'), ('tt', 'Tatar'), ('udm', 'Udmurt'), ('uk', 'Ukrainian'), ('ur', 'Urdu'), ('vi', 'Vietnamese'), ('zh-hans', 'Simplified Chinese'), ('zh-hant', 'Traditional Chinese')] LANGUAGES_BIDI = ['he', 'ar', 'fa', 'ur'] LANGUAGE_CODE = 'en-us' LANGUAGE_COOKIE_AGE = None LANGUAGE_COOKIE_DOMAIN = None LANGUAGE_COOKIE_NAME = 'django_language' LANGUAGE_COOKIE_PATH = '/' LDAP_CONFIG = None LOCALE_PATHS = [] LOGGING = {'version': 1, 'disable_existing_loggers': False, 'handlers': {'file': {'level': 'DEBUG', 'class': 'logging.FileHandler', 'filename': '/var/log/netbox.log'}}, 'loggers': {'django': {'handlers': ['file'], 'level': 'DEBUG'}}} LOGGING_CONFIG = 'logging.config.dictConfig' LOGIN_REDIRECT_URL = '/accounts/profile/' LOGIN_REQUIRED = True LOGIN_TIMEOUT = None LOGIN_URL = '/login/' LOGOUT_REDIRECT_URL = None MAINTENANCE_MODE = False MANAGERS = [] MAX_PAGE_SIZE = 1000 MEDIA_ROOT = '/opt/netbox/netbox/media' MEDIA_URL = '/media/' MESSAGE_STORAGE = 'django.contrib.messages.storage.fallback.FallbackStorage' MESSAGE_TAGS = {40: 'danger'} METRICS_ENABLED = False MIDDLEWARE = "('debug_toolbar.middleware.DebugToolbarMiddleware', 'django_prometheus.middleware.PrometheusBeforeMiddleware', 'corsheaders.middleware.CorsMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.security.SecurityMiddleware', 'utilities.middleware.ExceptionHandlingMiddleware', 'utilities.middleware.LoginRequiredMiddleware', 'utilities.middleware.APIVersionMiddleware', 'extras.middleware.ObjectChangeMiddleware', 'django_prometheus.middleware.PrometheusAfterMiddleware')" MIGRATION_MODULES = {} MONTH_DAY_FORMAT = 'F j' NAPALM_ARGS = {} NAPALM_PASSWORD = '********************' NAPALM_TIMEOUT = 30 NAPALM_USERNAME = '' NUMBER_GROUPING = 0 PAGINATE_COUNT = 50 PASSWORD_HASHERS = '********************' PASSWORD_RESET_TIMEOUT_DAYS = '********************' PER_PAGE_DEFAULTS = [25, 50, 100, 250, 500, 1000] PREFER_IPV4 = False PREPEND_WWW = False PROMETHEUS_EXPORT_MIGRATIONS = False REDIS = {'webhooks': {'HOST': 'localhost', 'PORT': 6379, 'PASSWORD': '********************', 'DATABASE': 0, 'DEFAULT_TIMEOUT': 300, 'SSL': False}, 'caching': {'HOST': 'localhost', 'PORT': 6379, 'PASSWORD': '********************', 'DATABASE': 0, 'DEFAULT_TIMEOUT': 300, 'SSL': False}} REDIS_CACHE_CON_STRING = 'redis://localhost:6379/0' REPORTS_ROOT = '/opt/netbox/netbox/reports' REST_FRAMEWORK = {'ALLOWED_VERSIONS': ['2.7'], 'DEFAULT_AUTHENTICATION_CLASSES': ('rest_framework.authentication.SessionAuthentication', 'netbox.api.TokenAuthentication'), 'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',), 'DEFAULT_PAGINATION_CLASS': 'netbox.api.OptionalLimitOffsetPagination', 'DEFAULT_PERMISSION_CLASSES': ('netbox.api.TokenPermissions',), 'DEFAULT_RENDERER_CLASSES': ('rest_framework.renderers.JSONRenderer', 'netbox.api.FormlessBrowsableAPIRenderer'), 'DEFAULT_VERSION': '2.7', 'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.AcceptHeaderVersioning', 'PAGE_SIZE': 50, 'VIEW_NAME_FUNCTION': 'netbox.api.get_view_name'} REST_FRAMEWORK_VERSION = '2.7' ROOT_URLCONF = 'netbox.urls' RQ_QUEUES = {'default': {'HOST': 'localhost', 'PORT': 6379, 'DB': 0, 'PASSWORD': '********************', 'DEFAULT_TIMEOUT': 300, 'SSL': False}} SCRIPTS_ROOT = '/opt/netbox/netbox/scripts' SECRETS_MIN_PUBKEY_SIZE = '********************' SECRET_KEY = '********************' SECURE_BROWSER_XSS_FILTER = False SECURE_CONTENT_TYPE_NOSNIFF = False SECURE_HSTS_INCLUDE_SUBDOMAINS = False SECURE_HSTS_PRELOAD = False SECURE_HSTS_SECONDS = 0 SECURE_PROXY_SSL_HEADER = "('HTTP_X_FORWARDED_PROTO', 'https')" SECURE_REDIRECT_EXEMPT = [] SECURE_SSL_HOST = None SECURE_SSL_REDIRECT = False SERVER_EMAIL = '' SESSION_CACHE_ALIAS = 'default' SESSION_COOKIE_AGE = 1209600 SESSION_COOKIE_DOMAIN = None SESSION_COOKIE_HTTPONLY = True SESSION_COOKIE_NAME = 'sessionid' SESSION_COOKIE_PATH = '/' SESSION_COOKIE_SAMESITE = 'Lax' SESSION_COOKIE_SECURE = False SESSION_ENGINE = 'django.contrib.sessions.backends.db' SESSION_EXPIRE_AT_BROWSER_CLOSE = False SESSION_FILE_PATH = None SESSION_SAVE_EVERY_REQUEST = False SESSION_SERIALIZER = 'django.contrib.sessions.serializers.JSONSerializer' SETTINGS_MODULE = 'netbox.settings' SHORT_DATETIME_FORMAT = 'Y-m-d H:i' SHORT_DATE_FORMAT = 'Y-m-d' SHORT_TIME_FORMAT = 'H:i:s' SIGNING_BACKEND = 'django.core.signing.TimestampSigner' SILENCED_SYSTEM_CHECKS = [] STATICFILES_DIRS = "('/opt/netbox/netbox/project-static',)" STATICFILES_FINDERS = ['django.contrib.staticfiles.finders.FileSystemFinder', 'django.contrib.staticfiles.finders.AppDirectoriesFinder'] STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.StaticFilesStorage' STATIC_ROOT = '/opt/netbox/netbox/static' STATIC_URL = '/static/' STORAGE_BACKEND = None STORAGE_CONFIG = {} SWAGGER_SETTINGS = {'DEFAULT_AUTO_SCHEMA_CLASS': 'utilities.custom_inspectors.NetBoxSwaggerAutoSchema', 'DEFAULT_FIELD_INSPECTORS': ['utilities.custom_inspectors.NullableBooleanFieldInspector', 'utilities.custom_inspectors.CustomChoiceFieldInspector', 'utilities.custom_inspectors.TagListFieldInspector', 'utilities.custom_inspectors.SerializedPKRelatedFieldInspector', 'drf_yasg.inspectors.CamelCaseJSONFilter', 'drf_yasg.inspectors.ReferencingSerializerInspector', 'drf_yasg.inspectors.RelatedFieldInspector', 'drf_yasg.inspectors.ChoiceFieldInspector', 'drf_yasg.inspectors.FileFieldInspector', 'drf_yasg.inspectors.DictFieldInspector', 'drf_yasg.inspectors.SerializerMethodFieldInspector', 'drf_yasg.inspectors.SimpleFieldInspector', 'drf_yasg.inspectors.StringDefaultFieldInspector'], 'DEFAULT_FILTER_INSPECTORS': ['utilities.custom_inspectors.IdInFilterInspector', 'drf_yasg.inspectors.CoreAPICompatInspector'], 'DEFAULT_INFO': 'netbox.urls.openapi_info', 'DEFAULT_MODEL_DEPTH': 1, 'DEFAULT_PAGINATOR_INSPECTORS': ['utilities.custom_inspectors.NullablePaginatorInspector', 'drf_yasg.inspectors.DjangoRestResponsePagination', 'drf_yasg.inspectors.CoreAPICompatInspector'], 'SECURITY_DEFINITIONS': {'Bearer': {'type': 'apiKey', 'name': 'Authorization', 'in': 'header'}}, 'VALIDATOR_URL': None} TEMPLATES = [{'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': ['/opt/netbox/netbox/templates'], 'APP_DIRS': True, 'OPTIONS': {'context_processors': ['django.template.context_processors.debug', 'django.template.context_processors.request', 'django.template.context_processors.media', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', 'utilities.context_processors.settings']}}] TEMPLATES_DIR = '/opt/netbox/netbox/templates' TEST_NON_SERIALIZED_APPS = [] TEST_RUNNER = 'django.test.runner.DiscoverRunner' THOUSAND_SEPARATOR = ',' TIME_FORMAT = 'g:i a' TIME_INPUT_FORMATS = ['%H:%M:%S', '%H:%M:%S.%f', '%H:%M'] TIME_ZONE = 'UTC' USE_I18N = True USE_L10N = False USE_THOUSAND_SEPARATOR = False USE_TZ = True USE_X_FORWARDED_HOST = True USE_X_FORWARDED_PORT = False VERSION = '2.7.8' WEBHOOKS_REDIS = {'HOST': 'localhost', 'PORT': 6379, 'PASSWORD': '********************', 'DATABASE': 0, 'DEFAULT_TIMEOUT': 300, 'SSL': False} WEBHOOKS_REDIS_DATABASE = 0 WEBHOOKS_REDIS_DEFAULT_TIMEOUT = 300 WEBHOOKS_REDIS_HOST = 'localhost' WEBHOOKS_REDIS_PASSWORD = '********************' WEBHOOKS_REDIS_PORT = 6379 WEBHOOKS_REDIS_SENTINELS = [] WEBHOOKS_REDIS_SENTINEL_SERVICE = 'default' WEBHOOKS_REDIS_SSL = False WEBHOOKS_REDIS_USING_SENTINEL = False WSGI_APPLICATION = 'netbox.wsgi.application' X_FRAME_OPTIONS = 'SAMEORIGIN' YEAR_MONTH_FORMAT = 'F Y' ```
adam added the status: revisions needed label 2025-12-29 18:28:59 +01:00
adam closed this issue 2025-12-29 18:28:59 +01:00
Author
Owner

@jeremystretch commented on GitHub (Feb 27, 2020):

Please revise your bug report so that it entails only a raw curl request and its response. Wrap CLI commands and output in triple backticks (```) so that they are legible.

@jeremystretch commented on GitHub (Feb 27, 2020): Please revise your bug report so that it entails only a raw curl request and its response. Wrap CLI commands and output in triple backticks (```) so that they are legible.
Author
Owner

@DanSheps commented on GitHub (Feb 27, 2020):

In addition to @jeremystretch's comment, this is not reproducible on master:

[root@miyu ~]# curl -X POST "https://master.netbox.dansheps.com/api/ipam/prefixes/" -H "accept: application/json" -H "Content-Type: application/json" -H "Authorization: Token XXX" -d '{ "prefix": "10.4.0.0/16", "status": "container"}'

{"id":22,"family":{"value":4,"label":"IPv4"},"prefix":"10.4.0.0/16","site":null,"vrf":null,"tenant":null,"vlan":null,"status":{"value":"container","label":"Container","id":0},"role":null,"is_pool":false,"description":"","tags":[],"created":"2020-02-27","last_updated":"2020-02-27T13:55:53.379230Z"}
[root@miyu ~]#
@DanSheps commented on GitHub (Feb 27, 2020): In addition to @jeremystretch's comment, this is not reproducible on master: ``` [root@miyu ~]# curl -X POST "https://master.netbox.dansheps.com/api/ipam/prefixes/" -H "accept: application/json" -H "Content-Type: application/json" -H "Authorization: Token XXX" -d '{ "prefix": "10.4.0.0/16", "status": "container"}' {"id":22,"family":{"value":4,"label":"IPv4"},"prefix":"10.4.0.0/16","site":null,"vrf":null,"tenant":null,"vlan":null,"status":{"value":"container","label":"Container","id":0},"role":null,"is_pool":false,"description":"","tags":[],"created":"2020-02-27","last_updated":"2020-02-27T13:55:53.379230Z"} [root@miyu ~]# ```
Author
Owner

@ross-alexander commented on GitHub (Feb 27, 2020):

Apologies and many thanks. The issue was I was missing the Content-type: application/json header. Once I had added that to the curl it worked on 2.7.8 with python 3.6.8 (Centos 8.1).

Many thanks for the quick response and again apologies for the my error.

@ross-alexander commented on GitHub (Feb 27, 2020): Apologies and many thanks. The issue was I was missing the Content-type: application/json header. Once I had added that to the curl it worked on 2.7.8 with python 3.6.8 (Centos 8.1). Many thanks for the quick response and again apologies for the my error.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#3423