diff options
author | Alejandro Sirgo Rica <asirgo@soleta.eu> | 2024-06-17 12:52:32 +0200 |
---|---|---|
committer | Alejandro Sirgo Rica <asirgo@soleta.eu> | 2024-06-17 14:03:00 +0200 |
commit | 4a74de1064c6cf0ef9ce10934efa24b63e661083 (patch) | |
tree | 5da99ed64437aaee27b037313f62940853905930 | |
parent | 664ad2bf7bad8014c024ce1b0f247f394a2fcaa4 (diff) |
ogcp: add move client to scopes management
Add front end for the client/move REST API.
Enable the move of multiple clients selected from the sidebar of
Scopes Management.
Show the target of the move operation as a list of paths in a
dropdown widget in the form. Each path will be structured as:
Server/Center/Room
The path will also contain folders if they are present.
-rw-r--r-- | ogcp/forms/action_forms.py | 5 | ||||
-rw-r--r-- | ogcp/templates/actions/client_move.html | 25 | ||||
-rw-r--r-- | ogcp/templates/scopes.html | 2 | ||||
-rw-r--r-- | ogcp/views.py | 63 |
4 files changed, 94 insertions, 1 deletions
diff --git a/ogcp/forms/action_forms.py b/ogcp/forms/action_forms.py index 718bd3d..9e3a9f6 100644 --- a/ogcp/forms/action_forms.py +++ b/ogcp/forms/action_forms.py @@ -142,6 +142,11 @@ class ClientDetailsForm(FlaskForm): boot = SelectField(label=_l('Boot Mode'), validate_choice=False) submit = SubmitField(label=_l('Submit')) +class ClientMoveForm(FlaskForm): + ips = HiddenField() + scopes = SelectField(label=_l('Scopes'), validate_choice=False) + submit = SubmitField(label=_l('Submit')) + class ImportClientsForm(FlaskForm): server = HiddenField() room = SelectField(label=_l('Room')) diff --git a/ogcp/templates/actions/client_move.html b/ogcp/templates/actions/client_move.html new file mode 100644 index 0000000..d9bcaac --- /dev/null +++ b/ogcp/templates/actions/client_move.html @@ -0,0 +1,25 @@ +{% extends 'scopes.html' %} +{% import "bootstrap/wtf.html" as wtf %} +{% import "macros.html" as macros %} + +{% set sidebar_state = 'disabled' %} +{% set btn_back = true %} + +{% block nav_client %} active {% endblock %} +{% block nav_client_move %} active {% endblock %} +{% block content %} + +{% set ip_list = form.ips.data.split(' ') %} +{% set ip_count = ip_list | length %} +<h1 class="m-5"> + {{ _('Move %(ip_count)d client(s)', ip_count=ip_count) }} +</h1> + +{{ macros.cmd_selected_clients(selected_clients) }} + +{{ wtf.quick_form(form, + method='post', + button_map={'submit': 'primary'}, + extra_classes="mx-5") }} + +{% endblock %} diff --git a/ogcp/templates/scopes.html b/ogcp/templates/scopes.html index 0dde6a6..a96ae62 100644 --- a/ogcp/templates/scopes.html +++ b/ogcp/templates/scopes.html @@ -26,6 +26,8 @@ form="scopesForm" formaction="{{ url_for('action_client_add') }}" formmethod="get"> <input class="btn btn-light dropdown-item {% block nav_client_update %}{% endblock %}" type="submit" value="{{ _('Edit client') }}" form="scopesForm" formaction="{{ url_for('action_client_update') }}" formmethod="get"> + <input class="btn btn-light dropdown-item {% block nav_client_move %}{% endblock %}" type="submit" value="{{ _('Move client') }}" + form="scopesForm" formaction="{{ url_for('action_client_move') }}" formmethod="get"> <input class="btn btn-light dropdown-item {% block nav_clients_import %}{% endblock %}" type="submit" value="{{ _('Import clients') }}" form="scopesForm" formaction="{{ url_for('action_clients_import_get') }}" formmethod="get"> <input class="btn btn-light dropdown-item {% block nav_client_delete %}{% endblock %}" type="submit" value="{{ _('Delete client') }}" diff --git a/ogcp/views.py b/ogcp/views.py index af65ddf..0133954 100644 --- a/ogcp/views.py +++ b/ogcp/views.py @@ -13,7 +13,8 @@ from ogcp.forms.action_forms import ( SessionForm, ImageRestoreForm, ImageCreateForm, SoftwareForm, BootModeForm, RoomForm, DeleteRoomForm, CenterForm, DeleteCenterForm, OgliveForm, GenericForm, SelectClientForm, ImageUpdateForm, ImportClientsForm, - ServerForm, DeleteRepositoryForm, RepoForm, FolderForm, CacheForm + ServerForm, DeleteRepositoryForm, RepoForm, FolderForm, CacheForm, + ClientMoveForm ) from flask_login import ( current_user, LoginManager, @@ -1574,6 +1575,66 @@ def action_client_add(): return render_template('actions/client_add.html', form=form, parent="scopes.html", scopes=scopes) +def build_client_move_choices(scopes, choices, path): + for scope in scopes.get('scope'): + new_path = f'{path}{scope.get("name")}/' + + if scope.get('type') == 'room': + choices.append((f'{scope["id"]} 0', new_path)) + + for room_child in scope.get('scope'): + if room_child.get('type') == 'folder': + choices.append( + (f'{scope["id"]} {room_child["id"]}', + f'{new_path}{room_child.get("name")}/') + ) + else: + build_client_move_choices(scope, choices, new_path) + +def get_client_move_choices(scopes): + choices = [] + build_client_move_choices(scopes, choices, '') + return choices + +@app.route('/action/client/move', methods=['GET', 'POST']) +@login_required +def action_client_move(): + form = ClientMoveForm(request.form) + if request.method == 'POST': + ips = form.ips.data.split(' ') + if not validate_elements(ips): + return redirect(url_for('scopes')) + + room_id, folder_id = form.scopes.data.split(' ') + + payload = {"clients": ips, + "room": int(room_id), + "folder_id": int(folder_id)} + server = get_server_from_clients(ips) + r = server.post('/client/move', payload) + if r.status_code != requests.codes.ok: + flash(_('ogServer: error moving client'), + category='error') + else: + flash(_('Client moved successfully'), + category='info') + return redirect(url_for('scopes')) + else: + ips = parse_elements(request.args.to_dict()) + form.ips.data = " ".join(ips) + + if not validate_elements(ips): + return redirect(url_for('scopes')) + + scopes, clients = get_scopes(set(ips)) + form.scopes.choices = get_client_move_choices(scopes) + selected_clients = list(get_selected_clients(scopes['scope']).items()) + + return render_template('actions/client_move.html', form=form, + selected_clients=selected_clients, + scopes=scopes) + + PLACEHOLDER_TEXT = '''host example1 { hardware ethernet 94:c6:91:a6:25:1a; fixed-address 10.141.10.100; } host example2 { hardware ethernet 94:c6:91:a6:25:1b; fixed-address 10.141.10.101; } host example3 { hardware ethernet 94:c6:91:a6:25:1c; fixed-address 10.141.10.102; } |