Local Dev workflow updates (#20)

* local development workflow draft
This commit is contained in:
Ryan Merolle 2022-07-07 14:54:53 -04:00 committed by GitHub
parent 2e2cb8191e
commit 2b51fec511
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
60 changed files with 1723 additions and 1 deletions

104
.devcontainer/.bashrc Normal file
View File

@ -0,0 +1,104 @@
# If you come from bash you might have to change your $PATH.
# export PATH=$HOME/bin:/usr/local/bin:$PATH
# Path to your oh-my-zsh installation.
export ZSH="$HOME/.oh-my-zsh"
# Set name of the theme to load --- if set to "random", it will
# load a random theme each time oh-my-zsh is loaded, in which case,
# to know which specific one was loaded, run: echo $RANDOM_THEME
# See https://github.com/ohmyzsh/ohmyzsh/wiki/Themes
ZSH_THEME="robbyrussell"
# Set list of themes to pick from when loading at random
# Setting this variable when ZSH_THEME=random will cause zsh to load
# a theme from this variable instead of looking in $ZSH/themes/
# If set to an empty array, this variable will have no effect.
# ZSH_THEME_RANDOM_CANDIDATES=( "robbyrussell" "agnoster" )
# Uncomment the following line to use case-sensitive completion.
# CASE_SENSITIVE="true"
# Uncomment the following line to use hyphen-insensitive completion.
# Case-sensitive completion must be off. _ and - will be interchangeable.
# HYPHEN_INSENSITIVE="true"
# Uncomment one of the following lines to change the auto-update behavior
# zstyle ':omz:update' mode disabled # disable automatic updates
# zstyle ':omz:update' mode auto # update automatically without asking
# zstyle ':omz:update' mode reminder # just remind me to update when it's time
# Uncomment the following line to change how often to auto-update (in days).
# zstyle ':omz:update' frequency 13
# Uncomment the following line if pasting URLs and other text is messed up.
# DISABLE_MAGIC_FUNCTIONS="true"
# Uncomment the following line to disable colors in ls.
# DISABLE_LS_COLORS="true"
# Uncomment the following line to disable auto-setting terminal title.
# DISABLE_AUTO_TITLE="true"
# Uncomment the following line to enable command auto-correction.
# ENABLE_CORRECTION="true"
# Uncomment the following line to display red dots whilst waiting for completion.
# You can also set it to another string to have that shown instead of the default red dots.
# e.g. COMPLETION_WAITING_DOTS="%F{yellow}waiting...%f"
# Caution: this setting can cause issues with multiline prompts in zsh < 5.7.1 (see #5765)
# COMPLETION_WAITING_DOTS="true"
# Uncomment the following line if you want to disable marking untracked files
# under VCS as dirty. This makes repository status check for large repositories
# much, much faster.
# DISABLE_UNTRACKED_FILES_DIRTY="true"
# Uncomment the following line if you want to change the command execution time
# stamp shown in the history command output.
# You can set one of the optional three formats:
# "mm/dd/yyyy"|"dd.mm.yyyy"|"yyyy-mm-dd"
# or set a custom format using the strftime function format specifications,
# see 'man strftime' for details.
# HIST_STAMPS="mm/dd/yyyy"
# Would you like to use another custom folder than $ZSH/custom?
# ZSH_CUSTOM=/path/to/new-custom-folder
# Which plugins would you like to load?
# Standard plugins can be found in $ZSH/plugins/
# Custom plugins may be added to $ZSH_CUSTOM/plugins/
# Example format: plugins=(rails git textmate ruby lighthouse)
# Add wisely, as too many plugins slow down shell startup.
plugins=(common-aliases colored-man-pages colorize docker docker-compose emoji safe-paste git git-auto-fetch git-extras history jsontools pip)
source $ZSH/oh-my-zsh.sh
# User configuration
# export MANPATH="/usr/local/man:$MANPATH"
# You may need to manually set your language environment
# export LANG=en_US.UTF-8
# Preferred editor for local and remote sessions
# if [[ -n $SSH_CONNECTION ]]; then
# export EDITOR='vim'
# else
# export EDITOR='mvim'
# fi
# Compilation flags
# export ARCHFLAGS="-arch x86_64"
# Set personal aliases, overriding those provided by oh-my-zsh libs,
# plugins, and themes. Aliases can be placed here, though oh-my-zsh
# users are encouraged to define aliases within the ZSH_CUSTOM folder.
# For a full list of active aliases, run `alias`.
#
# Example aliases
# alias zshconfig="mate ~/.zshrc"
# alias ohmyzsh="mate ~/.oh-my-zsh"
# Activate Python venv in terminal
source /opt/netbox/venv/bin/activate

104
.devcontainer/.zshrc Normal file
View File

@ -0,0 +1,104 @@
# If you come from bash you might have to change your $PATH.
# export PATH=$HOME/bin:/usr/local/bin:$PATH
# Path to your oh-my-zsh installation.
export ZSH="$HOME/.oh-my-zsh"
# Set name of the theme to load --- if set to "random", it will
# load a random theme each time oh-my-zsh is loaded, in which case,
# to know which specific one was loaded, run: echo $RANDOM_THEME
# See https://github.com/ohmyzsh/ohmyzsh/wiki/Themes
ZSH_THEME="robbyrussell"
# Set list of themes to pick from when loading at random
# Setting this variable when ZSH_THEME=random will cause zsh to load
# a theme from this variable instead of looking in $ZSH/themes/
# If set to an empty array, this variable will have no effect.
# ZSH_THEME_RANDOM_CANDIDATES=( "robbyrussell" "agnoster" )
# Uncomment the following line to use case-sensitive completion.
# CASE_SENSITIVE="true"
# Uncomment the following line to use hyphen-insensitive completion.
# Case-sensitive completion must be off. _ and - will be interchangeable.
# HYPHEN_INSENSITIVE="true"
# Uncomment one of the following lines to change the auto-update behavior
# zstyle ':omz:update' mode disabled # disable automatic updates
# zstyle ':omz:update' mode auto # update automatically without asking
# zstyle ':omz:update' mode reminder # just remind me to update when it's time
# Uncomment the following line to change how often to auto-update (in days).
# zstyle ':omz:update' frequency 13
# Uncomment the following line if pasting URLs and other text is messed up.
# DISABLE_MAGIC_FUNCTIONS="true"
# Uncomment the following line to disable colors in ls.
# DISABLE_LS_COLORS="true"
# Uncomment the following line to disable auto-setting terminal title.
# DISABLE_AUTO_TITLE="true"
# Uncomment the following line to enable command auto-correction.
# ENABLE_CORRECTION="true"
# Uncomment the following line to display red dots whilst waiting for completion.
# You can also set it to another string to have that shown instead of the default red dots.
# e.g. COMPLETION_WAITING_DOTS="%F{yellow}waiting...%f"
# Caution: this setting can cause issues with multiline prompts in zsh < 5.7.1 (see #5765)
# COMPLETION_WAITING_DOTS="true"
# Uncomment the following line if you want to disable marking untracked files
# under VCS as dirty. This makes repository status check for large repositories
# much, much faster.
# DISABLE_UNTRACKED_FILES_DIRTY="true"
# Uncomment the following line if you want to change the command execution time
# stamp shown in the history command output.
# You can set one of the optional three formats:
# "mm/dd/yyyy"|"dd.mm.yyyy"|"yyyy-mm-dd"
# or set a custom format using the strftime function format specifications,
# see 'man strftime' for details.
# HIST_STAMPS="mm/dd/yyyy"
# Would you like to use another custom folder than $ZSH/custom?
# ZSH_CUSTOM=/path/to/new-custom-folder
# Which plugins would you like to load?
# Standard plugins can be found in $ZSH/plugins/
# Custom plugins may be added to $ZSH_CUSTOM/plugins/
# Example format: plugins=(rails git textmate ruby lighthouse)
# Add wisely, as too many plugins slow down shell startup.
plugins=(common-aliases colored-man-pages colorize docker docker-compose emoji safe-paste git git-auto-fetch git-extras history jsontools pip)
source $ZSH/oh-my-zsh.sh
# User configuration
# export MANPATH="/usr/local/man:$MANPATH"
# You may need to manually set your language environment
# export LANG=en_US.UTF-8
# Preferred editor for local and remote sessions
# if [[ -n $SSH_CONNECTION ]]; then
# export EDITOR='vim'
# else
# export EDITOR='mvim'
# fi
# Compilation flags
# export ARCHFLAGS="-arch x86_64"
# Set personal aliases, overriding those provided by oh-my-zsh libs,
# plugins, and themes. Aliases can be placed here, though oh-my-zsh
# users are encouraged to define aliases within the ZSH_CUSTOM folder.
# For a full list of active aliases, run `alias`.
#
# Example aliases
# alias zshconfig="mate ~/.zshrc"
# alias ohmyzsh="mate ~/.oh-my-zsh"
# Activate Python venv in terminal
source /opt/netbox/venv/bin/activate

View File

@ -0,0 +1,42 @@
ARG VARIANT=latest
FROM tgenannt/netbox:${VARIANT}
ARG DEBIAN_FRONTEND=noninteractive
# Install APT packages
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
&& apt-get -y install --no-install-recommends curl git make openssh-client sudo wget zsh \
&& apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/*
# Install development & ide dependencies
COPY requirements-dev.txt /tmp/pip-tmp/
RUN /opt/netbox/venv/bin/python3 -m pip install --disable-pip-version-check --no-cache-dir install -r /tmp/pip-tmp/requirements-dev.txt \
&& rm -rf /tmp/*
ARG USERNAME=vscode
ARG USER_UID=1000
ARG USER_GID=$USER_UID
RUN useradd -md /home/vscode -s /usr/bin/zsh -u $USER_UID $USERNAME \
&& usermod -aG sudo $USERNAME \
&& echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers \
&& mkdir /opt/netbox/netbox/netbox-access-lists \
&& chown $USERNAME:$USERNAME /opt/netbox /etc/netbox -R
USER $USERNAME
# Add oh my zsh
RUN wget --quiet https://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh -O - | zsh || true
COPY .bashrc /home/vscode/.bashrc
COPY .zshrc /home/vscode/.zshrc
WORKDIR /opt/netbox/netbox/netbox-access-lists
USER root
COPY entrypoint-dev.sh /bin/entrypoint.sh
RUN chmod +x /bin/entrypoint.sh
CMD ["/bin/entrypoint.sh"]

View File

@ -0,0 +1,248 @@
####
## We recommend to not edit this file.
## Create separate files to overwrite the settings.
## See `extra.py` as an example.
####
import re
from os import environ
from os.path import abspath, dirname, join
# For reference see https://netbox.readthedocs.io/en/stable/configuration/
# Based on https://github.com/netbox-community/netbox/blob/master/netbox/netbox/configuration.example.py
# Read secret from file
def _read_secret(secret_name, default = None):
try:
f = open('/run/secrets/' + secret_name, 'r', encoding='utf-8')
except EnvironmentError:
return default
else:
with f:
return f.readline().strip()
_BASE_DIR = dirname(dirname(abspath(__file__)))
#########################
# #
# 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 = environ.get('ALLOWED_HOSTS', '*').split(' ')
# 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': environ.get('DB_NAME', 'netbox'), # Database name
'USER': environ.get('DB_USER', ''), # PostgreSQL username
'PASSWORD': _read_secret('db_password', environ.get('DB_PASSWORD', '')),
# PostgreSQL password
'HOST': environ.get('DB_HOST', 'localhost'), # Database server
'PORT': environ.get('DB_PORT', ''), # Database port (leave blank for default)
'OPTIONS': {'sslmode': environ.get('DB_SSLMODE', 'prefer')},
# Database connection SSLMODE
'CONN_MAX_AGE': int(environ.get('DB_CONN_MAX_AGE', '300')),
# Max database connection age
'DISABLE_SERVER_SIDE_CURSORS': environ.get('DB_DISABLE_SERVER_SIDE_CURSORS', 'False').lower() == 'true',
# Disable the use of server-side cursors transaction pooling
}
# 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': environ.get('REDIS_HOST', 'localhost'),
'PORT': int(environ.get('REDIS_PORT', 6379)),
'PASSWORD': _read_secret('redis_password', environ.get('REDIS_PASSWORD', '')),
'DATABASE': int(environ.get('REDIS_DATABASE', 0)),
'SSL': environ.get('REDIS_SSL', 'False').lower() == 'true',
'INSECURE_SKIP_TLS_VERIFY': environ.get('REDIS_INSECURE_SKIP_TLS_VERIFY', 'False').lower() == 'true',
},
'caching': {
'HOST': environ.get('REDIS_CACHE_HOST', environ.get('REDIS_HOST', 'localhost')),
'PORT': int(environ.get('REDIS_CACHE_PORT', environ.get('REDIS_PORT', 6379))),
'PASSWORD': _read_secret('redis_cache_password', environ.get('REDIS_CACHE_PASSWORD', environ.get('REDIS_PASSWORD', ''))),
'DATABASE': int(environ.get('REDIS_CACHE_DATABASE', 1)),
'SSL': environ.get('REDIS_CACHE_SSL', environ.get('REDIS_SSL', 'False')).lower() == 'true',
'INSECURE_SKIP_TLS_VERIFY': environ.get('REDIS_CACHE_INSECURE_SKIP_TLS_VERIFY', environ.get('REDIS_INSECURE_SKIP_TLS_VERIFY', 'False')).lower() == 'true',
},
}
# 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 = _read_secret('secret_key', environ.get('SECRET_KEY', ''))
#########################
# #
# Optional settings #
# #
#########################
# Specify one or more name and email address tuples representing NetBox administrators. These people will be notified of
# application errors (assuming correct email settings are provided).
ADMINS = [
# ['John Doe', 'jdoe@example.com'],
]
# URL schemes that are allowed within links in NetBox
ALLOWED_URL_SCHEMES = (
'file', 'ftp', 'ftps', 'http', 'https', 'irc', 'mailto', 'sftp', 'ssh', 'tel', 'telnet', 'tftp', 'vnc', 'xmpp',
)
# Optionally display a persistent banner at the top and/or bottom of every page. HTML is allowed. To display the same
# content in both banners, define BANNER_TOP and set BANNER_BOTTOM = BANNER_TOP.
BANNER_TOP = environ.get('BANNER_TOP', '')
BANNER_BOTTOM = environ.get('BANNER_BOTTOM', '')
# Text to include on the login page above the login form. HTML is allowed.
BANNER_LOGIN = environ.get('BANNER_LOGIN', '')
# Base URL path if accessing NetBox within a directory. For example, if installed at http://example.com/netbox/, set:
# BASE_PATH = 'netbox/'
BASE_PATH = environ.get('BASE_PATH', '')
# Maximum number of days to retain logged changes. Set to 0 to retain changes indefinitely. (Default: 90)
CHANGELOG_RETENTION = int(environ.get('CHANGELOG_RETENTION', 90))
# API Cross-Origin Resource Sharing (CORS) settings. If CORS_ORIGIN_ALLOW_ALL is set to True, all origins will be
# allowed. Otherwise, define a list of allowed origins using either CORS_ORIGIN_WHITELIST or
# CORS_ORIGIN_REGEX_WHITELIST. For more information, see https://github.com/ottoyiu/django-cors-headers
CORS_ORIGIN_ALLOW_ALL = environ.get('CORS_ORIGIN_ALLOW_ALL', 'False').lower() == 'true'
CORS_ORIGIN_WHITELIST = list(filter(None, environ.get('CORS_ORIGIN_WHITELIST', 'https://localhost').split(' ')))
CORS_ORIGIN_REGEX_WHITELIST = [re.compile(r) for r in list(filter(None, environ.get('CORS_ORIGIN_REGEX_WHITELIST', '').split(' ')))]
# 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 = environ.get('DEBUG', 'False').lower() == 'true'
# Email settings
EMAIL = {
'SERVER': environ.get('EMAIL_SERVER', 'localhost'),
'PORT': int(environ.get('EMAIL_PORT', 25)),
'USERNAME': environ.get('EMAIL_USERNAME', ''),
'PASSWORD': _read_secret('email_password', environ.get('EMAIL_PASSWORD', '')),
'USE_SSL': environ.get('EMAIL_USE_SSL', 'False').lower() == 'true',
'USE_TLS': environ.get('EMAIL_USE_TLS', 'False').lower() == 'true',
'SSL_CERTFILE': environ.get('EMAIL_SSL_CERTFILE', ''),
'SSL_KEYFILE': environ.get('EMAIL_SSL_KEYFILE', ''),
'TIMEOUT': int(environ.get('EMAIL_TIMEOUT', 10)), # seconds
'FROM_EMAIL': environ.get('EMAIL_FROM', ''),
}
# Enforcement of unique IP space can be toggled on a per-VRF basis. To enforce unique IP space within the global table
# (all prefixes and IP addresses not assigned to a VRF), set ENFORCE_GLOBAL_UNIQUE to True.
ENFORCE_GLOBAL_UNIQUE = environ.get('ENFORCE_GLOBAL_UNIQUE', 'False').lower() == 'true'
# 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 = list(filter(None, environ.get('EXEMPT_VIEW_PERMISSIONS', '').split(' ')))
# Enable GraphQL API.
GRAPHQL_ENABLED = environ.get('GRAPHQL_ENABLED', 'True').lower() == 'true'
# Enable custom logging. Please see the Django documentation for detailed guidance on configuring custom logs:
# https://docs.djangoproject.com/en/stable/topics/logging/
LOGGING = {}
# Setting this to True will permit only authenticated users to access any part of NetBox. By default, anonymous users
# are permitted to access most data in NetBox (excluding secrets) but not make any changes.
LOGIN_REQUIRED = environ.get('LOGIN_REQUIRED', 'False').lower() == 'true'
# 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 = int(environ.get('LOGIN_TIMEOUT', 1209600))
# Setting this to True will display a "maintenance mode" banner at the top of every page.
MAINTENANCE_MODE = environ.get('MAINTENANCE_MODE', 'False').lower() == 'true'
# An API consumer can request an arbitrary number of objects =by appending the "limit" parameter to the URL (e.g.
# "?limit=1000"). This setting defines the maximum limit. Setting it to 0 or None will allow an API consumer to request
# all objects by specifying "?limit=0".
MAX_PAGE_SIZE = int(environ.get('MAX_PAGE_SIZE', 1000))
# 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 = environ.get('MEDIA_ROOT', join(_BASE_DIR, 'media'))
# Expose Prometheus monitoring metrics at the HTTP endpoint '/metrics'
METRICS_ENABLED = environ.get('METRICS_ENABLED', 'False').lower() == 'true'
# Credentials that NetBox will uses to authenticate to devices when connecting via NAPALM.
NAPALM_USERNAME = environ.get('NAPALM_USERNAME', '')
NAPALM_PASSWORD = _read_secret('napalm_password', environ.get('NAPALM_PASSWORD', ''))
# NAPALM timeout (in seconds). (Default: 30)
NAPALM_TIMEOUT = int(environ.get('NAPALM_TIMEOUT', 30))
# NAPALM optional arguments (see http://napalm.readthedocs.io/en/latest/support/#optional-arguments). Arguments must
# be provided as a dictionary.
NAPALM_ARGS = {}
# Determine how many objects to display per page within a list. (Default: 50)
PAGINATE_COUNT = int(environ.get('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 = {
}
# When determining the primary IP address for a device, IPv6 is preferred over IPv4 by default. Set this to True to
# prefer IPv4 instead.
PREFER_IPV4 = environ.get('PREFER_IPV4', 'False').lower() == 'true'
# Rack elevation size defaults, in pixels. For best results, the ratio of width to height should be roughly 10:1.
RACK_ELEVATION_DEFAULT_UNIT_HEIGHT = int(environ.get('RACK_ELEVATION_DEFAULT_UNIT_HEIGHT', 22))
RACK_ELEVATION_DEFAULT_UNIT_WIDTH = int(environ.get('RACK_ELEVATION_DEFAULT_UNIT_WIDTH', 220))
# Remote authentication support
REMOTE_AUTH_ENABLED = environ.get('REMOTE_AUTH_ENABLED', 'False').lower() == 'true'
REMOTE_AUTH_BACKEND = environ.get('REMOTE_AUTH_BACKEND', 'netbox.authentication.RemoteUserBackend')
REMOTE_AUTH_HEADER = environ.get('REMOTE_AUTH_HEADER', 'HTTP_REMOTE_USER')
REMOTE_AUTH_AUTO_CREATE_USER = environ.get('REMOTE_AUTH_AUTO_CREATE_USER', 'True').lower() == 'true'
REMOTE_AUTH_DEFAULT_GROUPS = list(filter(None, environ.get('REMOTE_AUTH_DEFAULT_GROUPS', '').split(' ')))
# 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.
# https://api.github.com/repos/netbox-community/netbox/releases
RELEASE_CHECK_URL = environ.get('RELEASE_CHECK_URL', None)
# 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 = environ.get('REPORTS_ROOT', '/etc/netbox/reports')
# Maximum execution time for background tasks, in seconds.
RQ_DEFAULT_TIMEOUT = int(environ.get('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 = environ.get('SCRIPTS_ROOT', '/etc/netbox/scripts')
# 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 = environ.get('SESSIONS_ROOT', None)
# Time zone (default: UTC)
TIME_ZONE = environ.get('TIME_ZONE', 'UTC')
# Date/time formatting. See the following link for supported formats:
# https://docs.djangoproject.com/en/stable/ref/templates/builtins/#date
DATE_FORMAT = environ.get('DATE_FORMAT', 'N j, Y')
SHORT_DATE_FORMAT = environ.get('SHORT_DATE_FORMAT', 'Y-m-d')
TIME_FORMAT = environ.get('TIME_FORMAT', 'g:i a')
SHORT_TIME_FORMAT = environ.get('SHORT_TIME_FORMAT', 'H:i:s')
DATETIME_FORMAT = environ.get('DATETIME_FORMAT', 'N j, Y g:i a')
SHORT_DATETIME_FORMAT = environ.get('SHORT_DATETIME_FORMAT', 'Y-m-d H:i')

View File

@ -0,0 +1,55 @@
# Remove first comment(#) on each line to implement this working logging example.
# Add LOGLEVEL environment variable to netbox if you use this example & want a different log level.
from os import environ
# Set LOGLEVEL in netbox.env or docker-compose.overide.yml to override a logging level of INFO.
LOGLEVEL = environ.get('LOGLEVEL', 'INFO')
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'verbose': {
'format': '{levelname} {asctime} {module} {process:d} {thread:d} {message}',
'style': '{',
},
'simple': {
'format': '{levelname} {message}',
'style': '{',
},
},
'filters': {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse',
},
},
'handlers': {
'console': {
'level': LOGLEVEL,
'filters': ['require_debug_false'],
'class': 'logging.StreamHandler',
'formatter': 'simple'
},
'mail_admins': {
'level': 'ERROR',
'class': 'django.utils.log.AdminEmailHandler',
'filters': ['require_debug_false']
}
},
'loggers': {
'django': {
'handlers': ['console'],
'propagate': True,
},
'django.request': {
'handlers': ['mail_admins'],
'level': 'ERROR',
'propagate': False,
},
'django_auth_ldap': {
'handlers': ['console',],
'level': LOGLEVEL,
}
}
}

View File

@ -0,0 +1,13 @@
# Add your plugins and plugin settings here.
# Of course uncomment this file out.
# To learn how to build images with your required plugins
# See https://github.com/netbox-community/netbox-docker/wiki/Using-Netbox-Plugins
PLUGINS = [
"netbox_access_lists"
]
PLUGINS_CONFIG = {
"netbox_access_lists":{}
}

View File

@ -0,0 +1,85 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
// https://github.com/microsoft/vscode-dev-containers/tree/v0.238.0/containers/python-3-postgres
// Update the VARIANT arg in docker-compose.yml to pick a Python version
{
"name": "NetBox Plugin Develoment",
"dockerComposeFile": [
"docker-compose.yml",
"docker-compose.override.yml"
],
"service": "netbox",
//"workspaceMount": "source=${localWorkspaceFolder},target=/opt/netbox/netbox/netbox-access-lists,type=bind,consistency=cached",
"workspaceFolder": "/opt/netbox/netbox/netbox-access-lists",
"overrideCommand":false,
// Configure tool-specific properties.
"customizations": {
// Configure properties specific to VS Code.
"vscode": {
// Set *default* container specific settings.json values on container create.
"settings": {
//"[python]": {
// "editor.codeActionsOnSave": {
// "source.organizeImports": true
// }
//},
//"python.sortImports.args": [
// "--profile=black"
//],
//"python.sortImports.path": "/opt/netbox/venv/bin/isort",
"python.analysis.typeCheckingMode": "strict",
"python.analysis.extraPaths": [
"/opt/netbox/",
"/opt/netbox/netbox"
],
"python.autoComplete.extraPaths": [
"/opt/netbox/",
"/opt/netbox/netbox"
],
"python.defaultInterpreterPath": "/opt/netbox/venv/bin/python",
"python.formatting.autopep8Path": "/opt/netbox/venv/lib/python3.9/site-packages/autopep8",
"python.formatting.blackPath": "/opt/netbox/venv/lib/python3.9/site-packages/black",
"python.formatting.provider": "black",
"python.formatting.yapfPath": "/opt/netbox/venv/lib/python3.9/site-packages/yapf",
"python.linting.banditPath": "/opt/netbox/venv/lib/python3.9/site-packages/bandit",
"python.linting.enabled": true,
"python.linting.flake8Path": "/opt/netbox/venv/lib/python3.9/site-packages/flake8",
"python.linting.mypyPath": "/opt/netbox/venv/lib/python3.9/site-packages/mypy",
"python.linting.pycodestylePath": "/opt/netbox/venv/lib/python3.9/site-packages/pycodestyle",
"python.linting.pydocstylePath": "/opt/netbox/venv/lib/python3.9/site-packages/pydocstyle",
"python.linting.pylintEnabled": true,
"python.linting.pylintPath": "/opt/netbox/venv/lib/python3.9/site-packages/pylint",
"python.pythonPath": "/opt/netbox/venv/bin/python",
"python.terminal.activateEnvironment": true,
"python.venvPath": "/opt/netbox/"
},
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"ms-python.python",
"ms-python.vscode-pylance",
"DavidAnson.vscode-markdownlint",
"searKing.preview-vscode",
"esbenp.prettier-vscode",
"aaron-bond.better-comments",
"GitHub.codespaces",
"codezombiech.gitignore",
"Tyriar.sort-lines"
]
}
},
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// This can be used to network with other containers or the host.
// "forwardPorts": [5000, 5432],
// Use 'postCreateCommand' to run commands after the container is created.
// "postCreateCommand": "pip install --user -r requirements-dev.txt",
//"postAttachCommand": "source /opt/netbox/venv/bin/activate",
// Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
"remoteUser": "vscode"
}

View File

@ -0,0 +1,12 @@
version: '3.4'
services:
netbox:
image: netbox-plugin_dev
build:
dockerfile: Dockerfile-plugin_dev
ports:
- 8000:8080
volumes:
- ../:/opt/netbox/netbox/netbox-access-lists
- ~/.gitconfig:/home/vscode/.gitconfig:z,ro
- ~/.ssh:/home/vscode/.ssh

View File

@ -0,0 +1,64 @@
version: '3.4'
services:
netbox: &netbox
image: tgenannt/netbox:${VARIANT-latest}
depends_on:
- postgres
- redis
#- redis-cache
- netbox-worker
env_file: env/netbox.env
user: 'unit:root'
volumes:
- ./initializers:/opt/netbox/initializers:z,ro
- ./configuration:/etc/netbox/config:z,ro
#- netbox-media-files:/opt/netbox/netbox/media:z
netbox-worker:
<<: *netbox
depends_on:
- redis
- postgres
command:
- /opt/netbox/venv/bin/python
- /opt/netbox/netbox/manage.py
- rqworker
#netbox-housekeeping:
# <<: *netbox
# depends_on:
# - redis
# - postgres
# command:
# - /opt/netbox/housekeeping.sh
# postgres
postgres:
image: postgres:14-alpine
env_file: env/postgres.env
volumes:
- netbox-postgres-data:/var/lib/postgresql/data
# redis
redis:
image: redis:6-alpine
command:
- sh
- -c # this is to evaluate the $REDIS_PASSWORD from the env
- redis-server --appendonly yes --requirepass $$REDIS_PASSWORD ## $$ because of docker-compose
env_file: env/redis.env
#volumes:
# - netbox-redis-data:/data
#redis-cache:
# image: redis:6-alpine
# command:
# - sh
# - -c # this is to evaluate the $REDIS_PASSWORD from the env
# - redis-server --requirepass $$REDIS_PASSWORD ## $$ because of docker-compose
# env_file: env/redis-cache.env
volumes:
#netbox-media-files:
# driver: local
netbox-postgres-data:
driver: local
#netbox-redis-data:
# driver: local

View File

@ -0,0 +1,32 @@
#!/bin/bash
USER=vscode
# Reconfigure User id if set by user
if [ ! -z "${USER_UID}" ] && [ "${USER_UID}" != "`id -u ${USER}`" ] ; then
echo -n "Update uid for user ${USER} with ${USER_UID}"
usermod -u ${USER_UID} ${USER}
echo "... updated"
else
echo "skipping UID configuration"
fi
if [ -n "${USER_GID}" ] && [ "${USER_GID}" != "`id -g ${USER}`" ] ; then
echo -n "Update gid for group ${USER} with ${USER_GID}"
usermod -u ${USER_UID} ${USER}
echo "... updated"
else
echo "skipping GID configuration"
fi
#if [ -z "$SSH_AUTH_SOCK" ]; then
# # Check for a currently running instance of the agent
# RUNNING_AGENT="`ps -ax | grep 'ssh-agent -s' | grep -v grep | wc -l | tr -d '[:space:]'`"
# if [ "$RUNNING_AGENT" = "0" ]; then
# # Launch a new instance of the agent
# ssh-agent -s &> $HOME/.ssh/ssh-agent
# fi
# eval `cat $HOME/.ssh/ssh-agent`
#fi
/bin/sh -c "while sleep 1000; do :; done"

20
.devcontainer/env/netbox.env vendored Normal file
View File

@ -0,0 +1,20 @@
ALLOWED_HOSTS=*
CORS_ORIGIN_ALLOW_ALL=True
DB_HOST=postgres
DB_NAME=netbox
DB_PASSWORD=J5brHrAXFLQSif0K
DB_USER=netbox
DEBUG=true
GRAPHQL_ENABLED=true
MAX_PAGE_SIZE=1000
MEDIA_ROOT=/opt/netbox/netbox/media
REDIS_DATABASE=0
REDIS_HOST=redis
REDIS_INSECURE_SKIP_TLS_VERIFY=false
REDIS_PASSWORD=H733Kdjndks81
SECRET_KEY=r8OwDznj!!dciP9ghmRfdu1Ysxm0AiPeDCQhKE+N_rClfWNj
SUPERUSER_API_TOKEN=0123456789abcdef0123456789abcdef01234567
SUPERUSER_EMAIL=admin@example.com
SUPERUSER_NAME=admin
SUPERUSER_PASSWORD=admin
WEBHOOKS_ENABLED=true

3
.devcontainer/env/postgres.env vendored Normal file
View File

@ -0,0 +1,3 @@
POSTGRES_DB=netbox
POSTGRES_PASSWORD=J5brHrAXFLQSif0K
POSTGRES_USER=netbox

1
.devcontainer/env/redis.env vendored Normal file
View File

@ -0,0 +1 @@
REDIS_PASSWORD=H733Kdjndks81

View File

@ -0,0 +1,7 @@
- prefix: 10.0.0.0/16
rir: RFC1918
tenant: tenant1
- prefix: fd00:ccdd::/32
rir: RFC4193 ULA
- prefix: 2001:db8::/32
rir: RFC3849

View File

@ -0,0 +1,7 @@
- asn: 1
rir: RFC1918
tenant: tenant1
- asn: 2
rir: RFC4193 ULA
- asn: 3
rir: RFC3849

View File

@ -0,0 +1,6 @@
- name: VPLS
slug: vpls
- name: MPLS
slug: mpls
- name: Internet
slug: internet

View File

@ -0,0 +1,7 @@
- cid: Circuit_ID-1
provider: Provider1
type: Internet
tenant: tenant1
- cid: Circuit_ID-2
provider: Provider2
type: MPLS

View File

@ -0,0 +1,4 @@
- name: Group 1
slug: group-1
- name: Group 2
slug: group-2

View File

@ -0,0 +1,2 @@
- name: Hyper-V
slug: hyper-v

View File

@ -0,0 +1,7 @@
- name: cluster1
type: Hyper-V
group: Group 1
tenant: tenant1
- name: cluster2
type: Hyper-V
site: SING 1

View File

@ -0,0 +1,18 @@
#Possible Choices:
# type:
# - virtual
# - lag
# - 1000base-t
# - ... and many more. See for yourself:
# https://github.com/netbox-community/netbox/blob/295d4f0394b431351c0cb2c3ecc791df68c6c2fb/netbox/dcim/choices.py#L510
##
#Examples:
- device: server01
enabled: true
type: virtual
name: to-server02
- device: server02
enabled: true
type: virtual
name: to-server01

View File

@ -0,0 +1,15 @@
- name: switch
slug: switch
color: Grey
- name: router
slug: router
color: Cyan
- name: load-balancer
slug: load-balancer
color: Red
- name: server
slug: server
color: Blue
- name: patchpanel
slug: patchpanel
color: Black

View File

@ -0,0 +1,15 @@
- model: Model 1
manufacturer: Manufacturer 1
slug: model-1
u_height: 2
- model: Model 2
manufacturer: Manufacturer 1
slug: model-2
- model: Model 3
manufacturer: Manufacturer 1
slug: model-3
is_full_depth: false
u_height: 0
- model: Other
manufacturer: No Name
slug: other

View File

@ -0,0 +1,45 @@
#Possible Choices:
# face:
# - front
# - rear
# status:
# - offline
# - active
# - planned
# - staged
# - failed
# - inventory
# - decommissioning
##
#Examples:
- name: server01
device_role: server
device_type: Other
site: AMS 1
rack: rack-01
face: front
position: 1
- name: server02
device_role: server
device_type: Other
site: AMS 2
rack: rack-02
face: front
position: 2
primary_ip4: 10.1.1.2/24
primary_ip6: 2001:db8:a000:1::2/64
- name: server03
device_role: server
device_type: Other
site: SING 1
rack: rack-03
face: front
position: 3
- name: server04
device_role: server
device_type: Other
site: SING 1
location: cage 101
face: front
position: 3

View File

@ -0,0 +1,9 @@
# applications:
# users:
# - technical_user
# readers:
# users:
# - reader
# writers:
# users:
# - writer

View File

@ -0,0 +1,44 @@
#Possible Choices:
# status:
# - active
# - reserved
# - deprecated
# - dhcp
# role:
# - loopback
# - secondary
# - anycast
# - vip
# - vrrp
# - hsrp
# - glbp
# - carp
##
#Examples:
- address: 10.1.1.1/24
device: server01
interface: to-server02
status: active
vrf: vrf1
- address: 2001:db8:a000:1::1/64
device: server01
interface: to-server02
status: active
vrf: vrf1
- address: 10.1.1.2/24
device: server02
interface: to-server01
status: active
- address: 2001:db8:a000:1::2/64
device: server02
interface: to-server01
status: active
- address: 10.1.1.10/24
description: reserved IP
status: reserved
tenant: tenant1
- address: 2001:db8:a000:1::10/64
description: reserved IP
status: reserved
tenant: tenant1

View File

@ -0,0 +1,3 @@
- name: cage 101
slug: cage-101
site: SING 1

View File

@ -0,0 +1,6 @@
- name: Manufacturer 1
slug: manufacturer-1
- name: Manufacturer 2
slug: manufacturer-2
- name: No Name
slug: no-name

View File

@ -0,0 +1,48 @@
# all.ro:
# actions:
# - view
# description: 'Read Only for All Objects'
# enabled: true
# groups:
# - applications
# - readers
# object_types: all
# users:
# - jdoe
# all.rw:
# actions:
# - add
# - change
# - delete
# - view
# description: 'Read/Write for All Objects'
# enabled: true
# groups:
# - writers
# object_types: all
# network_team.rw:
# actions:
# - add
# - change
# - delete
# - view
# description: "Network Team Permissions"
# enabled: true
# object_types:
# circuits:
# - circuit
# - circuittermination
# - circuittype
# - provider
# dcim: all
# ipam:
# - aggregate
# - ipaddress
# - prefix
# - rir
# - role
# - routetarget
# - service
# - vlan
# - vlangroup
# - vrf

View File

@ -0,0 +1,15 @@
- name: Platform 1
slug: platform-1
manufacturer: Manufacturer 1
napalm_driver: driver1
napalm_args: "{'arg1': 'value1', 'arg2': 'value2'}"
- name: Platform 2
slug: platform-2
manufacturer: Manufacturer 2
napalm_driver: driver2
napalm_args: "{'arg1': 'value1', 'arg2': 'value2'}"
- name: Platform 3
slug: platform-3
manufacturer: No Name
napalm_driver: driver3
napalm_args: "{'arg1': 'value1', 'arg2': 'value2'}"

View File

@ -0,0 +1,14 @@
- name: power feed 1
power_panel: power panel AMS 1
voltage: 208
amperage: 50
max_utilization: 80
phase: Single phase
rack: rack-01
- name: power feed 2
power_panel: power panel SING 1
voltage: 208
amperage: 50
max_utilization: 80
phase: Three-phase
rack: rack-03

View File

@ -0,0 +1,5 @@
- name: power panel AMS 1
site: AMS 1
- name: power panel SING 1
site: SING 1
location: cage 101

View File

@ -0,0 +1,2 @@
- name: Main Management
slug: main-management

View File

@ -0,0 +1,29 @@
#Possible Choices:
# status:
# - container
# - active
# - reserved
# - deprecated
##
#Examples:
- description: prefix1
prefix: 10.1.1.0/24
site: AMS 1
status: active
tenant: tenant1
vlan: vlan1
- description: prefix2
prefix: 10.1.2.0/24
site: AMS 2
status: active
tenant: tenant2
vlan: vlan2
is_pool: true
vrf: vrf2
- description: ipv6 prefix1
prefix: 2001:db8:a000:1::/64
site: AMS 2
status: active
tenant: tenant2
vlan: vlan2

View File

@ -0,0 +1,6 @@
- name: Provider1
slug: provider1
asn: 121
- name: Provider2
slug: provider2
asn: 122

View File

@ -0,0 +1,12 @@
- name: Role 1
slug: role-1
color: Pink
- name: Role 2
slug: role-2
color: Cyan
- name: Role 3
slug: role-3
color: Grey
- name: Role 4
slug: role-4
color: Teal

View File

@ -0,0 +1,35 @@
#Possible Choices:
# width:
# - 19
# - 23
# types:
# - 2-post-frame
# - 4-post-frame
# - 4-post-cabinet
# - wall-frame
# - wall-cabinet
# outer_unit:
# - mm
# - in
##
#Examples:
- site: AMS 1
name: rack-01
role: Role 1
type: 4-post-cabinet
width: 19
u_height: 47
- site: AMS 2
name: rack-02
role: Role 2
type: 4-post-cabinet
width: 19
u_height: 47
- site: SING 1
name: rack-03
location: cage 101
role: Role 3
type: 4-post-cabinet
width: 19
u_height: 47

View File

@ -0,0 +1,10 @@
- name: Singapore
slug: singapore
- name: Amsterdam
slug: amsterdam
- name: Downtown
slug: downtown
parent: Amsterdam
- name: Suburbs
slug: suburbs
parent: Amsterdam

View File

@ -0,0 +1,9 @@
- is_private: true
name: RFC1918
slug: rfc1918
- is_private: true
name: RFC4193 ULA
slug: rfc4193-ula
- is_private: true
name: RFC3849
slug: rfc3849

View File

@ -0,0 +1,3 @@
- name: 65000:1001
tenant: tenant1
- name: 65000:1002

View File

@ -0,0 +1,15 @@
- name: DNS
protocol: TCP
ports:
- 53
virtual_machine: virtual machine 1
- name: DNS
protocol: UDP
ports:
- 53
virtual_machine: virtual machine 1
- name: MISC
protocol: UDP
ports:
- 4000
device: server01

View File

@ -0,0 +1,22 @@
- name: AMS 1
slug: ams1
region: Downtown
status: active
facility: Amsterdam 1
- name: AMS 2
slug: ams2
region: Downtown
status: active
facility: Amsterdam 2
- name: AMS 3
slug: ams3
region: Suburbs
status: active
facility: Amsterdam 3
tenant: tenant1
- name: SING 1
slug: sing1
region: Singapore
status: active
facility: Singapore 1
tenant: tenant2

View File

@ -0,0 +1,12 @@
- name: Tag 1
slug: tag-1
color: Pink
- name: Tag 2
slug: tag-2
color: Cyan
- name: Tag 3
slug: tag-3
color: Grey
- name: Tag 4
slug: tag-4
color: Teal

View File

@ -0,0 +1,4 @@
- name: Tenant Group 1
slug: tenant-group-1
- name: Tenant Group 2
slug: tenant-group-2

View File

@ -0,0 +1,5 @@
- name: tenant1
slug: tenant1
- name: tenant2
slug: tenant2
group: Tenant Group 2

View File

@ -0,0 +1,6 @@
admin:
api_token: 0123456789admin789abcdef01234567admin
is_active: True
is_staff: True
is_superuser: True
password: admin

View File

@ -0,0 +1,28 @@
#Possible Choices:
# status:
# - active
# - offline
# - staged
##
#Examples:
- cluster: cluster1
comments: VM1
disk: 200
memory: 4096
name: virtual machine 1
platform: Platform 2
status: active
tenant: tenant1
vcpus: 8
- cluster: cluster1
comments: VM2
disk: 100
memory: 2048
name: virtual machine 2
platform: Platform 2
primary_ip4: 10.1.1.10/24
primary_ip6: 2001:db8:a000:1::10/64
status: active
tenant: tenant1
vcpus: 8

View File

@ -0,0 +1,12 @@
- description: Network Interface 1
enabled: true
mac_address: 00:77:77:77:77:77
mtu: 1500
name: Network Interface 1
virtual_machine: virtual machine 1
- description: Network Interface 2
enabled: true
mac_address: 00:55:55:55:55:55
mtu: 1500
name: Network Interface 2
virtual_machine: virtual machine 1

View File

@ -0,0 +1,24 @@
- name: VLAN group 1
scope_type: dcim.region
scope: Amsterdam
slug: vlan-group-1
- name: VLAN group 2
scope_type: dcim.site
scope: AMS 1
slug: vlan-group-2
- name: VLAN group 3
scope_type: dcim.location
scope: cage 101
slug: vlan-group-3
- name: VLAN group 4
scope_type: dcim.rack
scope: rack-01
slug: vlan-group-4
- name: VLAN group 5
scope_type: virtualization.cluster
scope: cluster1
slug: vlan-group-5
- name: VLAN group 6
scope_type: virtualization.clustergroup
scope: Group 1
slug: vlan-group-6

View File

@ -0,0 +1,19 @@
#Possible Choices:
# status:
# - active
# - reserved
# - deprecated
##
#Examples:
- name: vlan1
site: AMS 1
status: active
vid: 5
role: Main Management
description: VLAN 5 for MGMT
- group: VLAN group 2
name: vlan2
site: AMS 1
status: active
vid: 1300

View File

@ -0,0 +1,8 @@
- enforce_unique: true
name: vrf1
tenant: tenant1
description: main VRF
- enforce_unique: true
name: vrf2
rd: "6500:6500"
tenant: tenant2

View File

@ -0,0 +1,27 @@
#Possible Choices:
# object_types:
# - device
# - site
# - any-other-content-type
# types:
# - type_create
# - type_update
# - type_delete
#Examples:
- name: device_creation
payload_url: 'http://localhost:8080'
object_types:
- device
- cable
type_create: True
- name: device_update
payload_url: 'http://localhost:8080'
object_types:
- device
type_update: True
- name: device_delete
payload_url: 'http://localhost:8080'
object_types:
- device
type_delete: True

View File

@ -0,0 +1,11 @@
autopep8
bandit
black
flake8
isort
mypy
pre-commit
pycodestyle
pydocstyle
pylint
yapf

163
.gitignore vendored Normal file
View File

@ -0,0 +1,163 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
#.env
.venv
#env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
# VS Code
.vscode/

57
.pre-commit-config.yaml Normal file
View File

@ -0,0 +1,57 @@
repos:
- repo: 'https://github.com/pre-commit/pre-commit-hooks'
rev: v4.3.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-merge-conflict
- id: debug-statements
- id: name-tests-test
- id: requirements-txt-fixer
- id: check-docstring-first
- repo: 'https://github.com/asottile/add-trailing-comma'
rev: v2.2.3
hooks:
- id: add-trailing-comma
args:
- '--py36-plus'
- repo: 'https://github.com/asottile/pyupgrade'
rev: v2.34.0
hooks:
- id: pyupgrade
args:
- '--py37-plus'
- repo: 'https://github.com/PyCQA/isort'
rev: 5.10.1
hooks:
- id: isort
args:
- '--filter-files'
- repo: 'https://github.com/psf/black'
rev: 22.6.0
hooks:
- id: black
language_version: python3
#- repo: 'https://github.com/adrienverge/yamllint'
# rev: v1.26.3
# hooks:
# - id: yamllint
- repo: 'https://github.com/psf/black'
rev: 22.6.0
hooks:
- id: black
- repo: 'https://github.com/igorshubovych/markdownlint-cli'
rev: v0.31.1
hooks:
- id: markdownlint
- repo: local
hooks:
- repo: local
hooks:
- id: wily
name: wily
entry: wily diff
verbose: true
language: python
additional_dependencies: [wily]

82
Makefile Normal file
View File

@ -0,0 +1,82 @@
PLUGIN_NAME=netbox_access_lists
REPO_PATH=/opt/netbox/netbox/netbox-access-lists
VENV_PY_PATH=/opt/netbox/venv/bin/python3
NETBOX_MANAGE_PATH=/opt/netbox/netbox/manage.py
VERFILE=./version.py
.PHONY: help
help: ## Display help message
@grep -E '^[0-9a-zA-Z_-]+\.*[0-9a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
#################
# DOCKER #
#################
# Outside of Devcontainer
.PHONY: cleanup
cleanup: ## Clean associated docker resources.
-docker-compose -p netbox-access-lists_devcontainer rm -fv
##################
# PLUGIN DEV #
##################
# in VS Code Devcontianer
.PHONY: setup
setup: ## Copy plugin settings. Setup NetBox plugin.
-${VENV_PY_PATH} -m pip install --disable-pip-version-check --no-cache-dir -e ${REPO_PATH}
#-python3 setup.py develop
.PHONY: makemigrations
makemigrations: ## Run makemigrations
-${VENV_PY_PATH} ${NETBOX_MANAGE_PATH} makemigrations --name ${PLUGIN_NAME}
.PHONY: migrate
migrate: ## Run migrate
-${VENV_PY_PATH} ${NETBOX_MANAGE_PATH} migrate
.PHONY: startup_scripts
startup_scripts:
-echo "import runpy; runpy.run_path('/opt/netbox/startup_scripts')" | ${NETBOX_MANAGE_PATH} shell --interface python
.PHONY: collectstatic
collectstatic:
-${VENV_PY_PATH} ${NETBOX_MANAGE_PATH} collectstatic --no-input
.PHONY: start
start: ## Start NetBox
-${VENV_PY_PATH} ${NETBOX_MANAGE_PATH} runserver
.PHONY: all
all: setup makemigrations migrate collectstatic startup_scripts start ## Run all PLUGIN DEV targets
#.PHONY: test
#test:
# ${VENV_PY_PATH} /opt/netbox/netbox/manage.py runserver test ${PLUGIN_NAME}
#relpatch:
# $(eval GSTATUS := $(shell git status --porcelain))
#ifneq ($(GSTATUS),)
# $(error Git status is not clean. $(GSTATUS))
#endif
# git checkout develop
# git remote update
# git pull origin develop
# $(eval CURVER := $(shell cat $(VERFILE) | grep -oE '[0-9]+\.[0-9]+\.[0-9]+'))
# $(eval NEWVER := $(shell pysemver bump patch $(CURVER)))
# $(eval RDATE := $(shell date '+%Y-%m-%d'))
# git checkout -b release-$(NEWVER) origin/develop
# echo '__version__ = "$(NEWVER)"' > $(VERFILE)
# git commit -am 'bump ver'
# git push origin release-$(NEWVER)
# git checkout develop
#pbuild:
# ${VENV_PY_PATH} -m pip install --upgrade build
# ${VENV_PY_PATH} -m build
#
#pypipub:
# ${VENV_PY_PATH} -m pip install --upgrade twine
# ${VENV_PY_PATH} -m twine upload dist/*

4
TODO Normal file
View File

@ -0,0 +1,4 @@
- https://code.visualstudio.com/remote/advancedcontainers/connect-multiple-containers
- docker from docker
- slim down netbox-docker
- make

View File

@ -0,0 +1 @@
__version__ = "0.0.0"

29
pyproject.toml Normal file
View File

@ -0,0 +1,29 @@
[tool.black]
line-length = 100
[tool.pylint]
[tool.pylint.format]
max-line-length = 100
[tool.pylint.master]
# pylint defaults + fh for with open .. as (f|fh)
good-names = "i,j,k,ex,Run,_,f,fh"
no-docstring-rgx = "__.*__"
[tool.pylint.messages_control]
# missing module docstring will be picked up by pydocstyle
# could not do infile b/c older version of pylint didn't have it
# and ansible-test sanity uses older version in earlier ansible
# pointless-string-statement allows for attribute docstring in dataclasses
disable = [
"duplicate-code",
"fixme",
"missing-module-docstring",
"pointless-string-statement",
"too-few-public-methods",
"unsubscriptable-object",
]
enable = [
"useless-suppression", # Identify unneeded pylint disable statements
]

View File

@ -1,9 +1,36 @@
#import codecs
#import os.path
#
from setuptools import find_packages, setup
#
#
#with open("README.md", "r") as fh:
# long_description = fh.read()
#
#
#def read(rel_path):
# here = os.path.abspath(os.path.dirname(__file__))
# with codecs.open(os.path.join(here, rel_path), 'r') as fp:
# return fp.read()
#
#
#def get_version(rel_path):
# for line in read(rel_path).splitlines():
# if line.startswith('__version__'):
# delim = '"' if '"' in line else "'"
# return line.split(delim)[1]
# else:
# raise RuntimeError("Unable to find version string.")
#
setup(
name='netbox-access-lists',
version='0.2',
version='0.1.0',
#version=get_version('netbox_access_lists/version.py'),
description='A NetBox plugin for Access-List management',
#long_description=long_description,
long_description_content_type="text/markdown",
url='https://github.com/ryanmerolle/netbox-access-lists',
install_requires=[],
packages=find_packages(),
include_package_data=True,