1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

Merge branch 'develop' into develop-2.10

This commit is contained in:
Jeremy Stretch
2020-12-10 10:26:15 -05:00
12 changed files with 124 additions and 112 deletions

50
.github/workflows/ci.yml vendored Normal file
View File

@ -0,0 +1,50 @@
name: CI
on: push
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.6, 3.7, 3.8]
services:
redis:
image: redis
ports:
- 6379:6379
postgres:
image: postgres
env:
POSTGRES_USER: netbox
POSTGRES_PASSWORD: netbox
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
steps:
- name: Check out repo
uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies & set up configuration
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install pycodestyle coverage
ln -s configuration.testing.py netbox/netbox/configuration.py
- name: Check PEP8 compliance
run: pycodestyle --ignore=W504,E501 netbox/
- name: Run tests
run: coverage run --source="netbox/" netbox/manage.py test netbox/
- name: Show coverage report
run: coverage report --skip-covered --omit *migrations*

View File

@ -1,20 +0,0 @@
sudo: required
services:
- postgresql
- redis-server
addons:
postgresql: "9.6"
language: python
python:
- "3.6"
- "3.7"
- "3.8"
install:
- pip install -r requirements.txt
- pip install pycodestyle
- pip install coverage
before_script:
- psql --version
- psql -U postgres -c 'SELECT version();'
script:
- ./scripts/cibuild.sh

View File

@ -4,15 +4,31 @@ If you encounter any issues installing or using NetBox, try one of the
following resources to get assistance. Please **do not** open a GitHub issue
except to report bugs or request features.
### GitHub Discussions
GitHub's discussions are the best place to get help or propose rough ideas for
new functionality. Their integration with GitHub allows for easily cross-
referencing and converting posts to issues as needed. There are several
categories for discussions:
* **General** - General community discussion
* **Ideas** - Ideas for new functionality that isn't yet ready for a formal
feature request
* **Q&A** - Request help with installing or using NetBox
### Mailing List
We have established a Google Groups Mailing List for issues and general
discussion. This is the best forum for obtaining assistance with NetBox
installation. You can find us [here](https://groups.google.com/g/netbox-discuss).
We also have a Google Groups [mailing list](https://groups.google.com/g/netbox-discuss)
for general discussion, however we're encouraging people to use GitHub
discussions where possible, as it's much easier for newcomers to review past
discussions.
### Slack
For real-time discussion, you can join the #netbox Slack channel on [NetworkToCode](https://slack.networktocode.com/).
For real-time chat, you can join the **#netbox** Slack channel on [NetworkToCode](https://slack.networktocode.com/).
Unfortunately, the Slack channel does not provide long-term retention of chat
history, so try to avoid it for any discussions would benefit from being
preserved for future reference.
## Reporting Bugs
@ -171,7 +187,7 @@ overlooked.
* Official channels for communication include:
* GitHub issues/pull requests
* GitHub issues, pull requests, and discussions
* The [netbox-discuss](https://groups.google.com/g/netbox-discuss) mailing list
* The **#netbox** channel on [NetworkToCode Slack](https://networktocode.slack.com/)

View File

@ -12,15 +12,15 @@ complete list of requirements, see `requirements.txt`. The code is available [on
The complete documentation for NetBox can be found at [Read the Docs](http://netbox.readthedocs.io/en/stable/).
Questions? Comments? Please subscribe to [the netbox-discuss mailing list](https://groups.google.com/g/netbox-discuss),
or join us in the #netbox Slack channel on [NetworkToCode](https://networktocode.slack.com/)!
Questions? Comments? Please start a [discussion on GitHub](https://github.com/netbox-community/netbox/discussions),
or join us in the **#netbox** Slack channel on [NetworkToCode](https://networktocode.slack.com/)!
### Build Status
| | status |
|-------------|------------|
| **master** | [![Build Status](https://travis-ci.org/netbox-community/netbox.svg?branch=master)](https://travis-ci.com/netbox-community/netbox/) |
| **develop** | [![Build Status](https://travis-ci.org/netbox-community/netbox.svg?branch=develop)](https://travis-ci.com/netbox-community/netbox/) |
| **master** | ![Build status](https://github.com/netbox-community/netbox/workflows/CI/badge.svg?branch=master) |
| **develop** | ![Build status](https://github.com/netbox-community/netbox/workflows/CI/badge.svg?branch=develop) |
### Screenshots

View File

@ -3,7 +3,7 @@
This documentation provides example configurations for both [nginx](https://www.nginx.com/resources/wiki/) and [Apache](http://httpd.apache.org/docs/current/), though any HTTP server which supports WSGI should be compatible.
!!! info
For the sake of brevity, only Ubuntu 20.04 instructions are provided here, these tasks not unique to NetBox and should carry over to other distributions with mininal changes. Please consult your distribution's documentation for assistance if needed.
For the sake of brevity, only Ubuntu 20.04 instructions are provided here. These tasks are not unique to NetBox and should carry over to other distributions with minimal changes. Please consult your distribution's documentation for assistance if needed.
## Obtain an SSL Certificate

View File

@ -2,9 +2,18 @@
## v2.9.11 (FUTURE)
### Enhancements
* [#5424](https://github.com/netbox-community/netbox/issues/5424) - Allow passing Python code to `nbshell` using `--command`
### Bug Fixes
* [#5383](https://github.com/netbox-community/netbox/issues/5383) - Fix setting user password via REST API
* [#5396](https://github.com/netbox-community/netbox/issues/5396) - Fix uniqueness constraint for virtual machine names
* [#5407](https://github.com/netbox-community/netbox/issues/5407) - Add direct link to secret on secrets list
* [#5408](https://github.com/netbox-community/netbox/issues/5408) - Fix updating secrets without setting new plaintext
* [#5410](https://github.com/netbox-community/netbox/issues/5410) - Restore tags field on cable connection forms
* [#5436](https://github.com/netbox-community/netbox/issues/5436) - Show assigned IP addresses in interfaces list
---

View File

@ -25,12 +25,18 @@ class Command(BaseCommand):
help = "Start the Django shell with all NetBox models already imported"
django_models = {}
def add_arguments(self, parser):
parser.add_argument(
'-c', '--command',
help='Python code to execute (instead of starting an interactive shell)',
)
def _lsmodels(self):
for app, models in self.django_models.items():
app_name = apps.get_app_config(app).verbose_name
print('{}:'.format(app_name))
print(f'{app_name}:')
for m in models:
print(' {}'.format(m))
print(f' {m}')
def get_namespace(self):
namespace = {}
@ -46,7 +52,7 @@ class Command(BaseCommand):
# Constants
try:
app_constants = sys.modules['{}.constants'.format(app)]
app_constants = sys.modules[f'{app}.constants']
for name in dir(app_constants):
namespace[name] = getattr(app_constants, name)
except KeyError:
@ -64,5 +70,10 @@ class Command(BaseCommand):
return namespace
def handle(self, **options):
# If Python code has been passed, execute it and exit.
if options['command']:
exec(options['command'], self.get_namespace())
return
shell = code.interact(banner=BANNER_TEXT, local=self.get_namespace())
return shell

View File

@ -7,8 +7,8 @@ ALLOWED_HOSTS = ['*']
DATABASE = {
'NAME': 'netbox',
'USER': '',
'PASSWORD': '',
'USER': 'netbox',
'PASSWORD': 'netbox',
'HOST': 'localhost',
'PORT': '',
'CONN_MAX_AGE': 300,

View File

@ -30,15 +30,21 @@ class SecretRoleTable(BaseTable):
class SecretTable(BaseTable):
pk = ToggleColumn()
id = tables.Column( # Provides a link to the secret
linkify=True
)
assigned_object = tables.Column(
linkify=True,
verbose_name='Assigned object'
)
role = tables.Column(
linkify=True
)
tags = TagColumn(
url_name='secrets:secret_list'
)
class Meta(BaseTable.Meta):
model = Secret
fields = ('pk', 'assigned_object', 'role', 'name', 'last_updated', 'hash', 'tags')
default_columns = ('pk', 'assigned_object', 'role', 'name', 'last_updated')
fields = ('pk', 'id', 'assigned_object', 'role', 'name', 'last_updated', 'hash', 'tags')
default_columns = ('pk', 'id', 'assigned_object', 'role', 'name', 'last_updated')

View File

@ -98,13 +98,14 @@ class SecretEditView(generic.ObjectEditView):
if form.is_valid():
logger.debug("Form validation was successful")
secret = form.save(commit=False)
# We must have a session key in order to create a secret or update the plaintext of an existing secret
if (form.cleaned_data['plaintext'] or secret.pk is None) and session_key is None:
# We must have a session key in order to set the plaintext of a Secret
if form.cleaned_data['plaintext'] and session_key is None:
logger.debug("Unable to proceed: No session key was provided with the request")
form.add_error(None, "No session key was provided with the request. Unable to encrypt secret data.")
else:
elif form.cleaned_data['plaintext']:
master_key = None
try:
sk = SessionKey.objects.get(userkey__user=request.user)
@ -115,19 +116,18 @@ class SecretEditView(generic.ObjectEditView):
if master_key is not None:
logger.debug("Successfully resolved master key for encryption")
secret = form.save(commit=False)
if form.cleaned_data['plaintext']:
secret.plaintext = str(form.cleaned_data['plaintext'])
secret.plaintext = str(form.cleaned_data['plaintext'])
secret.encrypt(master_key)
secret.save()
form.save_m2m()
msg = '{} secret'.format('Created' if not form.instance.pk else 'Modified')
logger.info(f"{msg} {secret} (PK: {secret.pk})")
msg = '{} <a href="{}">{}</a>'.format(msg, secret.get_absolute_url(), escape(secret))
messages.success(request, mark_safe(msg))
secret.save()
form.save_m2m()
return redirect(self.get_return_url(request, secret))
msg = '{} secret'.format('Created' if not form.instance.pk else 'Modified')
logger.info(f"{msg} {secret} (PK: {secret.pk})")
msg = f'{msg} <a href="{secret.get_absolute_url()}">{escape(secret)}</a>'
messages.success(request, mark_safe(msg))
return redirect(self.get_return_url(request, secret))
else:
logger.debug("Form validation failed")

View File

@ -308,10 +308,10 @@ class VirtualMachine(ChangeLoggedModel, ConfigContextModel, CustomFieldModel):
# because Django does not consider two NULL fields to be equal, and thus will not trigger a violation
# of the uniqueness constraint without manual intervention.
if self.tenant is None and VirtualMachine.objects.exclude(pk=self.pk).filter(
name=self.name, tenant__isnull=True
name=self.name, cluster=self.cluster, tenant__isnull=True
):
raise ValidationError({
'name': 'A virtual machine with this name already exists.'
'name': 'A virtual machine with this name already exists in the assigned cluster.'
})
super().validate_unique(exclude)

View File

@ -1,60 +0,0 @@
#!/bin/bash
# Exit code starts at 0 but is modified if any checks fail
EXIT=0
# Output a line prefixed with a timestamp
info()
{
echo "$(date +'%F %T') |"
}
# Track number of seconds required to run script
START=$(date +%s)
echo "$(info) starting build checks."
# Syntax check all python source files
SYNTAX=$(find . -name "*.py" -type f -exec python -m py_compile {} \; 2>&1)
if [[ ! -z $SYNTAX ]]; then
echo -e "$SYNTAX"
echo -e "\n$(info) detected one or more syntax errors, failing build."
EXIT=1
fi
# Check all python source files for PEP 8 compliance, but explicitly
# ignore:
# - W504: line break after binary operator
# - E501: line greater than 80 characters in length
pycodestyle \
--ignore=W504,E501 \
netbox/
RC=$?
if [[ $RC != 0 ]]; then
echo -e "\n$(info) one or more PEP 8 errors detected, failing build."
EXIT=$RC
fi
# Point to the testing configuration file for use in CI
ln -s configuration.testing.py netbox/netbox/configuration.py
# Run NetBox tests
coverage run --source="netbox/" netbox/manage.py test netbox/
RC=$?
if [[ $RC != 0 ]]; then
echo -e "\n$(info) one or more tests failed, failing build."
EXIT=$RC
fi
# Show code coverage report
coverage report --skip-covered --omit *migrations*
RC=$?
if [[ $RC != 0 ]]; then
echo -e "\n$(info) failed to generate code coverage report."
EXIT=$RC
fi
# Show build duration
END=$(date +%s)
echo "$(info) exiting with code $EXIT after $(($END - $START)) seconds."
exit $EXIT