mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2025-01-31 00:24:13 +00:00
cleanup, more tests
This commit is contained in:
parent
d09690823d
commit
a8382a5356
@ -70,9 +70,12 @@ def load_grid_manager(config_path, config_location):
|
|||||||
with config_file:
|
with config_file:
|
||||||
config = json.load(config_file)
|
config = json.load(config_file)
|
||||||
|
|
||||||
if not config:
|
gm_version = config.get(u'grid_manager_config_version', None)
|
||||||
|
if gm_version != 0:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"Invalid Grid Manager config in '{}'".format(config_location)
|
"Missing or unknown version '{}' of Grid Manager config".format(
|
||||||
|
gm_version
|
||||||
|
)
|
||||||
)
|
)
|
||||||
if 'private_key' not in config:
|
if 'private_key' not in config:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
@ -101,13 +104,6 @@ def load_grid_manager(config_path, config_location):
|
|||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
|
|
||||||
gm_version = config.get(u'grid_manager_config_version', None)
|
|
||||||
if gm_version != 0:
|
|
||||||
raise ValueError(
|
|
||||||
"Missing or unknown version '{}' of Grid Manager config".format(
|
|
||||||
gm_version
|
|
||||||
)
|
|
||||||
)
|
|
||||||
return _GridManager(private_key_bytes, storage_servers)
|
return _GridManager(private_key_bytes, storage_servers)
|
||||||
|
|
||||||
|
|
||||||
@ -153,6 +149,7 @@ class _GridManager(object):
|
|||||||
vk = ed25519.verifying_key_from_signing_key(self._private_key)
|
vk = ed25519.verifying_key_from_signing_key(self._private_key)
|
||||||
ed25519.verify_signature(vk, sig, cert_data)
|
ed25519.verify_signature(vk, sig, cert_data)
|
||||||
|
|
||||||
|
srv.add_certificate(certificate)
|
||||||
return certificate
|
return certificate
|
||||||
|
|
||||||
def add_storage_server(self, name, public_key):
|
def add_storage_server(self, name, public_key):
|
||||||
@ -215,3 +212,137 @@ def save_grid_manager(file_path, grid_manager):
|
|||||||
fileutil.make_dirs(file_path.path, mode=0o700)
|
fileutil.make_dirs(file_path.path, mode=0o700)
|
||||||
with file_path.child("config.json").open("w") as f:
|
with file_path.child("config.json").open("w") as f:
|
||||||
f.write("{}\n".format(data))
|
f.write("{}\n".format(data))
|
||||||
|
|
||||||
|
|
||||||
|
def parse_grid_manager_certificate(gm_data):
|
||||||
|
"""
|
||||||
|
:param gm_data: some data that might be JSON that might be a valid
|
||||||
|
Grid Manager Certificate
|
||||||
|
|
||||||
|
:returns: json data of a valid Grid Manager certificate, or an
|
||||||
|
exception if the data is not valid.
|
||||||
|
"""
|
||||||
|
|
||||||
|
required_keys = {
|
||||||
|
'certificate',
|
||||||
|
'signature',
|
||||||
|
}
|
||||||
|
|
||||||
|
js = json.loads(gm_data)
|
||||||
|
|
||||||
|
if not isinstance(js, dict):
|
||||||
|
raise ValueError(
|
||||||
|
"Grid Manager certificate must be a dict"
|
||||||
|
)
|
||||||
|
if set(js.keys()) != required_keys:
|
||||||
|
raise ValueError(
|
||||||
|
"Grid Manager certificate must contain: {}".format(
|
||||||
|
", ".join("'{}'".format(k) for k in js.keys()),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return js
|
||||||
|
|
||||||
|
|
||||||
|
def validate_grid_manager_certificate(gm_key, alleged_cert):
|
||||||
|
"""
|
||||||
|
:param gm_key: a VerifyingKey instance, a Grid Manager's public
|
||||||
|
key.
|
||||||
|
|
||||||
|
:param alleged_cert: dict with "certificate" and "signature" keys, where
|
||||||
|
"certificate" contains a JSON-serialized certificate for a Storage
|
||||||
|
Server (comes from a Grid Manager).
|
||||||
|
|
||||||
|
:return: a dict consisting of the deserialized certificate data or
|
||||||
|
None if the signature is invalid. Note we do NOT check the
|
||||||
|
expiry time in this function.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
ed25519.verify_signature(
|
||||||
|
gm_key,
|
||||||
|
base32.a2b(alleged_cert['signature'].encode('ascii')),
|
||||||
|
alleged_cert['certificate'].encode('ascii'),
|
||||||
|
)
|
||||||
|
except ed25519.BadSignature:
|
||||||
|
return None
|
||||||
|
# signature is valid; now we can load the actual data
|
||||||
|
cert = json.loads(alleged_cert['certificate'])
|
||||||
|
return cert
|
||||||
|
|
||||||
|
|
||||||
|
def create_grid_manager_verifier(keys, certs, now_fn=None, bad_cert=None):
|
||||||
|
"""
|
||||||
|
Creates a predicate for confirming some Grid Manager-issued
|
||||||
|
certificates against Grid Manager keys. A predicate is used
|
||||||
|
(instead of just returning True/False here) so that the
|
||||||
|
expiry-time can be tested on each call.
|
||||||
|
|
||||||
|
:param list keys: 0 or more `VerifyingKey` instances
|
||||||
|
|
||||||
|
:param list certs: 1 or more Grid Manager certificates each of
|
||||||
|
which is a `dict` containing 'signature' and 'certificate' keys.
|
||||||
|
|
||||||
|
:param callable now_fn: a callable which returns the current UTC
|
||||||
|
timestamp (or datetime.utcnow if None).
|
||||||
|
|
||||||
|
:param callable bad_cert: a two-argument callable which is invoked
|
||||||
|
when a certificate verification fails. The first argument is
|
||||||
|
the verifying key and the second is the certificate. If None
|
||||||
|
(the default) errors are print()-ed. Note that we may have
|
||||||
|
several certificates and only one must be valid, so this may
|
||||||
|
be called (multiple times) even if the function ultimately
|
||||||
|
returns successfully.
|
||||||
|
|
||||||
|
:returns: a callable which will return True only-if there is at
|
||||||
|
least one valid certificate (that has not at this moment
|
||||||
|
expired) in `certs` signed by one of the keys in `keys`.
|
||||||
|
"""
|
||||||
|
|
||||||
|
now_fn = datetime.utcnow if now_fn is None else now_fn
|
||||||
|
valid_certs = []
|
||||||
|
|
||||||
|
# if we have zero grid-manager keys then everything is valid
|
||||||
|
if not keys:
|
||||||
|
return lambda: True
|
||||||
|
|
||||||
|
if bad_cert is None:
|
||||||
|
|
||||||
|
def bad_cert(key, alleged_cert):
|
||||||
|
"""
|
||||||
|
We might want to let the user know about this failed-to-verify
|
||||||
|
certificate .. but also if you have multiple grid-managers
|
||||||
|
then a bunch of these messages would appear. Better would
|
||||||
|
be to bubble this up to some sort of status API (or maybe
|
||||||
|
on the Welcome page?)
|
||||||
|
|
||||||
|
The only thing that might actually be interesting, though,
|
||||||
|
is whether this whole function returns false or not..
|
||||||
|
"""
|
||||||
|
print(
|
||||||
|
"Grid Manager certificate signature failed. Certificate: "
|
||||||
|
"\"{cert}\" for key \"{key}\".".format(
|
||||||
|
cert=alleged_cert,
|
||||||
|
key=ed25519.string_from_verifying_key(key),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# validate the signatures on any certificates we have (not yet the expiry dates)
|
||||||
|
for alleged_cert in certs:
|
||||||
|
for key in keys:
|
||||||
|
cert = _validate_grid_manager_certificate(key, alleged_cert)
|
||||||
|
if cert is not None:
|
||||||
|
valid_certs.append(cert)
|
||||||
|
else:
|
||||||
|
bad_cert(key, alleged_cert)
|
||||||
|
|
||||||
|
def validate():
|
||||||
|
now = now_fn()
|
||||||
|
# if *any* certificate is still valid then we consider the server valid
|
||||||
|
for cert in valid_certs:
|
||||||
|
expires = datetime.utcfromtimestamp(cert['expires'])
|
||||||
|
# cert_pubkey = keyutil.parse_pubkey(cert['public_key'].encode('ascii'))
|
||||||
|
if expires > now:
|
||||||
|
# not-expired
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
return validate
|
||||||
|
@ -7,8 +7,8 @@ from os.path import exists, join
|
|||||||
from twisted.python import usage
|
from twisted.python import usage
|
||||||
#from allmydata.node import read_config
|
#from allmydata.node import read_config
|
||||||
from allmydata.client import read_config
|
from allmydata.client import read_config
|
||||||
from allmydata.storage_client import (
|
from allmydata.grid_manager import (
|
||||||
parse_grid_manager_data,
|
parse_grid_manager_certificate,
|
||||||
)
|
)
|
||||||
from allmydata.scripts.cli import _default_nodedir
|
from allmydata.scripts.cli import _default_nodedir
|
||||||
from allmydata.scripts.common import BaseOptions
|
from allmydata.scripts.common import BaseOptions
|
||||||
@ -90,7 +90,7 @@ class AddGridManagerCertOptions(BaseOptions):
|
|||||||
data = f.read()
|
data = f.read()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.certificate_data = parse_grid_manager_data(data)
|
self.certificate_data = parse_grid_manager_certificate(data)
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
raise usage.UsageError(
|
raise usage.UsageError(
|
||||||
"Error parsing certificate: {}".format(e)
|
"Error parsing certificate: {}".format(e)
|
||||||
@ -142,11 +142,9 @@ def add_grid_manager_cert(options):
|
|||||||
# write all the data out
|
# write all the data out
|
||||||
|
|
||||||
fileutil.write(cert_path, cert_bytes)
|
fileutil.write(cert_path, cert_bytes)
|
||||||
# print("created {}: {} bytes".format(cert_fname, len(cert_bytes)))
|
|
||||||
with open(config_path, "w") as f:
|
with open(config_path, "w") as f:
|
||||||
# XXX probably want a _Config.write_tahoe_cfg() or something? or just set_config() does that automagically
|
# XXX probably want a _Config.write_tahoe_cfg() or something?
|
||||||
config.config.write(f)
|
config.config.write(f)
|
||||||
# print("wrote {}".format(config_fname))
|
|
||||||
|
|
||||||
cert_count = len(config.enumerate_section("grid_manager_certificates"))
|
cert_count = len(config.enumerate_section("grid_manager_certificates"))
|
||||||
print("There are now {} certificates".format(cert_count), file=options.parent.parent.stderr)
|
print("There are now {} certificates".format(cert_count), file=options.parent.parent.stderr)
|
||||||
|
@ -11,7 +11,7 @@ from allmydata.version_checks import get_package_versions_string
|
|||||||
from allmydata.scripts.common import get_default_nodedir
|
from allmydata.scripts.common import get_default_nodedir
|
||||||
from allmydata.scripts import debug, create_node, cli, \
|
from allmydata.scripts import debug, create_node, cli, \
|
||||||
stats_gatherer, admin, tahoe_daemonize, tahoe_start, \
|
stats_gatherer, admin, tahoe_daemonize, tahoe_start, \
|
||||||
tahoe_stop, tahoe_restart, tahoe_run, tahoe_invite, tahoe_grid_manager
|
tahoe_stop, tahoe_restart, tahoe_run, tahoe_invite
|
||||||
from allmydata.util.encodingutil import quote_output, quote_local_unicode_path, get_io_encoding
|
from allmydata.util.encodingutil import quote_output, quote_local_unicode_path, get_io_encoding
|
||||||
from allmydata.util.eliotutil import (
|
from allmydata.util.eliotutil import (
|
||||||
opt_eliot_destination,
|
opt_eliot_destination,
|
||||||
@ -63,7 +63,6 @@ class Options(usage.Options):
|
|||||||
+ debug.subCommands
|
+ debug.subCommands
|
||||||
+ cli.subCommands
|
+ cli.subCommands
|
||||||
+ tahoe_invite.subCommands
|
+ tahoe_invite.subCommands
|
||||||
+ tahoe_grid_manager.subCommands
|
|
||||||
)
|
)
|
||||||
|
|
||||||
optFlags = [
|
optFlags = [
|
||||||
@ -155,8 +154,6 @@ def dispatch(config,
|
|||||||
# these are blocking, and must be run in a thread
|
# these are blocking, and must be run in a thread
|
||||||
f0 = cli.dispatch[command]
|
f0 = cli.dispatch[command]
|
||||||
f = lambda so: threads.deferToThread(f0, so)
|
f = lambda so: threads.deferToThread(f0, so)
|
||||||
elif command in tahoe_grid_manager.dispatch:
|
|
||||||
f = tahoe_grid_manager.dispatch[command]
|
|
||||||
elif command in tahoe_invite.dispatch:
|
elif command in tahoe_invite.dispatch:
|
||||||
f = tahoe_invite.dispatch[command]
|
f = tahoe_invite.dispatch[command]
|
||||||
else:
|
else:
|
||||||
|
@ -431,124 +431,6 @@ class StubServer(object):
|
|||||||
return "?"
|
return "?"
|
||||||
|
|
||||||
|
|
||||||
def parse_grid_manager_data(gm_data):
|
|
||||||
"""
|
|
||||||
:param gm_data: some data that might be JSON that might be a valid
|
|
||||||
Grid Manager Certificate
|
|
||||||
|
|
||||||
:returns: json data of a valid Grid Manager certificate, or an
|
|
||||||
exception if the data is not valid.
|
|
||||||
"""
|
|
||||||
|
|
||||||
required_keys = allowed_keys = [
|
|
||||||
'certificate',
|
|
||||||
'signature',
|
|
||||||
]
|
|
||||||
|
|
||||||
js = json.loads(gm_data)
|
|
||||||
for k in js.keys():
|
|
||||||
if k not in allowed_keys:
|
|
||||||
raise ValueError(
|
|
||||||
"Grid Manager certificate JSON may not contain '{}'".format(
|
|
||||||
k,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
for k in required_keys:
|
|
||||||
if k not in js:
|
|
||||||
raise ValueError(
|
|
||||||
"Grid Manager certificate JSON must contain '{}'".format(
|
|
||||||
k,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
return js
|
|
||||||
|
|
||||||
|
|
||||||
def _validate_grid_manager_certificate(gm_key, alleged_cert):
|
|
||||||
"""
|
|
||||||
:param gm_key: a VerifyingKey instance, a Grid Manager's public
|
|
||||||
key.
|
|
||||||
|
|
||||||
:param alleged_cert: dict with "certificate" and "signature" keys, where
|
|
||||||
"certificate" contains a JSON-serialized certificate for a Storage
|
|
||||||
Server (comes from a Grid Manager).
|
|
||||||
|
|
||||||
:return: a dict consisting of the deserialized certificate data or
|
|
||||||
None if the signature is invalid. Note we do NOT check the
|
|
||||||
expiry time in this function.
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
ed25519.verify_signature(
|
|
||||||
gm_key,
|
|
||||||
base32.a2b(alleged_cert['signature'].encode('ascii')),
|
|
||||||
alleged_cert['certificate'].encode('ascii'),
|
|
||||||
)
|
|
||||||
except ed25519.BadSignature:
|
|
||||||
return None
|
|
||||||
# signature is valid; now we can load the actual data
|
|
||||||
cert = json.loads(alleged_cert['certificate'])
|
|
||||||
return cert
|
|
||||||
|
|
||||||
|
|
||||||
def create_grid_manager_verifier(keys, certs, now_fn=None):
|
|
||||||
"""
|
|
||||||
Creates a predicate for confirming some Grid Manager-issued
|
|
||||||
certificates against Grid Manager keys. A predicate is used
|
|
||||||
(instead of just returning True/False here) so that the
|
|
||||||
expiry-time can be tested on each call.
|
|
||||||
|
|
||||||
:param list keys: 0 or more `VerifyingKey` instances
|
|
||||||
|
|
||||||
:param list certs: 1 or more Grid Manager certificates each of
|
|
||||||
which is a `dict` containing 'signature' and 'certificate' keys.
|
|
||||||
|
|
||||||
:param callable now_fn: a callable which returns the current UTC
|
|
||||||
timestamp (or datetime.utcnow if None).
|
|
||||||
|
|
||||||
:returns: a callable which will return True only-if there is at
|
|
||||||
least one valid certificate in `certs` signed by one of the keys
|
|
||||||
in `keys`.
|
|
||||||
"""
|
|
||||||
|
|
||||||
now_fn = datetime.utcnow if now_fn is None else now_fn
|
|
||||||
valid_certs = []
|
|
||||||
|
|
||||||
# if we have zero grid-manager keys then everything is valid
|
|
||||||
if not keys:
|
|
||||||
return lambda: True
|
|
||||||
|
|
||||||
# validate the signatures on any certificates we have (not yet the expiry dates)
|
|
||||||
for alleged_cert in certs:
|
|
||||||
for key in keys:
|
|
||||||
cert = _validate_grid_manager_certificate(key, alleged_cert)
|
|
||||||
if cert is not None:
|
|
||||||
valid_certs.append(cert)
|
|
||||||
else:
|
|
||||||
# we might want to let the user know about this
|
|
||||||
# failed-to-verify certificate .. but also if you have
|
|
||||||
# multiple grid-managers then a bunch of these
|
|
||||||
# messages would appear
|
|
||||||
print(
|
|
||||||
"Grid Manager certificate signature failed. Certificate: "
|
|
||||||
"\"{cert}\" for key \"{key}\".".format(
|
|
||||||
key=key,
|
|
||||||
cert=alleged_cert,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
def validate():
|
|
||||||
now = now_fn()
|
|
||||||
# if *any* certificate is still valid then we consider the server valid
|
|
||||||
for cert in valid_certs:
|
|
||||||
expires = datetime.utcfromtimestamp(cert['expires'])
|
|
||||||
# cert_pubkey = keyutil.parse_pubkey(cert['public_key'].encode('ascii'))
|
|
||||||
if expires > now:
|
|
||||||
# not-expired
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
return validate
|
|
||||||
|
|
||||||
|
|
||||||
class IFoolscapStorageServer(Interface):
|
class IFoolscapStorageServer(Interface):
|
||||||
"""
|
"""
|
||||||
An internal interface that mediates between ``NativeStorageServer`` and
|
An internal interface that mediates between ``NativeStorageServer`` and
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
|
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
from twisted.python.filepath import (
|
||||||
|
FilePath,
|
||||||
|
)
|
||||||
|
|
||||||
from allmydata.client import (
|
from allmydata.client import (
|
||||||
create_storage_farm_broker,
|
create_storage_farm_broker,
|
||||||
)
|
)
|
||||||
@ -10,6 +14,17 @@ from allmydata.node import (
|
|||||||
from allmydata.client import (
|
from allmydata.client import (
|
||||||
_valid_config as client_valid_config,
|
_valid_config as client_valid_config,
|
||||||
)
|
)
|
||||||
|
from allmydata.crypto import (
|
||||||
|
ed25519,
|
||||||
|
)
|
||||||
|
from allmydata.util import (
|
||||||
|
base32,
|
||||||
|
)
|
||||||
|
from allmydata.grid_manager import (
|
||||||
|
load_grid_manager,
|
||||||
|
save_grid_manager,
|
||||||
|
create_grid_manager,
|
||||||
|
)
|
||||||
|
|
||||||
from .common import SyncTestCase
|
from .common import SyncTestCase
|
||||||
|
|
||||||
@ -78,3 +93,182 @@ class GridManagerUtilities(SyncTestCase):
|
|||||||
1,
|
1,
|
||||||
len(config.enumerate_section("grid_managers"))
|
len(config.enumerate_section("grid_managers"))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class GridManagerVerifier(SyncTestCase):
|
||||||
|
"""
|
||||||
|
Tests related to rejecting or accepting Grid Manager certificates.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.gm = create_grid_manager()
|
||||||
|
return super(GridManagerVerifier, self).setUp()
|
||||||
|
|
||||||
|
def test_sign_cert(self):
|
||||||
|
"""
|
||||||
|
Add a storage-server and sign a certificate for it
|
||||||
|
"""
|
||||||
|
priv, pub = ed25519.create_signing_keypair()
|
||||||
|
self.gm.add_storage_server("test", pub)
|
||||||
|
cert = self.gm.sign("test", 86400)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
set(cert.keys()),
|
||||||
|
{"certificate", "signature"},
|
||||||
|
)
|
||||||
|
gm_key = ed25519.verifying_key_from_string(self.gm.public_identity())
|
||||||
|
self.assertEqual(
|
||||||
|
ed25519.verify_signature(
|
||||||
|
gm_key,
|
||||||
|
base32.a2b(cert["signature"]),
|
||||||
|
cert["certificate"],
|
||||||
|
),
|
||||||
|
None
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_sign_cert_wrong_name(self):
|
||||||
|
"""
|
||||||
|
Try to sign a storage-server that doesn't exist
|
||||||
|
"""
|
||||||
|
with self.assertRaises(KeyError):
|
||||||
|
self.gm.sign("doesn't exist", 86400)
|
||||||
|
|
||||||
|
def test_add_cert(self):
|
||||||
|
"""
|
||||||
|
Add a storage-server and serialize it
|
||||||
|
"""
|
||||||
|
priv, pub = ed25519.create_signing_keypair()
|
||||||
|
self.gm.add_storage_server("test", pub)
|
||||||
|
|
||||||
|
data = self.gm.marshal()
|
||||||
|
self.assertEqual(
|
||||||
|
data["storage_servers"],
|
||||||
|
{
|
||||||
|
"test": {
|
||||||
|
"public_key": ed25519.string_from_verifying_key(pub),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_remove(self):
|
||||||
|
"""
|
||||||
|
Add then remove a storage-server
|
||||||
|
"""
|
||||||
|
priv, pub = ed25519.create_signing_keypair()
|
||||||
|
self.gm.add_storage_server("test", pub)
|
||||||
|
self.gm.remove_storage_server("test")
|
||||||
|
self.assertEqual(len(self.gm.storage_servers), 0)
|
||||||
|
|
||||||
|
def test_serialize(self):
|
||||||
|
"""
|
||||||
|
Write and then read a Grid Manager config
|
||||||
|
"""
|
||||||
|
priv0, pub0 = ed25519.create_signing_keypair()
|
||||||
|
priv1, pub1 = ed25519.create_signing_keypair()
|
||||||
|
self.gm.add_storage_server("test0", pub0)
|
||||||
|
self.gm.add_storage_server("test1", pub1)
|
||||||
|
|
||||||
|
tempdir = self.mktemp()
|
||||||
|
fp = FilePath(tempdir)
|
||||||
|
|
||||||
|
save_grid_manager(fp, self.gm)
|
||||||
|
gm2 = load_grid_manager(fp, tempdir)
|
||||||
|
self.assertEqual(
|
||||||
|
self.gm.public_identity(),
|
||||||
|
gm2.public_identity(),
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
len(self.gm.storage_servers),
|
||||||
|
len(gm2.storage_servers),
|
||||||
|
)
|
||||||
|
for name, ss0 in self.gm.storage_servers.items():
|
||||||
|
ss1 = gm2.storage_servers[name]
|
||||||
|
self.assertEqual(ss0.name, ss1.name)
|
||||||
|
self.assertEqual(ss0.public_key(), ss1.public_key())
|
||||||
|
self.assertEqual(self.gm.marshal(), gm2.marshal())
|
||||||
|
|
||||||
|
def test_invalid_no_version(self):
|
||||||
|
"""
|
||||||
|
Invalid Grid Manager config with no version
|
||||||
|
"""
|
||||||
|
tempdir = self.mktemp()
|
||||||
|
fp = FilePath(tempdir)
|
||||||
|
bad_config = {
|
||||||
|
"private_key": "at least we have one",
|
||||||
|
}
|
||||||
|
fp.makedirs()
|
||||||
|
with fp.child("config.json").open("w") as f:
|
||||||
|
json.dump(bad_config, f)
|
||||||
|
|
||||||
|
with self.assertRaises(ValueError) as ctx:
|
||||||
|
load_grid_manager(fp, tempdir)
|
||||||
|
self.assertIn(
|
||||||
|
"unknown version",
|
||||||
|
str(ctx.exception),
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_invalid_no_private_key(self):
|
||||||
|
"""
|
||||||
|
Invalid Grid Manager config with no private key
|
||||||
|
"""
|
||||||
|
tempdir = self.mktemp()
|
||||||
|
fp = FilePath(tempdir)
|
||||||
|
bad_config = {
|
||||||
|
"grid_manager_config_version": 0,
|
||||||
|
}
|
||||||
|
fp.makedirs()
|
||||||
|
with fp.child("config.json").open("w") as f:
|
||||||
|
json.dump(bad_config, f)
|
||||||
|
|
||||||
|
with self.assertRaises(ValueError) as ctx:
|
||||||
|
load_grid_manager(fp, tempdir)
|
||||||
|
self.assertIn(
|
||||||
|
"requires a 'private_key'",
|
||||||
|
str(ctx.exception),
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_invalid_bad_private_key(self):
|
||||||
|
"""
|
||||||
|
Invalid Grid Manager config with bad private-key
|
||||||
|
"""
|
||||||
|
tempdir = self.mktemp()
|
||||||
|
fp = FilePath(tempdir)
|
||||||
|
bad_config = {
|
||||||
|
"grid_manager_config_version": 0,
|
||||||
|
"private_key": "not actually encoded key",
|
||||||
|
}
|
||||||
|
fp.makedirs()
|
||||||
|
with fp.child("config.json").open("w") as f:
|
||||||
|
json.dump(bad_config, f)
|
||||||
|
|
||||||
|
with self.assertRaises(ValueError) as ctx:
|
||||||
|
load_grid_manager(fp, tempdir)
|
||||||
|
self.assertIn(
|
||||||
|
"Invalid Grid Manager private_key",
|
||||||
|
str(ctx.exception),
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_invalid_storage_server(self):
|
||||||
|
"""
|
||||||
|
Invalid Grid Manager config with missing public-key for
|
||||||
|
storage-server
|
||||||
|
"""
|
||||||
|
tempdir = self.mktemp()
|
||||||
|
fp = FilePath(tempdir)
|
||||||
|
bad_config = {
|
||||||
|
"grid_manager_config_version": 0,
|
||||||
|
"private_key": "priv-v0-ub7knkkmkptqbsax4tznymwzc4nk5lynskwjsiubmnhcpd7lvlqa",
|
||||||
|
"storage_servers": {
|
||||||
|
"bad": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fp.makedirs()
|
||||||
|
with fp.child("config.json").open("w") as f:
|
||||||
|
json.dump(bad_config, f)
|
||||||
|
|
||||||
|
with self.assertRaises(ValueError) as ctx:
|
||||||
|
load_grid_manager(fp, tempdir)
|
||||||
|
self.assertIn(
|
||||||
|
"No 'public_key' for storage server",
|
||||||
|
str(ctx.exception),
|
||||||
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user