Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/running_the_federation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1047,6 +1047,7 @@ Importing the Workspace

.. code-block:: console

fx collaborator create -n {COL_LABEL} -d {DATA_PATH:optional}
fx collaborator generate-cert-request -n {COL_LABEL}


Expand Down
39 changes: 25 additions & 14 deletions openfl/interface/collaborator.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,24 @@ def start_(plan, collaborator_name, data_config, secure):
plan.get_collaborator(collaborator_name).run()


@collaborator.command(name='create')
@option('-n', '--collaborator_name', required=True,
help='The certified common name of the collaborator')
@option('-d', '--data_path',
help='The data path to be associated with the collaborator')
@option('-s', '--silent', help='Do not prompt', is_flag=True)
def create_(collaborator_name, data_path, silent):
"""Creates a user for an experiment."""
if data_path and is_directory_traversal(data_path):
echo('Data path is out of the openfl workspace scope.')
sys.exit(1)

common_name = f'{collaborator_name}'.lower()

# TODO: There should be some association with the plan made here as well
register_data_path(common_name, data_path=data_path, silent=silent)


def register_data_path(collaborator_name, data_path=None, silent=False):
"""Register dataset path in the plan/data.yaml file.

Expand Down Expand Up @@ -103,30 +121,26 @@ def register_data_path(collaborator_name, data_path=None, silent=False):
d[collaborator_name] = dir_path

# Write the data.yaml
with open(data_yaml, 'w', encoding='utf-8') as f:
for key, val in d.items():
f.write(f'{key}{separator}{val}\n')
if isfile(data_yaml):
with open(data_yaml, 'w', encoding='utf-8') as f:
for key, val in d.items():
f.write(f'{key}{separator}{val}\n')


@collaborator.command(name='generate-cert-request')
@option('-n', '--collaborator_name', required=True,
help='The certified common name of the collaborator')
@option('-d', '--data_path',
help='The data path to be associated with the collaborator')
@option('-s', '--silent', help='Do not prompt', is_flag=True)
@option('-x', '--skip-package',
help='Do not package the certificate signing request for export',
is_flag=True)
def generate_cert_request_(collaborator_name,
data_path, silent, skip_package):
silent, skip_package):
"""Generate certificate request for the collaborator."""
if data_path and is_directory_traversal(data_path):
echo('Data path is out of the openfl workspace scope.')
sys.exit(1)
generate_cert_request(collaborator_name, data_path, silent, skip_package)
generate_cert_request(collaborator_name, silent, skip_package)


def generate_cert_request(collaborator_name, data_path, silent, skip_package):
def generate_cert_request(collaborator_name, silent, skip_package):
"""
Create collaborator certificate key pair.

Expand Down Expand Up @@ -192,9 +206,6 @@ def generate_cert_request(collaborator_name, data_path, silent, skip_package):
echo('This file should be sent to the certificate authority'
' (typically hosted by the aggregator) for signing')

# TODO: There should be some association with the plan made here as well
register_data_path(common_name, data_path=data_path, silent=silent)


def find_certificate_name(file_name):
"""Parse the collaborator name."""
Expand Down
8 changes: 5 additions & 3 deletions openfl/native/native.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,8 @@ def init(workspace_template: str = 'default', log_level: str = 'INFO',
aggregator.certify(agg_fqdn, silent=True)
data_path = 1
for col_name in col_names:
collaborator.create(
col_name, str(data_path), silent=True)
collaborator.generate_cert_request(
col_name, str(data_path), silent=True, skip_package=True)
collaborator.certify(col_name, silent=True)
Expand All @@ -208,7 +210,7 @@ def init(workspace_template: str = 'default', log_level: str = 'INFO',
setup_logging(level=log_level, log_file=log_file)


def create_collaborator(plan, name, model, aggregator):
def get_collaborator(plan, name, model, aggregator):
"""
Create the collaborator.

Expand Down Expand Up @@ -282,9 +284,9 @@ def run_experiment(collaborator_dict: dict, override_config: dict = None):

aggregator = plan.get_aggregator()

# Create the collaborators
# get the collaborators
collaborators = {
collaborator: create_collaborator(
collaborator: get_collaborator(
plan, collaborator, collaborator_dict[collaborator], aggregator
) for collaborator in plan.authorized_cols
}
Expand Down
7 changes: 6 additions & 1 deletion tests/github/pki_wrong_cn.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,14 @@ def prepare_workspace():
])
for col in ['one', 'two']:
subprocess.check_call([
'fx', 'collaborator', 'generate-cert-request',
'fx', 'collaborator', 'create',
'-n', col,
'-d', '1',
'-s'
])
subprocess.check_call([
'fx', 'collaborator', 'generate-cert-request',
'-n', col,
'-s', '-x'
])
subprocess.check_call([
Expand Down
3 changes: 2 additions & 1 deletion tests/github/test_graminize.sh
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ create_collaborator() {

# Create collaborator certificate request
cd ${COL_DIRECTORY}/${FED_WORKSPACE}
fx collaborator generate-cert-request -d ${DATA_PATH} -n ${COL} --silent # Remove '--silent' if you run this manually
fx collaborator create -d ${DATA_PATH} -n ${COL} --silent # Remove '--silent' if you run this manually
fx collaborator generate-cert-request -n ${COL} --silent # Remove '--silent' if you run this manually

# Sign collaborator certificate
cd ${FED_DIRECTORY} # Move back to the Aggregator
Expand Down
11 changes: 9 additions & 2 deletions tests/github/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,13 @@ def create_collaborator(col, workspace_root, data_path, archive_name, fed_worksp
)

# Create collaborator certificate request
check_call(
['fx', 'collaborator', 'create', '-d', data_path, '-n', col, '--silent'],
cwd=col_path / fed_workspace
)
# Remove '--silent' if you run this manually
check_call(
['fx', 'collaborator', 'generate-cert-request', '-d', data_path, '-n', col, '--silent'],
['fx', 'collaborator', 'generate-cert-request', '-n', col, '--silent'],
cwd=col_path / fed_workspace
)

Expand Down Expand Up @@ -84,7 +88,10 @@ def create_signed_cert_for_collaborator(col, data_path):
print(f'Certifying collaborator {col} with data path {data_path}...')
# Create collaborator certificate request
check_call([
'fx', 'collaborator', 'generate-cert-request', '-d', data_path, '-n', col, '--silent'
'fx', 'collaborator', 'create', '-d', data_path, '-n', col, '--silent'
])
check_call([
'fx', 'collaborator', 'generate-cert-request', '-n', col, '--silent'
])
# Sign collaborator certificate
check_call([
Expand Down