Ejemplo n.º 1
0
def UpdateInstallLogSchema(cursor=None, num_updated=0):
    """Puts all InstallLog entities so any new properties are created."""
    q = models.InstallLog.all()

    if cursor:
        logging.debug('Continuing with cursor: %s', cursor)
        q.with_cursor(cursor)

    entities = q.fetch(INSTALL_LOG_MAX_FETCH)
    if not entities:
        logging.debug('No remaining entities to convert.')
        return

    entities_to_put = []
    for e in entities:
        e.success = e.IsSuccess()
        e.applesus = getattr(e, 'applesus', False)
        if not getattr(e, 'server_datetime', False):
            e.server_datetime = e.mtime
        entities_to_put.append(e)
    gae_util.BatchDatastoreOp(models.db.put, entities_to_put, 100)

    cursor = q.cursor()
    num_updated += len(entities_to_put)
    logging.info('%s entities converted', num_updated)

    deferred.defer(UpdateInstallLogSchema,
                   cursor=cursor,
                   num_updated=num_updated)
Ejemplo n.º 2
0
    def Log(cls, products, action):
        """Puts batches of product changes to AdminAppleSUSProductLog.

    Args:
      products: list of or single models.AppleSUSProduct entity.
      action: str, description of the change taking place to the batch.
    """
        # Support products being a single product entity.
        if not isinstance(products, (list, tuple)):
            products = (products, )

        to_put = []
        for p in products:
            log = cls(product_id=p.product_id, action=action, tracks=p.tracks)
            log.mtime = datetime.datetime.utcnow()
            to_put.append(log)
        # Put all log entities together.
        gae_util.BatchDatastoreOp(db.put, to_put)
    def _AddManifestModification(self):
        """Adds a new manifest modification to Datastore."""
        mod_type = self.request.get('mod_type')
        targets = [
            x.strip() for x in self.request.get('target').split(',')
            if x.strip()
        ]
        munki_pkg_name = self.request.get('munki_pkg_name').strip()
        manifests = self.request.get_all('manifests')
        install_types = self.request.get_all('install_types')
        remove_from_manifest = bool(self.request.get('remove-from-manifest'))

        # Security users are only able to inject specific packages.
        if not self.IsAdminUser():
            grp = None
            if auth.IsSupportUser():
                grp = common.MANIFEST_MOD_SUPPORT_GROUP
                # Support users can only inject items into optional_installs.
                install_types = ['optional_installs']
            elif auth.IsSecurityUser():
                grp = common.MANIFEST_MOD_SECURITY_GROUP
                # Security users can only inject items into managed_installs.
                install_types = ['managed_installs']

            munki_pkg_names = models.PackageInfo.GetManifestModPkgNames(
                grp, only_names=True)
            if munki_pkg_name not in munki_pkg_names:
                self.response.out.write('You are not allowed to inject: %s' %
                                        munki_pkg_name)
                self.response.set_status(httplib.FORBIDDEN)
                return
            elif mod_type not in [k for k, _ in MOD_GROUP_TYPES.get(grp, [])]:
                self.response.out.write(
                    'You are not allowed to inject to: %s' % mod_type)
                self.response.set_status(httplib.FORBIDDEN)
                return

        # Validation.
        error_msg = None
        if not targets or not munki_pkg_name or not install_types:
            error_msg = (
                'target, munki_pkg_name, and install_types are all required')
        if not error_msg:
            for manifest in manifests:
                if manifest not in common.TRACKS:
                    error_msg = 'manifest %s is not in %s' % (manifest,
                                                              common.TRACKS)
        if not error_msg:
            for install_type in install_types:
                if install_type not in common.INSTALL_TYPES:
                    error_msg = 'install_type %s is not in %s' % (
                        install_type, common.INSTALL_TYPES)
        if not error_msg:
            if not models.PackageInfo.all().filter('name =',
                                                   munki_pkg_name).get():
                error_msg = 'No package found with Munki name: %s' % munki_pkg_name
        if not error_msg and len(targets) > MAX_TARGETS_PER_POST:
            error_msg = 'too many targets'
        if error_msg:
            self.redirect('/admin/manifest_modifications?msg=%s' % error_msg)
            return

        to_put = []
        for target in targets:
            mod = models.BaseManifestModification.GenerateInstance(
                mod_type,
                target,
                munki_pkg_name,
                manifests=manifests,
                install_types=install_types,
                user=users.get_current_user(),
                remove=remove_from_manifest)
            to_put.append(mod)

        gae_util.BatchDatastoreOp(db.put, to_put)
        for target in targets:
            models.BaseManifestModification.ResetModMemcache(mod_type, target)

        msg = 'Manifest Modification successfully saved.'
        self.redirect('/admin/manifest_modifications?mod_type=%s&msg=%s' %
                      (mod_type, msg))
Ejemplo n.º 4
0
            pkg = '%s-%s' % (name, version)
            entity = models.InstallLog(uuid=computer.uuid,
                                       computer=computer,
                                       package=pkg,
                                       status=status,
                                       on_corp=on_corp,
                                       applesus=applesus,
                                       unattended=unattended,
                                       duration_seconds=duration_seconds,
                                       mtime=install_datetime,
                                       dl_kbytes_per_sec=dl_kbytes_per_sec)
            entity.success = entity.IsSuccess()
            to_put.append(entity)

        gae_util.BatchDatastoreOp(models.db.put, to_put)

    def post(self):
        """Reports get handler.

    Returns:
      A webapp.Response() response.
    """
        session = gaeserver.DoMunkiAuth()
        uuid = main_common.SanitizeUUID(session.uuid)
        report_type = self.request.get('_report_type')
        feedback_requested = self.request.get('_feedback')
        message = None
        details = None
        client_id = None
        computer = None
Ejemplo n.º 5
0
    def _LogInstalls(self, installs, computer):
        """Logs a batch of installs for a given computer.

    Args:
      installs: list, of str install data from a preflight/postflight report.
      computer: models.Computer entity.
    """
        if not installs:
            return

        on_corp = self.request.get('on_corp')
        if on_corp == '1':
            on_corp = True
        elif on_corp == '0':
            on_corp = False
        else:
            on_corp = None

        to_put = []
        for install in installs:
            if install.startswith('Install of'):
                d = {
                    'applesus': 'false',
                    'duration_seconds': None,
                    'download_kbytes_per_sec': None,
                    'name': install,
                    'status': 'UNKNOWN',
                    'version': '',
                    'unattended': 'false',
                }
                # support for old 'Install of FooPkg-1.0: SUCCESSFUL' style strings.
                try:
                    m = LEGACY_INSTALL_RESULTS_STRING_REGEX.search(install)
                    if not m:
                        raise ValueError
                    elif m.group(3) == INSTALL_RESULT_SUCCESSFUL:
                        d['status'] = 0
                    else:
                        d['status'] = m.group(4)
                    d['name'] = m.group(1)
                    d['version'] = m.group(2)
                except (IndexError, AttributeError, ValueError):
                    logging.warning('Unknown install string format: %s',
                                    install)
            else:
                # support for new 'name=pkg|version=foo|...' style strings.
                d = common.KeyValueStringToDict(install)

            name = d.get('display_name', '') or d.get('name', '')
            version = d.get('version', '')
            status = str(d.get('status', ''))
            applesus = common.GetBoolValueFromString(d.get('applesus', '0'))
            unattended = common.GetBoolValueFromString(d.get(
                'unattended', '0'))
            try:
                duration_seconds = int(d.get('duration_seconds', None))
            except (TypeError, ValueError):
                duration_seconds = None
            try:
                dl_kbytes_per_sec = int(d.get('download_kbytes_per_sec', None))
                # Ignore zero KB/s download speeds, as that's how Munki reports
                # unknown speed.
                if dl_kbytes_per_sec == 0:
                    dl_kbytes_per_sec = None
            except (TypeError, ValueError):
                dl_kbytes_per_sec = None

            try:
                install_datetime = util.Datetime.utcfromtimestamp(
                    d.get('time', None))
            except ValueError as e:
                logging.info('Ignoring invalid install_datetime: %s', str(e))
                install_datetime = datetime.datetime.utcnow()
            except util.EpochExtremeFutureValueError as e:
                logging.info('Ignoring extreme future install_datetime: %s',
                             str(e))
                install_datetime = datetime.datetime.utcnow()
            except util.EpochFutureValueError:
                install_datetime = datetime.datetime.utcnow()

            pkg = '%s-%s' % (name, version)
            entity = models.InstallLog(uuid=computer.uuid,
                                       computer=computer,
                                       package=pkg,
                                       status=status,
                                       on_corp=on_corp,
                                       applesus=applesus,
                                       unattended=unattended,
                                       duration_seconds=duration_seconds,
                                       mtime=install_datetime,
                                       dl_kbytes_per_sec=dl_kbytes_per_sec)
            entity.success = entity.IsSuccess()
            to_put.append(entity)

        gae_util.BatchDatastoreOp(models.db.put, to_put)