mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2024-12-22 14:22:25 +00:00
wip
This commit is contained in:
parent
31246c84ab
commit
c874a388ce
@ -49,13 +49,19 @@ class AddOptions(BasedirOptions):
|
||||
self['name'] = unicode(args[0])
|
||||
try:
|
||||
# WTF?! why does it want 'str' and not six.text_type?
|
||||
self['storage_public_key'] = keyutil.parse_public_key(args[1])
|
||||
self['storage_public_key'] = keyutil.parse_pubkey(args[1])
|
||||
except Exception as e:
|
||||
raise usage.UsageError(
|
||||
"Invalid public_key argument: {}".format(e)
|
||||
)
|
||||
|
||||
|
||||
class ListOptions(BasedirOptions):
|
||||
description = (
|
||||
"List all storage servers in this Grid Manager"
|
||||
)
|
||||
|
||||
|
||||
class SignOptions(BasedirOptions):
|
||||
description = (
|
||||
"Create and sign a new certificate for a storage-server"
|
||||
@ -75,6 +81,7 @@ class GridManagerOptions(BasedirOptions):
|
||||
["create", None, CreateOptions, "Create a Grid Manager."],
|
||||
["public-identity", None, ShowIdentityOptions, "Get the public-key for this Grid Manager."],
|
||||
["add", None, AddOptions, "Add a storage server to this Grid Manager."],
|
||||
["list", None, ListOptions, "List all storage servers in this Grid Manager."],
|
||||
["sign", None, SignOptions, "Create and sign a new Storage Certificate."],
|
||||
]
|
||||
|
||||
@ -107,8 +114,10 @@ def _create_gridmanager():
|
||||
}
|
||||
|
||||
def _create(gridoptions, options):
|
||||
"""
|
||||
Create a new Grid Manager
|
||||
"""
|
||||
gm_config = gridoptions['config']
|
||||
assert gm_config is not None
|
||||
|
||||
# pre-conditions check
|
||||
fp = None
|
||||
@ -123,19 +132,78 @@ def _create(gridoptions, options):
|
||||
_save_gridmanager_config(fp, gm)
|
||||
|
||||
|
||||
class _GridManager(object):
|
||||
"""
|
||||
A Grid Manager's configuration.
|
||||
"""
|
||||
|
||||
def __init__(self, config, config_location):
|
||||
if 'private_key' not in config:
|
||||
raise RuntimeError(
|
||||
"Grid Manager config from '{}' requires a 'private_key'".format(
|
||||
config_config
|
||||
)
|
||||
)
|
||||
|
||||
private_key_str = config['private_key']
|
||||
try:
|
||||
self._private_key_bytes = base32.a2b(private_key_str.encode('ascii'))
|
||||
self._private_key = ed25519.SigningKey(self._private_key_bytes)
|
||||
except Exception as e:
|
||||
raise RuntimeError(
|
||||
"Invalid Grid Manager private_key: {}".format(e)
|
||||
)
|
||||
|
||||
gm_version = config.get('grid_manager_config_version', None)
|
||||
if gm_version != 0:
|
||||
raise RuntimeError(
|
||||
"Missing or unknown version '{}' of Grid Manager config".format(
|
||||
gm_version
|
||||
)
|
||||
)
|
||||
self._version = 0
|
||||
self._storage_servers = dict()
|
||||
|
||||
@property
|
||||
def storage_servers(self):
|
||||
return self._storage_servers
|
||||
|
||||
def add_storage_server(self, name, public_key):
|
||||
"""
|
||||
:param name: a user-meaningful name for the server
|
||||
:param public_key: ed25519.VerifyingKey the public-key of the
|
||||
storage provider (e.g. from the contents of node.pubkey
|
||||
for the client)
|
||||
"""
|
||||
if name in self._storage_servers:
|
||||
raise KeyError(
|
||||
"Already have a storage server called '{}'".format(name)
|
||||
)
|
||||
assert public_key.vk_bytes
|
||||
self._storage_servers[name] = public_key
|
||||
|
||||
def marshal(self):
|
||||
data = {
|
||||
u"grid_manager_config_version": self._version,
|
||||
u"private_key": base32.b2a(self._private_key.sk_and_vk[:32]),
|
||||
}
|
||||
if self._storage_servers:
|
||||
data[u"storage_servers"] = {
|
||||
name: base32.b2a(public_key.vk_bytes)
|
||||
for name, public_key
|
||||
in self._storage_servers.items()
|
||||
}
|
||||
|
||||
|
||||
def _save_gridmanager_config(file_path, grid_manager):
|
||||
"""
|
||||
Writes a Grid Manager configuration to the place specified by
|
||||
'file_path' (if None, stdout is used).
|
||||
"""
|
||||
# FIXME probably want a GridManagerConfig class or something with
|
||||
# .save and .load instead of this crap
|
||||
raw_data = {
|
||||
k: v
|
||||
for k, v in grid_manager.items()
|
||||
}
|
||||
raw_data['private_key'] = base32.b2a(raw_data['private_key'].sk_and_vk[:32])
|
||||
data = json.dumps(raw_data, indent=4)
|
||||
data = json.dumps(
|
||||
grid_manager.marshal(),
|
||||
indent=4,
|
||||
)
|
||||
|
||||
if file_path is None:
|
||||
print("{}\n".format(data))
|
||||
@ -167,30 +235,7 @@ def _load_gridmanager_config(gm_config):
|
||||
with fp.child("config.json").open("r") as f:
|
||||
gm = json.load(f)
|
||||
|
||||
if 'private_key' not in gm:
|
||||
raise RuntimeError(
|
||||
"Grid Manager config from '{}' requires a 'private_key'".format(
|
||||
gm_config
|
||||
)
|
||||
)
|
||||
|
||||
private_key_str = gm['private_key']
|
||||
try:
|
||||
private_key_bytes = base32.a2b(private_key_str.encode('ascii')) # WTF?! why is a2b requiring "str", not "unicode"?
|
||||
gm['private_key'] = ed25519.SigningKey(private_key_bytes)
|
||||
except Exception as e:
|
||||
raise RuntimeError(
|
||||
"Invalid Grid Manager private_key: {}".format(e)
|
||||
)
|
||||
|
||||
gm_version = gm.get('grid_manager_config_version', None)
|
||||
if gm_version != 0:
|
||||
raise RuntimeError(
|
||||
"Missing or unknown version '{}' of Grid Manager config".format(
|
||||
gm_version
|
||||
)
|
||||
)
|
||||
return gm
|
||||
return _GridManager(gm, gm_config)
|
||||
|
||||
|
||||
def _show_identity(gridoptions, options):
|
||||
@ -210,26 +255,40 @@ def _add(gridoptions, options):
|
||||
Add a new storage-server by name to a Grid Manager
|
||||
"""
|
||||
gm_config = gridoptions['config'].strip()
|
||||
assert gm_config is not None
|
||||
fp = FilePath(gm_config) if gm_config.strip() != '-' else None
|
||||
|
||||
gm = _load_gridmanager_config(gm_config)
|
||||
if options['name'] in gm.get('storage_severs', set()):
|
||||
try:
|
||||
gm.add_storage_server(
|
||||
options['name'],
|
||||
options['storage_public_key'],
|
||||
)
|
||||
except KeyError:
|
||||
raise usage.UsageError(
|
||||
"A storage-server called '{}' already exists".format(options['name'])
|
||||
)
|
||||
if 'storage_servers' not in gm:
|
||||
gm['storage_servers'] = dict()
|
||||
gm['storage_servers'][options['name']] = base32.b2a(options['storage_public_key'].vk_bytes)
|
||||
|
||||
_save_gridmanager_config(fp, gm)
|
||||
|
||||
|
||||
def _list(gridoptions, options):
|
||||
"""
|
||||
List all storage-servers known to a Grid Manager
|
||||
"""
|
||||
gm_config = gridoptions['config'].strip()
|
||||
fp = FilePath(gm_config) if gm_config.strip() != '-' else None
|
||||
|
||||
gm = _load_gridmanager_config(gm_config)
|
||||
for name in sorted(gm.storage_servers.keys()):
|
||||
key = "pub-v0-" + gm.storage_servers[name].vk_bytes
|
||||
print("{}: {}".format(name, key))
|
||||
|
||||
|
||||
def _sign(gridoptions, options):
|
||||
"""
|
||||
sign a new certificate
|
||||
"""
|
||||
gm_config = gridoptions['config'].strip()
|
||||
assert gm_config is not None
|
||||
fp = FilePath(gm_config) if gm_config.strip() != '-' else None
|
||||
gm = _load_gridmanager_config(gm_config)
|
||||
|
||||
@ -262,6 +321,7 @@ grid_manager_commands = {
|
||||
CreateOptions: _create,
|
||||
ShowIdentityOptions: _show_identity,
|
||||
AddOptions: _add,
|
||||
ListOptions: _list,
|
||||
SignOptions: _sign,
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user