mirror of https://git.48k.eu/ogcp
ogcp: add support to run scripts in clients
Add view at /action/script/run to visualize the available scripts and run a single script file in the selected clients. Use shell/list to request the script list and shell/run API call to request the execution.master
parent
8bcd8fd7a4
commit
af8236b189
|
@ -147,6 +147,15 @@ class ClientMoveForm(FlaskForm):
|
|||
scopes = SelectField(label=_l('Scopes'), validate_choice=False)
|
||||
submit = SubmitField(label=_l('Submit'))
|
||||
|
||||
class RunScriptForm(FlaskForm):
|
||||
ips = HiddenField()
|
||||
script = SelectField(label=_l('Script'),
|
||||
choices=[],
|
||||
validators=[InputRequired()],
|
||||
validate_choice=False)
|
||||
arguments = StringField(label=_l('Arguments'))
|
||||
submit = SubmitField(label=_l('Submit'))
|
||||
|
||||
class ImportClientsForm(FlaskForm):
|
||||
server = HiddenField()
|
||||
room = SelectField(label=_l('Room'))
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
{% extends 'commands.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_script_run %} active {% endblock %}
|
||||
{% block content %}
|
||||
|
||||
{% set ip_list = form.ips.data.split(' ') %}
|
||||
{% set ip_count = ip_list | length %}
|
||||
<h1 class="m-5">
|
||||
{{ _('Run script for %(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 %}
|
|
@ -87,6 +87,15 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dropdown btn">
|
||||
<button class="btn btn-secondary btn-light dropdown-toggle{% block nav_script %}{% endblock %}" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-expanded="false">
|
||||
{{ _('Script') }}
|
||||
</button>
|
||||
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
|
||||
<input class="btn btn-light dropdown-item{% block nav_run_script %}{% endblock %}" type="submit" value="{{ _('Run') }}"
|
||||
form="scopesForm" formaction="{{ url_for('action_run_script') }}" formmethod="get">
|
||||
</div>
|
||||
|
||||
<div class="dropdown btn">
|
||||
<button class="btn btn-secondary btn-light dropdown-toggle{% block nav_logs %}{% endblock %}" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-expanded="false">
|
||||
Logs
|
||||
|
|
|
@ -14,7 +14,7 @@ from ogcp.forms.action_forms import (
|
|||
RoomForm, DeleteRoomForm, CenterForm, DeleteCenterForm, OgliveForm,
|
||||
GenericForm, SelectClientForm, ImageUpdateForm, ImportClientsForm,
|
||||
ServerForm, DeleteRepositoryForm, RepoForm, FolderForm, CacheForm,
|
||||
ClientMoveForm
|
||||
ClientMoveForm, RunScriptForm
|
||||
)
|
||||
from flask_login import (
|
||||
current_user, LoginManager,
|
||||
|
@ -1812,6 +1812,75 @@ def action_client_delete():
|
|||
else:
|
||||
return redirect(url_for('scopes'))
|
||||
|
||||
@app.route('/action/script/run', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def action_run_script():
|
||||
form = RunScriptForm(request.form)
|
||||
if request.method == 'POST':
|
||||
ips = form.ips.data.split(' ')
|
||||
if not validate_elements(ips):
|
||||
return redirect(url_for('commands'))
|
||||
|
||||
arguments = form.arguments.data.split(' ')
|
||||
cmd_elems = [form.script.data] + arguments
|
||||
|
||||
payload = {
|
||||
'clients': ips,
|
||||
'run': ';|\n\r'.join(cmd_elems),
|
||||
'echo': True
|
||||
}
|
||||
server = get_server_from_clients(ips)
|
||||
r = server.post('/shell/run', payload)
|
||||
|
||||
if not r:
|
||||
return ogserver_down('commands')
|
||||
if r.status_code != requests.codes.ok:
|
||||
return ogserver_error('commands')
|
||||
|
||||
flash(_('Script run sent successfully'), category='info')
|
||||
return redirect(url_for('commands'))
|
||||
else:
|
||||
ips = parse_elements(request.args.to_dict())
|
||||
form.ips.data = " ".join(ips)
|
||||
if not validate_elements(ips):
|
||||
return redirect(url_for('commands'))
|
||||
|
||||
server = get_server_from_clients(ips)
|
||||
different_setups = False
|
||||
reference_patitioning = None
|
||||
for ip in ips:
|
||||
r = server.get('/client/setup', payload={'client': [ip]})
|
||||
if not r:
|
||||
return ogserver_down('commands')
|
||||
if r.status_code != requests.codes.ok:
|
||||
return ogserver_error('commands')
|
||||
|
||||
partitions = r.json()['partitions'][1:]
|
||||
if not reference_patitioning:
|
||||
reference_patitioning = partitions
|
||||
elif reference_patitioning != partitions:
|
||||
different_setups = True
|
||||
|
||||
if different_setups:
|
||||
flash(_('Some clients don\'t have same configuration'), category='info')
|
||||
|
||||
r = server.get('/shell/list')
|
||||
if not r:
|
||||
return ogserver_down('commands')
|
||||
if r.status_code != requests.codes.ok:
|
||||
return ogserver_error('commands')
|
||||
|
||||
scripts = r.json()['scripts']
|
||||
|
||||
for script in scripts:
|
||||
form.script.choices.append((script, script))
|
||||
|
||||
scopes, clients = get_scopes(set(ips))
|
||||
selected_clients = list(get_selected_clients(scopes['scope']).items())
|
||||
return render_template('actions/script_run.html', form=form,
|
||||
selected_clients=selected_clients,
|
||||
scopes=scopes)
|
||||
|
||||
def get_clients_modes(ips, server):
|
||||
modes = {}
|
||||
for ip in ips:
|
||||
|
|
Loading…
Reference in New Issue