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

Feature/mesh switch time #3

Open
wants to merge 9 commits into
base: master
Choose a base branch
from

Conversation

julianschuh
Copy link

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

@staticmethod
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
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
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
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
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
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
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
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
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

return
except ValueError:
print('Invalid meshid specified')
return
Copy link
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

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
Contributor

Choose a reason for hiding this comment

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

see below

switch_time_parsed = datetime.utcfromtimestamp(switch_time)
except ValueError:
print('Invalid switch time specified')
return
Copy link
Contributor

Choose a reason for hiding this comment

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

as before


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
Contributor

Choose a reason for hiding this comment

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

as before

@@ -28,7 +28,7 @@ def load_domain_polygons(geojson_input):
return polygons


def get_domain(lat, lon, domain_polygons, treshold_distance=0):
def get_domain_by_location(lat, lon, domain_polygons, treshold_distance=0):
Copy link
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
Author

Choose a reason for hiding this comment

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

agreed

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
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
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
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
Author

Choose a reason for hiding this comment

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

done, i think

is_vpn_only = False
mesh_id = Node.get_mesh_id(node_id)
if mesh_id is None:
domain = default_domain
out_switch_time = default_switch_time
Copy link
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
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
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
Contributor

Choose a reason for hiding this comment

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

Copy link
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
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
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
Copy link
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