Files
Samsara/samsara/collectors/importer.py

54 lines
2.6 KiB
Python

"""Offline intake shared by Windows and Linux desktops. No code is executed."""
import json
from pathlib import Path
from samsara.models.inventory import validate_inventory, restrict_inventory_fields
MAX_IMPORT_BYTES = 10 * 1024 * 1024
def load_inventory(path):
with Path(path).open('rb') as source:
raw = source.read(MAX_IMPORT_BYTES + 1)
if len(raw) > MAX_IMPORT_BYTES:
raise ValueError('Inventory exceeds the 10 MiB import limit.')
try:
data = json.loads(raw.decode('utf-8-sig'))
except (ValueError, UnicodeError):
raise ValueError('The selected file is not valid UTF-8 inventory JSON.') from None
# A report wrapper is accepted, but its precomputed assessment is never trusted.
if isinstance(data, dict) and 'inventory_result' in data:
data = data['inventory_result']
validate_inventory(data)
# Keep diagnostic contents out of logs and exported reports. Diagnostics may
# contain command lines or credentials from external collection tools.
safe_errors = {
'access_denied': 'Current account could not read this scope.',
'command_unavailable': 'Required command was unavailable.',
'timeout': 'Section time limit exceeded.',
'overall_timeout': 'Overall collection time limit exceeded.',
'output_limit': 'Collection output limit exceeded.',
'powershell_failed': 'PowerShell could not execute the collector.',
'invalid_output': 'Invalid section output.',
'collection_failed': 'A local query failed.'
}
checks = {}
for name, check in data['checks'].items():
clean = {'status': check['status'], 'message':
'Imported check status. Source assertions are unverified; raw diagnostics excluded.'}
for field in ('started_at', 'completed_at'):
if field in check:
clean[field] = check[field]
if 'errors' in check:
clean['errors'] = []
for error in check['errors']:
code = error['code'] if error['code'] in safe_errors else 'collection_failed'
clean['errors'].append({'code': code, 'scope': 'Imported check', 'message': safe_errors[code]})
if 'permission_limitations' in check:
clean['permission_limitations'] = ['Collector reported limited read access; details excluded.'] if check['permission_limitations'] else []
if 'limitations' in check:
clean['limitations'] = ['Collector reported scope limitations; consult the inventory owner.'] if check['limitations'] else []
checks[name] = clean
data['checks'] = checks
return restrict_inventory_fields(data)