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
             })
Example #2
0
    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
             })
Example #4
0
    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")
Example #7
0
    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