Horizon implementation for sessions endpoint
Implements: blueprint freezer-api-web-ui Change-Id: I2ff6b4bb77f50c98bb96fb812c67a391f7410789
This commit is contained in:
parent
206a0ec9b7
commit
e5ec8452a8
|
@ -1 +0,0 @@
|
||||||
__author__ = 'jonas'
|
|
|
@ -90,6 +90,18 @@ class ActionJob(object):
|
||||||
self.backup_name = backup_name
|
self.backup_name = backup_name
|
||||||
|
|
||||||
|
|
||||||
|
class Session(object):
|
||||||
|
def __init__(self, session_id, description, status, jobs,
|
||||||
|
start_datetime, interval, end_datetime):
|
||||||
|
self.session_id = session_id
|
||||||
|
self.description = description
|
||||||
|
self.status = status
|
||||||
|
self.jobs = jobs
|
||||||
|
self.start_datetime = start_datetime
|
||||||
|
self.interval = interval
|
||||||
|
self.end_datetime = end_datetime
|
||||||
|
|
||||||
|
|
||||||
@memoized
|
@memoized
|
||||||
def get_service_url(request):
|
def get_service_url(request):
|
||||||
""" Get Freezer API url from keystone catalog.
|
""" Get Freezer API url from keystone catalog.
|
||||||
|
@ -263,3 +275,74 @@ def client_list(request):
|
||||||
clients = _freezerclient(request).registration.list()
|
clients = _freezerclient(request).registration.list()
|
||||||
clients = [Client(client) for client in clients]
|
clients = [Client(client) for client in clients]
|
||||||
return clients
|
return clients
|
||||||
|
|
||||||
|
|
||||||
|
def add_job_to_session(request, session_id, job_id):
|
||||||
|
"""This function will add a job to a session and the API will handle the
|
||||||
|
copy of job information to the session """
|
||||||
|
return _freezerclient(request).sessions.add_job(session_id, job_id)
|
||||||
|
|
||||||
|
|
||||||
|
def remove_job_from_session(request, session_id, job_id):
|
||||||
|
"""Remove a job from a session will delete the job information but not the
|
||||||
|
job itself """
|
||||||
|
return _freezerclient(request).sessions.remove_job(session_id, job_id)
|
||||||
|
|
||||||
|
|
||||||
|
def session_create(request, context):
|
||||||
|
"""A session is a group of jobs who share the same scheduling time. """
|
||||||
|
session = create_dict_action(**context)
|
||||||
|
session['description'] = session.pop('description', None)
|
||||||
|
schedule = {
|
||||||
|
'end_datetime': session.pop('end_datetime', None),
|
||||||
|
'interval': session.pop('interval', None),
|
||||||
|
'start_datetime': session.pop('start_datetime', None),
|
||||||
|
}
|
||||||
|
session['schedule'] = schedule
|
||||||
|
return _freezerclient(request).sessions.create(session)
|
||||||
|
|
||||||
|
|
||||||
|
def session_update(request, context):
|
||||||
|
"""Update session information """
|
||||||
|
session = create_dict_action(**context)
|
||||||
|
session_id = session.pop('session_id', None)
|
||||||
|
session['description'] = session.pop('description', None)
|
||||||
|
schedule = {
|
||||||
|
'end_datetime': session.pop('end_datetime', None),
|
||||||
|
'interval': session.pop('interval', None),
|
||||||
|
'start_datetime': session.pop('start_datetime', None),
|
||||||
|
}
|
||||||
|
session['schedule'] = schedule
|
||||||
|
return _freezerclient(request).sessions.update(session_id, session)
|
||||||
|
|
||||||
|
|
||||||
|
def session_delete(request, session_id):
|
||||||
|
"""Delete session from API """
|
||||||
|
return _freezerclient(request).sessions.delete(session_id)
|
||||||
|
|
||||||
|
|
||||||
|
def session_list(request):
|
||||||
|
"""List all sessions """
|
||||||
|
sessions = _freezerclient(request).sessions.list_all()
|
||||||
|
sessions = [Session(s['session_id'],
|
||||||
|
s['description'],
|
||||||
|
s['status'],
|
||||||
|
s['jobs'],
|
||||||
|
s['schedule']['start_datetime'],
|
||||||
|
s['schedule']['interval'],
|
||||||
|
s['schedule']['end_datetime'])
|
||||||
|
for s in sessions]
|
||||||
|
return sessions
|
||||||
|
|
||||||
|
|
||||||
|
def session_get(request, session_id):
|
||||||
|
"""Get a single session """
|
||||||
|
session = _freezerclient(request).sessions.get(session_id)
|
||||||
|
session = Session(session['session_id'],
|
||||||
|
session['description'],
|
||||||
|
session['status'],
|
||||||
|
session['jobs'],
|
||||||
|
session['schedule']['start_datetime'],
|
||||||
|
session['schedule']['interval'],
|
||||||
|
session['schedule']['end_datetime'])
|
||||||
|
return session
|
||||||
|
|
|
@ -18,7 +18,7 @@ import horizon
|
||||||
class FreezerDR(horizon.PanelGroup):
|
class FreezerDR(horizon.PanelGroup):
|
||||||
slug = "freezerdr"
|
slug = "freezerdr"
|
||||||
name = _("Backup and Restore")
|
name = _("Backup and Restore")
|
||||||
panels = ('jobs',)
|
panels = ('jobs', 'sessions')
|
||||||
|
|
||||||
|
|
||||||
class Freezer(horizon.Dashboard):
|
class Freezer(horizon.Dashboard):
|
||||||
|
|
|
@ -47,6 +47,20 @@ def format_last_backup(last_backup):
|
||||||
'en="true"></span> {}</span>'.format(colour, icon, text))
|
'en="true"></span> {}</span>'.format(colour, icon, text))
|
||||||
|
|
||||||
|
|
||||||
|
class AttachJobToSession(tables.LinkAction):
|
||||||
|
name = "attach_job_to_session"
|
||||||
|
verbose_name = _("Attach To Session")
|
||||||
|
classes = ("ajax-modal")
|
||||||
|
url = "horizon:freezer_ui:sessions:attach"
|
||||||
|
|
||||||
|
def allowed(self, request, instance):
|
||||||
|
return True
|
||||||
|
|
||||||
|
def get_link_url(self, datum):
|
||||||
|
return reverse("horizon:freezer_ui:sessions:attach",
|
||||||
|
kwargs={'job_id': datum.job_id})
|
||||||
|
|
||||||
|
|
||||||
class Restore(tables.Action):
|
class Restore(tables.Action):
|
||||||
name = "restore"
|
name = "restore"
|
||||||
verbose_name = _("Restore")
|
verbose_name = _("Restore")
|
||||||
|
@ -149,6 +163,7 @@ class JobsTable(tables.DataTable):
|
||||||
multi_select = False
|
multi_select = False
|
||||||
row_actions = (CreateAction,
|
row_actions = (CreateAction,
|
||||||
EditJob,
|
EditJob,
|
||||||
|
AttachJobToSession,
|
||||||
CloneJob,
|
CloneJob,
|
||||||
DeleteJob,)
|
DeleteJob,)
|
||||||
|
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
{% load i18n horizon humanize %}
|
|
||||||
|
|
||||||
{% block help_message %}
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
<!-- Jquery code to hide freezer inputs -->
|
|
||||||
<script type='text/javascript' src='{{ STATIC_URL }}freezer/js/freezer.actions.snapshot.js'></script>
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
# Copyright 2012 Nebula, Inc.
|
||||||
|
# Copyright 2015 Hewlett-Packard
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
from horizon import browsers
|
||||||
|
from horizon_web_ui.freezer_ui.sessions import tables
|
||||||
|
|
||||||
|
|
||||||
|
class SessionBrowser(browsers.ResourceBrowser):
|
||||||
|
name = "session_configuration"
|
||||||
|
verbose_name = _("Session Configuration")
|
||||||
|
navigation_table_class = tables.SessionsTable
|
||||||
|
content_table_class = tables.JobsTable
|
||||||
|
navigable_item_name = _("Sessions")
|
||||||
|
navigation_kwarg_name = "session_id"
|
|
@ -0,0 +1,24 @@
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
import horizon
|
||||||
|
from horizon_web_ui.freezer_ui import dashboard
|
||||||
|
|
||||||
|
|
||||||
|
class SessionsPanel(horizon.Panel):
|
||||||
|
name = _("Sessions")
|
||||||
|
slug = "sessions"
|
||||||
|
|
||||||
|
|
||||||
|
dashboard.Freezer.register(SessionsPanel)
|
|
@ -0,0 +1,154 @@
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
import datetime
|
||||||
|
from django import shortcuts
|
||||||
|
from django.utils import safestring
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
from django.utils.translation import ungettext_lazy
|
||||||
|
|
||||||
|
from horizon import messages
|
||||||
|
from horizon import tables
|
||||||
|
from horizon.utils.urlresolvers import reverse
|
||||||
|
|
||||||
|
import horizon_web_ui.freezer_ui.api.api as freezer_api
|
||||||
|
from horizon_web_ui.freezer_ui.django_utils import timestamp_to_string
|
||||||
|
|
||||||
|
|
||||||
|
def get_link(session):
|
||||||
|
return reverse('horizon:freezer_ui:sessions:index',
|
||||||
|
kwargs={'session_id': session.session_id})
|
||||||
|
|
||||||
|
|
||||||
|
class CreateJob(tables.LinkAction):
|
||||||
|
name = "create_session"
|
||||||
|
verbose_name = _("Create Session")
|
||||||
|
url = "horizon:freezer_ui:sessions:create"
|
||||||
|
classes = ("ajax-modal",)
|
||||||
|
icon = "plus"
|
||||||
|
|
||||||
|
|
||||||
|
class DeleteSession(tables.DeleteAction):
|
||||||
|
name = "delete"
|
||||||
|
classes = ("btn-danger",)
|
||||||
|
icon = "remove"
|
||||||
|
help_text = _("Delete sessions is not recoverable.")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def action_present(count):
|
||||||
|
return ungettext_lazy(
|
||||||
|
u"Delete Session",
|
||||||
|
u"Delete Sessions",
|
||||||
|
count
|
||||||
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def action_past(count):
|
||||||
|
return ungettext_lazy(
|
||||||
|
u"Deleted Session",
|
||||||
|
u"Deleted Sessions",
|
||||||
|
count
|
||||||
|
)
|
||||||
|
|
||||||
|
def delete(self, request, session_id):
|
||||||
|
return freezer_api.session_delete(request, session_id)
|
||||||
|
|
||||||
|
|
||||||
|
class EditSession(tables.LinkAction):
|
||||||
|
name = "edit_session"
|
||||||
|
verbose_name = _("Edit Session")
|
||||||
|
classes = ("ajax-modal",)
|
||||||
|
icon = "pencil"
|
||||||
|
|
||||||
|
def get_link_url(self, datum=None):
|
||||||
|
return reverse("horizon:freezer_ui:sessions:edit",
|
||||||
|
kwargs={'session_id': datum.session_id})
|
||||||
|
|
||||||
|
|
||||||
|
class DeleteMultipleActions(DeleteSession):
|
||||||
|
name = "delete_multiple_actions"
|
||||||
|
|
||||||
|
|
||||||
|
class DeleteJobFromSession(tables.DeleteAction):
|
||||||
|
name = "delete_job_from_session"
|
||||||
|
classes = ("btn-danger",)
|
||||||
|
icon = "remove"
|
||||||
|
help_text = _("Delete jobs is not recoverable.")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def action_present(count):
|
||||||
|
return ungettext_lazy(
|
||||||
|
u"Delete Job",
|
||||||
|
u"Delete Jobs",
|
||||||
|
count
|
||||||
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def action_past(count):
|
||||||
|
return ungettext_lazy(
|
||||||
|
u"Deleted Job",
|
||||||
|
u"Deleted Jobs",
|
||||||
|
count
|
||||||
|
)
|
||||||
|
|
||||||
|
def delete(self, request, session):
|
||||||
|
job_id, session_id = session.split('===')
|
||||||
|
return freezer_api.remove_job_from_session(
|
||||||
|
request,
|
||||||
|
session_id,
|
||||||
|
job_id)
|
||||||
|
|
||||||
|
|
||||||
|
class JobsTable(tables.DataTable):
|
||||||
|
client_id = tables.Column(
|
||||||
|
'client_id',
|
||||||
|
verbose_name=_("Client ID"))
|
||||||
|
|
||||||
|
status = tables.Column(
|
||||||
|
'status',
|
||||||
|
verbose_name=_("Status"))
|
||||||
|
|
||||||
|
def get_object_id(self, job):
|
||||||
|
# this is used to pass to values as an url
|
||||||
|
# TODO: look for a way to improve this
|
||||||
|
ids = '{0}==={1}'.format(job.job_id, job.session_id)
|
||||||
|
return ids
|
||||||
|
|
||||||
|
class Meta(object):
|
||||||
|
name = "jobs"
|
||||||
|
verbose_name = _("Jobs")
|
||||||
|
table_actions = ()
|
||||||
|
row_actions = (DeleteJobFromSession,)
|
||||||
|
footer = False
|
||||||
|
multi_select = True
|
||||||
|
|
||||||
|
|
||||||
|
class SessionsTable(tables.DataTable):
|
||||||
|
description = tables.Column('description',
|
||||||
|
link=get_link,
|
||||||
|
verbose_name=_("Session"))
|
||||||
|
|
||||||
|
status = tables.Column('status',
|
||||||
|
verbose_name=_("Status"))
|
||||||
|
|
||||||
|
def get_object_id(self, session):
|
||||||
|
return session.session_id
|
||||||
|
|
||||||
|
class Meta(object):
|
||||||
|
name = "sessions"
|
||||||
|
verbose_name = _("Sessions")
|
||||||
|
table_actions = (CreateJob,
|
||||||
|
DeleteMultipleActions)
|
||||||
|
row_actions = (EditSession,
|
||||||
|
DeleteSession,)
|
||||||
|
footer = False
|
||||||
|
multi_select = True
|
|
@ -0,0 +1,11 @@
|
||||||
|
{% extends 'base.html' %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% block title %}{% trans "Session Configurations" %}{% endblock %}
|
||||||
|
|
||||||
|
{% block page_header %}
|
||||||
|
{% include "horizon/common/_page_header.html" with title=_("Session Configurations") %}
|
||||||
|
{% endblock page_header %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
{{ session_configuration_browser.render }}
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,38 @@
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
from django.conf.urls import patterns
|
||||||
|
from django.conf.urls import url
|
||||||
|
|
||||||
|
from horizon_web_ui.freezer_ui.sessions import views
|
||||||
|
|
||||||
|
|
||||||
|
urlpatterns = patterns(
|
||||||
|
'',
|
||||||
|
|
||||||
|
url(r'^(?P<session_id>[^/]+)?$',
|
||||||
|
views.SessionsView.as_view(),
|
||||||
|
name='index'),
|
||||||
|
|
||||||
|
url(r'^attach_to_session/(?P<job_id>[^/]+)?$',
|
||||||
|
views.AttachToSessionWorkflow.as_view(),
|
||||||
|
name='attach'),
|
||||||
|
|
||||||
|
url(r'^create/$',
|
||||||
|
views.CreateSessionWorkflow.as_view(),
|
||||||
|
name='create'),
|
||||||
|
|
||||||
|
url(r'^edit/(?P<session_id>[^/]+)?$',
|
||||||
|
views.CreateSessionWorkflow.as_view(),
|
||||||
|
name='edit'),
|
||||||
|
|
||||||
|
)
|
|
@ -0,0 +1,114 @@
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed `under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
|
||||||
|
from django.core.urlresolvers import reverse
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
from horizon import browsers
|
||||||
|
from horizon import exceptions
|
||||||
|
from horizon import workflows
|
||||||
|
|
||||||
|
import horizon_web_ui.freezer_ui.sessions.browsers as project_browsers
|
||||||
|
from horizon_web_ui.freezer_ui.sessions.workflows import attach
|
||||||
|
from horizon_web_ui.freezer_ui.sessions.workflows import create_session
|
||||||
|
import horizon_web_ui.freezer_ui.api.api as freezer_api
|
||||||
|
from horizon_web_ui.freezer_ui.utils import SessionJob
|
||||||
|
|
||||||
|
|
||||||
|
class AttachToSessionWorkflow(workflows.WorkflowView):
|
||||||
|
workflow_class = attach.AttachJobToSession
|
||||||
|
|
||||||
|
def get_object(self, *args, **kwargs):
|
||||||
|
job_id = self.kwargs['job_id']
|
||||||
|
try:
|
||||||
|
return freezer_api.job_get(self.request, job_id)
|
||||||
|
except Exception:
|
||||||
|
redirect = reverse("horizon:freezer_ui:jobs:index")
|
||||||
|
msg = _('Unable to retrieve details.')
|
||||||
|
exceptions.handle(self.request, msg, redirect=redirect)
|
||||||
|
|
||||||
|
def is_update(self):
|
||||||
|
return 'job_id' in self.kwargs and \
|
||||||
|
bool(self.kwargs['job_id'])
|
||||||
|
|
||||||
|
def get_initial(self):
|
||||||
|
initial = super(AttachToSessionWorkflow, self).get_initial()
|
||||||
|
job = self.get_object()[0]
|
||||||
|
initial.update({'job_id': job.id})
|
||||||
|
return initial
|
||||||
|
|
||||||
|
|
||||||
|
class SessionsView(browsers.ResourceBrowserView):
|
||||||
|
browser_class = project_browsers.SessionBrowser
|
||||||
|
template_name = "freezer_ui/sessions/browser.html"
|
||||||
|
|
||||||
|
def get_sessions_data(self):
|
||||||
|
sessions = []
|
||||||
|
try:
|
||||||
|
sessions = freezer_api.session_list(self.request)
|
||||||
|
except Exception:
|
||||||
|
msg = _('Unable to retrieve sessions list.')
|
||||||
|
exceptions.handle(self.request, msg)
|
||||||
|
return sessions
|
||||||
|
|
||||||
|
def get_jobs_data(self):
|
||||||
|
jobs = []
|
||||||
|
session = None
|
||||||
|
try:
|
||||||
|
if self.kwargs['session_id']:
|
||||||
|
session = freezer_api.session_get(
|
||||||
|
self.request,
|
||||||
|
self.kwargs['session_id'])
|
||||||
|
|
||||||
|
try:
|
||||||
|
jobs = [SessionJob(k,
|
||||||
|
self.kwargs['session_id'],
|
||||||
|
v['client_id'],
|
||||||
|
v['status'])
|
||||||
|
for k, v in session.jobs.iteritems()]
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
except Exception:
|
||||||
|
msg = _('Unable to retrieve session information.')
|
||||||
|
exceptions.handle(self.request, msg)
|
||||||
|
return jobs
|
||||||
|
|
||||||
|
|
||||||
|
class CreateSessionWorkflow(workflows.WorkflowView):
|
||||||
|
workflow_class = create_session.CreateSession
|
||||||
|
|
||||||
|
def get_object(self, *args, **kwargs):
|
||||||
|
session_id = self.kwargs['session_id']
|
||||||
|
try:
|
||||||
|
return freezer_api.session_get(self.request, session_id)
|
||||||
|
except Exception:
|
||||||
|
redirect = reverse("horizon:freezer_ui:sessions:index")
|
||||||
|
msg = _('Unable to retrieve session.')
|
||||||
|
exceptions.handle(self.request, msg, redirect=redirect)
|
||||||
|
|
||||||
|
def get_initial(self):
|
||||||
|
initial = super(CreateSessionWorkflow, self).get_initial()
|
||||||
|
if self.is_update():
|
||||||
|
session = self.get_object()
|
||||||
|
initial.update({
|
||||||
|
'description': session.description,
|
||||||
|
'session_id': session.session_id,
|
||||||
|
'start_datetime': session.start_datetime,
|
||||||
|
'interval': session.interval,
|
||||||
|
'end_datetime': session.end_datetime
|
||||||
|
})
|
||||||
|
return initial
|
||||||
|
|
||||||
|
def is_update(self):
|
||||||
|
return 'session_id' in self.kwargs and \
|
||||||
|
bool(self.kwargs['session_id'])
|
|
@ -0,0 +1,72 @@
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
class SessionConfigurationAction(workflows.Action):
|
||||||
|
session_id = forms.ChoiceField(
|
||||||
|
help_text=_("Set a session to attach this job"),
|
||||||
|
label=_("Session Name"),
|
||||||
|
required=True)
|
||||||
|
|
||||||
|
job_id = forms.CharField(
|
||||||
|
widget=forms.HiddenInput(),
|
||||||
|
required=True)
|
||||||
|
|
||||||
|
def populate_session_id_choices(self, request, context):
|
||||||
|
sessions = []
|
||||||
|
try:
|
||||||
|
sessions = freezer_api.session_list(request)
|
||||||
|
except Exception:
|
||||||
|
exceptions.handle(request, _('Error getting session list'))
|
||||||
|
|
||||||
|
sessions = [(s.session_id, s.description) for s in sessions]
|
||||||
|
sessions.insert(0, ('', _('Select A Session')))
|
||||||
|
return sessions
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
name = _("Sessions")
|
||||||
|
slug = "sessions"
|
||||||
|
|
||||||
|
|
||||||
|
class SessionConfiguration(workflows.Step):
|
||||||
|
action_class = SessionConfigurationAction
|
||||||
|
contributes = ('session_id',
|
||||||
|
'job_id')
|
||||||
|
|
||||||
|
|
||||||
|
class AttachJobToSession(workflows.Workflow):
|
||||||
|
slug = "attach_job"
|
||||||
|
name = _("Attach To Session")
|
||||||
|
finalize_button_name = _("Attach")
|
||||||
|
success_message = _('Job saved successfully.')
|
||||||
|
failure_message = _('Unable to attach to session.')
|
||||||
|
success_url = "horizon:freezer_ui:jobs:index"
|
||||||
|
default_steps = (SessionConfiguration,)
|
||||||
|
|
||||||
|
def handle(self, request, context):
|
||||||
|
try:
|
||||||
|
freezer_api.add_job_to_session(
|
||||||
|
request,
|
||||||
|
context['session_id'],
|
||||||
|
context['job_id'])
|
||||||
|
return True
|
||||||
|
except Exception:
|
||||||
|
exceptions.handle(request)
|
||||||
|
return False
|
|
@ -0,0 +1,123 @@
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
class SessionConfigurationAction(workflows.Action):
|
||||||
|
description = forms.CharField(
|
||||||
|
label=_("Session Name"),
|
||||||
|
help_text=_("Define a name for this session"),
|
||||||
|
required=True)
|
||||||
|
|
||||||
|
session_id = forms.CharField(
|
||||||
|
widget=forms.HiddenInput(),
|
||||||
|
required=False)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
name = _("Session Information")
|
||||||
|
slug = "sessions"
|
||||||
|
|
||||||
|
|
||||||
|
class SessionConfiguration(workflows.Step):
|
||||||
|
action_class = SessionConfigurationAction
|
||||||
|
contributes = ('description',
|
||||||
|
'session_id')
|
||||||
|
|
||||||
|
|
||||||
|
class SchedulingConfigurationAction(workflows.Action):
|
||||||
|
start_datetime = forms.CharField(
|
||||||
|
label=_("Start Date and Time"),
|
||||||
|
required=False,
|
||||||
|
help_text=_(""))
|
||||||
|
|
||||||
|
interval = forms.CharField(
|
||||||
|
label=_("Interval"),
|
||||||
|
required=False,
|
||||||
|
help_text=_(""))
|
||||||
|
|
||||||
|
end_datetime = forms.CharField(
|
||||||
|
label=_("End Date and Time"),
|
||||||
|
required=False,
|
||||||
|
help_text=_(""))
|
||||||
|
|
||||||
|
def __init__(self, request, context, *args, **kwargs):
|
||||||
|
self.request = request
|
||||||
|
self.context = context
|
||||||
|
super(SchedulingConfigurationAction, self).__init__(
|
||||||
|
request, context, *args, **kwargs)
|
||||||
|
|
||||||
|
def clean(self):
|
||||||
|
cleaned_data = super(SchedulingConfigurationAction, self).clean()
|
||||||
|
self._check_start_datetime(cleaned_data)
|
||||||
|
self._check_end_datetime(cleaned_data)
|
||||||
|
return cleaned_data
|
||||||
|
|
||||||
|
def _validate_iso_format(self, start_date):
|
||||||
|
try:
|
||||||
|
return datetime.datetime.strptime(
|
||||||
|
start_date, "%Y-%m-%dT%H:%M:%S")
|
||||||
|
except ValueError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def _check_start_datetime(self, cleaned_data):
|
||||||
|
if cleaned_data.get('start_datetime') and not \
|
||||||
|
self._validate_iso_format(cleaned_data.get('start_datetime')):
|
||||||
|
msg = _("Start date time is not in ISO format.")
|
||||||
|
self._errors['start_datetime'] = self.error_class([msg])
|
||||||
|
|
||||||
|
def _check_end_datetime(self, cleaned_data):
|
||||||
|
if cleaned_data.get('end_datetime') and not \
|
||||||
|
self._validate_iso_format(cleaned_data.get('end_datetime')):
|
||||||
|
msg = _("End date time is not in ISO format.")
|
||||||
|
self._errors['end_datetime'] = self.error_class([msg])
|
||||||
|
|
||||||
|
class Meta(object):
|
||||||
|
name = _("Scheduling")
|
||||||
|
slug = "scheduling"
|
||||||
|
help_text_template = "freezer_ui/jobs" \
|
||||||
|
"/_scheduling.html"
|
||||||
|
|
||||||
|
|
||||||
|
class SchedulingConfiguration(workflows.Step):
|
||||||
|
action_class = SchedulingConfigurationAction
|
||||||
|
contributes = ('start_datetime',
|
||||||
|
'interval',
|
||||||
|
'end_datetime')
|
||||||
|
|
||||||
|
|
||||||
|
class CreateSession(workflows.Workflow):
|
||||||
|
slug = "create_session"
|
||||||
|
name = _("Create Session")
|
||||||
|
finalize_button_name = _("Create")
|
||||||
|
success_message = _('Session created successfully.')
|
||||||
|
failure_message = _('Unable to create session.')
|
||||||
|
success_url = "horizon:freezer_ui:sessions:index"
|
||||||
|
default_steps = (SessionConfiguration,
|
||||||
|
SchedulingConfiguration)
|
||||||
|
|
||||||
|
def handle(self, request, context):
|
||||||
|
try:
|
||||||
|
if context['session_id'] == '':
|
||||||
|
return freezer_api.session_create(request, context)
|
||||||
|
else:
|
||||||
|
return freezer_api.session_update(request, context)
|
||||||
|
except Exception:
|
||||||
|
exceptions.handle(request)
|
||||||
|
return False
|
|
@ -17,3 +17,11 @@ def create_dict_action(**kwargs):
|
||||||
None values
|
None values
|
||||||
"""
|
"""
|
||||||
return {k: v for k, v in kwargs.items() if v}
|
return {k: v for k, v in kwargs.items() if v}
|
||||||
|
|
||||||
|
|
||||||
|
class SessionJob(object):
|
||||||
|
def __init__(self, job_id, session_id, client_id, status):
|
||||||
|
self.job_id = job_id
|
||||||
|
self.session_id = session_id
|
||||||
|
self.client_id = client_id
|
||||||
|
self.status = status
|
||||||
|
|
Loading…
Reference in New Issue