summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJavier Sánchez Parra <jsanchez@soleta.eu>2022-08-31 17:45:20 +0200
committerJavier Sánchez Parra <jsanchez@soleta.eu>2022-09-07 17:49:15 +0200
commitcf02e0c051e664cdfd77162fac3a7c8302620324 (patch)
tree494e05e3c118848770ae40beb9a8b11e001ec5f1
parent7039b2942611f605f610888e6c7970135f4b67e4 (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.py6
-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.html4
-rw-r--r--ogcp/templates/repositories.html37
-rw-r--r--ogcp/templates/servers.html38
-rw-r--r--ogcp/views.py171
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)