import json import os from django.conf import settings from django.core.management.base import BaseCommand from jinja2 import FileSystemLoader, Environment from dcim.choices import * TEMPLATE_FILENAME = 'devicetype_schema.jinja2' OUTPUT_FILENAME = 'contrib/generated_schema.json' CHOICES_MAP = { 'airflow_choices': DeviceAirflowChoices, 'weight_unit_choices': WeightUnitChoices, 'subdevice_role_choices': SubdeviceRoleChoices, 'console_port_type_choices': ConsolePortTypeChoices, 'console_server_port_type_choices': ConsolePortTypeChoices, 'power_port_type_choices': PowerPortTypeChoices, 'power_outlet_type_choices': PowerOutletTypeChoices, 'power_outlet_feedleg_choices': PowerOutletFeedLegChoices, 'interface_type_choices': InterfaceTypeChoices, 'interface_poe_mode_choices': InterfacePoEModeChoices, 'interface_poe_type_choices': InterfacePoETypeChoices, 'front_port_type_choices': PortTypeChoices, 'rear_port_type_choices': PortTypeChoices, } class Command(BaseCommand): help = "Generate JSON schema for validating NetBox device type definitions" def add_arguments(self, parser): parser.add_argument( '--write', action='store_true', help="Write the generated schema to file" ) def handle(self, *args, **kwargs): # Initialize template template_loader = FileSystemLoader(searchpath=f'{settings.TEMPLATES_DIR}/extras/schema/') template_env = Environment(loader=template_loader) template = template_env.get_template(TEMPLATE_FILENAME) # Render template context = { key: json.dumps(choices.values()) for key, choices in CHOICES_MAP.items() } rendered = template.render(**context) if kwargs['write']: # $root/contrib/generated_schema.json filename = os.path.join(os.path.split(settings.BASE_DIR)[0], OUTPUT_FILENAME) with open(filename, mode='w', encoding='UTF-8') as f: f.write(json.dumps(json.loads(rendered), indent=4)) f.write('\n') f.close() self.stdout.write(self.style.SUCCESS(f"Schema written to {filename}.")) else: self.stdout.write(rendered)