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.
async-tree
Javier Sánchez Parra 2022-08-31 17:45:20 +02:00
parent 07c5cb25d2
commit 3459de36f3
7 changed files with 162 additions and 104 deletions

View File

@ -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):

View File

@ -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'}) }}

View File

@ -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") }}

View File

@ -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 %}">

View File

@ -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 %}

View File

@ -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 %}

View File

@ -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)
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('/repositories/delete', methods=['POST'])
@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)