Example #1
0
    def __post_init__(self, iden, triggers):

        self.iden = iden
        self.triggers = triggers

        if self.ver != 1:
            raise s_exc.BadOptValu(mesg='Unexpected rule version')
        if self.cond not in Conditions:
            raise s_exc.BadOptValu(mesg='Invalid trigger condition')
        if self.cond in ('node:add', 'node:del') and self.form is None:
            raise s_exc.BadOptValu(
                mesg='form must be present for node:add or node:del')
        if self.cond in ('node:add', 'node:del') and self.tag is not None:
            raise s_exc.BadOptValu(
                mesg='tag must not be present for node:add or node:del')
        if self.cond == 'prop:set' and (self.form is not None
                                        or self.tag is not None):
            raise s_exc.BadOptValu(
                mesg='form and tag must not be present for prop:set')
        if self.cond in ('tag:add', 'tag:del'):
            if self.tag is None:
                raise s_exc.BadOptValu(mesg='missing tag')
            s_chop.validateTagMatch(self.tag)
        if self.prop is not None and self.cond != 'prop:set':
            raise s_exc.BadOptValu(mesg='prop parameter invalid')
        if self.cond == 'prop:set' and self.prop is None:
            raise s_exc.BadOptValu(mesg='missing prop parameter')
Example #2
0
 async def setViewInfo(self, name, valu):
     '''
     Set a mutable view property.
     '''
     if name not in ('name', ):
         mesg = f'{name} is not a valid view info key'
         raise s_exc.BadOptValu(mesg=mesg)
     # TODO when we can set more props, we may need to parse values.
     await self.info.set(name, valu)
     return valu
Example #3
0
    def load(self, tdef):

        trig = Trigger(self.view, tdef)

        # Make sure the query parses
        storm = trig.tdef['storm']
        self.view.core.getStormQuery(storm)

        cond = trig.tdef.get('cond')
        tag = trig.tdef.get('tag')
        form = trig.tdef.get('form')
        prop = trig.tdef.get('prop')

        if cond not in Conditions:
            raise s_exc.NoSuchCond(name=cond)

        if cond in ('node:add', 'node:del') and form is None:
            raise s_exc.BadOptValu(
                mesg='form must be present for node:add or node:del')
        if cond in ('node:add', 'node:del') and tag is not None:
            raise s_exc.BadOptValu(
                mesg='tag must not be present for node:add or node:del')
        if cond in ('tag:add', 'tag:del'):
            if tag is None:
                raise s_exc.BadOptValu(mesg='missing tag')
            s_chop.validateTagMatch(tag)
        if prop is not None and cond != 'prop:set':
            raise s_exc.BadOptValu(mesg='prop parameter invalid')

        if cond == 'node:add':
            self.nodeadd[form].append(trig)

        elif cond == 'node:del':
            self.nodedel[form].append(trig)

        elif cond == 'prop:set':
            if prop is None:
                raise s_exc.BadOptValu(mesg='missing prop parameter')
            if form is not None or tag is not None:
                raise s_exc.BadOptValu(
                    mesg='form and tag must not be present for prop:set')
            self.propset[prop].append(trig)

        elif cond == 'tag:add':

            if '*' not in tag:
                self.tagadd[(form, tag)].append(trig)
            else:
                # we have a glob add
                self.tagaddglobs[form].add(tag, trig)

        elif cond == 'tag:del':

            if '*' not in tag:
                self.tagdel[(form, tag)].append(trig)
            else:
                self.tagdelglobs[form].add(tag, trig)

        self.triggers[trig.iden] = trig
        return trig
Example #4
0
    async def setViewInfo(self, name, valu):
        '''
        Set a mutable view property.
        '''
        if name not in ('name', 'desc', 'parent'):
            mesg = f'{name} is not a valid view info key'
            raise s_exc.BadOptValu(mesg=mesg)

        if name == 'parent':

            parent = self.core.getView(valu)
            if parent is None:
                mesg = 'The parent view must already exist.'
                raise s_exc.NoSuchView(mesg=mesg)

            if parent.iden == self.iden:
                mesg = 'A view may not have parent set to itself.'
                raise s_exc.BadArg(mesg=mesg)

            if parent.isForkOf(self.iden):
                mesg = 'Circular dependency of view parents is not supported.'
                raise s_exc.BadArg(mesg=mesg)

            if self.parent is not None:
                mesg = 'You may not set parent on a view which already has one.'
                raise s_exc.BadArg(mesg=mesg)

            if len(self.layers) != 1:
                mesg = 'You may not set parent on a view which has more than one layer.'
                raise s_exc.BadArg(mesg=mesg)

            self.parent = parent
            await self.info.set(name, valu)

            await self._calcForkLayers()

            for view in self.core.views.values():
                if view.isForkOf(self.iden):
                    await view._calcForkLayers()

            await self.core._calcViewsByLayer()

        else:
            await self.info.set(name, valu)

        return valu
Example #5
0
    async def execStormCmd(self, runt, genr):

        async for node, path in genr:  # type: s_node.Node, s_node.Path

            # repr all prop vals and try to scrape nodes from them
            reprs = node.reprs()

            # make sure any provided props are valid
            for fprop in self.opts.props:
                if node.form.props.get(fprop, None) is None:
                    raise s_exc.BadOptValu(
                        mesg=f'{fprop} not a valid prop for {node.ndef[1]}',
                        name='props',
                        valu=self.opts.props)

            # if a list of props haven't been specified, then default to ALL of them
            proplist = self.opts.props
            if not proplist:
                proplist = [k for k in node.props.keys()]

            for prop in proplist:
                val = node.props.get(prop)
                if val is None:
                    await runt.snap.printf(f'No prop ":{prop}" for {node.ndef}'
                                           )
                    continue

                # use the repr val or the system mode val as appropriate
                sval = reprs.get(prop, val)

                for form, valu in s_scrape.scrape(sval):
                    nnode = await node.snap.addNode(form, valu)
                    npath = path.fork(nnode)
                    yield nnode, npath

                    if self.opts.refs:
                        rnode = await node.snap.addNode(
                            'edge:refs', (node.ndef, nnode.ndef))
                        rpath = path.fork(rnode)
                        yield rnode, rpath

            if self.opts.join:
                yield node, path
Example #6
0
    def query(self):

        self.ignore(whitespace)

        query = s_ast.Query()
        query.text = self.text

        while True:

            self.ignorespace()

            if not self.more():
                break

            # if we are sub-query, time to go...
            if self.nextstr('}'):
                break

            # | <command> syntax...
            if self.nextstr('|'):

                self.offs += 1

                # trailing | case...
                self.ignore(whitespace)
                if not self.more():
                    break

                # switch to command interpreter...
                name = self.cmdname()
                argv = self.cmdargv()

                oper = s_ast.CmdOper(kids=(name, argv))
                query.addKid(oper)

                # command is last query text case...
                if not self.more():
                    break

                self.ignorespace()

                # End of subquery
                if self.nextstr('}'):
                    continue

                # back to storm mode...
                if self.nextstr('|'):
                    self.offs += 1
                    continue

                self._raiseSyntaxError('expected | or end of input for cmd')

            # parse a query option: %foo=10
            if self.nextstr('%'):

                self.offs += 1

                self.ignore(whitespace)
                name = self.noms(optset)

                self.ignore(whitespace)
                self.nextmust('=')

                valu = self.noms(alphanum)

                cast = optcast.get(name)
                if cast is None:
                    raise s_exc.NoSuchOpt(name=name)

                try:
                    valu = cast(valu)
                except Exception:
                    raise s_exc.BadOptValu(name=name, valu=valu)

                query.opts[name] = valu

                continue

            # edit operations...
            if self.nextstr('['):

                self.offs += 1

                self.ignore(whitespace)
                while not self.nextstr(']'):
                    oper = self.editoper()
                    query.kids.append(oper)
                    self.ignore(whitespace)

                self.offs += 1
                continue

            oper = self.oper()
            query.addKid(oper)

            self.ignorespace()

        return query