Add local Windows Server inventory collection and validation; include core package
This commit is contained in:
41
samsara/models/inventory.py
Normal file
41
samsara/models/inventory.py
Normal file
@@ -0,0 +1,41 @@
|
||||
"""The shared v1 inventory contract, used at live collection and import boundaries."""
|
||||
import json
|
||||
from functools import lru_cache
|
||||
from pathlib import Path
|
||||
from jsonschema import Draft202012Validator, FormatChecker
|
||||
|
||||
SCHEMA_PATH = Path(__file__).resolve().parents[2] / 'schemas' / 'inventory-v1.schema.json'
|
||||
|
||||
|
||||
@lru_cache(maxsize=1)
|
||||
def inventory_schema():
|
||||
return json.loads(SCHEMA_PATH.read_text(encoding='utf-8'))
|
||||
|
||||
|
||||
def validate_inventory(data):
|
||||
validator = Draft202012Validator(inventory_schema(), format_checker=FormatChecker())
|
||||
if not validator.is_valid(data):
|
||||
raise ValueError('Inventory does not match the v1 schema; required fields, types or check statuses are invalid.')
|
||||
return data
|
||||
|
||||
|
||||
ALLOWED = {
|
||||
'roles': {'name', 'state', 'display_name', 'feature_type'},
|
||||
'services': {'name', 'display_name', 'state', 'startup', 'account', 'pid'},
|
||||
'network': {'state', 'local_address', 'local_port', 'remote_address', 'remote_port', 'pid', 'process', 'direction'},
|
||||
'tasks': {'name', 'path', 'enabled', 'account', 'triggers', 'state', 'associated_unit', 'executables'},
|
||||
'software': {'name', 'publisher', 'version', 'installation_date', 'registry_view'},
|
||||
'storage': {'type', 'name', 'path', 'capacity_gib', 'free_gib', 'filesystem', 'special'},
|
||||
'certificates': {'subject', 'issuer', 'expires', 'thumbprint', 'store'},
|
||||
}
|
||||
SERVER_FIELDS = {'hostname', 'platform', 'operating_system', 'os_version', 'os_build', 'kernel_version', 'product_type', 'domain_joined', 'last_boot', 'ip_addresses', 'network_adapters', 'domain'}
|
||||
|
||||
|
||||
def restrict_inventory_fields(data, local_source=None):
|
||||
"""Keep only metadata fields; never serialize raw CIM/task/service objects."""
|
||||
data["server"] = {key: value for key, value in data["server"].items() if key in SERVER_FIELDS}
|
||||
if local_source:
|
||||
data["server"]["collection_source"] = local_source
|
||||
data["inventory"] = {section: [{key: value for key, value in row.items() if key in ALLOWED[section]}
|
||||
for row in rows] for section, rows in data["inventory"].items()}
|
||||
return data
|
||||
Reference in New Issue
Block a user