Skip to content

Commit

Permalink
Merge branch 'arraysize-virts' of https://github.com/vertexproject/sy…
Browse files Browse the repository at this point in the history
…napse into arraysize-virts
  • Loading branch information
Cisphyx committed Jan 2, 2025
2 parents b0d968a + 53979b6 commit d73250b
Show file tree
Hide file tree
Showing 35 changed files with 1,285 additions and 212 deletions.
39 changes: 39 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,45 @@
Synapse Changelog
*****************

v2.192.0 - 2024-12-13
=====================

Features and Enhancements
-------------------------
- Added the user-agent string to the structured log information captured by the
HTTP API handlers.
(`#4026 <https://github.com/vertexproject/synapse/pull/4026>`_)
- Added support for passing ``$lib.true`` to Storm HTTP APIs that accept a
proxy argument to indicate that the configured proxy should be used if set.
(`#4030 <https://github.com/vertexproject/synapse/pull/4030>`_)
- Added support for passing ``True`` as a proxy argument to the ``wget``,
``wput``, and ``postfiles`` Axon APIs to indicate that the configured proxy
should be used if set.
(`#4030 <https://github.com/vertexproject/synapse/pull/4030>`_)
- Added ``synapse.tools.apikey`` tool for managing user API keys via telepath.
(`#4032 <https://github.com/vertexproject/synapse/pull/4032>`_)

Bugfixes
--------
- Fixed an issue where mirrors of Synapse services may fail to indicate that
they have entered into realtime change windows.
(`#4028 <https://github.com/vertexproject/synapse/pull/4028>`_)
- Fixed a bug that skipped global and form pivots when validating graph
projection Storm queries.
(`#4031 <https://github.com/vertexproject/synapse/pull/4031>`_)
- Fixed an issue where line number information was not added to exceptions
raised while dereferencing a Storm variable.
(`#4035 <https://github.com/vertexproject/synapse/pull/4035>`_)

Deprecations
------------
- Deprecated passing ``None`` as a proxy argument to the ``wget``, ``wput``,
and ``postfiles`` Axon APIs.
(`#4030 <https://github.com/vertexproject/synapse/pull/4030>`_)
- Deprecated passing ``$lib.null`` to Storm HTTP APIs that accept a proxy
argument.
(`#4030 <https://github.com/vertexproject/synapse/pull/4030>`_)

v2.191.0 - 2024-12-06
=====================

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ dependencies = [
'aiohttp-socks>=0.9.0,<0.10.0',
'aioimaplib>=1.1.0,<1.2.0',
'aiosmtplib>=3.0.0,<3.1.0',
'prompt-toolkit>=3.0.4,<3.1.0',
'prompt_toolkit>=3.0.29,<3.1.0',
'lark==1.2.2',
'Pygments>=2.7.4,<2.18.0',
'packaging>=20.0,<25.0',
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ aiohttp>=3.10.0,<4.0
aiohttp-socks>=0.9.0,<0.10.0
aioimaplib>=1.1.0,<1.2.0
aiosmtplib>=3.0.0,<3.1.0
prompt-toolkit>=3.0.4,<3.1.0
prompt_toolkit>=3.0.29,<3.1.0
lark==1.2.2
Pygments>=2.7.4,<2.18.0
fastjsonschema>=2.18.0,<2.20.0
Expand Down
15 changes: 15 additions & 0 deletions synapse/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
import contextlib
import collections

import http.cookies

import yaml
import regex

Expand All @@ -38,6 +40,8 @@
import synapse.lib.structlog as s_structlog

import synapse.vendor.cpython.lib.ipaddress as ipaddress
import synapse.vendor.cpython.lib.http.cookies as v_cookies


try:
from yaml import CSafeLoader as Loader
Expand Down Expand Up @@ -1195,6 +1199,17 @@ def trimText(text: str, n: int = 256, placeholder: str = '...') -> str:
assert n > plen
return f'{text[:mlen]}{placeholder}'

def _patch_http_cookies():
'''
Patch stdlib http.cookies._unquote from the 3.11.10 implementation if
the interpreter we are using is not patched for CVE-2024-7592.
'''
if not hasattr(http.cookies, '_QuotePatt'):
return
http.cookies._unquote = v_cookies._unquote

_patch_http_cookies()

# TODO: Switch back to using asyncio.wait_for when we are using py 3.12+
# This is a workaround for a race where asyncio.wait_for can end up
# ignoring cancellation https://github.com/python/cpython/issues/86296
Expand Down
38 changes: 18 additions & 20 deletions synapse/cortex.py
Original file line number Diff line number Diff line change
Expand Up @@ -1496,7 +1496,7 @@ async def reqValidStormGraph(self, gdef):
for filt in gdef.get('filters', ()):
await self.getStormQuery(filt)

for pivo in gdef.get('filters', ()):
for pivo in gdef.get('pivots', ()):
await self.getStormQuery(pivo)

for form, rule in gdef.get('forms', {}).items():
Expand All @@ -1506,7 +1506,7 @@ async def reqValidStormGraph(self, gdef):
for filt in rule.get('filters', ()):
await self.getStormQuery(filt)

for pivo in rule.get('filters', ()):
for pivo in rule.get('pivots', ()):
await self.getStormQuery(pivo)

async def addStormGraph(self, gdef, user=None):
Expand Down Expand Up @@ -2049,7 +2049,7 @@ async def _onSetStormCmd(self, cdef):
'''
name = cdef.get('name')
await self._setStormCmd(cdef)
self._setStormCmd(cdef)
self.cmddefs.set(name, cdef)

async def _reqStormCmd(self, cdef):
Expand All @@ -2060,7 +2060,7 @@ async def _reqStormCmd(self, cdef):

await self.getStormQuery(cdef.get('storm'))

async def _setStormCmd(self, cdef):
def _setStormCmd(self, cdef):
'''
Note:
No change control or persistence
Expand Down Expand Up @@ -2115,13 +2115,9 @@ def getRuntPode():
name = cdef.get('name')
self.stormcmds[name] = ctor

await self.fire('core:cmd:change', cmd=name, act='add')

async def _popStormCmd(self, name):
def _popStormCmd(self, name):
self.stormcmds.pop(name, None)

await self.fire('core:cmd:change', cmd=name, act='del')

async def delStormCmd(self, name):
'''
Remove a previously set pure storm command.
Expand All @@ -2147,8 +2143,6 @@ async def _delStormCmd(self, name):
self.cmddefs.pop(name)
self.stormcmds.pop(name, None)

await self.fire('core:cmd:change', cmd=name, act='del')

async def addStormPkg(self, pkgdef, verify=False):
'''
Add the given storm package to the cortex.
Expand Down Expand Up @@ -2202,11 +2196,11 @@ async def _addStormPkg(self, pkgdef):
olddef = self.pkgdefs.get(name, None)
if olddef is not None:
if s_hashitem.hashitem(pkgdef) != s_hashitem.hashitem(olddef):
await self._dropStormPkg(olddef)
self._dropStormPkg(olddef)
else:
return

await self.loadStormPkg(pkgdef)
self.loadStormPkg(pkgdef)
self.pkgdefs.set(name, pkgdef)

self._clearPermDefs()
Expand Down Expand Up @@ -2236,7 +2230,7 @@ async def _delStormPkg(self, name):
if pkgdef is None:
return

await self._dropStormPkg(pkgdef)
self._dropStormPkg(pkgdef)

self._clearPermDefs()

Expand Down Expand Up @@ -2285,7 +2279,7 @@ def getDataModel(self):
async def _tryLoadStormPkg(self, pkgdef):
try:
await self._normStormPkg(pkgdef, validstorm=False)
await self.loadStormPkg(pkgdef)
self.loadStormPkg(pkgdef)

except asyncio.CancelledError: # pragma: no cover TODO: remove once >= py 3.8 only
raise
Expand Down Expand Up @@ -2444,7 +2438,9 @@ async def _normStormPkg(self, pkgdef, validstorm=True):
for configvar in pkgdef.get('configvars', ()):
self._reqStormPkgVarType(pkgname, configvar.get('type'))

async def loadStormPkg(self, pkgdef):
# N.B. This function is intentionally not async in order to prevent possible user race conditions for code
# executing outside of the nexus lock.
def loadStormPkg(self, pkgdef):
'''
Load a storm package into the storm library for this cortex.
Expand Down Expand Up @@ -2474,7 +2470,7 @@ async def loadStormPkg(self, pkgdef):
self.stormmods = stormmods

for cdef in cmds:
await self._setStormCmd(cdef)
self._setStormCmd(cdef)

for gdef in pkgdef.get('graphs', ()):
gdef = copy.deepcopy(gdef)
Expand All @@ -2500,7 +2496,9 @@ async def _onload():
await self.fire('core:pkg:onload:complete', pkg=name)
self.schedCoro(_onload())

async def _dropStormPkg(self, pkgdef):
# N.B. This function is intentionally not async in order to prevent possible user race conditions for code
# executing outside of the nexus lock.
def _dropStormPkg(self, pkgdef):
'''
Reverse the process of loadStormPkg()
'''
Expand All @@ -2511,7 +2509,7 @@ async def _dropStormPkg(self, pkgdef):

for cdef in pkgdef.get('commands', ()):
name = cdef.get('name')
await self._popStormCmd(name)
self._popStormCmd(name)

pkgname = pkgdef.get('name')

Expand Down Expand Up @@ -3939,7 +3937,7 @@ async def _initPureStormCmds(self):

async def _trySetStormCmd(self, name, cdef):
try:
await self._setStormCmd(cdef)
self._setStormCmd(cdef)
except (asyncio.CancelledError, Exception):
logger.exception(f'Storm command load failed: {name}')

Expand Down
7 changes: 6 additions & 1 deletion synapse/exc.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,14 @@ def setdefault(self, name, valu):
self.errinfo[name] = valu
self._setExcMesg()

def update(self, items: dict):
'''Update multiple items in the errinfo dict at once.'''
self.errinfo.update(**items)
self._setExcMesg()

class StormRaise(SynErr):
'''
This represents a user provided exception inside of a Storm runtime. It requires a errname key.
This represents a user provided exception raised in the Storm runtime. It requires a errname key.
'''
def __init__(self, *args, **info):
SynErr.__init__(self, *args, **info)
Expand Down
2 changes: 0 additions & 2 deletions synapse/lib/agenda.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@
import logging
import calendar
import datetime
import functools
import itertools
import collections
from datetime import timezone as tz
from collections.abc import Iterable, Mapping

Expand Down
42 changes: 30 additions & 12 deletions synapse/lib/ast.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ def getPosInfo(self):
}

def addExcInfo(self, exc):
exc.errinfo['highlight'] = self.getPosInfo()
if 'highlight' not in exc.errinfo:
exc.set('highlight', self.getPosInfo())
return exc

def repr(self):
Expand Down Expand Up @@ -3556,7 +3557,10 @@ async def compute(self, runt, path):

valu = s_stormtypes.fromprim(base, path=path)
with s_scope.enter({'runt': runt}):
return await valu.deref(name)
try:
return await valu.deref(name)
except s_exc.SynErr as e:
raise self.kids[1].addExcInfo(e)

class FuncCall(Value):

Expand All @@ -3577,10 +3581,23 @@ async def compute(self, runt, path):
kwargs = {k: v for (k, v) in await self.kids[2].compute(runt, path)}

with s_scope.enter({'runt': runt}):
retn = func(*argv, **kwargs)
if s_coro.iscoro(retn):
return await retn
return retn
try:
retn = func(*argv, **kwargs)
if s_coro.iscoro(retn):
return await retn
return retn

except TypeError as e:
mesg = str(e)
if (funcpath := getattr(func, '_storm_funcpath', None)) is not None:
mesg = f"{funcpath}(){mesg.split(')', 1)[1]}"

raise self.addExcInfo(s_exc.StormRuntimeError(mesg=mesg))

except s_exc.SynErr as e:
if getattr(func, '_storm_runtime_lib_func', None) is not None:
e.errinfo.pop('highlight', None)
raise self.addExcInfo(e)

class DollarExpr(Value):
'''
Expand Down Expand Up @@ -5035,8 +5052,9 @@ async def once():

@s_stormtypes.stormfunc(readonly=True)
async def realfunc(*args, **kwargs):
return await self.callfunc(runt, argdefs, args, kwargs)
return await self.callfunc(runt, argdefs, args, kwargs, realfunc._storm_funcpath)

realfunc._storm_funcpath = self.name
await runt.setVar(self.name, realfunc)

count = 0
Expand All @@ -5058,7 +5076,7 @@ def validate(self, runt):
# var scope validation occurs in the sub-runtime
pass

async def callfunc(self, runt, argdefs, args, kwargs):
async def callfunc(self, runt, argdefs, args, kwargs, funcpath):
'''
Execute a function call using the given runtime.
Expand All @@ -5069,7 +5087,7 @@ async def callfunc(self, runt, argdefs, args, kwargs):

argcount = len(args) + len(kwargs)
if argcount > len(argdefs):
mesg = f'{self.name}() takes {len(argdefs)} arguments but {argcount} were provided'
mesg = f'{funcpath}() takes {len(argdefs)} arguments but {argcount} were provided'
raise self.kids[1].addExcInfo(s_exc.StormRuntimeError(mesg=mesg))

# Fill in the positional arguments
Expand All @@ -5083,7 +5101,7 @@ async def callfunc(self, runt, argdefs, args, kwargs):
valu = kwargs.pop(name, s_common.novalu)
if valu is s_common.novalu:
if defv is s_common.novalu:
mesg = f'{self.name}() missing required argument {name}'
mesg = f'{funcpath}() missing required argument {name}'
raise self.kids[1].addExcInfo(s_exc.StormRuntimeError(mesg=mesg))
valu = defv

Expand All @@ -5094,11 +5112,11 @@ async def callfunc(self, runt, argdefs, args, kwargs):
# used a kwarg not defined.
kwkeys = list(kwargs.keys())
if kwkeys[0] in posnames:
mesg = f'{self.name}() got multiple values for parameter {kwkeys[0]}'
mesg = f'{funcpath}() got multiple values for parameter {kwkeys[0]}'
raise self.kids[1].addExcInfo(s_exc.StormRuntimeError(mesg=mesg))

plural = 's' if len(kwargs) > 1 else ''
mesg = f'{self.name}() got unexpected keyword argument{plural}: {",".join(kwkeys)}'
mesg = f'{funcpath}() got unexpected keyword argument{plural}: {",".join(kwkeys)}'
raise self.kids[1].addExcInfo(s_exc.StormRuntimeError(mesg=mesg))

assert len(mergargs) == len(argdefs)
Expand Down
Loading

0 comments on commit d73250b

Please sign in to comment.