2018-11-28 08:06:53 +00:00
|
|
|
import sys
|
|
|
|
import time
|
|
|
|
import json
|
|
|
|
import shutil
|
|
|
|
from os import mkdir, unlink, listdir, utime
|
|
|
|
from os.path import join, exists, getmtime
|
|
|
|
|
|
|
|
from allmydata.util import keyutil
|
|
|
|
from allmydata.util import base32
|
2018-11-28 09:54:49 +00:00
|
|
|
from allmydata.util import configutil
|
2018-11-28 08:06:53 +00:00
|
|
|
|
|
|
|
import util
|
|
|
|
|
2019-04-09 01:42:39 +00:00
|
|
|
import pytest_twisted
|
2018-11-28 08:06:53 +00:00
|
|
|
|
|
|
|
|
2019-04-09 01:42:39 +00:00
|
|
|
@pytest_twisted.inlineCallbacks
|
2018-11-28 08:06:53 +00:00
|
|
|
def test_create_certificate(reactor):
|
2020-05-07 20:37:45 +00:00
|
|
|
"""
|
|
|
|
The Grid Manager produces a valid, correctly-signed certificate.
|
|
|
|
"""
|
2018-11-28 08:06:53 +00:00
|
|
|
gm_config = yield util.run_tahoe(
|
|
|
|
reactor, "grid-manager", "--config", "-", "create",
|
|
|
|
)
|
|
|
|
privkey_bytes = json.loads(gm_config)['private_key'].encode('ascii')
|
|
|
|
privkey, pubkey_bytes = keyutil.parse_privkey(privkey_bytes)
|
|
|
|
pubkey = keyutil.parse_pubkey(pubkey_bytes)
|
|
|
|
|
2020-05-07 20:37:45 +00:00
|
|
|
# Note that zara + her key here are arbitrary and don't match any
|
|
|
|
# "actual" clients in the test-grid; we're just checking that the
|
|
|
|
# Grid Manager signs this properly.
|
2018-11-28 08:06:53 +00:00
|
|
|
gm_config = yield util.run_tahoe(
|
|
|
|
reactor, "grid-manager", "--config", "-", "add",
|
2020-05-07 20:37:45 +00:00
|
|
|
"zara", "pub-v0-kzug3ut2m7ziihf3ndpqlquuxeie4foyl36wn54myqc4wmiwe4ga",
|
2018-11-28 08:06:53 +00:00
|
|
|
stdin=gm_config,
|
|
|
|
)
|
2020-05-07 20:37:45 +00:00
|
|
|
zara_cert_bytes = yield util.run_tahoe(
|
|
|
|
reactor, "grid-manager", "--config", "-", "sign", "zara",
|
2018-11-28 08:06:53 +00:00
|
|
|
stdin=gm_config,
|
|
|
|
)
|
2020-05-07 20:37:45 +00:00
|
|
|
zara_cert = json.loads(zara_cert_bytes)
|
2018-11-28 08:06:53 +00:00
|
|
|
|
2020-05-07 20:37:45 +00:00
|
|
|
# confirm that zara's certificate is made by the Grid Manager
|
2018-11-28 08:22:49 +00:00
|
|
|
# (.verify returns None on success, raises exception on error)
|
|
|
|
pubkey.verify(
|
2020-05-07 20:37:45 +00:00
|
|
|
base32.a2b(zara_cert['signature'].encode('ascii')),
|
|
|
|
zara_cert['certificate'].encode('ascii'),
|
2018-11-28 08:06:53 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
2019-04-09 01:42:39 +00:00
|
|
|
@pytest_twisted.inlineCallbacks
|
2018-11-28 08:06:53 +00:00
|
|
|
def test_remove_client(reactor):
|
2020-05-07 20:37:45 +00:00
|
|
|
"""
|
|
|
|
A Grid Manager can add and successfully remove a client
|
|
|
|
"""
|
2018-11-28 08:06:53 +00:00
|
|
|
gm_config = yield util.run_tahoe(
|
|
|
|
reactor, "grid-manager", "--config", "-", "create",
|
|
|
|
)
|
|
|
|
|
2018-11-28 08:20:51 +00:00
|
|
|
gm_config = yield util.run_tahoe(
|
|
|
|
reactor, "grid-manager", "--config", "-", "add",
|
2020-05-07 20:37:45 +00:00
|
|
|
"zara", "pub-v0-kzug3ut2m7ziihf3ndpqlquuxeie4foyl36wn54myqc4wmiwe4ga",
|
2018-11-28 08:20:51 +00:00
|
|
|
stdin=gm_config,
|
|
|
|
)
|
|
|
|
gm_config = yield util.run_tahoe(
|
|
|
|
reactor, "grid-manager", "--config", "-", "add",
|
2020-05-07 20:37:45 +00:00
|
|
|
"yakov", "pub-v0-kvxhb3nexybmipkrar2ztfrwp4uxxsmrjzkpzafit3ket4u5yldq",
|
2018-11-28 08:20:51 +00:00
|
|
|
stdin=gm_config,
|
|
|
|
)
|
2020-05-07 20:40:10 +00:00
|
|
|
assert "zara" in json.loads(gm_config)['storage_servers']
|
|
|
|
assert "yakov" in json.loads(gm_config)['storage_servers']
|
2018-11-28 08:20:51 +00:00
|
|
|
|
|
|
|
gm_config = yield util.run_tahoe(
|
|
|
|
reactor, "grid-manager", "--config", "-", "remove",
|
2020-05-07 20:37:45 +00:00
|
|
|
"zara",
|
2018-11-28 08:20:51 +00:00
|
|
|
stdin=gm_config,
|
|
|
|
)
|
2020-05-07 20:40:10 +00:00
|
|
|
assert "zara" not in json.loads(gm_config)['storage_servers']
|
|
|
|
assert "yakov" in json.loads(gm_config)['storage_servers']
|
2018-11-28 08:20:51 +00:00
|
|
|
|
|
|
|
|
2019-04-09 01:42:39 +00:00
|
|
|
@pytest_twisted.inlineCallbacks
|
2018-11-28 08:20:51 +00:00
|
|
|
def test_remove_last_client(reactor):
|
2020-05-07 20:50:10 +00:00
|
|
|
"""
|
|
|
|
A Grid Manager can remove all clients
|
|
|
|
"""
|
2018-11-28 08:20:51 +00:00
|
|
|
gm_config = yield util.run_tahoe(
|
|
|
|
reactor, "grid-manager", "--config", "-", "create",
|
|
|
|
)
|
|
|
|
|
2018-11-28 08:06:53 +00:00
|
|
|
gm_config = yield util.run_tahoe(
|
|
|
|
reactor, "grid-manager", "--config", "-", "add",
|
2020-05-07 20:37:45 +00:00
|
|
|
"zara", "pub-v0-kzug3ut2m7ziihf3ndpqlquuxeie4foyl36wn54myqc4wmiwe4ga",
|
2018-11-28 08:06:53 +00:00
|
|
|
stdin=gm_config,
|
|
|
|
)
|
2020-05-07 20:40:10 +00:00
|
|
|
assert "zara" in json.loads(gm_config)['storage_servers']
|
2018-11-28 08:06:53 +00:00
|
|
|
|
|
|
|
gm_config = yield util.run_tahoe(
|
|
|
|
reactor, "grid-manager", "--config", "-", "remove",
|
2020-05-07 20:37:45 +00:00
|
|
|
"zara",
|
2018-11-28 08:06:53 +00:00
|
|
|
stdin=gm_config,
|
|
|
|
)
|
|
|
|
# there are no storage servers left at all now
|
2020-05-07 20:40:10 +00:00
|
|
|
assert "storage_servers" not in json.loads(gm_config)
|
2018-11-28 09:54:49 +00:00
|
|
|
|
|
|
|
|
2019-04-09 01:42:39 +00:00
|
|
|
@pytest_twisted.inlineCallbacks
|
2018-12-11 19:48:37 +00:00
|
|
|
def test_reject_storage_server(reactor, request, storage_nodes, temp_dir, introducer_furl, flog_gatherer):
|
2020-05-07 20:50:10 +00:00
|
|
|
"""
|
|
|
|
A client using grid-manager refuses to upload to a storage-server
|
|
|
|
without a valid certificate
|
|
|
|
"""
|
2018-11-28 09:54:49 +00:00
|
|
|
gm_config = yield util.run_tahoe(
|
|
|
|
reactor, "grid-manager", "--config", "-", "create",
|
|
|
|
)
|
|
|
|
privkey_bytes = json.loads(gm_config)['private_key'].encode('ascii')
|
|
|
|
privkey, pubkey_bytes = keyutil.parse_privkey(privkey_bytes)
|
|
|
|
pubkey = keyutil.parse_pubkey(pubkey_bytes)
|
|
|
|
|
|
|
|
# create certificates for first 2 storage-servers
|
|
|
|
for idx, storage in enumerate(storage_nodes[:2]):
|
|
|
|
pubkey_fname = join(storage._node_dir, "node.pubkey")
|
|
|
|
with open(pubkey_fname, 'r') as f:
|
|
|
|
pubkey = f.read().strip()
|
|
|
|
|
|
|
|
gm_config = yield util.run_tahoe(
|
|
|
|
reactor, "grid-manager", "--config", "-", "add",
|
|
|
|
"storage{}".format(idx), pubkey,
|
|
|
|
stdin=gm_config,
|
|
|
|
)
|
|
|
|
assert sorted(json.loads(gm_config)['storage_servers'].keys()) == ['storage0', 'storage1']
|
|
|
|
|
2018-12-11 19:48:37 +00:00
|
|
|
# XXX FIXME need to shut-down and nuke carol when we're done this
|
|
|
|
# test (i.d. request.addfinalizer)
|
|
|
|
carol = yield util._create_node(
|
|
|
|
reactor, request, temp_dir, introducer_furl, flog_gatherer, "carol",
|
|
|
|
web_port="tcp:9982:interface=localhost",
|
|
|
|
storage=False,
|
|
|
|
)
|
|
|
|
|
2018-11-28 09:54:49 +00:00
|
|
|
print("inserting certificates")
|
|
|
|
# insert their certificates
|
|
|
|
for idx, storage in enumerate(storage_nodes[:2]):
|
|
|
|
print(idx, storage)
|
|
|
|
cert = yield util.run_tahoe(
|
|
|
|
reactor, "grid-manager", "--config", "-", "sign",
|
|
|
|
"storage{}".format(idx),
|
|
|
|
stdin=gm_config,
|
|
|
|
)
|
|
|
|
with open(join(storage._node_dir, "gridmanager.cert"), "w") as f:
|
|
|
|
f.write(cert)
|
|
|
|
config = configutil.get_config(join(storage._node_dir, "tahoe.cfg"))
|
2019-04-09 05:33:40 +00:00
|
|
|
config.set("storage", "grid_management", "True")
|
|
|
|
config.add_section("grid_manager_certificates")
|
|
|
|
config.set("grid_manager_certificates", "default", "gridmanager.cert")
|
2018-11-28 09:54:49 +00:00
|
|
|
config.write(open(join(storage._node_dir, "tahoe.cfg"), "w"))
|
|
|
|
|
|
|
|
# re-start this storage server
|
|
|
|
storage.signalProcess('TERM')
|
|
|
|
yield storage._protocol.exited
|
|
|
|
time.sleep(1)
|
|
|
|
storage_nodes[idx] = yield util._run_node(
|
|
|
|
reactor, storage._node_dir, request, None,
|
|
|
|
)
|
|
|
|
|
|
|
|
# now only two storage-servers have certificates .. configure
|
2018-12-11 19:54:22 +00:00
|
|
|
# carol to have the grid-manager certificate
|
2018-12-11 19:48:37 +00:00
|
|
|
|
|
|
|
config = configutil.get_config(join(carol._node_dir, "tahoe.cfg"))
|
2018-11-28 09:54:49 +00:00
|
|
|
print(dir(config))
|
|
|
|
config.add_section("grid_managers")
|
|
|
|
config.set("grid_managers", "test", pubkey_bytes)
|
2018-12-11 19:48:37 +00:00
|
|
|
config.write(open(join(carol._node_dir, "tahoe.cfg"), "w"))
|
|
|
|
carol.signalProcess('TERM')
|
|
|
|
yield carol._protocol.exited
|
2020-05-07 20:54:50 +00:00
|
|
|
|
2018-12-11 19:54:22 +00:00
|
|
|
carol = yield util._run_node(
|
2018-12-11 19:48:37 +00:00
|
|
|
reactor, carol._node_dir, request, None,
|
2018-11-28 09:54:49 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
# try to put something into the grid, which should fail (because
|
2018-12-11 19:48:37 +00:00
|
|
|
# carol has happy=3 but should only find storage0, storage1 to be
|
2018-11-28 09:54:49 +00:00
|
|
|
# acceptable to upload to)
|
|
|
|
|
|
|
|
try:
|
|
|
|
yield util.run_tahoe(
|
2018-12-11 19:48:37 +00:00
|
|
|
reactor, "--node-directory", carol._node_dir,
|
2018-11-28 09:54:49 +00:00
|
|
|
"put", "-",
|
|
|
|
stdin="some content" * 200,
|
|
|
|
)
|
|
|
|
assert False, "Should get a failure"
|
|
|
|
except Exception as e:
|
2018-12-07 22:57:21 +00:00
|
|
|
# depending on the full output being in the error-message
|
|
|
|
# here; see util.py
|
|
|
|
assert 'UploadUnhappinessError' in str(e)
|
|
|
|
print("found expected UploadUnhappinessError")
|