def checkin(request): data = request.POST # Take out some of the weird junk VMware puts in. Keep an eye out in case # Apple actually uses these: serial = data.get('serial', '').upper().translate(SERIAL_TRANSLATE) # Are we using Sal for some sort of inventory (like, I don't know, Puppet?) if utils.get_django_setting('ADD_NEW_MACHINES', True): if serial: try: machine = Machine.objects.get(serial=serial) except Machine.DoesNotExist: machine = Machine(serial=serial) else: machine = get_object_or_404(Machine, serial=serial) machine_group_key = data.get('key') if machine_group_key in (None, 'None'): machine_group_key = utils.get_django_setting('DEFAULT_MACHINE_GROUP_KEY') machine.machine_group = get_object_or_404(MachineGroup, key=machine_group_key) machine.last_checkin = django.utils.timezone.now() machine.hostname = data.get('name', '<NO NAME>') machine.sal_version = data.get('sal_version') if utils.get_django_setting('DEPLOYED_ON_CHECKIN', True): machine.deployed = True if bool(data.get('broken_client', False)): machine.broken_client = True machine.save() return HttpResponse("Broken Client report submmitted for %s" % data.get('serial')) report = None # Find the report in the submitted data. It could be encoded # and/or compressed with base64 and bz2. for key in ('bz2report', 'base64report', 'base64bz2report'): if key in data: encoded_report = data[key] report = text_utils.decode_to_string(encoded_report, compression=key) break machine.report = report if not report: machine.activity = False machine.errors = machine.warnings = 0 return report_data = plistlib.readPlistFromString(report) if report_data.get('ConsoleUser') and report_data.get('ConsoleUser') != '_mbsetupuser': machine.console_user = report_data.get('ConsoleUser') elif data.get('username') and data.get('username') != '_mbsetupuser': machine.console_user = data.get('username') else: machine.console_user = None activity_keys = ('AppleUpdates', 'InstallResults', 'RemovalResults') machine.activity = any(report_data.get(s) for s in activity_keys) # Check errors and warnings. machine.errors = len(report_data.get("Errors", [])) machine.warnings = len(report_data.get("Warnings", [])) machine.puppet_version = report_data.get('Puppet_Version') machine.manifest = report_data.get('ManifestName') machine.munki_version = report_data.get('ManagedInstallVersion') puppet = report_data.get('Puppet', {}) if 'time' in puppet: last_run_epoch = float(puppet['time']['last_run']) machine.last_puppet_run = datetime.fromtimestamp(last_run_epoch, tz=pytz.UTC) if 'events' in puppet: machine.puppet_errors = puppet['events']['failure'] # Handle gosal submissions slightly differently from others. machine.os_family = ( report_data['OSFamily'] if 'OSFamily' in report_data else report_data.get('os_family')) machine_info = report_data.get('MachineInfo', {}) if 'os_vers' in machine_info: machine.operating_system = machine_info['os_vers'] # macOS major OS updates don't have a minor version, so add one. if len(machine.operating_system) <= 4 and machine.os_family == 'Darwin': machine.operating_system = machine.operating_system + '.0' else: # Handle gosal and missing os_vers cases. machine.operating_system = machine_info.get('OSVers') # TODO: These should be a number type. # TODO: Cleanup all of the casting to str if we make a number. machine.hd_space = report_data.get('AvailableDiskSpace', '0') machine.hd_total = data.get('disk_size', '0') space = float(machine.hd_space) total = float(machine.hd_total) if space == float(0) or total == float(0): machine.hd_percent = '0' else: try: machine.hd_percent = str(int((total - space) / total * 100)) except ZeroDivisionError: machine.hd_percent = '0' # Get macOS System Profiler hardware info. # Older versions use `HardwareInfo` key, so start there. hwinfo = machine_info.get('HardwareInfo', {}) if not hwinfo: for profile in machine_info.get('SystemProfile', []): if profile['_dataType'] == 'SPHardwareDataType': hwinfo = profile._items[0] break if hwinfo: key_style = 'old' if 'MachineModel' in hwinfo else 'new' machine.machine_model = hwinfo.get(MACHINE_KEYS['machine_model'][key_style]) machine.machine_model_friendly = machine_info.get('machine_model_friendly', '') machine.cpu_type = hwinfo.get(MACHINE_KEYS['cpu_type'][key_style]) machine.cpu_speed = hwinfo.get(MACHINE_KEYS['cpu_speed'][key_style]) machine.memory = hwinfo.get(MACHINE_KEYS['memory'][key_style]) machine.memory_kb = process_memory(machine) # if not machine.machine_model_friendly: # try: # machine.machine_model_friendly = utils.friendly_machine_model(machine) # except Exception: # machine.machine_model_friendly = machine.machine_model machine.save() historical_days = utils.get_setting('historical_retention') now = django.utils.timezone.now() datelimit = now - timedelta(days=historical_days) # Process plugin scripts. # Clear out too-old plugin script submissions first. PluginScriptSubmission.objects.filter(recorded__lt=datelimit).delete() utils.process_plugin_script(report_data.get('Plugin_Results', []), machine) process_managed_items(machine, report_data, data.get('uuid'), now, datelimit) process_facts(machine, report_data, datelimit) process_conditions(machine, report_data) utils.run_plugin_processing(machine, report_data) if utils.get_setting('send_data') in (None, True): # If setting is None, it hasn't been configured yet; assume True utils.send_report() return HttpResponse("Sal report submmitted for %s" % data.get('name'))
from server import text_utils from server import utils from server.models import (Machine, Condition, Fact, HistoricalFact, MachineGroup, UpdateHistory, UpdateHistoryItem, InstalledUpdate, PendingAppleUpdate, PluginScriptSubmission, PendingUpdate, Plugin, Report, MachineDetailPlugin) if settings.DEBUG: import logging logging.basicConfig(level=logging.INFO) # The database probably isn't going to change while this is loaded. IS_POSTGRES = utils.is_postgres() IGNORED_CSV_FIELDS = ('id', 'machine_group', 'report', 'os_family') HISTORICAL_FACTS = utils.get_django_setting('HISTORICAL_FACTS', []) IGNORE_PREFIXES = utils.get_django_setting('IGNORE_FACTS', []) MACHINE_KEYS = { 'machine_model': {'old': 'MachineModel', 'new': 'machine_model'}, 'cpu_type': {'old': 'CPUType', 'new': 'cpu_type'}, 'cpu_speed': {'old': 'CurrentProcessorSpeed', 'new': 'current_processor_speed'}, 'memory': {'old': 'PhysicalMemory', 'new': 'physical_memory'}} MEMORY_EXPONENTS = {'KB': 0, 'MB': 1, 'GB': 2, 'TB': 3} # Build a translation table for serial numbers, to remove garbage # VMware puts in. SERIAL_TRANSLATE = {ord(c): None for c in '+/'} @login_required def tableajax(request, plugin_name, data, group_type='all', group_id=None): """Table ajax for dataTables"""