Coverage for sm/utils_starterpack.py: 89%
44 statements
« prev ^ index » next coverage.py v7.17.0, created at 2026-10-24 19:06 +0000
« prev ^ index » next coverage.py v7.17.0, created at 2026-10-24 19:06 +0000
1from pathlib import Path
2import yaml
3from django.conf import settings
4from django.contrib.auth.models import Group
5from django.db import transaction
6from vendor.models import Model as Vendor
7from operatingsystem.models import Model as OS
8from typing import Dict, List, Any
11def _load_fixture(app_label: str) -> List[Any]:
12 """Loads a YAML fixture from an app's fixtures dir; [] if absent."""
13 path = Path(settings.BASE_DIR) / app_label / "fixtures" / "01_initial.yaml"
14 if not path.is_file():
15 return []
16 with open(path) as f:
17 return yaml.safe_load(f) or []
20def import_starter_pack(group: Group) -> Dict[str, int]:
21 """
22 Imports vendors and operating systems from fixtures into the specified
23 group. Runs atomically so a partial import can never leave the group in a
24 half-populated state.
25 """
26 # Vendor name (as referenced from the OS fixture) -> group-scoped Vendor
27 vendor_map = {}
28 vendor_count = 0
29 os_count = 0
31 with transaction.atomic():
32 vendor_data = _load_fixture("vendor")
33 for item in vendor_data:
34 if not isinstance(item, dict) or item.get("model") != "vendor.model":
35 continue
36 fields = item["fields"]
37 vendor, created = Vendor.objects.get_or_create(
38 name=fields["name"],
39 group=group,
40 defaults={
41 "is_hardware": fields.get("is_hardware", True),
42 "is_software": fields.get("is_software", True),
43 },
44 )
45 vendor_map[fields["name"]] = vendor
46 if created:
47 vendor_count += 1
49 os_data = _load_fixture("operatingsystem")
50 for item in os_data:
51 if (
52 not isinstance(item, dict)
53 or item.get("model") != "operatingsystem.model"
54 ):
55 continue
56 fields = item["fields"]
57 vendor_names = fields.get("vendor")
58 if isinstance(vendor_names, list):
59 vendor_name = vendor_names[0] if vendor_names else None
60 else:
61 vendor_name = vendor_names
63 vendor = vendor_map.get(vendor_name) if vendor_name else None
64 if vendor is None:
65 continue
66 _, created = OS.objects.get_or_create(
67 version=fields["version"], vendor=vendor, group=group
68 )
69 if created:
70 os_count += 1
72 return {"vendors": vendor_count, "os": os_count}