Flexible way to create, update, delete actions in a job
Job workflow now has a sortable list to select actions in order Change-Id: I67c624d3a45109e4328259fca7b42cb4fb2077f7
This commit is contained in:
parent
6ba4d85a3e
commit
a9e52f2ffe
|
@ -164,11 +164,21 @@ def job_create(request, context):
|
|||
job = create_dict_action(**context)
|
||||
client_id = job.pop('client_id', None)
|
||||
job['description'] = job.pop('description', None)
|
||||
actions = job.pop('job_actions', None)
|
||||
job.pop('clients', None)
|
||||
|
||||
schedule = {}
|
||||
if context['schedule_end_date']:
|
||||
schedule['schedule_end_date'] = context.pop('schedule_end_date')
|
||||
if context['schedule_interval']:
|
||||
schedule['schedule_interval'] = context.pop('schedule_interval')
|
||||
if context['schedule_start_date']:
|
||||
schedule['schedule_start_date'] = context.pop('schedule_start_date')
|
||||
|
||||
job.pop('clients', None)
|
||||
|
||||
job['job_schedule'] = schedule
|
||||
job['job_actions'] = []
|
||||
job['job_actions'] = actions
|
||||
job['client_id'] = client_id
|
||||
return _freezerclient(request).jobs.create(job)
|
||||
|
||||
|
@ -187,8 +197,11 @@ def job_edit(request, context):
|
|||
|
||||
job = create_dict_action(**context)
|
||||
job['description'] = job.pop('description', None)
|
||||
# job['client_id'] = job.pop('client_id', None)
|
||||
actions = job.pop('job_actions', None)
|
||||
job.pop('clients', None)
|
||||
|
||||
job['job_schedule'] = schedule
|
||||
job['job_actions'] = actions
|
||||
job_id = job.pop('original_name', None)
|
||||
return _freezerclient(request).jobs.update(job_id, job)
|
||||
|
||||
|
@ -256,6 +269,22 @@ def action_list(request):
|
|||
return actions
|
||||
|
||||
|
||||
def action_list_json(request):
|
||||
return _freezerclient(request).actions.list()
|
||||
|
||||
|
||||
def actions_in_job_json(request, job_id):
|
||||
job = _freezerclient(request).jobs.get(job_id)
|
||||
action_list = []
|
||||
for action in job['job_actions']:
|
||||
a = {
|
||||
"action_id": action['action_id'],
|
||||
"freezer_action": action['freezer_action']
|
||||
}
|
||||
action_list.append(a)
|
||||
return action_list
|
||||
|
||||
|
||||
def actions_in_job(request, job_id):
|
||||
job = _freezerclient(request).jobs.get(job_id)
|
||||
actions = []
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import functools
|
||||
|
||||
from django.http import HttpResponse
|
||||
from django.views import generic
|
||||
|
||||
import json
|
||||
from openstack_dashboard.api.rest import utils as rest_utils
|
||||
from openstack_dashboard.api.rest.utils import JSONResponse
|
||||
|
||||
|
@ -31,7 +32,34 @@ class Clients(generic.View):
|
|||
|
||||
# we don't have a "get all clients" api (probably for good reason) so
|
||||
# we need to resort to getting a very high number.
|
||||
clients = freezer_api.client_list(request, limit=9999)
|
||||
clients = freezer_api.client_list(request)
|
||||
clients = [c.get_dict() for c in clients]
|
||||
|
||||
return clients
|
||||
|
||||
|
||||
class Actions(generic.View):
|
||||
"""API for clients"""
|
||||
|
||||
@prevent_json_hijacking
|
||||
@rest_utils.ajax()
|
||||
def get(self, request):
|
||||
"""Get all registered freezer actions"""
|
||||
actions = freezer_api.action_list_json(request)
|
||||
actions = json.dumps(actions)
|
||||
return HttpResponse(actions,
|
||||
content_type="application/json")
|
||||
|
||||
|
||||
class ActionsInJob(generic.View):
|
||||
"""API for actions in a job"""
|
||||
|
||||
@prevent_json_hijacking
|
||||
@rest_utils.ajax()
|
||||
def get(self, request, job_id=None):
|
||||
"""Get all registered freezer actions"""
|
||||
actions = freezer_api.actions_in_job_json(request, job_id)
|
||||
actions = json.dumps(actions)
|
||||
return HttpResponse(actions,
|
||||
content_type="application/json")
|
||||
|
||||
|
|
|
@ -28,4 +28,7 @@ import rest_api
|
|||
urlpatterns = patterns(
|
||||
'',
|
||||
url(r'^api/clients$', rest_api.Clients.as_view(), name="api_clients"),
|
||||
url(r'^api/actions/$', rest_api.Actions.as_view(), name="api_actions"),
|
||||
url(r'^api/actions/job/(?P<job_id>[^/]+)?$',
|
||||
rest_api.ActionsInJob.as_view(), name="api_actions_in_job"),
|
||||
)
|
||||
|
|
|
@ -3,5 +3,43 @@
|
|||
{% block help_message %}
|
||||
{% endblock %}
|
||||
|
||||
<!-- Jquery code to hide freezer inputs -->
|
||||
<script type='text/javascript' src='{{ STATIC_URL }}freezer/js/freezer.jobs.actions.action.js'></script>
|
||||
<style>
|
||||
#sortable1, #sortable2 {
|
||||
position: relative;
|
||||
min-height: 100px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="sortable_lists row">
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">Available Actions</div>
|
||||
<div class="panel-body">
|
||||
<ul id="sortable1" class="connectedSortable list-group dark_stripe">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">Selected Actions In Order</div>
|
||||
<div class="panel-body">
|
||||
<ul id="sortable2" class="connectedSortable list-group dark_stripe">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="col-sm-6">
|
||||
{% include "horizon/common/_form_fields.html" %}
|
||||
{{ table.render }}
|
||||
</div>
|
||||
<div class="col-sm-12">
|
||||
{{ step.get_help_text }}
|
||||
</div>
|
||||
|
||||
<script type='text/javascript' src='{{ STATIC_URL }}freezer/js/freezer.jobs.sortable.js'></script>
|
|
@ -10,13 +10,30 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
import datetime
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from horizon import exceptions
|
||||
from horizon import forms
|
||||
from horizon import workflows
|
||||
|
||||
import horizon_web_ui.freezer_ui.api.api as freezer_api
|
||||
from horizon_web_ui.freezer_ui.utils import actions_in_job
|
||||
|
||||
|
||||
class ActionsConfigurationAction(workflows.Action):
|
||||
pass
|
||||
|
||||
class Meta(object):
|
||||
name = _("Actions")
|
||||
slug = "actions"
|
||||
help_text_template = "freezer_ui/jobs" \
|
||||
"/_actions.html"
|
||||
|
||||
class ActionsConfiguration(workflows.Step):
|
||||
action_class = ActionsConfigurationAction
|
||||
contributes = ('actions',)
|
||||
|
||||
|
||||
class ClientsConfigurationAction(workflows.MembershipAction):
|
||||
|
@ -133,6 +150,10 @@ class SchedulingConfiguration(workflows.Step):
|
|||
|
||||
|
||||
class InfoConfigurationAction(workflows.Action):
|
||||
actions = forms.CharField(
|
||||
widget=forms.HiddenInput(),
|
||||
required=False)
|
||||
|
||||
description = forms.CharField(
|
||||
label=_("Job Name"),
|
||||
help_text=_("Set a short description for this job"),
|
||||
|
@ -150,7 +171,8 @@ class InfoConfigurationAction(workflows.Action):
|
|||
class InfoConfiguration(workflows.Step):
|
||||
action_class = InfoConfigurationAction
|
||||
contributes = ('description',
|
||||
'original_name',)
|
||||
'original_name',
|
||||
'actions')
|
||||
|
||||
|
||||
class ConfigureJob(workflows.Workflow):
|
||||
|
@ -162,15 +184,49 @@ class ConfigureJob(workflows.Workflow):
|
|||
success_url = "horizon:freezer_ui:jobs:index"
|
||||
default_steps = (InfoConfiguration,
|
||||
ClientsConfiguration,
|
||||
SchedulingConfiguration)
|
||||
SchedulingConfiguration,
|
||||
ActionsConfiguration)
|
||||
|
||||
def handle(self, request, context):
|
||||
try:
|
||||
if context['original_name'] == '':
|
||||
|
||||
# for each action_id get the action object and append it
|
||||
# to context['job_actions']
|
||||
actions = actions_in_job(context.pop('actions', []))
|
||||
actions_for_job = []
|
||||
for action in actions:
|
||||
a = freezer_api.action_get(request, action)
|
||||
a = {
|
||||
'action_id': a['action_id'],
|
||||
'freezer_action': a['freezer_action']
|
||||
}
|
||||
actions_for_job.append(a)
|
||||
|
||||
context['job_actions'] = actions_for_job
|
||||
|
||||
for client in context['clients']:
|
||||
context['client_id'] = client
|
||||
freezer_api.job_create(request, context)
|
||||
else:
|
||||
actions = actions_in_job(context.pop('actions', []))
|
||||
actions_for_job = []
|
||||
|
||||
job_id = context['original_name']
|
||||
job = freezer_api.job_get(request, job_id)
|
||||
|
||||
del job[0].data_dict['job_actions']
|
||||
|
||||
for action in actions:
|
||||
a = freezer_api.action_get(request, action)
|
||||
a = {
|
||||
'action_id': a['action_id'],
|
||||
'freezer_action': a['freezer_action']
|
||||
}
|
||||
actions_for_job.append(a)
|
||||
|
||||
context['job_actions'] = actions_for_job
|
||||
|
||||
return freezer_api.job_edit(request, context)
|
||||
return True
|
||||
except Exception:
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
$(function() {
|
||||
$( "#sortable1, #sortable2" ).sortable({
|
||||
connectWith: ".connectedSortable"
|
||||
}).disableSelection();
|
||||
});
|
||||
|
||||
var parent = $(".sortable_lists").parent();
|
||||
parent.removeClass("col-sm-6");
|
||||
parent.addClass("col-sm-12");
|
||||
var siblings = parent.siblings();
|
||||
siblings.remove();
|
||||
|
||||
|
||||
$("form").submit(function(event){
|
||||
var ids = "";
|
||||
$("#sortable2 li").each(function(index) {
|
||||
ids += ($(this).attr('id'));
|
||||
ids += "==="
|
||||
});
|
||||
console.log(ids);
|
||||
$('#id_actions').val(ids);
|
||||
});
|
||||
|
||||
|
||||
function get_actions_url() {
|
||||
var url = $(location).attr("origin");
|
||||
url += '/freezer_ui/api/actions';
|
||||
return url
|
||||
}
|
||||
|
||||
var job_id = $('#id_original_name').val();
|
||||
if (job_id != "") {
|
||||
|
||||
var url_available = get_actions_url();
|
||||
|
||||
$.ajax({
|
||||
url: url_available,
|
||||
type: "GET",
|
||||
cache: false,
|
||||
dataType: 'json',
|
||||
contentType: 'application/json; charset=utf-8',
|
||||
success: function (data) {
|
||||
$.each(data, function (index, item) {
|
||||
$("#sortable1").append(
|
||||
"<li class='list-group-item' id=" + item['action_id'] + ">" +
|
||||
item['freezer_action']['backup_name'] +
|
||||
"</li>"
|
||||
);
|
||||
});
|
||||
},
|
||||
error: function (request, error) {
|
||||
console.error(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
else {
|
||||
var url = get_actions_url();
|
||||
|
||||
$.ajax({
|
||||
url: url,
|
||||
type: "GET",
|
||||
cache: false,
|
||||
dataType: 'json',
|
||||
contentType: 'application/json; charset=utf-8' ,
|
||||
success: function(data) {
|
||||
$.each(data, function(index, item) {
|
||||
$("#sortable1").append(
|
||||
"<li class='list-group-item' id=" + item['action_id'] + ">" +
|
||||
item['freezer_action']['backup_name'] +
|
||||
"</li>"
|
||||
);
|
||||
});
|
||||
},
|
||||
error: function(request, error) {
|
||||
console.error(error);
|
||||
}
|
||||
});
|
||||
}
|
|
@ -35,5 +35,11 @@ def create_dummy_id():
|
|||
This is needed when the scheduler creates jobs with actions attached
|
||||
directly, those actions are not registered in the db.
|
||||
"""
|
||||
|
||||
return uuid.uuid4().hex
|
||||
|
||||
|
||||
def actions_in_job(ids):
|
||||
"""Return an ordered list of actions for a new job
|
||||
"""
|
||||
ids = ids.split('===')
|
||||
return [i for i in ids if i]
|
||||
|
|
Loading…
Reference in New Issue