synapse 2.220.0__py311-none-any.whl → 2.221.0__py311-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of synapse might be problematic. Click here for more details.
- synapse/lib/layer.py +134 -0
- synapse/lib/rstorm.py +65 -2
- synapse/lib/snap.py +21 -13
- synapse/lib/stormhttp.py +10 -10
- synapse/lib/stormlib/aha.py +3 -3
- synapse/lib/stormlib/auth.py +11 -11
- synapse/lib/stormlib/cell.py +1 -1
- synapse/lib/stormlib/cortex.py +9 -9
- synapse/lib/stormlib/env.py +4 -5
- synapse/lib/stormlib/ethereum.py +1 -1
- synapse/lib/stormlib/gen.py +3 -3
- synapse/lib/stormlib/hex.py +2 -2
- synapse/lib/stormlib/imap.py +2 -2
- synapse/lib/stormlib/infosec.py +2 -2
- synapse/lib/stormlib/iters.py +2 -2
- synapse/lib/stormlib/model.py +5 -5
- synapse/lib/stormlib/notifications.py +1 -1
- synapse/lib/stormlib/oauth.py +2 -2
- synapse/lib/stormlib/project.py +3 -3
- synapse/lib/stormlib/scrape.py +2 -1
- synapse/lib/stormlib/smtp.py +3 -3
- synapse/lib/stormlib/stats.py +2 -2
- synapse/lib/stormlib/stix.py +2 -2
- synapse/lib/stormlib/utils.py +19 -0
- synapse/lib/stormlib/vault.py +1 -1
- synapse/lib/stormlib/xml.py +2 -2
- synapse/lib/stormlib/yaml.py +1 -1
- synapse/lib/stormtypes.py +164 -60
- synapse/lib/version.py +2 -2
- synapse/tests/test_lib_layer.py +86 -67
- synapse/tests/test_lib_rstorm.py +132 -0
- synapse/tests/test_lib_storm.py +6 -0
- synapse/tests/test_lib_stormlib_env.py +3 -1
- synapse/tests/test_lib_stormlib_utils.py +10 -0
- synapse/tests/test_lib_stormtypes.py +551 -2
- synapse/tools/aha/list.py +9 -9
- synapse/tools/aha/provision/service.py +2 -2
- {synapse-2.220.0.dist-info → synapse-2.221.0.dist-info}/METADATA +1 -1
- {synapse-2.220.0.dist-info → synapse-2.221.0.dist-info}/RECORD +42 -42
- {synapse-2.220.0.dist-info → synapse-2.221.0.dist-info}/WHEEL +0 -0
- {synapse-2.220.0.dist-info → synapse-2.221.0.dist-info}/licenses/LICENSE +0 -0
- {synapse-2.220.0.dist-info → synapse-2.221.0.dist-info}/top_level.txt +0 -0
|
@@ -17,6 +17,7 @@ import synapse.axon as s_axon
|
|
|
17
17
|
import synapse.common as s_common
|
|
18
18
|
|
|
19
19
|
import synapse.lib.json as s_json
|
|
20
|
+
import synapse.lib.node as s_node
|
|
20
21
|
import synapse.lib.time as s_time
|
|
21
22
|
import synapse.lib.storm as s_storm
|
|
22
23
|
import synapse.lib.hashset as s_hashset
|
|
@@ -884,13 +885,32 @@ class StormTypesTest(s_test.SynTest):
|
|
|
884
885
|
self.eq(2, await core.callStorm('return($lib.len($lib.layer.get().getStorNodes()))', opts=opts))
|
|
885
886
|
|
|
886
887
|
await core.nodes('[ media:news=c0dc5dc1f7c3d27b725ef3015422f8e2 +(refs)> { inet:ipv4=1.2.3.4 } ]')
|
|
888
|
+
expN1 = [('refs', '20153b758f9d5eaaa38e4f4a65c36da797c3e59e549620fa7c4895e1a920991f')]
|
|
889
|
+
expN2 = [('refs', 'ddf7f87c0164d760e8e1e5cd2cae2fee96868a3cf184f6dab9154e31ad689528')]
|
|
890
|
+
|
|
887
891
|
edges = await core.callStorm('''
|
|
888
892
|
$edges = ([])
|
|
889
893
|
media:news=c0dc5dc1f7c3d27b725ef3015422f8e2
|
|
890
894
|
for $i in $lib.layer.get().getEdgesByN1($node.iden()) { $edges.append($i) }
|
|
891
895
|
fini { return($edges) }
|
|
892
896
|
''')
|
|
893
|
-
self.eq(
|
|
897
|
+
self.eq(expN1, edges)
|
|
898
|
+
|
|
899
|
+
edges = await core.callStorm('''
|
|
900
|
+
$edges = ([])
|
|
901
|
+
media:news=c0dc5dc1f7c3d27b725ef3015422f8e2
|
|
902
|
+
for $i in $lib.layer.get().getEdgesByN1($node.iden(), verb=refs) { $edges.append($i) }
|
|
903
|
+
fini { return($edges) }
|
|
904
|
+
''')
|
|
905
|
+
self.eq(expN1, edges)
|
|
906
|
+
|
|
907
|
+
edges = await core.callStorm('''
|
|
908
|
+
$edges = ([])
|
|
909
|
+
media:news=c0dc5dc1f7c3d27b725ef3015422f8e2
|
|
910
|
+
for $i in $lib.layer.get().getEdgesByN1($node.iden(), verb=newp) { $edges.append($i) }
|
|
911
|
+
fini { return($edges) }
|
|
912
|
+
''')
|
|
913
|
+
self.eq([], edges)
|
|
894
914
|
|
|
895
915
|
edges = await core.callStorm('''
|
|
896
916
|
$edges = ([])
|
|
@@ -898,7 +918,37 @@ class StormTypesTest(s_test.SynTest):
|
|
|
898
918
|
for $i in $lib.layer.get().getEdgesByN2($node.iden()) { $edges.append($i) }
|
|
899
919
|
fini { return($edges) }
|
|
900
920
|
''')
|
|
901
|
-
self.eq(
|
|
921
|
+
self.eq(expN2, edges)
|
|
922
|
+
|
|
923
|
+
edges = await core.callStorm('''
|
|
924
|
+
$edges = ([])
|
|
925
|
+
inet:ipv4=1.2.3.4
|
|
926
|
+
for $i in $lib.layer.get().getEdgesByN2($node.iden(), verb=refs) { $edges.append($i) }
|
|
927
|
+
fini { return($edges) }
|
|
928
|
+
''')
|
|
929
|
+
self.eq(expN2, edges)
|
|
930
|
+
|
|
931
|
+
edges = await core.callStorm('''
|
|
932
|
+
$edges = ([])
|
|
933
|
+
inet:ipv4=1.2.3.4
|
|
934
|
+
for $i in $lib.layer.get().getEdgesByN2($node.iden(), verb=newp) { $edges.append($i) }
|
|
935
|
+
fini { return($edges) }
|
|
936
|
+
''')
|
|
937
|
+
self.eq([], edges)
|
|
938
|
+
|
|
939
|
+
ret = await core.callStorm('''
|
|
940
|
+
$n1 = { media:news=c0dc5dc1f7c3d27b725ef3015422f8e2 return($node.iden()) }
|
|
941
|
+
$n2 = { inet:ipv4=1.2.3.4 return($node.iden()) }
|
|
942
|
+
return($lib.layer.get().hasEdge($n1, refs, $n2))
|
|
943
|
+
''')
|
|
944
|
+
self.true(ret)
|
|
945
|
+
|
|
946
|
+
ret = await core.callStorm('''
|
|
947
|
+
$n1 = { media:news=c0dc5dc1f7c3d27b725ef3015422f8e2 return($node.iden()) }
|
|
948
|
+
$n2 = { inet:ipv4=1.2.3.4 return($node.iden()) }
|
|
949
|
+
return($lib.layer.get().hasEdge($n1, newp, $n2))
|
|
950
|
+
''')
|
|
951
|
+
self.false(ret)
|
|
902
952
|
|
|
903
953
|
edges = await core.callStorm('''
|
|
904
954
|
$edges = ([])
|
|
@@ -1767,6 +1817,435 @@ class StormTypesTest(s_test.SynTest):
|
|
|
1767
1817
|
await visi.addRule((True, ('layer', 'read')), gateiden=layriden)
|
|
1768
1818
|
await core.callStorm('return($lib.layer.get($layriden).getStorNode($iden))', opts=opts)
|
|
1769
1819
|
|
|
1820
|
+
async def test_storm_layer_getstornodesbyprop(self):
|
|
1821
|
+
async with self.getTestCore() as core:
|
|
1822
|
+
nodes = await core.nodes('[ test:str=foobar :hehe=foobaz ]')
|
|
1823
|
+
self.len(1, nodes)
|
|
1824
|
+
|
|
1825
|
+
buid00 = nodes[0].iden()
|
|
1826
|
+
sode00 = {
|
|
1827
|
+
'form': 'test:str',
|
|
1828
|
+
'props': {
|
|
1829
|
+
'.created': (nodes[0].get('.created'), 21),
|
|
1830
|
+
'hehe': ('foobaz', 1)
|
|
1831
|
+
},
|
|
1832
|
+
'valu': ('foobar', 1),
|
|
1833
|
+
}
|
|
1834
|
+
expval00 = (buid00, sode00)
|
|
1835
|
+
|
|
1836
|
+
nodes = await core.nodes('[ test:str=boobar :hehe=boobaz ]')
|
|
1837
|
+
self.len(1, nodes)
|
|
1838
|
+
|
|
1839
|
+
buid01 = nodes[0].iden()
|
|
1840
|
+
sode01 = {
|
|
1841
|
+
'form': 'test:str',
|
|
1842
|
+
'props': {
|
|
1843
|
+
'.created': (nodes[0].get('.created'), 21),
|
|
1844
|
+
'hehe': ('boobaz', 1)
|
|
1845
|
+
},
|
|
1846
|
+
'valu': ('boobar', 1),
|
|
1847
|
+
}
|
|
1848
|
+
expval01 = (buid01, sode01)
|
|
1849
|
+
|
|
1850
|
+
# just prop
|
|
1851
|
+
q = '''
|
|
1852
|
+
$sodes = ([])
|
|
1853
|
+
for ($buid, $sode) in $lib.layer.get().getStorNodesByProp(test:str:hehe) {
|
|
1854
|
+
$sodes.append(($buid, $sode))
|
|
1855
|
+
}
|
|
1856
|
+
return($sodes)
|
|
1857
|
+
'''
|
|
1858
|
+
sodes = await core.callStorm(q)
|
|
1859
|
+
self.len(2, sodes)
|
|
1860
|
+
self.sorteq(sodes, (expval00, expval01))
|
|
1861
|
+
|
|
1862
|
+
# prop with propvalu
|
|
1863
|
+
q = '''
|
|
1864
|
+
$sodes = ([])
|
|
1865
|
+
for ($buid, $sode) in $lib.layer.get().getStorNodesByProp(test:str:hehe, propvalu=foobaz) {
|
|
1866
|
+
$sodes.append(($buid, $sode))
|
|
1867
|
+
}
|
|
1868
|
+
return($sodes)
|
|
1869
|
+
'''
|
|
1870
|
+
sodes = await core.callStorm(q)
|
|
1871
|
+
self.len(1, sodes)
|
|
1872
|
+
self.eq(sodes[0], expval00)
|
|
1873
|
+
|
|
1874
|
+
# just form
|
|
1875
|
+
q = '''
|
|
1876
|
+
$sodes = ([])
|
|
1877
|
+
for ($buid, $sode) in $lib.layer.get().getStorNodesByProp(test:str) {
|
|
1878
|
+
$sodes.append(($buid, $sode))
|
|
1879
|
+
}
|
|
1880
|
+
return($sodes)
|
|
1881
|
+
'''
|
|
1882
|
+
sodes = await core.callStorm(q)
|
|
1883
|
+
self.len(2, sodes)
|
|
1884
|
+
self.sorteq(sodes, (expval00, expval01))
|
|
1885
|
+
|
|
1886
|
+
# form with valu
|
|
1887
|
+
q = '''
|
|
1888
|
+
$sodes = ([])
|
|
1889
|
+
for ($buid, $sode) in $lib.layer.get().getStorNodesByProp(test:str, propvalu=boobar) {
|
|
1890
|
+
$sodes.append(($buid, $sode))
|
|
1891
|
+
}
|
|
1892
|
+
return($sodes)
|
|
1893
|
+
'''
|
|
1894
|
+
sodes = await core.callStorm(q)
|
|
1895
|
+
self.len(1, sodes)
|
|
1896
|
+
self.eq(sodes[0], expval01)
|
|
1897
|
+
|
|
1898
|
+
# Non-existent prop
|
|
1899
|
+
msgs = await core.stormlist('for $item in $lib.layer.get().getStorNodesByProp(test:str:_custom) {}')
|
|
1900
|
+
self.stormIsInErr('The property test:str:_custom does not exist.', msgs)
|
|
1901
|
+
|
|
1902
|
+
async def test_storm_layer_setstornodeprop(self):
|
|
1903
|
+
async with self.getTestCore() as core:
|
|
1904
|
+
|
|
1905
|
+
nodes = await core.nodes('[ test:str=foo :hehe=bar ]')
|
|
1906
|
+
self.len(1, nodes)
|
|
1907
|
+
self.eq(nodes[0].repr(), 'foo')
|
|
1908
|
+
self.eq(nodes[0].get('hehe'), 'bar')
|
|
1909
|
+
|
|
1910
|
+
msgs = await core.stormlist('test:str $lib.layer.get().setStorNodeProp($node.iden(), test:str:hehe, baz)')
|
|
1911
|
+
self.stormHasNoWarnErr(msgs)
|
|
1912
|
+
|
|
1913
|
+
nodes = await core.nodes('test:str')
|
|
1914
|
+
self.len(1, nodes)
|
|
1915
|
+
self.eq(nodes[0].repr(), 'foo')
|
|
1916
|
+
self.eq(nodes[0].get('hehe'), 'baz')
|
|
1917
|
+
|
|
1918
|
+
# no test:str:newp prop
|
|
1919
|
+
q = '''
|
|
1920
|
+
[ test:str=foobar00 ]
|
|
1921
|
+
$lib.layer.get().setStorNodeProp($node.iden(), test:str:newp, bar00)
|
|
1922
|
+
'''
|
|
1923
|
+
msgs = await core.stormlist(q)
|
|
1924
|
+
self.stormIsInErr('No property named test:str:newp.', msgs)
|
|
1925
|
+
|
|
1926
|
+
# Bad type
|
|
1927
|
+
msgs = await core.stormlist('[ test:str=foobar01 ] $lib.layer.get().setStorNodeProp($node.iden(), test:str:tick, newp)')
|
|
1928
|
+
self.stormIsInErr('Unknown time format for newp', msgs)
|
|
1929
|
+
|
|
1930
|
+
# insufficient perms
|
|
1931
|
+
lowuser = await core.auth.addUser('lowuser')
|
|
1932
|
+
await lowuser.addRule((True, ('node', 'add', 'test:str')))
|
|
1933
|
+
|
|
1934
|
+
q = '''
|
|
1935
|
+
[ test:str=foobar02 ]
|
|
1936
|
+
$lib.layer.get().setStorNodeProp($node.iden(), test:str:hehe, baz02)
|
|
1937
|
+
'''
|
|
1938
|
+
msgs = await core.stormlist(q, opts={'user': lowuser.iden})
|
|
1939
|
+
self.stormIsInErr('setStorNodeProp() requires admin privileges.', msgs)
|
|
1940
|
+
|
|
1941
|
+
# readonly layer
|
|
1942
|
+
layer = core.view.layers[0]
|
|
1943
|
+
await layer.setLayerInfo('readonly', True)
|
|
1944
|
+
msgs = await core.stormlist('test:str $lib.layer.get().setStorNodeProp($node.iden(), test:str:hehe, baz)')
|
|
1945
|
+
self.stormIsInErr(f'Layer {layer.iden} is read only!', msgs)
|
|
1946
|
+
|
|
1947
|
+
async def test_storm_layer_delstornode(self):
|
|
1948
|
+
async with self.getTestCore() as core:
|
|
1949
|
+
await core.addTagProp('score00', ('int', {}), {})
|
|
1950
|
+
await core.addTagProp('score01', ('int', {}), {})
|
|
1951
|
+
q = '''
|
|
1952
|
+
[ test:str=foo
|
|
1953
|
+
:hehe=bar
|
|
1954
|
+
+#foo
|
|
1955
|
+
+#foo.bar=now
|
|
1956
|
+
+#foo.baz:score00=10
|
|
1957
|
+
+#foo.baz:score01=20
|
|
1958
|
+
|
|
1959
|
+
<(seen)+ {[ meta:source=* :name=seen]}
|
|
1960
|
+
+(refs)> {[ meta:source=* :name=refs]}
|
|
1961
|
+
]
|
|
1962
|
+
|
|
1963
|
+
$node.data.set(foo, foo)
|
|
1964
|
+
$node.data.set(bar, bar)
|
|
1965
|
+
$node.data.set(baz, baz)
|
|
1966
|
+
'''
|
|
1967
|
+
nodes = await core.nodes(q)
|
|
1968
|
+
self.len(1, nodes)
|
|
1969
|
+
opts = {'vars': {'iden': nodes[0].iden()}}
|
|
1970
|
+
created = nodes[0].get('.created')
|
|
1971
|
+
foobar = nodes[0].get('#foo.bar')
|
|
1972
|
+
|
|
1973
|
+
sode = await core.callStorm('return($lib.layer.get().getStorNode($iden))', opts=opts)
|
|
1974
|
+
self.eq(sode, {
|
|
1975
|
+
'form': 'test:str',
|
|
1976
|
+
'props': {'.created': (created, 21), 'hehe': ('bar', 1)},
|
|
1977
|
+
'tagprops': {
|
|
1978
|
+
'foo.baz': {
|
|
1979
|
+
'score00': (10, 9),
|
|
1980
|
+
'score01': (20, 9)
|
|
1981
|
+
}
|
|
1982
|
+
},
|
|
1983
|
+
'tags': {
|
|
1984
|
+
'foo': (None, None),
|
|
1985
|
+
'foo.bar': foobar,
|
|
1986
|
+
'foo.baz': (None, None)
|
|
1987
|
+
},
|
|
1988
|
+
'valu': ('foo', 1)
|
|
1989
|
+
})
|
|
1990
|
+
|
|
1991
|
+
msgs = await core.stormlist('$lib.layer.get().delStorNode($iden)', opts=opts)
|
|
1992
|
+
self.stormHasNoWarnErr(msgs)
|
|
1993
|
+
|
|
1994
|
+
sode = await core.callStorm('return($lib.layer.get().getStorNode($iden))', opts=opts)
|
|
1995
|
+
self.eq(sode, {})
|
|
1996
|
+
|
|
1997
|
+
q = '''
|
|
1998
|
+
$data = ([])
|
|
1999
|
+
for $item in $lib.layer.get().getNodeData($iden) {
|
|
2000
|
+
$data.append($item)
|
|
2001
|
+
}
|
|
2002
|
+
return($data)
|
|
2003
|
+
'''
|
|
2004
|
+
nodedata = await core.callStorm(q, opts=opts)
|
|
2005
|
+
self.len(0, nodedata)
|
|
2006
|
+
|
|
2007
|
+
q = '''
|
|
2008
|
+
$edges = ([])
|
|
2009
|
+
for $edge in $lib.layer.get().getEdgesByN1($iden) {
|
|
2010
|
+
$edges.append($edge)
|
|
2011
|
+
}
|
|
2012
|
+
for $edge in $lib.layer.get().getEdgesByN2($iden) {
|
|
2013
|
+
$edges.append($edge)
|
|
2014
|
+
}
|
|
2015
|
+
return($edges)
|
|
2016
|
+
'''
|
|
2017
|
+
edges = await core.callStorm(q, opts=opts)
|
|
2018
|
+
self.len(0, edges)
|
|
2019
|
+
|
|
2020
|
+
self.false(await core.callStorm('return($lib.layer.get().delStorNode($iden))', opts=opts))
|
|
2021
|
+
|
|
2022
|
+
# insufficient perms
|
|
2023
|
+
lowuser = await core.auth.addUser('lowuser')
|
|
2024
|
+
await lowuser.addRule((True, ('node', 'add', 'test:str')))
|
|
2025
|
+
|
|
2026
|
+
q = '''
|
|
2027
|
+
[ test:str=foobar02 ]
|
|
2028
|
+
$lib.layer.get().delStorNode($node.iden())
|
|
2029
|
+
'''
|
|
2030
|
+
msgs = await core.stormlist(q, opts={'user': lowuser.iden})
|
|
2031
|
+
self.stormIsInErr('delStorNode() requires admin privileges.', msgs)
|
|
2032
|
+
|
|
2033
|
+
# Readonly layer
|
|
2034
|
+
nodes = await core.nodes('[ test:str=foobar ]')
|
|
2035
|
+
self.len(1, nodes)
|
|
2036
|
+
self.eq(nodes[0].repr(), 'foobar')
|
|
2037
|
+
layer = core.view.layers[0]
|
|
2038
|
+
await layer.setLayerInfo('readonly', True)
|
|
2039
|
+
msgs = await core.stormlist('test:str $lib.layer.get().delStorNode($node.iden())')
|
|
2040
|
+
self.stormIsInErr(f'Layer {layer.iden} is read only!', msgs)
|
|
2041
|
+
|
|
2042
|
+
async def test_storm_layer_delstornodeprop(self):
|
|
2043
|
+
async with self.getTestCore() as core:
|
|
2044
|
+
nodes = await core.nodes('[ test:str=foo :hehe=bar ]')
|
|
2045
|
+
self.len(1, nodes)
|
|
2046
|
+
self.eq(nodes[0].repr(), 'foo')
|
|
2047
|
+
self.eq(nodes[0].get('hehe'), 'bar')
|
|
2048
|
+
|
|
2049
|
+
msgs = await core.stormlist('test:str $lib.layer.get().delStorNodeProp($node.iden(), test:str:hehe)')
|
|
2050
|
+
self.stormHasNoWarnErr(msgs)
|
|
2051
|
+
|
|
2052
|
+
nodes = await core.nodes('test:str')
|
|
2053
|
+
self.len(1, nodes)
|
|
2054
|
+
self.eq(nodes[0].repr(), 'foo')
|
|
2055
|
+
self.none(nodes[0].get('hehe'))
|
|
2056
|
+
|
|
2057
|
+
# no test:str:newp prop
|
|
2058
|
+
q = '''
|
|
2059
|
+
[ test:str=foobar00 ]
|
|
2060
|
+
$lib.layer.get().delStorNodeProp($node.iden(), test:str:newp)
|
|
2061
|
+
'''
|
|
2062
|
+
msgs = await core.stormlist(q)
|
|
2063
|
+
self.stormIsInErr('No property named test:str:newp.', msgs)
|
|
2064
|
+
|
|
2065
|
+
# insufficient perms
|
|
2066
|
+
lowuser = await core.auth.addUser('lowuser')
|
|
2067
|
+
await lowuser.addRule((True, ('node', 'add', 'test:str')))
|
|
2068
|
+
|
|
2069
|
+
q = '''
|
|
2070
|
+
[ test:str=foobar02 ]
|
|
2071
|
+
$lib.layer.get().delStorNodeProp($node.iden(), test:str:hehe)
|
|
2072
|
+
'''
|
|
2073
|
+
msgs = await core.stormlist(q, opts={'user': lowuser.iden})
|
|
2074
|
+
self.stormIsInErr('delStorNodeProp() requires admin privileges.', msgs)
|
|
2075
|
+
|
|
2076
|
+
# Readonly layer
|
|
2077
|
+
layer = core.view.layers[0]
|
|
2078
|
+
await layer.setLayerInfo('readonly', True)
|
|
2079
|
+
msgs = await core.stormlist('test:str $lib.layer.get().delStorNodeProp($node.iden(), test:str:hehe)')
|
|
2080
|
+
self.stormIsInErr(f'Layer {layer.iden} is read only!', msgs)
|
|
2081
|
+
|
|
2082
|
+
async def test_storm_layer_delnodedata(self):
|
|
2083
|
+
async with self.getTestCore() as core:
|
|
2084
|
+
q = '''
|
|
2085
|
+
$_ = { [test:str=foo] $node.data.set(foo, woot) }
|
|
2086
|
+
$_ = { [test:str=bar] $node.data.set(bar00, woot00) $node.data.set(bar01, woot01)}
|
|
2087
|
+
$_ = { [test:str=baz] $node.data.set(baz, woot) }
|
|
2088
|
+
'''
|
|
2089
|
+
msgs = await core.stormlist(q)
|
|
2090
|
+
self.stormHasNoWarnErr(msgs)
|
|
2091
|
+
|
|
2092
|
+
nodes = await core.nodes('test:str=foo')
|
|
2093
|
+
self.len(1, nodes)
|
|
2094
|
+
self.eq(nodes[0].repr(), 'foo')
|
|
2095
|
+
self.eq(await s_test.alist(nodes[0].iterData()), [('foo', 'woot')])
|
|
2096
|
+
|
|
2097
|
+
# Delete specific nodedata key
|
|
2098
|
+
msgs = await core.stormlist('test:str $lib.layer.get().delNodeData($node, foo)')
|
|
2099
|
+
self.stormHasNoWarnErr(msgs)
|
|
2100
|
+
|
|
2101
|
+
nodes = await core.nodes('test:str=foo')
|
|
2102
|
+
self.len(1, nodes)
|
|
2103
|
+
self.len(0, await s_test.alist(nodes[0].iterData()))
|
|
2104
|
+
|
|
2105
|
+
nodes = await core.nodes('test:str=bar')
|
|
2106
|
+
self.len(1, nodes)
|
|
2107
|
+
self.eq(nodes[0].repr(), 'bar')
|
|
2108
|
+
self.eq(await s_test.alist(nodes[0].iterData()), [('bar00', 'woot00'), ('bar01', 'woot01')])
|
|
2109
|
+
|
|
2110
|
+
# Delete all nodedata
|
|
2111
|
+
msgs = await core.stormlist('test:str=bar $lib.layer.get().delNodeData($node)')
|
|
2112
|
+
self.stormHasNoWarnErr(msgs)
|
|
2113
|
+
|
|
2114
|
+
nodes = await core.nodes('test:str=bar')
|
|
2115
|
+
self.len(1, nodes)
|
|
2116
|
+
self.len(0, await s_test.alist(nodes[0].iterData()))
|
|
2117
|
+
|
|
2118
|
+
# No edits to make
|
|
2119
|
+
self.false(await core.callStorm('test:str=bar return($lib.layer.get().delNodeData($node))'))
|
|
2120
|
+
|
|
2121
|
+
# insufficient perms
|
|
2122
|
+
lowuser = await core.auth.addUser('lowuser')
|
|
2123
|
+
await lowuser.addRule((True, ('node', 'add', 'test:str')))
|
|
2124
|
+
|
|
2125
|
+
q = '''
|
|
2126
|
+
test:str
|
|
2127
|
+
$lib.layer.get().delNodeData($node)
|
|
2128
|
+
'''
|
|
2129
|
+
msgs = await core.stormlist(q, opts={'user': lowuser.iden})
|
|
2130
|
+
self.stormIsInErr('delNodeData() requires admin privileges.', msgs)
|
|
2131
|
+
|
|
2132
|
+
# Readonly layer
|
|
2133
|
+
layer = core.view.layers[0]
|
|
2134
|
+
await layer.setLayerInfo('readonly', True)
|
|
2135
|
+
msgs = await core.stormlist('test:str=baz $lib.layer.get().delNodeData($node)')
|
|
2136
|
+
self.stormIsInErr(f'Layer {layer.iden} is read only!', msgs)
|
|
2137
|
+
|
|
2138
|
+
async def test_storm_layer_delnodeedge(self):
|
|
2139
|
+
async with self.getTestCore() as core:
|
|
2140
|
+
q = '''
|
|
2141
|
+
$seen00 = { [ meta:source=* :name=delnodeedge00 ] }
|
|
2142
|
+
$seen01 = { [ meta:source=* :name=delnodeedge01 ] }
|
|
2143
|
+
$refs = { [ it:dev:str=foobar ] }
|
|
2144
|
+
$_ = { [test:str=foo <(seen)+ $seen00 <(seen)+ $seen01]}
|
|
2145
|
+
$_ = { [test:str=bar <(seen)+ $seen00 +(refs)> $refs] }
|
|
2146
|
+
$_ = { [test:str=baz] }
|
|
2147
|
+
$_ = { [test:str=woot <(seen)+ $seen00 +(refs)> $refs] }
|
|
2148
|
+
'''
|
|
2149
|
+
msgs = await core.stormlist(q)
|
|
2150
|
+
self.stormHasNoWarnErr(msgs)
|
|
2151
|
+
|
|
2152
|
+
nodes = await core.nodes('meta:source:name=delnodeedge00')
|
|
2153
|
+
self.len(1, nodes)
|
|
2154
|
+
seen00 = nodes[0]
|
|
2155
|
+
|
|
2156
|
+
nodes = await core.nodes('meta:source:name=delnodeedge01')
|
|
2157
|
+
self.len(1, nodes)
|
|
2158
|
+
seen01 = nodes[0]
|
|
2159
|
+
|
|
2160
|
+
nodes = await core.nodes('it:dev:str=foobar')
|
|
2161
|
+
self.len(1, nodes)
|
|
2162
|
+
refs = nodes[0]
|
|
2163
|
+
|
|
2164
|
+
# Delete n2 edge
|
|
2165
|
+
nodes = await core.nodes('test:str=foo')
|
|
2166
|
+
self.len(1, nodes)
|
|
2167
|
+
self.len(0, await s_test.alist(nodes[0].iterEdgesN1()))
|
|
2168
|
+
self.sorteq(await s_test.alist(nodes[0].iterEdgesN2()), [('seen', seen00.iden()), ('seen', seen01.iden())])
|
|
2169
|
+
|
|
2170
|
+
q = '''
|
|
2171
|
+
$seen00 = { meta:source:name=delnodeedge00 }
|
|
2172
|
+
test:str=foo
|
|
2173
|
+
$lib.layer.get().delEdge($seen00, seen, $node)
|
|
2174
|
+
'''
|
|
2175
|
+
msgs = await core.stormlist(q)
|
|
2176
|
+
self.stormHasNoWarnErr(msgs)
|
|
2177
|
+
|
|
2178
|
+
nodes = await core.nodes('test:str=foo')
|
|
2179
|
+
self.len(1, nodes)
|
|
2180
|
+
self.len(0, await s_test.alist(nodes[0].iterEdgesN1()))
|
|
2181
|
+
self.eq(await s_test.alist(nodes[0].iterEdgesN2()), [('seen', seen01.iden())])
|
|
2182
|
+
|
|
2183
|
+
# Delete n1 edge
|
|
2184
|
+
nodes = await core.nodes('test:str=bar')
|
|
2185
|
+
self.len(1, nodes)
|
|
2186
|
+
self.sorteq(await s_test.alist(nodes[0].iterEdgesN1()), [('refs', refs.iden())])
|
|
2187
|
+
self.sorteq(await s_test.alist(nodes[0].iterEdgesN2()), [('seen', seen00.iden())])
|
|
2188
|
+
|
|
2189
|
+
q = '''
|
|
2190
|
+
$refs = { it:dev:str=foobar }
|
|
2191
|
+
test:str=bar
|
|
2192
|
+
$lib.layer.get().delEdge($node, refs, $refs)
|
|
2193
|
+
'''
|
|
2194
|
+
msgs = await core.stormlist(q)
|
|
2195
|
+
self.stormHasNoWarnErr(msgs)
|
|
2196
|
+
|
|
2197
|
+
nodes = await core.nodes('test:str=bar')
|
|
2198
|
+
self.len(1, nodes)
|
|
2199
|
+
self.len(0, await s_test.alist(nodes[0].iterEdgesN1()))
|
|
2200
|
+
self.eq(await s_test.alist(nodes[0].iterEdgesN2()), [('seen', seen00.iden())])
|
|
2201
|
+
|
|
2202
|
+
# No edits to make
|
|
2203
|
+
nodes = await core.nodes('test:str=baz')
|
|
2204
|
+
self.len(1, nodes)
|
|
2205
|
+
self.len(0, await s_test.alist(nodes[0].iterEdgesN1()))
|
|
2206
|
+
self.len(0, await s_test.alist(nodes[0].iterEdgesN2()))
|
|
2207
|
+
|
|
2208
|
+
q = '''
|
|
2209
|
+
$refs = { it:dev:str=foobar }
|
|
2210
|
+
test:str=baz
|
|
2211
|
+
$lib.layer.get().delEdge($node, refs, $refs)
|
|
2212
|
+
'''
|
|
2213
|
+
msgs = await core.stormlist(q)
|
|
2214
|
+
self.stormHasNoWarnErr(msgs)
|
|
2215
|
+
|
|
2216
|
+
# insufficient perms
|
|
2217
|
+
lowuser = await core.auth.addUser('lowuser')
|
|
2218
|
+
await lowuser.addRule((True, ('node', 'add', 'test:str')))
|
|
2219
|
+
|
|
2220
|
+
nodes = await core.nodes('test:str=woot')
|
|
2221
|
+
self.len(1, nodes)
|
|
2222
|
+
self.len(1, await s_test.alist(nodes[0].iterEdgesN1()))
|
|
2223
|
+
self.len(1, await s_test.alist(nodes[0].iterEdgesN2()))
|
|
2224
|
+
|
|
2225
|
+
q = '''
|
|
2226
|
+
$seen = { meta:source:name=delnodeedge00 }
|
|
2227
|
+
test:str=woot
|
|
2228
|
+
$lib.layer.get().delEdge($seen, seen, $node)
|
|
2229
|
+
'''
|
|
2230
|
+
msgs = await core.stormlist(q, opts={'user': lowuser.iden})
|
|
2231
|
+
self.stormIsInErr('delEdge() requires admin privileges.', msgs)
|
|
2232
|
+
|
|
2233
|
+
nodes = await core.nodes('test:str=woot')
|
|
2234
|
+
self.len(1, nodes)
|
|
2235
|
+
self.len(1, await s_test.alist(nodes[0].iterEdgesN1()))
|
|
2236
|
+
self.len(1, await s_test.alist(nodes[0].iterEdgesN2()))
|
|
2237
|
+
|
|
2238
|
+
# Readonly layer
|
|
2239
|
+
layer = core.view.layers[0]
|
|
2240
|
+
await layer.setLayerInfo('readonly', True)
|
|
2241
|
+
msgs = await core.stormlist(q)
|
|
2242
|
+
self.stormIsInErr(f'Layer {layer.iden} is read only!', msgs)
|
|
2243
|
+
|
|
2244
|
+
nodes = await core.nodes('test:str=woot')
|
|
2245
|
+
self.len(1, nodes)
|
|
2246
|
+
self.len(1, await s_test.alist(nodes[0].iterEdgesN1()))
|
|
2247
|
+
self.len(1, await s_test.alist(nodes[0].iterEdgesN2()))
|
|
2248
|
+
|
|
1770
2249
|
async def test_storm_lib_fire(self):
|
|
1771
2250
|
async with self.getTestCore() as core:
|
|
1772
2251
|
text = '$lib.fire(foo:bar, baz=faz)'
|
|
@@ -5671,6 +6150,76 @@ class StormTypesTest(s_test.SynTest):
|
|
|
5671
6150
|
q = '$tally = $lib.stats.tally() $tally.inc(foo) $tally.inc(foo) return($tally)'
|
|
5672
6151
|
self.eq({'foo': 2}, await core.callStorm(q))
|
|
5673
6152
|
|
|
6153
|
+
async def test_stormtypes_tobuid(self):
|
|
6154
|
+
async with self.getTestCore() as core:
|
|
6155
|
+
|
|
6156
|
+
buid = s_common.buid()
|
|
6157
|
+
sode = (
|
|
6158
|
+
buid,
|
|
6159
|
+
{
|
|
6160
|
+
'ndef': ('it:dev:str', 'foobar'),
|
|
6161
|
+
}
|
|
6162
|
+
)
|
|
6163
|
+
|
|
6164
|
+
async with await core.snap() as snap:
|
|
6165
|
+
node = s_node.Node(snap, sode)
|
|
6166
|
+
snode = s_stormtypes.Node(node)
|
|
6167
|
+
|
|
6168
|
+
self.eq(await s_stormtypes.tobuid(node), buid)
|
|
6169
|
+
self.eq(await s_stormtypes.tobuid(snode), buid)
|
|
6170
|
+
|
|
6171
|
+
self.eq(await s_stormtypes.tobuid(buid.hex()), buid)
|
|
6172
|
+
self.eq(await s_stormtypes.tobuid(buid), buid)
|
|
6173
|
+
|
|
6174
|
+
with self.raises(s_exc.BadCast) as exc:
|
|
6175
|
+
await s_stormtypes.tobuid('newp')
|
|
6176
|
+
self.eq(exc.exception.get('mesg'), 'Invalid buid string: newp')
|
|
6177
|
+
|
|
6178
|
+
with self.raises(s_exc.BadCast) as exc:
|
|
6179
|
+
await s_stormtypes.tobuid([])
|
|
6180
|
+
self.eq(exc.exception.get('mesg'), 'Invalid buid valu: ()')
|
|
6181
|
+
|
|
6182
|
+
with self.raises(s_exc.BadCast) as exc:
|
|
6183
|
+
await s_stormtypes.tobuid(b'newp')
|
|
6184
|
+
self.eq(exc.exception.get('mesg'), "Invalid buid valu: b'newp'")
|
|
6185
|
+
|
|
6186
|
+
async def test_stormtypes_tobuidhex(self):
|
|
6187
|
+
async with self.getTestCore() as core:
|
|
6188
|
+
|
|
6189
|
+
self.none(await s_stormtypes.tobuidhex(None, noneok=True))
|
|
6190
|
+
|
|
6191
|
+
buid = s_common.buid()
|
|
6192
|
+
buidhex = s_common.ehex(buid)
|
|
6193
|
+
sode = (
|
|
6194
|
+
buid,
|
|
6195
|
+
{
|
|
6196
|
+
'ndef': ('it:dev:str', 'foobar'),
|
|
6197
|
+
}
|
|
6198
|
+
)
|
|
6199
|
+
|
|
6200
|
+
async with await core.snap() as snap:
|
|
6201
|
+
node = s_node.Node(snap, sode)
|
|
6202
|
+
snode = s_stormtypes.Node(node)
|
|
6203
|
+
|
|
6204
|
+
self.eq(await s_stormtypes.tobuidhex(node), buidhex)
|
|
6205
|
+
self.eq(await s_stormtypes.tobuidhex(snode), buidhex)
|
|
6206
|
+
|
|
6207
|
+
self.eq(await s_stormtypes.tobuidhex(buidhex), buidhex)
|
|
6208
|
+
self.eq(await s_stormtypes.tobuidhex(buid), buidhex)
|
|
6209
|
+
|
|
6210
|
+
with self.raises(s_exc.BadCast) as exc:
|
|
6211
|
+
await s_stormtypes.tobuidhex('newp')
|
|
6212
|
+
self.eq(exc.exception.get('mesg'), 'Invalid buid string: newp')
|
|
6213
|
+
|
|
6214
|
+
with self.raises(s_exc.BadCast) as exc:
|
|
6215
|
+
await s_stormtypes.tobuidhex([])
|
|
6216
|
+
self.eq(exc.exception.get('mesg'), 'Invalid buid valu: ()')
|
|
6217
|
+
|
|
6218
|
+
newp = b'newp'
|
|
6219
|
+
with self.raises(s_exc.BadCast) as exc:
|
|
6220
|
+
await s_stormtypes.tobuidhex(newp)
|
|
6221
|
+
self.eq(exc.exception.get('mesg'), "Invalid buid valu: b'newp'")
|
|
6222
|
+
|
|
5674
6223
|
async def test_print_warn(self):
|
|
5675
6224
|
async with self.getTestCore() as core:
|
|
5676
6225
|
q = '$lib.print(hello)'
|
synapse/tools/aha/list.py
CHANGED
|
@@ -7,14 +7,17 @@ import synapse.lib.version as s_version
|
|
|
7
7
|
|
|
8
8
|
reqver = '>=2.11.0,<3.0.0'
|
|
9
9
|
|
|
10
|
+
descr = 'List AHA services.'
|
|
11
|
+
|
|
10
12
|
async def main(argv, outp=s_output.stdout):
|
|
11
13
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
pars = s_cmd.Parser(prog='synapse.tools.aha.list', outp=outp, description=descr)
|
|
15
|
+
pars.add_argument('url', help='The telepath URL to connect to the AHA service.')
|
|
16
|
+
pars.add_argument('network', nargs='?', default=None, help='The AHA network name.')
|
|
17
|
+
opts = pars.parse_args(argv)
|
|
15
18
|
|
|
16
19
|
async with s_telepath.withTeleEnv():
|
|
17
|
-
async with await s_telepath.openurl(
|
|
20
|
+
async with await s_telepath.openurl(opts.url) as prox:
|
|
18
21
|
try:
|
|
19
22
|
s_version.reqVersion(prox._getSynVers(), reqver)
|
|
20
23
|
except s_exc.BadVersion as e: # pragma: no cover
|
|
@@ -23,13 +26,10 @@ async def main(argv, outp=s_output.stdout):
|
|
|
23
26
|
return 1
|
|
24
27
|
classes = prox._getClasses()
|
|
25
28
|
if 'synapse.lib.aha.AhaApi' not in classes:
|
|
26
|
-
outp.printf(f'Service at {
|
|
29
|
+
outp.printf(f'Service at {opts.url} is not an Aha server')
|
|
27
30
|
return 1
|
|
28
31
|
|
|
29
|
-
|
|
30
|
-
network = argv[1]
|
|
31
|
-
except IndexError:
|
|
32
|
-
network = None
|
|
32
|
+
network = opts.network
|
|
33
33
|
|
|
34
34
|
mesg = f"{'Service':<20s} {'network':<30s} {'leader':<6} {'online':<6} {'scheme':<6} {'host':<20} {'port':<5} connection opts"
|
|
35
35
|
outp.printf(mesg)
|
|
@@ -10,10 +10,10 @@ A tool to prepare provisioning entries in the AHA server.
|
|
|
10
10
|
|
|
11
11
|
Examples:
|
|
12
12
|
|
|
13
|
-
# provision a new
|
|
13
|
+
# provision a new service named 00.axon from within the AHA container.
|
|
14
14
|
python -m synapse.tools.aha.provision.service 00.axon
|
|
15
15
|
|
|
16
|
-
# provision a new
|
|
16
|
+
# provision a new service named 01.cortex as a mirror from within the AHA container.
|
|
17
17
|
python -m synapse.tools.aha.provision.service 01.cortex --mirror 00.cortex
|
|
18
18
|
|
|
19
19
|
'''
|