diff options
author | Javier Sánchez Parra <jsanchez@soleta.eu> | 2022-08-31 17:45:20 +0200 |
---|---|---|
committer | Javier Sánchez Parra <jsanchez@soleta.eu> | 2022-09-27 09:48:36 +0200 |
commit | 3459de36f35839e98e894ae3b58c4f4374d90913 (patch) | |
tree | 80136e41ad43c3500ee584a61181b58deaa7303b | |
parent | 07c5cb25d2281d2253729ecc7b7b40efdf6db140 (diff) |
Add Servers section
In Servers section/view, users can add or delete ogServers from ogCP
configuration file.
Replaces Repositories views and recycle some of its code.
-rw-r--r-- | ogcp/forms/action_forms.py | 6 | ||||
-rw-r--r-- | ogcp/templates/actions/add_server.html (renamed from ogcp/templates/actions/add_repository.html) | 8 | ||||
-rw-r--r-- | ogcp/templates/actions/delete_server.html (renamed from ogcp/templates/actions/delete_repository.html) | 6 | ||||
-rw-r--r-- | ogcp/templates/base.html | 4 | ||||
-rw-r--r-- | ogcp/templates/repositories.html | 37 | ||||
-rw-r--r-- | ogcp/templates/servers.html | 38 | ||||
-rw-r--r-- | ogcp/views.py | 171 |
7 files changed, 164 insertions, 106 deletions
diff --git a/ogcp/forms/action_forms.py b/ogcp/forms/action_forms.py index dcf4965..d1789a7 100644 --- a/ogcp/forms/action_forms.py +++ b/ogcp/forms/action_forms.py @@ -194,11 +194,15 @@ class ImageDetailsForm(FlaskForm): permissions = StringField(label=_l('Permissions')) software_id = StringField(label=_l('Software id')) -class RepositoryForm(FlaskForm): +class ServerForm(FlaskForm): name = StringField(label=_l('Name'), validators=[InputRequired()]) ip = StringField(label=_l('IP'), validators=[InputRequired()]) + port = StringField(label=_l('Port'), + validators=[InputRequired()]) + api_token = StringField(label=_l('API token'), + validators=[InputRequired()]) submit = SubmitField(label=_l('Submit')) class DeleteRepositoryForm(FlaskForm): diff --git a/ogcp/templates/actions/add_repository.html b/ogcp/templates/actions/add_server.html index e7c50fa..c86dcba 100644 --- a/ogcp/templates/actions/add_repository.html +++ b/ogcp/templates/actions/add_server.html @@ -1,16 +1,16 @@ -{% extends 'repositories.html' %} +{% extends 'servers.html' %} {% import "bootstrap/wtf.html" as wtf %} {% set sidebar_state = 'disabled' %} {% set btn_back = true %} -{% block nav_repository_add %}active{% endblock %} +{% block nav_server_add %}active{% endblock %} {% block content %} -<h1 class="m-5">{{_('Add a repository')}}</h1> +<h1 class="m-5">{{_('Add a server')}}</h1> {{ wtf.quick_form(form, - action=url_for('repository_add_post'), + action=url_for('server_add_post'), method='post', button_map={'submit_btn':'primary'}) }} diff --git a/ogcp/templates/actions/delete_repository.html b/ogcp/templates/actions/delete_server.html index 82177a3..8f9417e 100644 --- a/ogcp/templates/actions/delete_repository.html +++ b/ogcp/templates/actions/delete_server.html @@ -1,4 +1,4 @@ -{% extends 'repositories.html' %} +{% extends 'servers.html' %} {% import "bootstrap/wtf.html" as wtf %} {% set sidebar_state = 'disabled' %} @@ -9,11 +9,11 @@ {{ args }} <h1 class="m-5"> - {{ _('Delete repository %(repo_name)s', repo_name=repo_name) }} +{{ _('Delete server %(server_name)s', server_name=form.name.data) }} </h1> {{ wtf.quick_form(form, - action=url_for('repository_delete_post'), + action=url_for('server_delete_post'), method='post', button_map={'submit': 'primary'}, extra_classes="mx-5") }} diff --git a/ogcp/templates/base.html b/ogcp/templates/base.html index dca6fda..da5f1db 100644 --- a/ogcp/templates/base.html +++ b/ogcp/templates/base.html @@ -36,8 +36,8 @@ <li class="nav-item {% block nav_images%}{% endblock %}"> <a class="nav-link" href="{{ url_for('images') }}">{{ _('Images') }}</a> </li> - <li class="nav-item {% block nav_repositories %}{% endblock %}"> - <a class="nav-link" href="{{ url_for('repositories') }}">{{ _('Repositories') }}</a> + <li class="nav-item {% block nav_servers %}{% endblock %}"> + <a class="nav-link" href="{{ url_for('manage_servers') }}">{{ _('Servers') }}</a> </li> {% if current_user.admin %} <li class="nav-item {% block nav_users %}{% endblock %}"> diff --git a/ogcp/templates/repositories.html b/ogcp/templates/repositories.html deleted file mode 100644 index 7aa2d06..0000000 --- a/ogcp/templates/repositories.html +++ /dev/null @@ -1,37 +0,0 @@ -{% extends 'base.html' %} - -{% block nav_repositories %}active{% endblock %} - -{% block container %} - <form id="repositoriesForm"> - <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/> - </form> - {{ super() }} -</form> -{% endblock %} - -{% block sidebar %} - <ul id="repositories-list" class="nav flex-column nav-pills"> - {% for repository in repositories %} - <li id="repository-{{ repository['id'] }}" class="nav-item"> - <input class="form-check-input" type="checkbox" form="repositoriesForm" - value="{{ repository['id'] }}" - name="{{ repository['name'] }}" /> - {{ repository['name'] }} - </li> - {% endfor %} - </ul> -{% endblock %} - -{% block commands %} - <input class="btn btn-light {% block nav_repository_add %}{% endblock %}" type="submit" value="{{ _('Add repository') }}" - form="repositoriesForm" formaction="{{ url_for('repository_add_get') }}" formmethod="get"> - <input class="btn btn-light {% block nav_repository_delete %}{% endblock %}" type="submit" value="{{ _('Delete repository') }}" - form="repositoriesForm" formaction="{{ url_for('repository_delete_get') }}" formmethod="get"> - {% if btn_back %} - <button class="btn btn-danger ml-3" type="button" id="backButton" onclick="history.back()"> - {{ _("Back") }} - </button> - {% endif %} -{% endblock %} - diff --git a/ogcp/templates/servers.html b/ogcp/templates/servers.html new file mode 100644 index 0000000..05b7c18 --- /dev/null +++ b/ogcp/templates/servers.html @@ -0,0 +1,38 @@ +{% extends 'base.html' %} + +{% block nav_servers %}active{% endblock %} + +{% block container %} + <form id="serversForm"> + <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/> + </form> + {{ super() }} +</form> +{% endblock %} + +{% block sidebar %} + <ul id="servers-list" class="nav flex-column nav-pills"> + {% for server in servers %} + {% set server_str = server["ip"] ~ ":" ~ server["port"] %} + <li class="nav-item"> + <input class="form-check-input" type="checkbox" form="serversForm" + value="{{ server_str }}" + name="selected-server" /> + {{ server["name"] }} + </li> + {% endfor %} + </ul> +{% endblock %} + +{% block commands %} + <input class="btn btn-light {% block nav_server_add %}{% endblock %}" type="submit" value="{{ _('Add server') }}" + form="serversForm" formaction="{{ url_for('server_add_get') }}" formmethod="get"> + <input class="btn btn-light {% block nav_server_delete %}{% endblock %}" type="submit" value="{{ _('Delete server') }}" + form="serversForm" formaction="{{ url_for('server_delete_get') }}" formmethod="get"> + {% if btn_back %} + <button class="btn btn-danger ml-3" type="button" id="backButton" onclick="history.back()"> + {{ _("Back") }} + </button> + {% endif %} +{% endblock %} + diff --git a/ogcp/views.py b/ogcp/views.py index 9641ed0..16b4fba 100644 --- a/ogcp/views.py +++ b/ogcp/views.py @@ -13,7 +13,7 @@ from ogcp.forms.action_forms import ( SessionForm, ImageRestoreForm, ImageCreateForm, SoftwareForm, BootModeForm, RoomForm, DeleteRoomForm, CenterForm, DeleteCenterForm, OgliveForm, GenericForm, SelectClientForm, ImageUpdateForm, ImportClientsForm, - RepositoryForm, DeleteRepositoryForm + ServerForm, DeleteRepositoryForm ) from flask_login import ( current_user, LoginManager, @@ -25,7 +25,7 @@ from pathlib import Path from ogcp.models import User from ogcp.forms.auth import LoginForm, UserForm, DeleteUserForm -from ogcp.og_server import servers +from ogcp.og_server import OGServer, servers from flask_babel import lazy_gettext as _l from flask_babel import _ from ogcp import app, ogcp_cfg_path @@ -143,8 +143,8 @@ def get_repository(repository_id): def get_repositories(): - r = g.server.get('/repositories') - repositories = r.json()['repositories'] + r = g.server.get('/servers') + repositories = r.json()['servers'] return repositories @@ -1382,73 +1382,76 @@ def images(): return render_template('images.html', responses=responses) -@app.route('/repositories/', methods=['GET']) +@app.route('/servers/', methods=['GET']) @login_required -def repositories(): - r = g.server.get('/repositories') - repositories = r.json()['repositories'] - return render_template('repositories.html', repositories=repositories) +def manage_servers(): + return render_template('servers.html', servers=servers) -@app.route('/repositories/add', methods=['GET']) +@app.route('/server/add', methods=['GET']) @login_required -def repository_add_get(): - form = RepositoryForm() - r = g.server.get('/repositories') - repositories = r.json()['repositories'] - return render_template('actions/add_repository.html', form=form, - repositories=repositories) +def server_add_get(): + form = ServerForm() + return render_template('actions/add_server.html', form=form, + servers=servers) -@app.route('/repositories/add', methods=['POST']) +@app.route('/server/add', methods=['POST']) @login_required -def repository_add_post(): - form = RepositoryForm(request.form) +def server_add_post(): + form = ServerForm(request.form) if not form.validate(): flash(form.errors, category='error') - return redirect(url_for('repositories')) - - payload = {"name": form.name.data, - "ip": form.ip.data} - r = g.server.post('/repository/add', payload) - if r.status_code != requests.codes.ok: - flash(_('ogServer: error adding the repository'), category='error') - else: - flash(_('Repository added successfully'), category='info') - return redirect(url_for("repositories")) + return redirect(url_for('servers')) + ip_port_str = form.ip.data + ":" + form.port.data + try: + get_server_from_ip_port(ip_port_str) + flash(_('Server {} already exists').format(ip_port_str), + category='error') + return redirect(url_for('manage_servers')) + except Exception: + return save_server(form) -@app.route('/repositories/delete', methods=['GET']) +@app.route('/server/delete', methods=['GET']) @login_required -def repository_delete_get(): - form = GenericForm() - repositories = get_repositories() - selected_repo = [(name, repo_id) for name, repo_id in - request.args.to_dict().items() if name != "csrf_token"] - if not validate_elements(selected_repo, max_len=1): - flash(_('Please select one repository to delete'), category='error') - return redirect(url_for('repositories')) - repo_name, repo_id = selected_repo[0] - form.ids.data = repo_id - return render_template('actions/delete_repository.html', form=form, - repo_name=repo_name, repositories=repositories) - - -@app.route('/repositories/delete', methods=['POST']) +def server_delete_get(): + params = request.args.to_dict() + try: + selected_server = get_server_from_ip_port(params['selected-server']) + except KeyError: + flash(_('Please, select one server'), category='error') + return redirect(url_for('manage_servers')) + + form = ServerForm() + form.name.data = selected_server.name + form.name.render_kw = {'readonly': True} + form.ip.data = selected_server.ip + form.ip.render_kw = {'readonly': True} + form.port.data = selected_server.port + form.port.render_kw = {'readonly': True} + form.api_token.data = selected_server.api_token + form.api_token.render_kw = {'readonly': True} + return render_template('actions/delete_server.html', form=form, + servers=servers) + + +@app.route('/server/delete', methods=['POST']) @login_required -def repository_delete_post(): - form = GenericForm(request.form) - ids = form.ids.data.split(' ') - if not validate_elements(ids, max_len=1): - return redirect(url_for('repositories')) - repo_id = ids.pop() - payload = {'id': repo_id} - r = g.server.post('/repository/delete', payload) - if r.status_code != requests.codes.ok: - flash(_('OgServer: error deleting repository'), category='error') - else: - flash(_('Repository deleted successfully'), category='info') - return redirect(url_for('repositories')) +def server_delete_post(): + form = ServerForm(request.form) + if not form.validate(): + flash(form.errors, category='error') + return redirect(url_for('manage_servers')) + + ip_port_str = form.ip.data + ":" + form.port.data + try: + server = get_server_from_ip_port(ip_port_str) + return delete_server(server) + except Exception: + flash(_('Server {} do not exists').format(ip_port_str), + category='error') + return redirect(url_for('manage_servers')) @app.route('/users/', methods=['GET']) @@ -1467,8 +1470,58 @@ def get_available_scopes(): return centers + rooms +def save_server(form): + server_dict = { + 'NAME': form.name.data, + 'IP': form.ip.data, + 'PORT': int(form.port.data), + 'API_TOKEN': form.api_token.data, + } + server_obj = OGServer(form.name.data, + form.ip.data, + int(form.port.data), + form.api_token.data) + + filename = os.path.join(app.root_path, ogcp_cfg_path) + with open(filename, 'r+') as file: + config = json.load(file) + + config['SERVERS'].append(server_dict) + + file.seek(0) + json.dump(config, file, indent='\t') + file.truncate() + + servers.append(server_obj) + + return redirect(url_for('manage_servers')) + + +def delete_server(server): + server_dict = { + 'NAME': server.name, + 'IP': server.ip, + 'PORT': int(server.port), + 'API_TOKEN': server.api_token, + } + + filename = os.path.join(app.root_path, ogcp_cfg_path) + with open(filename, 'r+') as file: + config = json.load(file) + + config['SERVERS'].remove(server_dict) + + file.seek(0) + json.dump(config, file, indent='\t') + file.truncate() + + servers.remove(server) + + return redirect(url_for('manage_servers')) + + def save_user(form): - username = form.username.data + username = form.username.datk pwd_hash = hash_password(form.pwd.data) pwd_hash_confirm = hash_password(form.pwd_confirm.data) |