Skip to content

Commit

Permalink
Merge pull request #17876 from netbox-community/develop
Browse files Browse the repository at this point in the history
Release v4.1.5
  • Loading branch information
jeremystretch authored Oct 28, 2024
2 parents 4deb6e5 + 8133471 commit 58d9057
Show file tree
Hide file tree
Showing 67 changed files with 76,833 additions and 88,078 deletions.
5 changes: 2 additions & 3 deletions .github/ISSUE_TEMPLATE/01-feature_request.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ body:
attributes:
label: NetBox version
description: What version of NetBox are you currently running?
placeholder: v4.1.4
placeholder: v4.1.5
validations:
required: true
- type: dropdown
Expand All @@ -36,9 +36,8 @@ body:
options:
- I volunteer to perform this work (if approved)
- I'm a NetBox Labs customer
- This is a very minor change
- N/A
default: 3
default: 2
validations:
required: true
- type: textarea
Expand Down
5 changes: 2 additions & 3 deletions .github/ISSUE_TEMPLATE/02-bug_report.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,15 @@ body:
options:
- I volunteer to perform this work (if approved)
- I'm a NetBox Labs customer
- This is preventing me from using NetBox
- N/A
default: 3
default: 2
validations:
required: true
- type: input
attributes:
label: NetBox Version
description: What version of NetBox are you currently running?
placeholder: v4.1.4
placeholder: v4.1.5
validations:
required: true
- type: dropdown
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<div align="center">
<img src="https://raw.githubusercontent.com/netbox-community/netbox/develop/docs/netbox_logo.svg" width="400" alt="NetBox logo" />
<img src="https://raw.githubusercontent.com/netbox-community/netbox/develop/docs/netbox_logo_light.svg" width="400" alt="NetBox logo" />
<p><strong>The cornerstone of every automated network</strong></p>
<a href="https://github.com/netbox-community/netbox/releases"><img src="https://img.shields.io/github/v/release/netbox-community/netbox" alt="Latest release" /></a>
<a href="https://github.com/netbox-community/netbox/blob/master/LICENSE.txt"><img src="https://img.shields.io/badge/license-Apache_2.0-blue.svg" alt="License" /></a>
Expand Down
6 changes: 5 additions & 1 deletion base_requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ django-rich

# Django integration for RQ (Reqis queuing)
# https://github.com/rq/django-rq/blob/master/CHANGELOG.md
django-rq
django-rq<3.0

# Abstraction models for rendering and paginating HTML tables
# https://github.com/jieter/django-tables2/blob/master/CHANGELOG.md
Expand Down Expand Up @@ -116,6 +116,10 @@ PyYAML
# https://github.com/psf/requests/blob/main/HISTORY.md
requests

# rq
# https://github.com/rq/rq/blob/master/CHANGES.md
rq<2.0

# Social authentication framework
# https://github.com/python-social-auth/social-core/blob/master/CHANGELOG.md
social-auth-core
Expand Down
52 changes: 52 additions & 0 deletions docs/administration/authentication/google.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Google

This guide explains how to configure single sign-on (SSO) support for NetBox using [Google OAuth2](https://developers.google.com/identity/protocols/oauth2/web-server) as an authentication backend.

## Google OAuth2 Configuration

1. Log into [console.cloud.google.com](https://console.cloud.google.com/).
2. Create new project for NetBox.
3. Under "APIs and Services" click "OAuth consent screen" and enter the required information.
4. Under "Credentials," click "Create Credentials" and select "OAuth 2.0 Client ID." Select type "Web application."
- "Authorized JavaScript origins" should follow the format `http[s]://<netbox>[:<port>]`
- "Authorized redirect URIs" should follow the format `http[s]://<netbox>[:<port>]/oauth/complete/google-oauth2/`
5. Copy the "Client ID" and "Client Secret" values somewhere convenient.

!!! note
Google requires the NetBox hostname to use a public top-level-domain (e.g. `.com`, `.net`). The use of IP addresses is not permitted (except `127.0.0.1`).

For more information, consult [Google's documentation](https://developers.google.com/identity/protocols/oauth2/web-server#prerequisites).

## NetBox Configuration

### 1. Enter configuration parameters

Enter the following configuration parameters in `configuration.py`, substituting your own values:

```python
REMOTE_AUTH_BACKEND = 'social_core.backends.google.GoogleOAuth2'
SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = '{CLIENT_ID}'
SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = '{CLIENT_SECRET}'
```

### 2. Restart NetBox

Restart the NetBox services so that the new configuration takes effect. This is typically done with the command below:

```no-highlight
sudo systemctl restart netbox
```

## Testing

Log out of NetBox if already authenticated, and click the "Log In" button at top right. You should see the normal login form as well as an option to authenticate using Google. Click that link.

![NetBox Google login form](../../media/authentication/netbox_google_login.png)

You should be redirected to Google's authentication portal. Enter the username/email and password of your test account to continue. You may also be prompted to grant this application access to your account.

![NetBox Google login form](../../media/authentication/google_login_portal.png)

If successful, you will be redirected back to the NetBox UI, and will be logged in as the Google user. You can verify this by navigating to your profile (using the button at top right).

This user account has been replicated locally to NetBox, and can now be assigned groups and permissions.
2 changes: 1 addition & 1 deletion docs/administration/authentication/microsoft-entra-id.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Under the Azure Active Directory dashboard, navigate to **Add > App registration

Enter a name for the registration (e.g. "NetBox") and ensure that the "single tenant" option is selected.

Under "Redirect URI", select "Web" for the platform and enter the path to your NetBox installation, ending with `/oauth/complete/entraid-oauth2/`. Note that this URI **must** begin with `https://` unless you are referencing localhost (for development purposes).
Under "Redirect URI", select "Web" for the platform and enter the path to your NetBox installation, ending with `/oauth/complete/azuread-oauth2/`. Note that this URI **must** begin with `https://` unless you are referencing localhost (for development purposes).

![App registration parameters](../../media/authentication/azure_ad_app_registration.png)

Expand Down
3 changes: 3 additions & 0 deletions docs/customization/custom-scripts.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ script_order = (MyCustomScript, AnotherCustomScript)

Script attributes are defined under a class named `Meta` within the script. These are optional, but encouraged.

!!! warning
These are also defined and used as properties on the base custom script class, so don't use the same names as variables or override them in your custom script.

### `name`

This is the human-friendly names of your script. If omitted, the class name will be used.
Expand Down
2 changes: 1 addition & 1 deletion docs/development/style-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,4 @@ When adding a new dependency, a short description of the package and the URL of

* When referring to NetBox in writing, use the proper form "NetBox," with the letters N and B capitalized. The lowercase form "netbox" should be used in code, filenames, etc. but never "Netbox" or any other deviation.

* There is an SVG form of the NetBox logo at [docs/netbox_logo.svg](../netbox_logo.svg). It is preferred to use this logo for all purposes as it scales to arbitrary sizes without loss of resolution. If a raster image is required, the SVG logo should be converted to a PNG image of the prescribed size.
* There are SVG forms of the NetBox logo for both [light mode](../netbox_logo_light.svg) and [dark mode](../netbox_logo_dark.svg) available. It is preferred to use the SVG logo for all purposes as it scales to arbitrary sizes without loss of resolution. If a raster image is required, the SVG logo should be converted to a PNG image of the desired size.
4 changes: 4 additions & 0 deletions docs/extra.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ img {
margin-right: auto;
}

.md-content img {
background-color: rgba(255, 255, 255, 0.64);
}

/* Tables */
table {
margin-bottom: 24px;
Expand Down
3 changes: 2 additions & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
![NetBox](netbox_logo.svg "NetBox logo"){style="height: 100px; margin-bottom: 3em"}
![NetBox](netbox_logo_light.svg#only-light "NetBox logo"){style="height: 100px; margin-bottom: 3em; background: none;"}
![NetBox](netbox_logo_dark.svg#only-dark "NetBox logo"){style="height: 100px; margin-bottom: 3em; background: none;"}

# The Premier Network Source of Truth

Expand Down
Binary file added docs/media/authentication/google_login_portal.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/media/authentication/netbox_google_login.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 24 additions & 0 deletions docs/netbox_logo_dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes
24 changes: 24 additions & 0 deletions docs/release-notes/version-4.1.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,29 @@
# NetBox v4.1

## v4.1.5 (2024-10-28)

### Enhancements

* [#17789](https://github.com/netbox-community/netbox/issues/17789) - Provide a single "scope" field for bulk editing VLAN group scope assignments

### Bug Fixes

* [#17358](https://github.com/netbox-community/netbox/issues/17358) - Fix validation of overlapping IP ranges
* [#17374](https://github.com/netbox-community/netbox/issues/17374) - Fix styling of highlighted table rows in dark mode
* [#17460](https://github.com/netbox-community/netbox/issues/17460) - Ensure bulk action buttons are consistent for device type components
* [#17635](https://github.com/netbox-community/netbox/issues/17635) - Ensure AbortTransaction is caught when running a custom script with `commit=False`
* [#17685](https://github.com/netbox-community/netbox/issues/17685) - Ensure background jobs are validated before being scheduled
* [#17710](https://github.com/netbox-community/netbox/issues/17710) - Remove cached fields on CableTermination model from GraphQL API
* [#17740](https://github.com/netbox-community/netbox/issues/17740) - Ensure support for image attachments with a `.webp` file extension
* [#17749](https://github.com/netbox-community/netbox/issues/17749) - Restore missing `devicetypes` and `children` fields for several objects in GraphQL API
* [#17754](https://github.com/netbox-community/netbox/issues/17754) - Remove paginator from version history table under plugin view
* [#17759](https://github.com/netbox-community/netbox/issues/17759) - Retain `job_timeout` value when scheduling a recurring custom script
* [#17774](https://github.com/netbox-community/netbox/issues/17774) - Fix SSO login support for Entra ID (formerly Azure AD)
* [#17802](https://github.com/netbox-community/netbox/issues/17802) - Fix background color for bulk rename buttons in list views
* [#17838](https://github.com/netbox-community/netbox/issues/17838) - Adjust `manage.py` to reference `python3` executable

---

## v4.1.4 (2024-10-15)

### Enhancements
Expand Down
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ nav:
- Administration:
- Authentication:
- Overview: 'administration/authentication/overview.md'
- Google: 'administration/authentication/google.md'
- Microsoft Entra ID: 'administration/authentication/microsoft-entra-id.md'
- Okta: 'administration/authentication/okta.md'
- Permissions: 'administration/permissions.md'
Expand Down
6 changes: 4 additions & 2 deletions netbox/core/models/jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ def clean(self):
super().clean()

# Validate the assigned object type
if self.object_type not in ObjectType.objects.with_feature('jobs'):
if self.object_type and self.object_type not in ObjectType.objects.with_feature('jobs'):
raise ValidationError(
_("Jobs cannot be assigned to this object type ({type}).").format(type=self.object_type)
)
Expand Down Expand Up @@ -223,7 +223,7 @@ def enqueue(cls, func, instance=None, name='', user=None, schedule_at=None, inte
rq_queue_name = get_queue_for_model(object_type.model if object_type else None)
queue = django_rq.get_queue(rq_queue_name)
status = JobStatusChoices.STATUS_SCHEDULED if schedule_at else JobStatusChoices.STATUS_PENDING
job = Job.objects.create(
job = Job(
object_type=object_type,
object_id=object_id,
name=name,
Expand All @@ -233,6 +233,8 @@ def enqueue(cls, func, instance=None, name='', user=None, schedule_at=None, inte
user=user,
job_id=uuid.uuid4()
)
job.full_clean()
job.save()

# Run the job immediately, rather than enqueuing it as a background task. Note that this is a synchronous
# (blocking) operation, and execution will pause until the job completes.
Expand Down
3 changes: 2 additions & 1 deletion netbox/dcim/graphql/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ class ModularComponentTemplateType(ComponentTemplateType):

@strawberry_django.type(
models.CableTermination,
exclude=('termination_type', 'termination_id'),
exclude=('termination_type', 'termination_id', '_device', '_rack', '_location', '_site'),
filters=CableTerminationFilter
)
class CableTerminationType(NetBoxObjectType):
Expand Down Expand Up @@ -243,6 +243,7 @@ class DeviceType(ConfigContextMixin, ImageAttachmentsMixin, ContactsMixin, NetBo
consoleserverports: List[Annotated["ConsoleServerPortType", strawberry.lazy('dcim.graphql.types')]]
poweroutlets: List[Annotated["PowerOutletType", strawberry.lazy('dcim.graphql.types')]]
frontports: List[Annotated["FrontPortType", strawberry.lazy('dcim.graphql.types')]]
devicebays: List[Annotated["DeviceBayType", strawberry.lazy('dcim.graphql.types')]]
modulebays: List[Annotated["ModuleBayType", strawberry.lazy('dcim.graphql.types')]]
services: List[Annotated["ServiceType", strawberry.lazy('ipam.graphql.types')]]
inventoryitems: List[Annotated["InventoryItemType", strawberry.lazy('dcim.graphql.types')]]
Expand Down
2 changes: 1 addition & 1 deletion netbox/dcim/models/cables.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ def clean(self):
if self.length is not None and not self.length_unit:
raise ValidationError(_("Must specify a unit when setting a cable length"))

if self._state.adding and (not self.a_terminations or not self.b_terminations):
if self._state.adding and self.pk is None and (not self.a_terminations or not self.b_terminations):
raise ValidationError(_("Must define A and B terminations when creating a new cable."))

if self._terminations_modified:
Expand Down
1 change: 0 additions & 1 deletion netbox/extras/jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ def run_script(self, script, request, data, commit):
script.log_info(message=_("Database changes have been reverted automatically."))
if script.failed:
logger.warning("Script failed")
raise

except Exception as e:
if type(e) is AbortScript:
Expand Down
2 changes: 1 addition & 1 deletion netbox/extras/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def image_upload(instance, filename):

# Rename the file to the provided name, if any. Attempt to preserve the file extension.
extension = filename.rsplit('.')[-1].lower()
if instance.name and extension in ['bmp', 'gif', 'jpeg', 'jpg', 'png']:
if instance.name and extension in ['bmp', 'gif', 'jpeg', 'jpg', 'png', 'webp']:
filename = '.'.join([instance.name, extension])
elif instance.name:
filename = instance.name
Expand Down
2 changes: 2 additions & 0 deletions netbox/ipam/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ def db_type(self, connection):
IPAddressField.register_lookup(lookups.NetHostContained)
IPAddressField.register_lookup(lookups.NetFamily)
IPAddressField.register_lookup(lookups.NetMaskLength)
IPAddressField.register_lookup(lookups.Host)
IPAddressField.register_lookup(lookups.Inet)


class ASNField(models.BigIntegerField):
Expand Down
Loading

0 comments on commit 58d9057

Please sign in to comment.