Add ability to add a comment to change log entries #11288

Closed
opened 2025-12-29 21:42:59 +01:00 by adam · 17 comments
Owner

Originally created by @fabi125 on GitHub (Jun 16, 2025).

Originally assigned to: @jeremystretch on GitHub.

NetBox version

v4.3.2

Feature type

Data model extension

Proposed functionality

Support an additional "netbox-change-comment: some comment goes here" header for changes made via the api that gets stored in the change log together with the changes.

Use case

We have a lot of automated systems that make changes to our NetBox instance. It would be great if we could send additional information about what caused a certain change to NetBox that would be included in the change log entry.

Database changes

Additional text field on the changelog model.

External dependencies

None.

Originally created by @fabi125 on GitHub (Jun 16, 2025). Originally assigned to: @jeremystretch on GitHub. ### NetBox version v4.3.2 ### Feature type Data model extension ### Proposed functionality Support an additional "netbox-change-comment: some comment goes here" header for changes made via the api that gets stored in the change log together with the changes. ### Use case We have a lot of automated systems that make changes to our NetBox instance. It would be great if we could send additional information about what caused a certain change to NetBox that would be included in the change log entry. ### Database changes Additional text field on the changelog model. ### External dependencies None.
adam added the status: acceptedtype: featurecomplexity: medium labels 2025-12-29 21:42:59 +01:00
adam closed this issue 2025-12-29 21:42:59 +01:00
Author
Owner

@arthanson commented on GitHub (Jun 17, 2025):

so basically add a comment field to ObjectChange.

@arthanson commented on GitHub (Jun 17, 2025): so basically add a comment field to ObjectChange.
Author
Owner

@fabi125 commented on GitHub (Jun 17, 2025):

so basically add a comment field to ObjectChange.

yep, thats the model change that is required. and then when making changes in netbox there would need to be a way to supply that comment. maybe something out-of-band like a header.

@fabi125 commented on GitHub (Jun 17, 2025): > so basically add a comment field to ObjectChange. yep, thats the model change that is required. and then when making changes in netbox there would need to be a way to supply that comment. maybe something out-of-band like a header.
Author
Owner

@jeremystretch commented on GitHub (Jun 17, 2025):

so basically add a comment field to ObjectChange.

This would also need a mechanism for passing the comment when creating, editing, or deleting an object, both via the REST API as well as the web UI, possibly to include bulk operations. I'd like to see this proposal fleshed out quite a bit more.

@jeremystretch commented on GitHub (Jun 17, 2025): > so basically add a comment field to ObjectChange. This would also need a mechanism for passing the comment when creating, editing, or deleting an object, both via the REST API as well as the web UI, possibly to include bulk operations. I'd like to see this proposal fleshed out quite a bit more.
Author
Owner

@github-actions[bot] commented on GitHub (Jun 25, 2025):

This is a reminder that additional information is needed in order to further triage this issue. If the requested details are not provided, the issue will soon be closed automatically.

@github-actions[bot] commented on GitHub (Jun 25, 2025): This is a reminder that additional information is needed in order to further triage this issue. If the requested details are not provided, the issue will soon be closed automatically.
Author
Owner

@fabi125 commented on GitHub (Jun 25, 2025):

For the API I would suggest using a header to keep things out-of-band and backwards compatible.

For UI edits this could be achieved with a field on the confirmation pop-up. Not sure if that would be seen as adding too much friction. Or this could start out as an API-only feature if that would be acceptable.

@fabi125 commented on GitHub (Jun 25, 2025): For the API I would suggest using a header to keep things out-of-band and backwards compatible. For UI edits this could be achieved with a field on the confirmation pop-up. Not sure if that would be seen as adding too much friction. Or this could start out as an API-only feature if that would be acceptable.
Author
Owner

@jeremystretch commented on GitHub (Jul 10, 2025):

For UI edits this could be achieved with a field on the confirmation pop-up. Not sure if that would be seen as adding too much friction.

Yeah, I'm afraid that would be a non-starter as it would be incredibly disruptive. Open to other ideas.

@jeremystretch commented on GitHub (Jul 10, 2025): > For UI edits this could be achieved with a field on the confirmation pop-up. Not sure if that would be seen as adding too much friction. Yeah, I'm afraid that would be a non-starter as it would be incredibly disruptive. Open to other ideas.
Author
Owner

@fabi125 commented on GitHub (Jul 10, 2025):

Would you be open to making it an API only feature? I don't have enough experience with UI/UX deisgn to make a sensible suggestion here :-/

@fabi125 commented on GitHub (Jul 10, 2025): Would you be open to making it an API only feature? I don't have enough experience with UI/UX deisgn to make a sensible suggestion here :-/
Author
Owner

@jeremystretch commented on GitHub (Jul 14, 2025):

No; it would need to be supported via the UI as well.

@jeremystretch commented on GitHub (Jul 14, 2025): No; it would need to be supported via the UI as well.
Author
Owner

@jeremystretch commented on GitHub (Jul 17, 2025):

I think the following implementation is feasible:

  1. Add a message field to the ObjectChange model. This field will be displayed at the end of each form in a separate "meta" section.
  2. Add an optional "changelog message" field to the relevant base forms (i.e. NetBoxModelForm, NetBoxModelBulkEditForm, etc.).
  3. Extend the clean() method on these forms to save the changelog message (if any) as an attribute on the instance being saved or deleted.
  4. Extend the to_objectchange() method on ChangeLoggingMixin to copy the changelog message set on the instance to the ObjectChange record.

For changes made via the REST API, an HTTP header would be preferable, to avoid introducing a write-only field on the model serializers.

@jeremystretch commented on GitHub (Jul 17, 2025): I think the following implementation is feasible: 1. Add a `message` field to the ObjectChange model. This field will be displayed at the end of each form in a separate "meta" section. 2. Add an optional "changelog message" field to the relevant base forms (i.e. NetBoxModelForm, NetBoxModelBulkEditForm, etc.). 3. Extend the `clean()` method on these forms to save the changelog message (if any) as an attribute on the instance being saved or deleted. 4. Extend the `to_objectchange()` method on ChangeLoggingMixin to copy the changelog message set on the instance to the ObjectChange record. For changes made via the REST API, an HTTP header would be preferable, to avoid introducing a write-only field on the model serializers.
Author
Owner

@fabi125 commented on GitHub (Jul 17, 2025):

That sounds amazing!

@fabi125 commented on GitHub (Jul 17, 2025): That sounds amazing!
Author
Owner

@kkthxbye-code commented on GitHub (Jul 17, 2025):

For changes made via the REST API, an HTTP header would be preferable, to avoid introducing a write-only field on the model serializers.

Probably not a great idea. HTTP header values are really not meant for content, they are limited to iso-8859-1 and they can't contain newlines, so the comment would have to be base64 encoded or similar by the sender and decoded on the server side. Wouldn't recommend that approach.

@kkthxbye-code commented on GitHub (Jul 17, 2025): > For changes made via the REST API, an HTTP header would be preferable, to avoid introducing a write-only field on the model serializers. Probably not a great idea. HTTP header values are really not meant for content, they are limited to iso-8859-1 and they can't contain newlines, so the comment would have to be base64 encoded or similar by the sender and decoded on the server side. Wouldn't recommend that approach.
Author
Owner

@jeremystretch commented on GitHub (Jul 18, 2025):

Image

@jeremystretch commented on GitHub (Jul 18, 2025): ![Image](https://github.com/user-attachments/assets/56d58612-89db-4c63-bde0-0508172f9c31)
Author
Owner

@jeremystretch commented on GitHub (Jul 18, 2025):

There doesn't seem to be a great option for conveying changelog messages when mutating objects via the REST API.

Option 1: HTTP Header

Example: curl -X PATCH -H "X-NetBox-Changelog-Message: Adding more IPs for ticket #123" ...

Pros

  • Very accessible to the client
  • Does not require setting a message per object

Cons

  • Not captured by the REST API schema
  • Charset limitations (?)
  • Arguably poor form as the message itself should be considered request data

Option 2: Write-only Serializer Field

Example: curl -X PATCH --data '{"status": "active", "changelog_message": "Site is being turned up today"}

Pros

  • Well-defined, conventional approach
  • Supports a unique message per object within a single bulk operation

Cons

  • Complicates the API schema (changelog_message would never appear on read requests)
  • Bulk operations require the message to be repeated for each object
  • The changelog_message field would need to be declared explicitly on each serializer class
    • This requires changes within a plugin to support changelog messages
@jeremystretch commented on GitHub (Jul 18, 2025): There doesn't seem to be a great option for conveying changelog messages when mutating objects via the REST API. ### Option 1: HTTP Header Example: `curl -X PATCH -H "X-NetBox-Changelog-Message: Adding more IPs for ticket #123" ...` #### Pros * Very accessible to the client * Does not require setting a message per object #### Cons * Not captured by the REST API schema * Charset limitations (?) * Arguably poor form as the message itself should be considered request data ### Option 2: Write-only Serializer Field Example: `curl -X PATCH --data '{"status": "active", "changelog_message": "Site is being turned up today"}` #### Pros * Well-defined, conventional approach * Supports a unique message per object within a single bulk operation #### Cons * Complicates the API schema (`changelog_message` would never appear on read requests) * Bulk operations require the message to be repeated for each object * The `changelog_message` field would need to be declared explicitly on each serializer class * This requires changes within a plugin to support changelog messages
Author
Owner

@kkthxbye-code commented on GitHub (Jul 18, 2025):

How about just letting the API user edit the objectchange changelog_message afterwards. The request id is already returned, so the flow would look like:

  • Modify object using API and get reuest id from the header
  • Filter objectchanges with the returned request id
  • Patch the objectchanges with the chosen message

It's more work for the API user but not complicated and keeps the netbox serializers clean.

@kkthxbye-code commented on GitHub (Jul 18, 2025): How about just letting the API user edit the objectchange changelog_message afterwards. The request id is already returned, so the flow would look like: * Modify object using API and get reuest id from the header * Filter objectchanges with the returned request id * Patch the objectchanges with the chosen message It's more work for the API user but not complicated and keeps the netbox serializers clean.
Author
Owner

@jeremystretch commented on GitHub (Jul 18, 2025):

How about just letting the API user edit the objectchange changelog_message afterwards.

This is a non-starter IMO: changelog entries must remain immutable.

@jeremystretch commented on GitHub (Jul 18, 2025): > How about just letting the API user edit the objectchange changelog_message afterwards. This is a non-starter IMO: changelog entries must remain immutable.
Author
Owner

@DanSheps commented on GitHub (Jul 18, 2025):

Cisco ISE ERS uses an interesting setup, that might work here. This would be incredibly breaking, but I do like it:

{
  "_metadata": {...}
  "Device": {...}
}

It would also potentially allow Bulk Operations similar to down the line:

{
  "_metadata": {...},
  "DeviceType": {...},
  "Device": {...},
  "Interface": [...]
}
@DanSheps commented on GitHub (Jul 18, 2025): Cisco ISE ERS uses an interesting setup, that might work here. This would be incredibly breaking, but I do like it: ``` { "_metadata": {...} "Device": {...} } ``` It would also potentially allow Bulk Operations similar to down the line: ``` { "_metadata": {...}, "DeviceType": {...}, "Device": {...}, "Interface": [...] } ```
Author
Owner

@jeremystretch commented on GitHub (Jul 29, 2025):

We ended up taking the per-object approach within the serializer. However, it was implemented in a manner that should not require plugins to adjust their serializers to support. For example:

curl -s -X POST \
-H "Authorization: Token $TOKEN" \
-H "Content-Type: application/json" \
http://netbox/api/dcim/sites/ \
--data '{
    "name": "Site A",
    "slug": "site-a",
    "changelog_message": "Adding a site for ticket #4137"
}'
@jeremystretch commented on GitHub (Jul 29, 2025): We ended up taking the per-object approach within the serializer. However, it was implemented in a manner that should not require plugins to adjust their serializers to support. For example: ```no-highlight curl -s -X POST \ -H "Authorization: Token $TOKEN" \ -H "Content-Type: application/json" \ http://netbox/api/dcim/sites/ \ --data '{ "name": "Site A", "slug": "site-a", "changelog_message": "Adding a site for ticket #4137" }' ```
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#11288