56 lines
2.2 KiB
Python
56 lines
2.2 KiB
Python
"""
|
||||
|
|
Позволяет декларативно описать группы/ресурсы в YAML-файле и синхронизировать
|
|||
|
|
с базой одной командой — удобно для версионирования конфигурации в git.
|
|||
|
|
|
|||
|
|
Использование:
|
|||
|
|
python manage.py sync_resources resources.yaml
|
|||
|
|
|
|||
|
|
Формат resources.yaml:
|
|||
|
|
|
|||
|
|
groups:
|
|||
|
|
- ad_group_name: admins-network
|
|||
|
|
display_name: "Сетевые администраторы"
|
|||
|
|
resources:
|
|||
|
|
- slug: resource1
|
|||
|
|
name: "Панель управления коммутаторами"
|
|||
|
|
description: "Cisco DNA Center"
|
|||
|
|
- slug: resource2
|
|||
|
|
name: "Мониторинг сети"
|
|||
|
|
description: "LibreNMS"
|
|||
|
|
"""
|
|||
|
|
import yaml
|
|||
|
|
from django.core.management.base import BaseCommand, CommandError
|
|||
|
|
|
|||
|
|
from portal.models import Resource, ResourceGroup
|
|||
|
|
|
|||
|
|
|
|||
|
|
class Command(BaseCommand):
|
|||
|
|
help = "Синхронизирует ResourceGroup/Resource с декларативным YAML-файлом"
|
|||
|
|
|
|||
|
|
def add_arguments(self, parser):
|
|||
|
|
parser.add_argument("yaml_path", type=str)
|
|||
|
|
|
|||
|
|
def handle(self, *args, **options):
|
|||
|
|
path = options["yaml_path"]
|
|||
|
|
try:
|
|||
|
|
with open(path, encoding="utf-8") as f:
|
|||
|
|
data = yaml.safe_load(f)
|
|||
|
|
except FileNotFoundError as exc:
|
|||
|
|
raise CommandError(f"Файл не найден: {path}") from exc
|
|||
|
|
|
|||
|
|
for group_data in data.get("groups", []):
|
|||
|
|
group, _ = ResourceGroup.objects.update_or_create(
|
|||
|
|
ad_group_name=group_data["ad_group_name"],
|
|||
|
|
defaults={"display_name": group_data["display_name"]},
|
|||
|
|
)
|
|||
|
|
for res_data in group_data.get("resources", []):
|
|||
|
|
Resource.objects.update_or_create(
|
|||
|
|
group=group,
|
|||
|
|
slug=res_data["slug"],
|
|||
|
|
defaults={
|
|||
|
|
"name": res_data["name"],
|
|||
|
|
"description": res_data.get("description", ""),
|
|||
|
|
"is_active": res_data.get("is_active", True),
|
|||
|
|
},
|
|||
|
|
)
|
|||
|
|
self.stdout.write(self.style.SUCCESS(f"Синхронизирована группа: {group.ad_group_name}"))
|