mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2024-12-23 06:42:26 +00:00
wip
This commit is contained in:
parent
31246c84ab
commit
c874a388ce
@ -49,13 +49,19 @@ class AddOptions(BasedirOptions):
|
|||||||
self['name'] = unicode(args[0])
|
self['name'] = unicode(args[0])
|
||||||
try:
|
try:
|
||||||
# WTF?! why does it want 'str' and not six.text_type?
|
# 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:
|
except Exception as e:
|
||||||
raise usage.UsageError(
|
raise usage.UsageError(
|
||||||
"Invalid public_key argument: {}".format(e)
|
"Invalid public_key argument: {}".format(e)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ListOptions(BasedirOptions):
|
||||||
|
description = (
|
||||||
|
"List all storage servers in this Grid Manager"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class SignOptions(BasedirOptions):
|
class SignOptions(BasedirOptions):
|
||||||
description = (
|
description = (
|
||||||
"Create and sign a new certificate for a storage-server"
|
"Create and sign a new certificate for a storage-server"
|
||||||
@ -75,6 +81,7 @@ class GridManagerOptions(BasedirOptions):
|
|||||||
["create", None, CreateOptions, "Create a Grid Manager."],
|
["create", None, CreateOptions, "Create a Grid Manager."],
|
||||||
["public-identity", None, ShowIdentityOptions, "Get the public-key for this 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."],
|
["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."],
|
["sign", None, SignOptions, "Create and sign a new Storage Certificate."],
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -107,8 +114,10 @@ def _create_gridmanager():
|
|||||||
}
|
}
|
||||||
|
|
||||||
def _create(gridoptions, options):
|
def _create(gridoptions, options):
|
||||||
|
"""
|
||||||
|
Create a new Grid Manager
|
||||||
|
"""
|
||||||
gm_config = gridoptions['config']
|
gm_config = gridoptions['config']
|
||||||
assert gm_config is not None
|
|
||||||
|
|
||||||
# pre-conditions check
|
# pre-conditions check
|
||||||
fp = None
|
fp = None
|
||||||
@ -123,19 +132,78 @@ def _create(gridoptions, options):
|
|||||||
_save_gridmanager_config(fp, gm)
|
_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):
|
def _save_gridmanager_config(file_path, grid_manager):
|
||||||
"""
|
"""
|
||||||
Writes a Grid Manager configuration to the place specified by
|
Writes a Grid Manager configuration to the place specified by
|
||||||
'file_path' (if None, stdout is used).
|
'file_path' (if None, stdout is used).
|
||||||
"""
|
"""
|
||||||
# FIXME probably want a GridManagerConfig class or something with
|
data = json.dumps(
|
||||||
# .save and .load instead of this crap
|
grid_manager.marshal(),
|
||||||
raw_data = {
|
indent=4,
|
||||||
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)
|
|
||||||
|
|
||||||
if file_path is None:
|
if file_path is None:
|
||||||
print("{}\n".format(data))
|
print("{}\n".format(data))
|
||||||
@ -167,30 +235,7 @@ def _load_gridmanager_config(gm_config):
|
|||||||
with fp.child("config.json").open("r") as f:
|
with fp.child("config.json").open("r") as f:
|
||||||
gm = json.load(f)
|
gm = json.load(f)
|
||||||
|
|
||||||
if 'private_key' not in gm:
|
return _GridManager(gm, gm_config)
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
def _show_identity(gridoptions, options):
|
def _show_identity(gridoptions, options):
|
||||||
@ -210,26 +255,40 @@ def _add(gridoptions, options):
|
|||||||
Add a new storage-server by name to a Grid Manager
|
Add a new storage-server by name to a Grid Manager
|
||||||
"""
|
"""
|
||||||
gm_config = gridoptions['config'].strip()
|
gm_config = gridoptions['config'].strip()
|
||||||
assert gm_config is not None
|
|
||||||
fp = FilePath(gm_config) if gm_config.strip() != '-' else None
|
fp = FilePath(gm_config) if gm_config.strip() != '-' else None
|
||||||
|
|
||||||
gm = _load_gridmanager_config(gm_config)
|
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(
|
raise usage.UsageError(
|
||||||
"A storage-server called '{}' already exists".format(options['name'])
|
"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)
|
_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):
|
def _sign(gridoptions, options):
|
||||||
"""
|
"""
|
||||||
sign a new certificate
|
sign a new certificate
|
||||||
"""
|
"""
|
||||||
gm_config = gridoptions['config'].strip()
|
gm_config = gridoptions['config'].strip()
|
||||||
assert gm_config is not None
|
|
||||||
fp = FilePath(gm_config) if gm_config.strip() != '-' else None
|
fp = FilePath(gm_config) if gm_config.strip() != '-' else None
|
||||||
gm = _load_gridmanager_config(gm_config)
|
gm = _load_gridmanager_config(gm_config)
|
||||||
|
|
||||||
@ -262,6 +321,7 @@ grid_manager_commands = {
|
|||||||
CreateOptions: _create,
|
CreateOptions: _create,
|
||||||
ShowIdentityOptions: _show_identity,
|
ShowIdentityOptions: _show_identity,
|
||||||
AddOptions: _add,
|
AddOptions: _add,
|
||||||
|
ListOptions: _list,
|
||||||
SignOptions: _sign,
|
SignOptions: _sign,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user