Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make flower-server start server with HTTPS by default #2591

Merged
merged 25 commits into from
Nov 17, 2023
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
5e5a405
add --insecure arg to parse_args_server
panh99 Nov 8, 2023
36254e6
add insecure and certificates args for flower-server
panh99 Nov 11, 2023
b788c69
Merge branch 'main' into make-https-default
panh99 Nov 11, 2023
859ed6f
update e2e/test_driver.sh
panh99 Nov 12, 2023
6dd5e68
Merge branch 'main' into make-https-default
panh99 Nov 14, 2023
015a246
Merge branch 'main' into make-https-default
panh99 Nov 14, 2023
bf07ee3
update run_driver_api and run_fleet_api
panh99 Nov 15, 2023
3e1b0f0
Merge branch 'main' into make-https-default
panh99 Nov 15, 2023
fc65ce0
Merge branch 'main' into make-https-default
panh99 Nov 15, 2023
c7d900e
Merge branch 'main' into make-https-default
panh99 Nov 15, 2023
2db7d2b
add e2e test
panh99 Nov 16, 2023
12a4431
Merge branch 'main' into make-https-default
panh99 Nov 16, 2023
18c42d7
add empty simulation.py for bare-https
panh99 Nov 16, 2023
2299b15
Merge branch 'make-https-default' of https://github.com/adap/flower i…
panh99 Nov 16, 2023
ea958f8
update command for test_driver.sh
panh99 Nov 16, 2023
14036c8
Merge branch 'main' into make-https-default
danieljanes Nov 16, 2023
aac2c2d
Merge branch 'main' into make-https-default
tanertopal Nov 16, 2023
b824baa
Update src/py/flwr/server/app.py
danieljanes Nov 16, 2023
4281c0d
Update e2e/bare-https/simulation.py
danieljanes Nov 16, 2023
d713c47
Merge branch 'main' into make-https-default
tanertopal Nov 16, 2023
80760ed
mv cert files to bare-https
panh99 Nov 16, 2023
a872d5f
Merge branch 'main' into make-https-default
panh99 Nov 16, 2023
eb4dffe
cert files on-the-fly
panh99 Nov 17, 2023
6e8b51a
add ./generate.sh call
panh99 Nov 17, 2023
8cee021
Merge branch 'main' into make-https-default
danieljanes Nov 17, 2023
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
4 changes: 3 additions & 1 deletion .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ jobs:
include:
- directory: bare

- directory: bare-https

- directory: jax

- directory: pytorch
Expand Down Expand Up @@ -135,7 +137,7 @@ jobs:
- name: Run virtual client test
run: python simulation.py
- name: Run driver test
run: ./../test_driver.sh
run: ./../test_driver.sh "${{ matrix.directory }}"

strategies:
runs-on: ubuntu-22.04
Expand Down
3 changes: 3 additions & 0 deletions e2e/bare-https/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Bare Flower testing

This directory is used for testing Flower in a bare minimum scenario, that is, with a dummy model and dummy operations. This is mainly to test the core functionnality of Flower independently from any framework. It can easily be extendended to test more complex communication set-ups.
35 changes: 35 additions & 0 deletions e2e/bare-https/client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import flwr as fl
import numpy as np
from pathlib import Path


danieljanes marked this conversation as resolved.
Show resolved Hide resolved
model_params = np.array([1])
objective = 5

# Define Flower client
class FlowerClient(fl.client.NumPyClient):
def get_parameters(self, config):
return model_params

def fit(self, parameters, config):
model_params = parameters
model_params = [param * (objective/np.mean(param)) for param in model_params]
return model_params, 1, {}

def evaluate(self, parameters, config):
model_params = parameters
loss = min(np.abs(1 - np.mean(model_params)/objective), 1)
accuracy = 1 - loss
return loss, 1, {"accuracy": accuracy}

def client_fn(cid):
return FlowerClient()


if __name__ == "__main__":
# Start Flower client
fl.client.start_numpy_client(
server_address="127.0.0.1:8080",
client=FlowerClient(),
root_certificates=Path("../certificates/ca.crt").read_bytes(),
)
12 changes: 12 additions & 0 deletions e2e/bare-https/driver.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import flwr as fl
from pathlib import Path


# Start Flower server
hist = fl.driver.start_driver(
server_address="127.0.0.1:9091",
config=fl.server.ServerConfig(num_rounds=3),
root_certificates=Path("../certificates/ca.crt").read_bytes(),
)

assert hist.losses_distributed[-1][1] == 0
13 changes: 13 additions & 0 deletions e2e/bare-https/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[build-system]
requires = ["poetry-core>=1.4.0"]
build-backend = "poetry.core.masonry.api"

[tool.poetry]
name = "bare_https_test"
version = "0.1.0"
description = "HTTPS-enabled bare Federated Learning test with Flower"
authors = ["The Flower Authors <[email protected]>"]

[tool.poetry.dependencies]
python = "^3.8"
flwr = { path = "../../", develop = true }
15 changes: 15 additions & 0 deletions e2e/bare-https/server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import flwr as fl
from pathlib import Path


hist = fl.server.start_server(
server_address="127.0.0.1:8080",
config=fl.server.ServerConfig(num_rounds=3),
certificates=(
Path("../certificates/ca.crt").read_bytes(),
Path("../certificates/server.pem").read_bytes(),
Path("../certificates/server.key").read_bytes(),
)
)

assert hist.losses_distributed[-1][1] == 0 or (hist.losses_distributed[0][1] / hist.losses_distributed[-1][1]) >= 0.98
1 change: 1 addition & 0 deletions e2e/bare-https/simulation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# No simulation test for bare-https
danieljanes marked this conversation as resolved.
Show resolved Hide resolved
30 changes: 30 additions & 0 deletions e2e/certificates/ca.crt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
-----BEGIN CERTIFICATE-----
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would not commit these here but rather generate them each time the test runs and delete them afterwards. It's often easier to commit them, but at the same time, I would prefer to avoid having any secret keys or certificates even for testing committed to prevent any possibility someone might accidentally use them somewhere.

Copy link
Member

@danieljanes danieljanes Nov 16, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tanertopal wdyt, should we also move the certificates directory into the bare-https dir? They are only required for that single test

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If they are only required here, then let's move it. The directory could also contain the script to generate the certificates.

MIIFOzCCAyOgAwIBAgIUI4Z1SFPZUIM0LS7TXUS87u0JMk4wDQYJKoZIhvcNAQEL
BQAwLTELMAkGA1UEBhMCREUxCzAJBgNVBAgMAkhIMREwDwYDVQQKDAhDQSwgSW5j
LjAeFw0yMzExMTUyMDI4NDRaFw0yNDExMTQyMDI4NDRaMC0xCzAJBgNVBAYTAkRF
MQswCQYDVQQIDAJISDERMA8GA1UECgwIQ0EsIEluYy4wggIiMA0GCSqGSIb3DQEB
AQUAA4ICDwAwggIKAoICAQCVDJfeHo3p9GBRpAUIjHuBK7yxUd1xCLWei457jEO8
B7N0yJyQ1xOAzqTfK/t7xAv8L45tHWTzJfhUVMxInES7ivSg3Zr3JB8vssONEpKK
t8CWJzh5eQY4P/qrfYhzzLLIcQwKVYd6kac1Tm0yvpArmfwpTHBpWzzkwQN3KmF2
SG2k51bfKTcLspeJD0cKI/PUWqKLlCmZ4qvXByIIIQdNuCbu0booEjm8C4uJXD23
SjxXSZNIRA8mRztC5AN/VJECPzu4Si9CsWlrsO5zdtc6XduXOXqbYmZgzpYDr1Tp
G7Kgsc87HDUzVd5Ec/SbBoLjInFIlrE88TmSvKC0x85HWEhQwTQv0WzxRvaty0jY
xUveTQ+2v103msgE5mddzCPecYgb0t7IpJ/9vvo4oA9PwXCy+jFVqyTCHwYg3sYT
hHSyBtYalBChZ9jdI8oj1KHt59Ft4mqT8olmATFU0of+1pwYj5LaFz/tFklLYXek
ewphcbzSgLXRcbLIKSTY6ISnMURjX++DV8DBwq4qmiEU/YkOi6iYxlV27X0p2KV9
CkgtlDueakrParYGsy3ND+O+nIJ1nujIUme6xVoQ0qUy/KF2O11keIBn1gHYYX0n
Tw5SSxhqfmlvCs1aiVwx6BLUTT1iytG4FQwrTFkABCF5Pd0GB9zcbQMRg7VWs6X1
mwIDAQABo1MwUTAdBgNVHQ4EFgQUEUQfIyktB1BkiiskGLSLycDFexIwHwYDVR0j
BBgwFoAUEUQfIyktB1BkiiskGLSLycDFexIwDwYDVR0TAQH/BAUwAwEB/zANBgkq
hkiG9w0BAQsFAAOCAgEAWO3LcrNZzv+RjkQYS9a72Xh1zxSsHwI/W9LemkQaGIRO
5kUoRdIJJAka5Rn5IlFi5Qoy16RZzfOTdvav9YO5D9AUZiLLwiegjnrW0g40THer
Hjc0RDXZSGF3BTqXxOQygcblulcty6+M0wBZ/HvYBCGpTbvBf+eVODXmE6XfvBSd
roA+xc3NvQoUVSyLMDgnPwCjM6vyV8g8nyM8lW+mq1NfDq8z/HzYdn0E0LNhnk1e
MubuFfHl8OEO5CXc7Z7MUpenn+ZNY/e8EjOzlSH6Qhyy/3p9evatZ/wXr682ZqKt
6GWNRRXDHZhWY980KZpeGocNwjFwop/eirbFhKfU5zw8e2KwEeFi9S0uXGDjx0oQ
g+nFC+xXGtsrQqM/9x6caEmECy3uCzw06uSu1/nLYQ5unuGOA21+tTPL97OQz5hK
bHcohzU6NdqF0rFQ/wufCvowAPww3oD7IqkFJoD8W245BnGPAb0SfZ6j8AEKgAko
r58r32ax5Axgx1QRSuR+HZX5jlF6fI4YNHe32jrBA3BXeyfwQpdOUOJTR02j4cII
hpode5GHr1zDI9W6xTaTyR3rZ5TiVR2SpZxxUNqeR70+YnoljXzluh+77AdVv7Kv
Aa1NOvuOuKW9paku3PsFsnGu783Yokjrh0V3Wez8y8HcmyFRbuTsnTWEf3Cbzbw=
-----END CERTIFICATE-----
52 changes: 52 additions & 0 deletions e2e/certificates/server.key
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
-----BEGIN PRIVATE KEY-----
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
DzNYhL6mO2B/QOWEZPjoJ3AgceHEkqg=
-----END PRIVATE KEY-----
31 changes: 31 additions & 0 deletions e2e/certificates/server.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
-----BEGIN CERTIFICATE-----
MIIFajCCA1KgAwIBAgIUEaOR43jMF3DXOiW7Cr/yYlbzq7UwDQYJKoZIhvcNAQEL
BQAwLTELMAkGA1UEBhMCREUxCzAJBgNVBAgMAkhIMREwDwYDVQQKDAhDQSwgSW5j
LjAeFw0yMzExMTUyMDI4NDVaFw0yNDExMTQyMDI4NDVaMD8xCzAJBgNVBAYTAkRF
MQswCQYDVQQIDAJISDEPMA0GA1UECgwGRmxvd2VyMRIwEAYDVQQDDAlsb2NhbGhv
c3QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC3IPN9IdJOH0rDJGva
hkZctu6BB7c3v5cvlHTebsfUY1SxeWdvgFYV00i1Btz6KBn967wAfjI+ngad6MLh
F7tqZgVkiCK5ae54qv07j2ZZVvWNA+gOMWz1yW3L7webO2VrYntFuHk1kI7j0hc7
0AHdWClEhjtv4/X8oTKyQOATns1Dzuv7lwYFnOZ43HkG9NJtyxUtrms6qK/Ftcpp
Pd0RHQe4MWEOZ4MA9Comr5N8pMzG6VcvNcZv8100Z2/RI80Y0l1mVFQ6JyWiDGSS
lIrNePBLnxQg8i9SAuQs1pCbyBJZcQwGZEWDzhsAvqXAU7+Q0gG8GsP9rAAPdFOF
Nmw9HpW37wOJKV9ezvqwHFv8GILAZcNii7fOLU4FAiq1VwVz1MKcJrkX1U54wNdW
cVuN5qm6qiwaxum0FaJuT39thitJhqh1JXziNRzEv4NEmnRlPqaLKDrBFjErbeNU
NzYt58MfM6DGFQZTeFzBKnceU699s7e+VXYhQqClx7Kzp5zcuoi+knxgaJWR2LVg
ngBc88R/E9hdIw3tRsTXPuP8oC6JHfQ8RlLl1kjCG+ymx+SDop6H7StuC249U87g
cM8fP4Etmu+jDhTUsCHmq3nTVRvZEmqWEC64rX6ozLUT7zjRH/og/QIgsQraK/Ns
COwwlGNdK/WhIzQzcxhX46fn6QIDAQABo3AwbjAsBgNVHREEJTAjgglsb2NhbGhv
c3SHEAAAAAAAAAAAAAAAAAAAAAGHBH8AAAEwHQYDVR0OBBYEFLw5D4yWbo1qaubM
EvSVqzwPQNmUMB8GA1UdIwQYMBaAFBFEHyMpLQdQZIorJBi0i8nAxXsSMA0GCSqG
SIb3DQEBCwUAA4ICAQACmQEykNsSPjaX/rfpvm4iaMudSCYZ2Ly2pFywhpcjZz//
IJEoiyo84k4PmenghRvcmU5CCY3rtRaOiNzcRMKv8+CcdMkMTcI8jVR29YIgARmu
qukgQ5DGPz0BG9nRoqS6N3rELkiQYcW6FfGQnr9zSaE+7Aq/u0o+B0P7WSr7jjsF
vEo6CljHGiYQI/e1I2XQ+/9KNBe7T24ttXl8uUMml1mg/zT4mfFMMELYaNFDwxi0
y1TwOc2HVn8PzlH7n89eMLKypxdemrwMV/UAPDS6YjOhXlpuB15UqpjZYRJtLJOx
KEFnf5MqUnBSjulwa7cbLw1ckThLw+zt6iXTG5bJTsnmTKMk8gRuUPwOkiA0/hTT
BPYqpzdaPDEJt7/iN0g1wk9c+W2bjAhwVCEwsdZdQx+yhba8wd62Nfn0vd6h9noB
Ra5tDSBkuno18yQNFzhTU8p/3lFjJdfsCV8+O/UcoJhxG7KMPLvSZ3mSPkS3SGe3
uwrL74GrSPEsg3Gut5xCUpY6BkthELGWSGEAtk7iAJNFyZoqLUoPulNM2IJnQ2KN
vH0xa3tNufca/IKqVHK/oA91Mgw1o08FNWMwnCBq4w798qffZoHBUHtw19Z9Uunk
Z3ZZOUbucVNQoGPPfLyffHduZjnJ+JAhMQjMKahjzQiDCpOZzZ4wy+FV3JOpfQ==
-----END CERTIFICATE-----
2 changes: 1 addition & 1 deletion e2e/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
set -e

case "$1" in
pandas)
pandas | bare-https)
server_file="server.py"
;;
*)
Expand Down
11 changes: 10 additions & 1 deletion e2e/test_driver.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
#!/bin/bash
set -e

timeout 2m flower-server --grpc-bidi --grpc-bidi-fleet-api-address 0.0.0.0:8080 &
case "$1" in
bare-https)
cert_arg="--certificates ../certificates/ca.crt ../certificates/server.pem ../certificates/server.key"
;;
*)
cert_arg="--insecure"
;;
esac

timeout 2m flower-server $cert_arg --grpc-bidi --grpc-bidi-fleet-api-address 0.0.0.0:8080 &
sleep 3

python client.py &
Expand Down
Loading