Skip to content

Feat: Closes #44 - Cisco EoX API integration#159

Draft
cflanderscpc wants to merge 3 commits into
DanSheps:mainfrom
cflanderscpc:close-44
Draft

Feat: Closes #44 - Cisco EoX API integration#159
cflanderscpc wants to merge 3 commits into
DanSheps:mainfrom
cflanderscpc:close-44

Conversation

@cflanderscpc

Copy link
Copy Markdown

This pull request introduces a major new feature: integration with the Cisco EoX (End-of-Life) API to automatically synchronize hardware lifecycle information for Cisco devices and modules. It includes database schema changes, background job automation, secure credential management, new forms and navigation, and comprehensive documentation for the new functionality.

The most important changes are:

Cisco EoX API Integration

  • Adds a new background job (CiscoEoXSyncJob) that periodically queries the Cisco EoX API for end-of-life data based on DeviceType and ModuleType, updating or creating HardwareLifecycle records accordingly. The job supports both serial number and part number lookups and reschedules itself according to the configured interval.
  • Introduces a singleton model CiscoEoXSettings to securely store API credentials (with Fernet encryption for the client secret), sync interval, and manufacturer names. Includes migration to create this model. [1] [2] [3]
  • Adds a form (CiscoEoXSettingsForm) for editing Cisco EoX settings via the Web UI, ensuring the client secret is never echoed back and is only updated when a new value is provided.

Configuration and Settings

  • Extends plugin configuration (PLUGINS_CONFIG) and documentation to support Cisco EoX settings as a fallback when no database settings exist, and documents the precedence and security recommendations for credential storage. [1] [2]
  • Provides detailed documentation in README.md explaining the Cisco EoX integration, configuration options, lookup order, and mapping of Cisco API fields to the plugin's model fields.

User Interface and Navigation

  • Adds a new navigation entry for "Cisco EoX Settings" in the plugin menu, allowing users with the appropriate permission to access and manage EoX integration settings.
  • Registers the background job and ensures it is available and scheduled when settings are updated.

These changes together provide automated, secure, and user-friendly synchronization of Cisco hardware lifecycle data, significantly enhancing the plugin's capabilities for NetBox users managing Cisco equipment.

@DanSheps DanSheps left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some stuff may be missing, but this should get you close enough to at least start moving forward on it.

Returns ``None`` if no valid, enabled configuration is found.
"""
# --- 1. Try database ---
try:

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
try:

Should not need this, for the reason stated as this appears to not be used anywhere where the DB will be in a non-initialized state

Comment on lines +64 to +66
except Exception as exc:
# DB may not be available during migrations or tests
logger.debug('Could not load CiscoEoXSettings from database: %s', exc)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
except Exception as exc:
# DB may not be available during migrations or tests
logger.debug('Could not load CiscoEoXSettings from database: %s', exc)

See related comment

Comment thread netbox_lifecycle/models/cisco_eox.py Outdated
return ''
try:
return _get_fernet().decrypt(self._client_secret.encode()).decode()
except Exception:

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
except Exception:
except cryptography.fernet.InvalidToken:

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should use NetBox views where possible

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will need to be regenerated

Comment thread netbox_lifecycle/__init__.py Outdated
Comment on lines +22 to +27
# Cisco EoX API — fallback to PLUGINS_CONFIG when no DB settings exist
'cisco_eox_enabled': False,
'cisco_eox_client_id': '',
'cisco_eox_client_secret': '',
'cisco_eox_sync_interval': 10080, # weekly, in minutes
'cisco_eox_manufacturer_names': 'Cisco',

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would maybe just straight up dump these. Require a setting to be configured

Suggested change
# Cisco EoX API — fallback to PLUGINS_CONFIG when no DB settings exist
'cisco_eox_enabled': False,
'cisco_eox_client_id': '',
'cisco_eox_client_secret': '',
'cisco_eox_sync_interval': 10080, # weekly, in minutes
'cisco_eox_manufacturer_names': 'Cisco',


super().ready()

from netbox_lifecycle.jobs import CiscoEoXSyncJob # noqa: F401 — registers job

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will need to loop here and queue jobs that are not queued.

Comment thread netbox_lifecycle/urls.py
Comment on lines +289 to +303
path(
'cisco-eox/settings/',
views.CiscoEoXSettingsView.as_view(),
name='cisco_eox_settings',
),
path(
'cisco-eox/settings/edit/',
views.CiscoEoXSettingsEditView.as_view(),
name='cisco_eox_settings_edit',
),
path(
'cisco-eox/run-now/',
views.CiscoEoXRunNowView.as_view(),
name='cisco_eox_run_now',
),

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
path(
'cisco-eox/settings/',
views.CiscoEoXSettingsView.as_view(),
name='cisco_eox_settings',
),
path(
'cisco-eox/settings/edit/',
views.CiscoEoXSettingsEditView.as_view(),
name='cisco_eox_settings_edit',
),
path(
'cisco-eox/run-now/',
views.CiscoEoXRunNowView.as_view(),
name='cisco_eox_run_now',
),
path(
'cisco-eox/',
include(get_model_urls(app_name, 'eoxapisetting', detail=False)),
),
path(
'cisco-eox/<int:pk>/',
include(get_model_urls(app_name, 'eoxapisetting')),
),

link='plugins:netbox_lifecycle:cisco_eox_settings',
link_text='Cisco EoX Settings',
permissions=['netbox_lifecycle.view_ciscoeoxsettings'],
)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
)
buttons=(
PluginMenuButton(
link='plugins:netbox_lifecycle:eoxapisetting_add',
title='Add',
icon_class=COL_ADD,
permissions=['netbox_lifecycle.add_eoxapisetting'],
),
),
)

Comment thread netbox_lifecycle/jobs.py

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No comment yet, but will need to be modified

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants