mirror of
https://github.com/netbox-community/netbox.git
synced 2025-09-06 14:23:36 -06:00
Populate namespaced models & constants from all core apps and plugins
This commit is contained in:
parent
19f89acc3a
commit
1f04cff828
@ -1,18 +1,18 @@
|
|||||||
import code
|
import code
|
||||||
import platform
|
import platform
|
||||||
import sys
|
from collections import defaultdict
|
||||||
|
from types import SimpleNamespace
|
||||||
|
|
||||||
from colorama import Fore, Style
|
from colorama import Fore, Style
|
||||||
from django import get_version
|
from django import get_version
|
||||||
from django.apps import apps
|
from django.apps import apps
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
|
from django.utils.module_loading import import_string
|
||||||
|
|
||||||
from netbox.constants import CORE_APPS
|
from netbox.constants import CORE_APPS
|
||||||
from netbox.plugins.utils import get_installed_plugins
|
from netbox.plugins.utils import get_installed_plugins
|
||||||
|
|
||||||
EXCLUDE_MODELS = ()
|
|
||||||
|
|
||||||
|
|
||||||
def color(color: str, text: str):
|
def color(color: str, text: str):
|
||||||
return getattr(Fore, color.upper()) + text + Style.RESET_ALL
|
return getattr(Fore, color.upper()) + text + Style.RESET_ALL
|
||||||
@ -22,6 +22,29 @@ def bright(text: str):
|
|||||||
return Style.BRIGHT + text + Style.RESET_ALL
|
return Style.BRIGHT + text + Style.RESET_ALL
|
||||||
|
|
||||||
|
|
||||||
|
def get_models(app_config):
|
||||||
|
"""
|
||||||
|
Return a list of all non-private models within an app.
|
||||||
|
"""
|
||||||
|
return [
|
||||||
|
model for model in app_config.get_models()
|
||||||
|
if not getattr(model, '_netbox_private', False)
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def get_constants(app_config):
|
||||||
|
"""
|
||||||
|
Return a dictionary mapping of all constants defined within an app.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
constants = import_string(f'{app_config.name}.constants')
|
||||||
|
except ImportError:
|
||||||
|
return {}
|
||||||
|
return {
|
||||||
|
name: value for name, value in vars(constants).items()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
help = "Start the Django shell with all NetBox models already imported"
|
help = "Start the Django shell with all NetBox models already imported"
|
||||||
django_models = {}
|
django_models = {}
|
||||||
@ -40,37 +63,31 @@ class Command(BaseCommand):
|
|||||||
print(f' {m}')
|
print(f' {m}')
|
||||||
|
|
||||||
def get_namespace(self):
|
def get_namespace(self):
|
||||||
namespace = {}
|
namespace = defaultdict(SimpleNamespace)
|
||||||
|
|
||||||
# Gather Django models and constants from each app
|
# Iterate through all core apps & plugins to compile namespace of models and constants
|
||||||
for app in CORE_APPS:
|
for app_name in [*CORE_APPS, *get_installed_plugins().keys()]:
|
||||||
models = []
|
app_config = apps.get_app_config(app_name)
|
||||||
|
|
||||||
# Load models from each app
|
# Populate models
|
||||||
for model in apps.get_app_config(app).get_models():
|
if models := get_models(app_config):
|
||||||
app_label = model._meta.app_label
|
for model in models:
|
||||||
model_name = model._meta.model_name
|
setattr(namespace[app_name], model.__name__, model)
|
||||||
if f'{app_label}.{model_name}' not in EXCLUDE_MODELS:
|
self.django_models[app_name] = sorted([
|
||||||
namespace[model.__name__] = model
|
model.__name__ for model in models
|
||||||
models.append(model.__name__)
|
])
|
||||||
self.django_models[app] = sorted(models)
|
|
||||||
|
|
||||||
# Constants
|
# Populate constants
|
||||||
try:
|
for const_name, const_value in get_constants(app_config).items():
|
||||||
app_constants = sys.modules[f'{app}.constants']
|
setattr(namespace[app_name], const_name, const_value)
|
||||||
for name in dir(app_constants):
|
|
||||||
namespace[name] = getattr(app_constants, name)
|
|
||||||
except KeyError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# Load convenience commands
|
return {
|
||||||
namespace.update({
|
**namespace,
|
||||||
'lsmodels': self._lsmodels,
|
'lsmodels': self._lsmodels,
|
||||||
})
|
}
|
||||||
|
|
||||||
return namespace
|
@staticmethod
|
||||||
|
def get_banner_text():
|
||||||
def get_banner_text(self):
|
|
||||||
lines = [
|
lines = [
|
||||||
'{title} ({hostname})'.format(
|
'{title} ({hostname})'.format(
|
||||||
title=bright('NetBox interactive shell'),
|
title=bright('NetBox interactive shell'),
|
||||||
@ -120,5 +137,4 @@ class Command(BaseCommand):
|
|||||||
readline.parse_and_bind('tab: complete')
|
readline.parse_and_bind('tab: complete')
|
||||||
|
|
||||||
# Run interactive shell
|
# Run interactive shell
|
||||||
shell = code.interact(banner=self.get_banner_text(), local=namespace)
|
return code.interact(banner=self.get_banner_text(), local=namespace)
|
||||||
return shell
|
|
||||||
|
Loading…
Reference in New Issue
Block a user