ogcp: add server ip configuration

Enable server view in the main toolbar.

Hide Add server and Delete server buttons.

Add Update server button.

Add server/update view to edit the server addresses.
master
Alejandro Sirgo Rica 2024-09-03 12:45:49 +02:00
parent c1ac88e47c
commit 7613cd8017
6 changed files with 180 additions and 6 deletions

View File

@ -276,6 +276,14 @@ class ServerForm(FlaskForm):
validators=[InputRequired()])
submit = SubmitField(label=_l('Submit'))
class ServerConfigurationForm(FlaskForm):
server_addr = HiddenField()
addr = FieldList(
StringField(label=_l('Address')),
label=_l('Addresses'),
)
submit = SubmitField(label=_l('Submit'))
class DeleteRepositoryForm(FlaskForm):
repository = SelectField(label=_l('Repository'),
validators=[InputRequired()])

View File

@ -37,6 +37,12 @@ class OGServer:
json=payload)
return r
def delete(self, path, payload):
r = requests.delete(f'{self.URL}{path}',
headers=self.HEADERS,
json=payload)
return r
@property
def id(self):
ip = self.ip.replace('.', '-')

View File

@ -0,0 +1,69 @@
{% extends 'servers.html' %}
{% import "bootstrap/wtf.html" as wtf %}
{% set sidebar_state = 'disabled' %}
{% set btn_back = true %}
{% block nav_server_add %}active{% endblock %}
{% block content %}
<h2 class="mx-5 subhead-heading">{{_('Update server')}}</h2>
<form class="form mx-5" method="POST">
{{ form.hidden_tag() }}
{{ form.server_addr() }}
<div class="form-group">
<div id="ip-fields">
{% for addr in form.addr %}
<div class="d-flex align-items-center mb-2">
{{ addr(class="form-control me-2", placeholder=_("Enter IP Address"), required=True) }}
<button type="button" class="btn btn-danger" onclick="removeIPField(this)">{{_('Remove') }}</button>
</div>
{% endfor %}
</div>
<button type="button" class="btn btn-primary" onclick="addIPField()">{{_('Add address') }}</button>
{{ form.submit(class="btn btn-success") }}
</div>
</form>
<script>
function addIPField() {
const container = document.createElement('div');
container.classList.add('d-flex', 'align-items-center', 'mb-2');
const newField = document.createElement('input');
newField.setAttribute('type', 'text');
newField.setAttribute('name', 'addr-' + document.querySelectorAll('input[name^="addr-"]').length);
newField.classList.add('form-control', 'me-2');
newField.setAttribute('placeholder', '{{ _('Enter IP Address') }}');
newField.required = true;
const removeButton = document.createElement('button');
removeButton.setAttribute('type', 'button');
removeButton.classList.add('btn', 'btn-danger');
removeButton.innerText = '{{ _('Remove') }}';
removeButton.onclick = function() {
removeIPField(this);
};
container.appendChild(newField);
container.appendChild(removeButton);
document.getElementById('ip-fields').appendChild(container);
}
function removeIPField(elem) {
const ipFieldsContainer = document.getElementById('ip-fields');
const ipFieldDivs = ipFieldsContainer.querySelectorAll('.d-flex');
if (ipFieldDivs.length <= 1) {
return;
}
const parentDiv = elem.parentElement;
parentDiv.remove();
}
</script>
{% endblock %}

View File

@ -40,6 +40,9 @@
<a class="nav-link" href="{{ url_for('manage_repos') }}">{{ _('Repos') }}</a>
</li>
{% if current_user.admin %}
<li class="nav-item {% block nav_servers %}{% endblock %}">
<a class="nav-link" href="{{ url_for('manage_servers') }}">{{ _('Servers') }}</a>
</li>
<li class="nav-item {% block nav_users %}{% endblock %}">
<a class="nav-link" href="{{ url_for('users') }}">{{ _('Users') }}</a>
</li>

View File

@ -17,7 +17,8 @@
<li class="nav-item">
<input class="form-check-input" type="checkbox" form="serversForm"
value="{{ server_str }}"
name="selected-server" />
name="selected-server"
{% if loop.index == 1 %}checked{% endif %} />
{{ server["name"] }}
</li>
{% endfor %}
@ -26,10 +27,8 @@
{% block commands %}
{% if current_user.is_authenticated %}
<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">
<input class="btn btn-light {% block nav_server_update %}{% endblock %}" type="submit" value="{{ _('Update server') }}"
form="serversForm" formaction="{{ url_for('server_update_get') }}" formmethod="get">
{% if btn_back %}
<button class="btn btn-danger ml-3" type="button" id="backButton" onclick="history.back()">
{{ _("Back") }}

View File

@ -14,7 +14,8 @@ from ogcp.forms.action_forms import (
RoomForm, DeleteRoomForm, CenterForm, DeleteCenterForm, OgliveForm,
GenericForm, SelectClientForm, ImageUpdateForm, ImportClientsForm,
ServerForm, DeleteRepositoryForm, RepoForm, FolderForm, CacheForm,
ClientMoveForm, RunScriptForm, ImageConfigForm, ImageFetchForm
ClientMoveForm, RunScriptForm, ImageConfigForm, ImageFetchForm,
ServerConfigurationForm
)
from flask_login import (
current_user, LoginManager,
@ -3278,6 +3279,94 @@ def manage_servers():
return render_template('servers.html', servers=servers)
@app.route('/server/update', methods=['GET'])
@login_required
def server_update_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'))
r = selected_server.get('/server')
if not r:
return ogserver_down('manage_servers')
if r.status_code != requests.codes.ok:
return ogserver_error('manage_servers')
form = ServerConfigurationForm()
server_config = r.json()['servers']
for c in server_config:
form.addr.append_entry(c['address'])
form.server_addr.data = selected_server.ip + ":" + str(selected_server.port)
return render_template('actions/server_update.html', form=form,
servers=servers)
@app.route('/server/update', methods=['POST'])
@login_required
def server_update_post():
form = ServerConfigurationForm(request.form)
try:
server = get_server_from_ip_port(form.server_addr.data)
except Exception:
flash(_('Server {} does not exist').format(form.server_addr.data),
category='error')
return redirect(url_for('manage_servers'))
addr_list = [ip.data.strip() for ip in form.addr]
invalid_ips = []
for ip in addr_list:
if not is_valid_ip(ip):
invalid_ips.append('"' + ip + '"')
if invalid_ips:
flash(_(f'The following addresses are invalid: {" ".join(invalid_ips)}'), category='error')
return redirect(url_for('manage_servers'))
r = server.get('/server')
if not r:
return ogserver_down('manage_servers')
if r.status_code != requests.codes.ok:
return ogserver_error('manage_servers')
server_config = r.json()['servers']
# Remove
for c in server_config:
if c['address'] in addr_list:
continue
payload = {'id': c['id']}
rd = server.delete('/server', payload=payload)
if not rd:
return ogserver_down('manage_servers')
if rd.status_code != requests.codes.ok:
return ogserver_error('manage_servers')
# Add
for ip in addr_list:
found = False
for c in server_config:
if ip == c['address']:
found = True
break
if found:
continue
payload = {'address': ip}
ra = server.post('/server', payload=payload)
if not ra:
return ogserver_down('manage_servers')
if ra.status_code != requests.codes.ok:
return ogserver_error('manage_servers')
flash(_('Server update request sent successfully'), category='info')
return redirect(url_for('manage_servers'))
@app.route('/server/add', methods=['GET'])
@login_required
def server_add_get():