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')
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
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
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
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
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