def test_ok(self): for build, (name, major, minor, patch) in (("12E4022", ("OS X", 10, 8, 4)), ("15G31", ("OS X", 10, 11, 6)), ("19A471t", ("macOS", 10, 15, 0)), ("19D76", ("macOS", 10, 15, 3)), ("20A2411", ("macOS", 11, 0, 0)), ("20B29", ("macOS", 11, 0, 1)), ("20B50", ("macOS", 11, 0, 1)), ("20C69", ("macOS", 11, 1, 0)), ("20D74", ("macOS", 11, 2, 1)), ("20D80", ("macOS", 11, 2, 2)), ("20D91", ("macOS", 11, 2, 3)), ("20G95", ("macOS", 11, 5, 2)), ("20G165", ("macOS", 11, 6, 0)), ("21A5522h", ("macOS Beta", 12, 0, 0)), ("21A558", ("macOS", 12, 0, 1)), ("21C5021h", ("macOS Beta", 12, 1, 0)), ("21D62", ("macOS", 12, 2, 1)), ("21E5212f", ("macOS Beta", 12, 3, 0))): self.assertEqual( macos_version_from_build(build), { "name": name, "major": major, "minor": minor, "patch": patch, "build": build })
def commit_machine_snapshot(self, data): # os version build = data["os_build"] os_version = dict( zip(('major', 'minor', 'patch'), (int(s) for s in data['os_version'].split('.')))) os_version.update({'name': 'macOS', 'build': build}) try: os_version.update(macos_version_from_build(build)) except ValueError: pass # tree tree = { 'source': { 'module': 'zentral.contrib.santa', 'name': 'Santa' }, 'reference': self.hardware_uuid, 'serial_number': self.machine_serial_number, 'os_version': os_version, 'system_info': { 'computer_name': data['hostname'] }, 'public_ip_address': self.ip, } if self.business_unit: tree['business_unit'] = self.business_unit.serialize() commit_machine_snapshot_and_trigger_events(tree)
def test_ok(self): for build, (name, minor, patch) in (("12E4022", ("OS X", 8, 4)), ("15G31", ("OS X", 11, 6)), ("19A471t", ("macOS", 15, 0)), ("19D76", ("macOS", 15, 3))): self.assertEqual( macos_version_from_build(build), { "name": name, "major": 10, "minor": minor, "patch": patch, "build": build })
def _commit_machine_snapshot(self): # os version build = self.request_data["os_build"] os_version = dict( zip(('major', 'minor', 'patch'), (int(s) for s in self.request_data['os_version'].split('.')))) os_version.update({'name': 'macOS', 'build': build}) try: os_version.update(macos_version_from_build(build)) except ValueError: pass # tree tree = { 'source': { 'module': 'zentral.contrib.santa', 'name': 'Santa' }, 'reference': self.hardware_uuid, 'serial_number': self.enrolled_machine.serial_number, 'os_version': os_version, 'system_info': { 'computer_name': self.request_data['hostname'] }, 'public_ip_address': self.ip, } # tree primary user primary_user = self._get_primary_user() if primary_user: tree['principal_user'] = { 'source': { 'type': PrincipalUserSource.SANTA_MACHINE_OWNER }, 'unique_id': primary_user, 'principal_name': primary_user, } # tree business unit business_unit = self.enrolled_machine.enrollment.secret.get_api_enrollment_business_unit( ) if business_unit: tree['business_unit'] = business_unit.serialize() commit_machine_snapshot_and_trigger_events(tree)
def test_wrong_errors(self): for build in ("A", "", "9"): with self.assertRaises(ValueError) as cm: macos_version_from_build(build) self.assertEqual(cm.exception.args[0], "Bad build number")
def test_too_old_errors(self): for build in ("11G56", "9A581"): with self.assertRaises(ValueError) as cm: macos_version_from_build(build) self.assertEqual(cm.exception.args[0], "Cannot parse build str for macos < 10.8")
def get_computer_machine_d(self, jamf_id): computer = self._computer(jamf_id) serial_number = computer['general']['serial_number'] # serial number, reference ct = {'source': self.get_source_d(), 'reference': self.machine_reference("computer", jamf_id), 'links': self._machine_links_from_id("computer", jamf_id), 'serial_number': serial_number} last_contact = computer['general'].get('last_contact_time_utc') if last_contact: ct['last_seen'] = parser.parse(last_contact) # business unit if self.business_unit: ct['business_unit'] = self.business_unit else: site_id = computer['general']['site']['id'] if site_id >= 0: site_reference = str(site_id) site_name = computer['general']['site']['name'] else: site_reference = "DEFAULT" site_name = "Default" ct['business_unit'] = {'source': self.get_source_d(), 'reference': site_reference, 'name': site_name} # groups groups = [] cg_names = computer['groups_accounts']['computer_group_memberships'] org_cg_num = len(cg_names) cg_names = set(cg_names) if len(cg_names) < org_cg_num: logger.warning("%s computer %s: duplicated group(s)", self.api_base_url, jamf_id) for computer_group_name in cg_names: try: group_id, is_smart = self.get_computer_group(computer_group_name) except KeyError: # TODO continue else: groups.append({'source': self.get_source_d(), 'reference': self.group_reference("computer", group_id, is_smart), 'name': computer_group_name, 'links': self._group_links("computer", group_id, is_smart)}) if groups: ct['groups'] = groups hardware = computer['hardware'] # os version os_version = None try: os_version = dict(zip(('major', 'minor', 'patch'), (int(s) for s in hardware['os_version'].split('.')))) except ValueError: try: os_version = macos_version_from_build(hardware["os_build"]) except ValueError: pass else: os_version.update({'name': hardware['os_name'], 'build': hardware['os_build']}) if os_version: ct['os_version'] = os_version # system info system_info = {'computer_name': computer['general']['name'], 'hardware_model': hardware['model_identifier']} # cpu physical cores try: cpu_physical_cores = int(hardware['number_cores']) except (TypeError, ValueError): pass else: if cpu_physical_cores > 0: system_info['cpu_physical_cores'] = cpu_physical_cores else: logger.warning("%s computer %s: cpu physical cores <= 0", self.api_base_url, jamf_id) # physical memory try: physical_memory = int(computer['hardware']['total_ram']) * 2**20 except (TypeError, ValueError): pass else: if physical_memory > 0: system_info['physical_memory'] = physical_memory else: logger.warning("%s computer %s physical memory <= 0 MB", self.api_base_url, jamf_id) # cpu type = processor_type + processor_speed_mhz cpu_type_items = [] processor_type = hardware["processor_type"] if processor_type: processor_type = processor_type.strip() if processor_type: cpu_type_items.append(processor_type) try: processor_speed_mhz = int(hardware["processor_speed_mhz"]) except (TypeError, ValueError): pass else: if processor_speed_mhz > 0: cpu_type_items.append("@{}MHZ".format(processor_speed_mhz)) else: logger.warning("%s computer %s cpu speed <= 0 MHz", self.api_base_url, jamf_id) if cpu_type_items: system_info['cpu_type'] = " ".join(cpu_type_items) ct['system_info'] = system_info # public ip last_reported_ip = clean_ip_address(computer['general'].get('ip_address', None)) if last_reported_ip: ct['public_ip_address'] = last_reported_ip # network interfaces network_interface = {} for attr, ni_attr in (('mac_address', 'mac'), ('last_reported_ip', 'address')): value = computer['general'].get(attr, None) if value: if attr == "last_reported_ip": value = clean_ip_address(value) if value: network_interface[ni_attr] = value if len(network_interface) == 2: network_interface['interface'] = 'primary' ct['network_interfaces'] = [network_interface] # osx apps osx_app_instances = [] if ( self.inventory_apps_shard == 100 or (self.inventory_apps_shard and serial_number and shard(serial_number, "jamf_apps") < self.inventory_apps_shard) ): has_duplicated_apps = False for app_d in computer['software']['applications']: osx_app_d = {'bundle_path': app_d['path'], 'app': {'bundle_name': app_d['name'], 'bundle_version_str': app_d['version']}} if osx_app_d not in osx_app_instances: osx_app_instances.append(osx_app_d) else: has_duplicated_apps = True if has_duplicated_apps: logger.warning("%s computer %s: duplicated app(s)", self.api_base_url, jamf_id) else: logger.debug("%s computer %s: skipped osx app instances", self.api_base_url, jamf_id) ct['osx_app_instances'] = osx_app_instances return ct