Skip to content

Feature/mesh switch time#3

Open
julianschuh wants to merge 9 commits intofreifunk-darmstadt:masterfrom
ffka:feature/mesh_switch_time
Open

Feature/mesh switch time#3
julianschuh wants to merge 9 commits intofreifunk-darmstadt:masterfrom
ffka:feature/mesh_switch_time

Conversation

@julianschuh
Copy link
Copy Markdown

This PR adds the ability to set a custom switch time per Mesh (via CLI) in order to migrate meshes manually and not all at once.

For this purpose, the column manual_switch_time is added to the Mesh model and the switch time selection logic is updated.

The command used to set the switch time for a mesh is domain_director set-switch-time [meshid] [switch_time as unix timestamp]

Additionally, some methods were renamed to make clear(er) what they are actually doing.

Feedback welcome ;-)

Thanks for your great work!

@blocktrron blocktrron self-requested a review December 28, 2018 14:26
@blocktrron blocktrron self-assigned this Dec 28, 2018
def set_domain(mesh_id, domain, decision_criteria):
Mesh.update(domain=domain, decision_criteria=int(decision_criteria)).where(Mesh.id == mesh_id).execute()

def set_manual_switch_time(mesh_id, manual_switch_time):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This method should also be static

@blocktrron
Copy link
Copy Markdown
Member

Thanks for your PR. This is actually something i wanted myself for a long time!

This might be a fundamental design question but i would prefer to have a http endpoint for changing mesh properties such as target domain or switch time.

We needed to adjust the target domain of multiple meshes already which was done by manually shutting down the director and editing the SQLite databse. I would like to avoid the "shutting down of director" part and provide an http endpoint which sits behind basic auth of an nginx or something along those lines.

What do you whink about that?

@julianschuh
Copy link
Copy Markdown
Author

Thanks for your feedback.

I thought about adding a HTTP endpoint, but ultimately decided against it due to having to handle authentication and so on. Handling the authentication via nginx would certainly be possible, but I usually try to avoid such setups as they are quite error prone (are all relevant paths protected? are the public parts available freely? and so on.)

If an authentication-less solution would be acceptable it should be quite easy.

With the current solution it should not be required to restart the director: You can invoke the domain directory binary with the sub-command, and it should then just update the db and stop again. As far as I know SQLite can handle cases where multiple threads/processes access the same database. The next time a node sends a request the new data should be returned (in theory).

@blocktrron
Copy link
Copy Markdown
Member

First of all: Sorry for my reply being late. I haven't noticed you already replied.

I would still very much prefer the HTTP endpoint solution. I think the protection should be pretty easy by protecting everything contained in '/admin'.

I have the concern that we might want to have some extensibility in terms of what an admin might want to set. The CLI might get a bit fiddely then.

I will habe to think a bit about this. In the meantime, i would merge b99742a and 29f9621 and also work on a migration strategy for the database.

@julianschuh
Copy link
Copy Markdown
Author

No worries, thanks for getting back :)

I'm currently working on a simple HTTP endpoint to update mesh settings, which should be easily expandable in the future.

I plan on pushing the changed in the next couple of days™ :)

@julianschuh
Copy link
Copy Markdown
Author

So, I added a first version of the http endpoint for modifying the mesh properties. What do you think? What is missing in your eyes?

Thanks in advance!

Best Regards

force = 'force' in request.values and request.values['force'].lower() in ['true', 'yes', '1']

if not force and (switch_time_parsed - now).total_seconds() < 0:
return 'Specified switch time lies in the past. Force to set value.', 400
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Do you have a use case for force setting a switch time in the past?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

the rationale here is to be able to force a node to switch as quickly as possible by setting the switch time to the past

Comment thread domain_director/cli.py Outdated
return
except ValueError:
print('Invalid meshid specified')
return
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

exit with sys.exit(code) and code > 0

Comment thread domain_director/cli.py Outdated
mesh_db_entry = Mesh.select().where(Mesh.id == int(kwargs['meshid'])).get()
except DoesNotExist:
print('Mesh with ID {} not found.'.format(kwargs['meshid']))
return
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

see below

Comment thread domain_director/cli.py Outdated
switch_time_parsed = datetime.utcfromtimestamp(switch_time)
except ValueError:
print('Invalid switch time specified')
return
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

as before

Comment thread domain_director/cli.py Outdated

if not force and (switch_time_parsed - now).total_seconds() < 0:
print('Specified switch time lies in the past. Force to set value.')
return
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

as before

Comment thread domain_director/domain.py Outdated


def get_domain(lat, lon, domain_polygons, treshold_distance=0):
def get_domain_by_location(lat, lon, domain_polygons, treshold_distance=0):
Copy link
Copy Markdown
Contributor

@mweinelt mweinelt Jan 23, 2019

Choose a reason for hiding this comment

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

I think get_domain_from_location sounds even better. It's not a "group by" after all.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

agreed

Comment thread domain_director/domain.py Outdated
def update_node_domain(node_id, polygons, wifis=None, api_key="test", lat=None, lon=None, accuracy=None,
default_domain=None,
max_accuracy=250, treshold_distance=0, switch_time=-1, migrate_only_vpn=False):
max_accuracy=250, treshold_distance=0, default_switch_time=-1, migrate_only_vpn=False):
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

underindentend for new func name

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

what exactly do you mean?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The parameters of this function call are under-indented.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

done, i think

Comment thread domain_director/domain.py Outdated
mesh_id = Node.get_mesh_id(node_id)
if mesh_id is None:
domain = default_domain
out_switch_time = default_switch_time
Copy link
Copy Markdown
Contributor

@mweinelt mweinelt Jan 23, 2019

Choose a reason for hiding this comment

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

I don't understand what "out" means in this case. Could likely be shortened to just "switch_time", no?

Copy link
Copy Markdown
Contributor

@mweinelt mweinelt Jan 23, 2019

Choose a reason for hiding this comment

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

default_switch_time could also stay as just switch_time param, that gets overwritten if certain requirements are met.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I changed the name to switch_time, good idea.
regarding the parameter: I think it would be more clear to leave the parameter name default_switch_time. When calling the function with the parameter named default_* you would probably expect that the value could be changed within the function.


def test_admin_mesh(self):
rv = self.app.patch('/admin/mesh/999999/', data={})
self.assertEqual(rv.status_code, 404)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

did you link to the correct line? the references line does not seem to be part of my changes ;)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Possibly, what I mean is the abort(400) responses.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I added more tests for all the paths

@julianschuh julianschuh force-pushed the feature/mesh_switch_time branch from 923d795 to 4f29e55 Compare March 14, 2019 21:26
@julianschuh
Copy link
Copy Markdown
Author

OK, i think I incorporated your feedback :)

I also rebased the branch on master.

Thanks for your time!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants