Retire karbor-dashboard

As announced on the openstack-discuss ML[1], Karbor is retiring
this cycle (Wallaby).

This commit retires this repository as per the process defined in
the project-guide[2].

Thank you to all the contributors of Karbor for your hard work!

[1] http://lists.openstack.org/pipermail/openstack-discuss/2020-November/018643.html
[2] https://docs.openstack.org/project-team-guide/repository.html#retiring-a-repository

Depends-On: https://review.opendev.org/c/openstack/project-config/+/767030
Change-Id: I972ffb299f93863c4e34b1f504b002095661e6af
This commit is contained in:
Kendall Nelson 2020-12-14 15:47:18 -08:00
parent 06e52e5126
commit 1d52e37d0a
129 changed files with 8 additions and 9912 deletions

11
.gitignore vendored
View File

@ -1,11 +0,0 @@
AUTHORS
ChangeLog
build
doc/source/sourcecode
.secret_key_store
.venv
.tox
*.pyc
*.lock
*.egg*
*.swp

View File

@ -1,5 +0,0 @@
- project:
templates:
- horizon-non-primary-django-jobs
- openstack-python3-victoria-jobs
- check-requirements

View File

@ -1,16 +0,0 @@
If you would like to contribute to the development of OpenStack,
you must follow the steps in this page:
https://docs.openstack.org/infra/manual/developers.html
Once those steps have been completed, changes to OpenStack
should be submitted for review via the Gerrit tool, following
the workflow documented at:
https://docs.openstack.org/infra/manual/developers.html#development-workflow
Pull requests submitted through GitHub will be ignored.
Bugs should be filed on Storyboard, not GitHub:
https://storyboard.openstack.org/#!/project/openstack/karbor-dashboard

View File

@ -1,4 +0,0 @@
karbor-dashboard Style Commandments
===================================
Read the OpenStack Style Commandments https://docs.openstack.org/hacking/latest/

176
LICENSE
View File

@ -1,176 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.

View File

@ -1,60 +1,10 @@
========================
Team and repository tags
========================
This project is no longer maintained.
.. image:: https://governance.openstack.org/tc/badges/karbor-dashboard.svg
:target: https://governance.openstack.org/tc/reference/tags/index.html
The contents of this repository are still available in the Git
source code management system. To see the contents of this
repository before it reached its end of life, please check out the
previous commit with "git checkout HEAD^1".
.. Change things from this point on
================
karbor-dashboard
================
Karbor Dashboard
* Free software: Apache license
* Source: https://opendev.org/openstack/karbor-dashboard/
* Bugs: https://storyboard.openstack.org/#!/project/openstack/karbor-dashboard
Installation instructions
-------------------------
Begin by cloning the Horizon and Karbor Dashboard repositories::
git clone https://opendev.org/openstack/horizon
git clone https://opendev.org/openstack/karbor-dashboard
Create a virtual environment and install Horizon dependencies::
cd horizon
python tools/install_venv.py
Set up your ``local_settings.py`` file::
cp openstack_dashboard/local/local_settings.py.example openstack_dashboard/local/local_settings.py
Open up the copied ``local_settings.py`` file in your preferred text
editor. You will want to customize several settings:
- ``OPENSTACK_HOST`` should be configured with the hostname of your
OpenStack server. Verify that the ``OPENSTACK_KEYSTONE_URL`` and
``OPENSTACK_KEYSTONE_DEFAULT_ROLE`` settings are correct for your
environment. (They should be correct unless you modified your
OpenStack server to change them.)
Install Karbor Dashboard with all dependencies in your virtual environment::
tools/with_venv.sh pip install -e ../karbor-dashboard/
And enable it in Horizon::
cp ../karbor-dashboard/karbor_dashboard/enabled/* openstack_dashboard/local/enabled/
To run horizon with the newly enabled Karbor Dashboard plugin run::
tox -e runserver 0.0.0.0:8080
to have the application start on port 8080 and the horizon dashboard will be
available in your browser at http://localhost:8080/
For any further questions, please email
openstack-discuss@lists.openstack.org or join #openstack-dev on
Freenode.

View File

@ -1,2 +0,0 @@
[python: **.py]
[django: **/templates/**.html]

View File

@ -1,2 +0,0 @@
[javascript: **.js]
[angular: **/static/**.html]

View File

@ -1,55 +0,0 @@
#!/usr/bin/env bash
# plugin.sh - DevStack plugin.sh dispatch script karbor-dashboard
KARBOR_DASH_DIR=$(cd $(dirname $BASH_SOURCE)/.. && pwd)
function install_karbor_dashboard {
setup_develop ${KARBOR_DASH_DIR}
}
function configure_karbor_dashboard {
cp -a ${KARBOR_DASH_DIR}/karbor_dashboard/enabled/* ${DEST}/horizon/openstack_dashboard/local/enabled/
# NOTE: If locale directory does not exist, compilemessages will fail,
# so check for an existence of locale directory is required.
if [ -d ${KARBOR_DASH_DIR}/karbor_dashboard/locale ]; then
(cd ${KARBOR_DASH_DIR}/karbor_dashboard; DJANGO_SETTINGS_MODULE=openstack_dashboard.settings ../manage.py compilemessages)
fi
}
# check for service enabled
if is_service_enabled karbor-dashboard; then
if [[ "$1" == "stack" && "$2" == "pre-install" ]]; then
# Set up system services
# no-op
:
elif [[ "$1" == "stack" && "$2" == "install" ]]; then
# Perform installation of service source
echo_summary "Installing Karbor Dashboard"
install_karbor_dashboard
elif [[ "$1" == "stack" && "$2" == "post-config" ]]; then
# Configure after the other layer 1 and 2 services have been configured
echo_summary "Configuring Karbor Dashboard"
configure_karbor_dashboard
elif [[ "$1" == "stack" && "$2" == "extra" ]]; then
# Initialize and start the app-catalog-ui service
# no-op
:
fi
if [[ "$1" == "unstack" ]]; then
# Shut down app-catalog-ui services
# no-op
:
fi
if [[ "$1" == "clean" ]]; then
# Remove state and transient data
# Remember clean.sh first calls unstack.sh
# no-op
:
fi
fi

View File

@ -1,79 +0,0 @@
# 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 os
import sys
sys.path.insert(0, os.path.abspath('../..'))
# -- General configuration ----------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = [
'sphinx.ext.autodoc',
'openstackdocstheme',
]
# -- Options for openstackdocstheme -------------------------------------------
repository_name = 'openstack/karbor-dashboard'
bug_project = 'karbor-dashboard'
bug_tag = ''
html_theme = 'openstackdocs'
# autodoc generation is a bit aggressive and a nuisance when doing heavy
# text edit cycles.
# execute "export SPHINX_DEBUG=1" in your terminal to disable
# The suffix of source filenames.
source_suffix = '.rst'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'karbor-dashboard'
copyright = u'2013, OpenStack Foundation'
# If true, '()' will be appended to :func: etc. cross-reference text.
add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
add_module_names = True
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# -- Options for HTML output --------------------------------------------------
# The theme to use for HTML and HTML Help pages. Major themes that come with
# Sphinx are currently 'default' and 'sphinxdoc'.
# html_theme_path = ["."]
# html_theme = '_theme'
# html_static_path = ['static']
# Output file base name for HTML help builder.
htmlhelp_basename = '%sdoc' % project
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass
# [howto/manual]).
latex_documents = [
('index',
'%s.tex' % project,
u'%s Documentation' % project,
u'OpenStack Foundation', 'manual'),
]
# Example configuration for intersphinx: refer to the Python standard library.
# intersphinx_mapping = {'http://docs.python.org/': None}

View File

@ -1 +0,0 @@
.. include:: ../../README.rst

View File

@ -1,17 +0,0 @@
# 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 pbr.version
__version__ = pbr.version.VersionInfo(
'karbor-dashboard').version_string()

View File

@ -1,489 +0,0 @@
# Copyright (c) 2016 Huawei, Inc.
#
# 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 __future__ import absolute_import
import logging
from django.conf import settings
from horizon import exceptions
from horizon.utils import functions as utils
from horizon.utils.memoized import memoized
from karborclient.v1 import client as karbor_client
from openstack_dashboard.api import base
LOG = logging.getLogger(__name__)
def get_karbor_endpoint(request):
endpoint = ""
try:
endpoint = base.url_for(request, "data-protect")
except exceptions.ServiceCatalogException:
endpoint = 'http://localhost:8799'
LOG.warning('Karbor API location could not be found in Service '
'Catalog, using default: {0}'.format(endpoint))
return endpoint
@memoized
def karborclient(request):
endpoint = get_karbor_endpoint(request)
LOG.debug('karborclient connection created using the token "%s" and url'
'"%s"' % (request.user.token.id, endpoint))
c = karbor_client.Client(endpoint=endpoint,
auth_url=getattr(settings,
'OPENSTACK_KEYSTONE_URL'),
token=request.user.token.id,
username=request.user.username,
project_id=request.user.tenant_id,
auth_plugin='token',
)
return c
def update_pagination(entities, page_size, marker, sort_dir, sort_key,
reversed_order):
entities, has_more_data, has_prev_data = get_pagination_info(
entities, page_size, marker, reversed_order)
# restore the original ordering here
if reversed_order:
entities = sorted(entities, key=lambda entity:
(getattr(entity, sort_key) or '').lower(),
reverse=(sort_dir == 'asc'))
return entities, has_more_data, has_prev_data
def get_pagination_info(entities, page_size, marker, reversed_order):
has_more_data = has_prev_data = False
if len(entities) > page_size:
has_more_data = True
entities.pop()
if marker is not None:
has_prev_data = True
# first page condition when reached via prev back
elif reversed_order and marker is not None:
has_more_data = True
# last page condition
elif marker is not None:
has_prev_data = True
return entities, has_more_data, has_prev_data
def plan_create(request, name, provider_id, resources, parameters):
return karborclient(request).plans.create(name, provider_id, resources,
parameters)
def plan_delete(request, plan_id):
return karborclient(request).plans.delete(plan_id)
def plan_update(request, plan_id, data):
return karborclient(request).plans.update(plan_id, data)
def plan_list(request, detailed=False, search_opts=None, marker=None,
limit=None, sort_key=None, sort_dir=None, sort=None):
return karborclient(request).plans.list(detailed=detailed,
search_opts=search_opts,
marker=marker,
limit=limit,
sort_key=sort_key,
sort_dir=sort_dir,
sort=sort)
def plan_list_paged(request, detailed=False, search_opts=None, marker=None,
limit=None, sort_key=None, sort_dir=None, sort=None,
paginate=False, reversed_order=False):
has_more_data = False
has_prev_data = False
if paginate:
if reversed_order:
sort_dir = 'desc' if sort_dir == 'asc' else 'asc'
page_size = utils.get_page_size(request)
plans = karborclient(request).plans.list(detailed=detailed,
search_opts=search_opts,
marker=marker,
limit=page_size + 1,
sort_key=sort_key,
sort_dir=sort_dir,
sort=sort)
plans, has_more_data, has_prev_data = update_pagination(
plans, page_size, marker, sort_dir, sort_key, reversed_order)
else:
plans = karborclient(request).plans.list(detailed=detailed,
search_opts=search_opts,
marker=marker,
limit=limit,
sort_key=sort_key,
sort_dir=sort_dir,
sort=sort)
return (plans, has_more_data, has_prev_data)
def plan_get(request, plan_id):
return karborclient(request).plans.get(plan_id)
def scheduled_operation_create(request, name, operation_type, trigger_id,
operation_definition):
return karborclient(request).scheduled_operations.create(
name,
operation_type,
trigger_id,
operation_definition)
def scheduled_operation_delete(request, scheduled_operation_id):
return karborclient(request).scheduled_operations.delete(
scheduled_operation_id)
def scheduled_operation_list(request, detailed=False, search_opts=None,
marker=None, limit=None, sort_key=None,
sort_dir=None, sort=None):
return karborclient(request).scheduled_operations.list(
detailed=detailed,
search_opts=search_opts,
marker=marker,
limit=limit,
sort_key=sort_key,
sort_dir=sort_dir,
sort=sort)
def scheduled_operation_list_paged(request, detailed=False, search_opts=None,
marker=None, limit=None, sort_key=None,
sort_dir=None, sort=None, paginate=False,
reversed_order=False):
has_more_data = False
has_prev_data = False
if paginate:
if reversed_order:
sort_dir = 'desc' if sort_dir == 'asc' else 'asc'
page_size = utils.get_page_size(request)
scheduled_operations = karborclient(request).scheduled_operations.list(
detailed=detailed,
search_opts=search_opts,
marker=marker,
limit=page_size + 1,
sort_key=sort_key,
sort_dir=sort_dir,
sort=sort)
scheduled_operations, has_more_data, has_prev_data = update_pagination(
scheduled_operations,
page_size,
marker,
sort_dir,
sort_key,
reversed_order)
else:
scheduled_operations = karborclient(request).scheduled_operations.list(
detailed=detailed,
search_opts=search_opts,
marker=marker,
limit=limit,
sort_key=sort_key,
sort_dir=sort_dir,
sort=sort)
return (scheduled_operations, has_more_data, has_prev_data)
def scheduled_operation_get(request, scheduled_operation_id):
return karborclient(request).scheduled_operations.get(
scheduled_operation_id)
def restore_create(request, provider_id, checkpoint_id,
restore_target, parameters, restore_auth):
return karborclient(request).restores.create(provider_id,
checkpoint_id,
restore_target,
parameters,
restore_auth)
def restore_delete(request, restore_id):
return karborclient(request).restores.delete(restore_id)
def restore_list(request, detailed=False, search_opts=None, marker=None,
limit=None, sort_key=None, sort_dir=None, sort=None):
return karborclient(request).restores.list(detailed=detailed,
search_opts=search_opts,
marker=marker,
limit=limit,
sort_key=sort_key,
sort_dir=sort_dir,
sort=sort)
def restore_list_paged(request, detailed=False, search_opts=None, marker=None,
limit=None, sort_key=None, sort_dir=None, sort=None,
paginate=False, reversed_order=False):
has_more_data = False
has_prev_data = False
if paginate:
if reversed_order:
sort_dir = 'desc' if sort_dir == 'asc' else 'asc'
page_size = utils.get_page_size(request)
restores = karborclient(request).restores.list(detailed=detailed,
search_opts=search_opts,
marker=marker,
limit=page_size + 1,
sort_key=sort_key,
sort_dir=sort_dir,
sort=sort)
restores, has_more_data, has_prev_data = update_pagination(
restores, page_size, marker, sort_dir, sort_key, reversed_order)
else:
restores = karborclient(request).restores.list(detailed=detailed,
search_opts=search_opts,
marker=marker,
limit=limit,
sort_key=sort_key,
sort_dir=sort_dir,
sort=sort)
return (restores, has_more_data, has_prev_data)
def restore_get(request, restore_id):
return karborclient(request).restores.get(restore_id)
def protectable_list(request):
return karborclient(request).protectables.list()
def protectable_get(request, protectable_type):
return karborclient(request).protectables.get(protectable_type)
def protectable_list_instances(request, protectable_type, search_opts=None,
marker=None, limit=None, sort_key=None,
sort_dir=None, sort=None):
return karborclient(request).protectables.list_instances(
protectable_type=protectable_type,
search_opts=search_opts,
marker=marker,
limit=limit,
sort_key=sort_key,
sort_dir=sort_dir,
sort=sort)
def protectable_list_instances_paged(request, protectable_type,
search_opts=None, marker=None, limit=None,
sort_key=None, sort_dir=None, sort=None,
paginate=False, reversed_order=False):
has_more_data = False
has_prev_data = False
if paginate:
if reversed_order:
sort_dir = 'desc' if sort_dir == 'asc' else 'asc'
page_size = utils.get_page_size(request)
instances = karborclient(request).protectables.list_instances(
protectable_type,
search_opts=search_opts,
marker=marker,
limit=page_size + 1,
sort_key=sort_key,
sort_dir=sort_dir,
sort=sort)
instances, has_more_data, has_prev_data = update_pagination(
instances, page_size, marker, sort_dir, sort_key, reversed_order)
else:
instances = karborclient(request).protectables.list_instances(
protectable_type,
search_opts=search_opts,
marker=marker,
limit=limit,
sort_key=sort_key,
sort_dir=sort_dir,
sort=sort)
return (instances, has_more_data, has_prev_data)
def protectable_get_instance(request, type, id):
return karborclient(request).protectables.get_instance(type, id)
def provider_list(request, detailed=False, search_opts=None, marker=None,
limit=None, sort_key=None, sort_dir=None, sort=None):
return karborclient(request).providers.list(detailed=detailed,
search_opts=search_opts,
marker=marker,
limit=limit,
sort_key=sort_key,
sort_dir=sort_dir,
sort=sort)
def provider_list_paged(request, detailed=False, search_opts=None, marker=None,
limit=None, sort_key=None, sort_dir=None, sort=None,
paginate=False, reversed_order=False):
has_more_data = False
has_prev_data = False
if paginate:
if reversed_order:
sort_dir = 'desc' if sort_dir == 'asc' else 'asc'
page_size = utils.get_page_size(request)
providers = karborclient(request).providers.list(
detailed=detailed,
search_opts=search_opts,
marker=marker,
limit=page_size + 1,
sort_key=sort_key,
sort_dir=sort_dir,
sort=sort)
providers, has_more_data, has_prev_data = update_pagination(
providers, page_size, marker, sort_dir, sort_key, reversed_order)
else:
providers = karborclient(request).providers.list(
detailed=detailed,
search_opts=search_opts,
marker=marker,
limit=limit,
sort_key=sort_key,
sort_dir=sort_dir,
sort=sort)
return (providers, has_more_data, has_prev_data)
def provider_get(request, provider_id):
return karborclient(request).providers.get(provider_id)
def checkpoint_create(request, provider_id, plan_id):
return karborclient(request).checkpoints.create(provider_id, plan_id)
def checkpoint_delete(request, provider_id, checkpoint_id):
return karborclient(request).checkpoints.delete(provider_id, checkpoint_id)
def checkpoint_list(request, provider_id=None, search_opts=None, marker=None,
limit=None, sort_key=None, sort_dir=None, sort=None):
return karborclient(request).checkpoints.list(provider_id=provider_id,
search_opts=search_opts,
marker=marker,
limit=limit,
sort_key=sort_key,
sort_dir=sort_dir,
sort=sort)
def checkpoint_list_paged(request, provider_id=None, search_opts=None,
marker=None, limit=None, sort_key=None,
sort_dir=None, sort=None, paginate=False,
reversed_order=False):
has_more_data = False
has_prev_data = False
if paginate:
if reversed_order:
sort_dir = 'desc' if sort_dir == 'asc' else 'asc'
page_size = utils.get_page_size(request)
checkpoints = karborclient(request).checkpoints.list(
provider_id=provider_id,
search_opts=search_opts,
marker=marker,
limit=page_size + 1,
sort_key=sort_key,
sort_dir=sort_dir,
sort=sort)
checkpoints, has_more_data, has_prev_data = \
get_pagination_info(
checkpoints, page_size, marker, reversed_order)
else:
checkpoints = karborclient(request).checkpoints.list(
provider_id=provider_id,
search_opts=search_opts,
marker=marker,
limit=limit,
sort_key=sort_key,
sort_dir=sort_dir,
sort=sort)
return (checkpoints, has_more_data, has_prev_data)
def checkpoint_get(request, provider_id, checkpoint_id):
return karborclient(request).checkpoints.get(provider_id, checkpoint_id)
def trigger_create(request, name, type, properties):
return karborclient(request).triggers.create(name, type, properties)
def trigger_delete(request, trigger_id):
return karborclient(request).triggers.delete(trigger_id)
def trigger_list(request, detailed=False, search_opts=None, marker=None,
limit=None, sort_key=None, sort_dir=None, sort=None):
return karborclient(request).triggers.list(detailed=detailed,
search_opts=search_opts,
marker=marker,
limit=limit,
sort_key=sort_key,
sort_dir=sort_dir,
sort=sort)
def trigger_list_paged(request, detailed=False, search_opts=None, marker=None,
limit=None, sort_key=None, sort_dir=None, sort=None,
paginate=False, reversed_order=False):
has_more_data = False
has_prev_data = False
if paginate:
if reversed_order:
sort_dir = 'desc' if sort_dir == 'asc' else 'asc'
page_size = utils.get_page_size(request)
triggers = karborclient(request).triggers.list(detailed=detailed,
search_opts=search_opts,
marker=marker,
limit=page_size + 1,
sort_key=sort_key,
sort_dir=sort_dir,
sort=sort)
triggers, has_more_data, has_prev_data = update_pagination(
triggers, page_size, marker, sort_dir, sort_key, reversed_order)
else:
triggers = karborclient(request).triggers.list(detailed=detailed,
search_opts=search_opts,
marker=marker,
limit=limit,
sort_key=sort_key,
sort_dir=sort_dir,
sort=sort)
return (triggers, has_more_data, has_prev_data)
def trigger_get(request, trigger_id):
return karborclient(request).triggers.get(trigger_id)

View File

@ -1,134 +0,0 @@
# Copyright (c) 2016 Huawei, Inc.
#
# 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 import forms
from django.utils.translation import ugettext_lazy as _
from django.views.decorators.debug import sensitive_variables # noqa
from horizon import exceptions
from horizon import forms as horizon_forms
from horizon import messages
from oslo_serialization import jsonutils
from karbor_dashboard.api import karbor as karborclient
EMPTY_VALUES = (None, '', u'', [], (), {})
class RestoreCheckpointForm(horizon_forms.SelfHandlingForm):
provider_id = forms.CharField(label=_("Provider ID"),
widget=forms.HiddenInput(),
required=False)
checkpoint_id = forms.CharField(label=_("Checkpoint ID"),
widget=forms.HiddenInput(),
required=False)
use_current_session = forms.BooleanField(
label=_("Use current session credentials"),
widget=forms.CheckboxInput(attrs={
'class': 'disable_input',
'data-slug': 'use_current_session',
'data-disable-on-checked': 'true',
'checked': 'checked'
}),
initial=False,
required=False)
restore_target = forms.URLField(
label=_("Restore Target"),
widget=forms.URLInput(attrs={
'class': 'disabled_input',
'data-disable-on': 'use_current_session',
'data-source-manual': _("Restore Target"),
'disabled': 'disabled',
'value': 'Target: Current project'
}),
required=False)
restore_target_username = forms.CharField(
label=_("Restore Target Username"),
widget=forms.TextInput(attrs={
'class': 'disabled_input',
'data-disable-on': 'use_current_session',
'data-source-manual': _("Restore Target Username"),
'disabled': 'disabled',
'value': 'Target Username: current user'
}),
required=False)
restore_target_password = forms.CharField(
label=_("Restore Target Password"),
widget=forms.PasswordInput(attrs={
'class': 'disabled_input',
'data-disable-on': 'use_current_session',
'data-source-manual': _("Restore Target Password"),
'disabled': 'disabled',
'hidden': 'hidden'
}),
required=False)
provider = forms.CharField(
widget=forms.HiddenInput(attrs={"class": "provider"}))
parameters = forms.CharField(
widget=forms.HiddenInput(attrs={"class": "parameters"}))
failure_url = 'horizon:karbor:checkpoints:index'
def __init__(self, request, *args, **kwargs):
super(RestoreCheckpointForm, self).\
__init__(request, *args, **kwargs)
provider_id = str(kwargs["initial"]["provider_id"])
provider = karborclient.provider_get(request, provider_id)
self.fields['provider'].initial = jsonutils.dumps(provider._info)
@sensitive_variables('restore_target_password')
def handle(self, request, data):
def all_empty(data_list):
return all(map(lambda x: x in EMPTY_VALUES, data_list))
def all_not_empty(data_list):
return all(map(lambda x: x not in EMPTY_VALUES, data_list))
def empty_to_none(data_):
return data_ if data_ not in EMPTY_VALUES else None
target = empty_to_none(data["restore_target"])
target_username = empty_to_none(data["restore_target_username"])
target_password = empty_to_none(data["restore_target_password"])
use_current_session = empty_to_none(data["use_current_session"])
if not use_current_session:
validate_data = [target, target_username, target_password]
if not (all_empty(validate_data) or all_not_empty(validate_data)):
messages.warning(request,
_('Restore Target, Restore Target Username '
'and Restore Target Password must be '
'assigned at the same time or not '
'assigned.'))
return False
try:
data_parameters = jsonutils.loads(data["parameters"])
restore_auth = {
"type": "password",
"username": target_username,
"password": target_password,
}
new_restore = karborclient.restore_create(
request,
provider_id=data["provider_id"],
checkpoint_id=data["checkpoint_id"],
restore_target=target,
parameters=data_parameters,
restore_auth=restore_auth)
messages.success(request, _("Checkpoint restore initiated"))
return new_restore
except Exception:
exceptions.handle(request, _('Unable to restore checkpoint.'))

View File

@ -1,26 +0,0 @@
# Copyright (c) 2016 Huawei, Inc.
#
# 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 karbor_dashboard import dashboard
class Checkpoints(horizon.Panel):
name = _("Checkpoints")
slug = 'checkpoints'
dashboard.DataProtection.register(Checkpoints)

View File

@ -1,150 +0,0 @@
# Copyright (c) 2016 Huawei, Inc.
#
# 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 pgettext_lazy
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ungettext_lazy
from horizon import tables
from karbor_dashboard.api import karbor as karborclient
class RestoreCheckpointLink(tables.LinkAction):
name = "restore"
verbose_name = _("Restore Checkpoint")
url = "horizon:karbor:checkpoints:restore"
classes = ("ajax-modal",)
icon = "plus"
def get_link_url(self, checkpoint):
checkpoint_id = checkpoint.id
return reverse(self.url, args=(checkpoint.provider_id, checkpoint_id))
def allowed(self, request, checkpoint):
return checkpoint.status == 'available'
class DeleteCheckpointsAction(tables.DeleteAction):
@staticmethod
def action_present(count):
return ungettext_lazy(u"Delete Checkpoint",
u"Delete Checkpoints",
count)
@staticmethod
def action_past(count):
return ungettext_lazy(u"Scheduled deletion of Checkpoint",
u"Scheduled deletion of Checkpoints",
count)
def allowed(self, request, checkpoint):
return checkpoint.status == 'available'
def delete(self, request, obj_id):
datum = self.table.get_object_by_id(obj_id)
provider_id = datum.provider_id
karborclient.checkpoint_delete(request,
provider_id=provider_id,
checkpoint_id=obj_id)
def get_provider_link(obj):
return reverse('horizon:karbor:protectionproviders:detail',
args=(obj.provider_id, ))
def get_checkpoint_link(obj):
"""url Two args"""
return reverse("horizon:karbor:checkpoints:detail",
args=(obj.provider_id, obj.id))
def get_plan_name(obj):
name = ""
plan = getattr(obj, 'protection_plan')
if plan is not None:
name = plan.get("name")
return name
class UpdateRow(tables.Row):
ajax = True
def __init__(self, table, datum=None):
super(UpdateRow, self).__init__(table, datum)
self.provider_id = getattr(table, 'provider_id')
def get_data(self, request, obj_id):
provider = karborclient.provider_get(request, self.provider_id)
checkpoint = karborclient.checkpoint_get(request,
self.provider_id,
obj_id)
setattr(checkpoint, "provider_name", provider.name)
setattr(checkpoint, "provider_id", provider.id)
return checkpoint
TASK_DISPLAY_CHOICES = (
("error", pgettext_lazy("Task status of an Checkpoint", u"Error")),
("protecting", pgettext_lazy("Task status of an Checkpoint",
u"Protecting")),
("available", pgettext_lazy("Task status of an Checkpoint", u"Available")),
("deleting", pgettext_lazy("Task status of an Checkpoint", u"Deleting")),
("deleted", pgettext_lazy("Task status of an Checkpoint", u"Deleted")),
("error-deleting", pgettext_lazy("Task status of an Checkpoint",
u"Error Deleting")),
)
class CheckpointsTable(tables.DataTable):
TASK_STATUS_CHOICES = (
("error", False),
("available", True),
("deleted", True),
("error-deleting", False),
)
checkpointId = tables.Column(
"id",
link=get_checkpoint_link,
verbose_name=_('Checkpoint ID'))
protectionProvider = tables.Column(
"provider_name",
link=get_provider_link,
verbose_name=_('Protection Provider'))
protectPlan = tables.Column(
get_plan_name,
verbose_name=_('Protection Plan'))
status = tables.Column(
'status',
verbose_name=_('Status'),
status=True,
status_choices=TASK_STATUS_CHOICES,
display_choices=TASK_DISPLAY_CHOICES)
class Meta(object):
name = 'checkpoints'
verbose_name = _('Checkpoints')
status_columns = ["status", ]
row_class = UpdateRow
row_actions = (RestoreCheckpointLink, DeleteCheckpointsAction)
class DetailTable(tables.DataTable):
class Meta(object):
name = "protectionresources"
verbose_name = _("Protection Resources")
hidden_title = False

View File

@ -1,29 +0,0 @@
# Copyright (c) 2016 Huawei, Inc.
#
# 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 url
from karbor_dashboard.checkpoints import views
urlpatterns = [
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^(?P<provider_id>[^/]+)/$',
views.IndexView.as_view(), name='index'),
url(r'^(?P<provider_id>[^/]+)/checkpoints/'
r'(?P<checkpoint_id>[^/]+)/restore$',
views.CheckpointsRestoreView.as_view(), name='restore'),
url(r'^(?P<provider_id>[^/]+)/checkpoints/'
r'(?P<checkpoint_id>[^/]+)/detail/$',
views.DetailView.as_view(), name='detail'),
]

View File

@ -1,89 +0,0 @@
# Copyright (c) 2016 Huawei, Inc.
#
# 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 collections
from collections import namedtuple
from django.utils.translation import ugettext_lazy as _
from oslo_serialization import jsonutils
FILTER_LIST = ['provider_filter', 'plan_filter', 'date_filter']
TODAY = 'today'
LASTESTONEWEEK = 'lastestoneweek'
LASTESTTWOWEEKS = 'lastesttwoweeks'
LASTESTONEMONTH = 'lastestonemonth'
LASTESTTHREEMONTHS = 'lastestthreemonths'
DATE_CHOICES = [(TODAY, _('Today')),
(LASTESTONEWEEK, _('Lastest one week')),
(LASTESTTWOWEEKS, _('Lastest two weeks')),
(LASTESTONEMONTH, _('Lastest one month')),
(LASTESTTHREEMONTHS, _('Lastest three months'))]
DATE_DICT = collections.OrderedDict(DATE_CHOICES)
Resource = namedtuple("Resource", (
'type',
'id',
'name'
))
GraphNode = namedtuple("GraphNode", (
"value",
"child_nodes",
))
PackedGraph = namedtuple('PackedGraph', ['nodes', 'adjacency'])
def deserialize_resource_graph(serialized_resource_graph):
deserialized_graph = jsonutils.loads(serialized_resource_graph)
packed_resource_graph = PackedGraph(nodes=deserialized_graph[0],
adjacency=deserialized_graph[1])
for sid, node in packed_resource_graph.nodes.items():
packed_resource_graph.nodes[sid] = Resource(type=node[0],
id=node[1],
name=node[2])
resource_graph = unpack_graph(packed_resource_graph)
return resource_graph
def unpack_graph(packed_graph):
"""Return a list of GraphNodes from a PackedGraph
Unpacks a PackedGraph, which must have the property: each parent node in
the adjacency list appears after its children.
"""
(nodes, adjacency_list) = packed_graph
nodes_dict = dict(nodes)
graph_nodes_dict = {}
for (parent_sid, children_sids) in adjacency_list:
if parent_sid in graph_nodes_dict:
raise Exception("PackedGraph adjacency list "
"must be topologically ordered")
children = []
for child_sid in children_sids:
if child_sid not in graph_nodes_dict:
graph_nodes_dict[child_sid] = GraphNode(
nodes_dict[child_sid], ())
children.append(graph_nodes_dict[child_sid])
nodes_dict.pop(child_sid, None)
graph_nodes_dict[parent_sid] = GraphNode(nodes_dict[parent_sid],
tuple(children))
result_nodes = []
for sid in nodes_dict:
if sid not in graph_nodes_dict:
graph_nodes_dict[sid] = GraphNode(nodes_dict[sid], ())
result_nodes.append(graph_nodes_dict[sid])
return result_nodes

View File

@ -1,311 +0,0 @@
# Copyright (c) 2016 Huawei, Inc.
#
# 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.core.urlresolvers import reverse_lazy
from django.utils.translation import ugettext_lazy as _
from calendar import monthrange
from datetime import date
from datetime import timedelta
from horizon import exceptions
from horizon import forms as horizon_forms
from horizon import tables as horizon_tables
from horizon.utils import memoized
from karbor_dashboard.api import karbor as karborclient
from karbor_dashboard.checkpoints import forms
from karbor_dashboard.checkpoints import tables
from karbor_dashboard.checkpoints import utils
from karborclient.v1 import protectables
from oslo_utils import uuidutils
class IndexView(horizon_tables.DataTableView):
table_class = tables.CheckpointsTable
template_name = 'checkpoints/index.html'
page_title = _("Checkpoints")
@memoized.memoized_method
def get_provider_list(self):
return karborclient.provider_list(self.request)
@memoized.memoized_method
def get_plan_list(self):
return karborclient.plan_list(self.request)
@memoized.memoized_method
def get_filter_list(self):
filters = {}
# Get all filter
for key in utils.FILTER_LIST:
filters[key] = self.request.POST.get(key, u"All")
# Remove the "All" of provider_filter
provider_filter = utils.FILTER_LIST[0]
try:
providers = self.get_provider_list()
filters[provider_filter] = \
self.request.POST.get(provider_filter, providers[0].id)
except Exception:
exceptions.handle(
self.request,
_('Unable to retrieve anyone provider.'))
# Get arguments from the providers page
if self.kwargs.get("provider_id", None) is not None:
filters[provider_filter] = self.kwargs["provider_id"]
return filters
def get_context_data(self, **kwargs):
context = super(IndexView, self).get_context_data(**kwargs)
try:
context["provider_list"] = self.get_provider_list()
except Exception:
exceptions.handle(
self.request,
_('Unable to retrieve anyone provider.'))
context["plan_list"] = self.get_plan_list()
context["date_list"] = utils.DATE_CHOICES
context["url"] = reverse("horizon:karbor:checkpoints:index")
context = dict(context, **self.get_filter_list())
return context
@memoized.memoized_method
def get_search_opts(self):
def _total_days(year, month, num_months):
days = 0
i = 0
while i < num_months:
days += monthrange(year, month)[1]
month = month - 1 if month > 1 else 12
year = year if month > 1 else year - 1
i += 1
return days
search_opts = {}
filters = self.get_filter_list()
provider_id = filters.get(utils.FILTER_LIST[0], None)
plan_id = filters.get(utils.FILTER_LIST[1], u"All")
if plan_id != u"All":
search_opts["plan_id"] = plan_id
now = date.today()
date_filter = filters.get(utils.FILTER_LIST[2], None)
if date_filter == utils.TODAY:
delta = timedelta(days=1)
elif date_filter == utils.LASTESTONEWEEK:
delta = timedelta(weeks=1)
elif date_filter == utils.LASTESTTWOWEEKS:
delta = timedelta(weeks=2)
elif date_filter == utils.LASTESTONEMONTH:
days = _total_days(now.year, now.month, 1)
delta = timedelta(days=days)
elif date_filter == utils.LASTESTTHREEMONTHS:
days = _total_days(now.year, now.month, 3)
delta = timedelta(days=days)
else:
delta = None
if delta:
search_opts["start_date"] = now - delta
search_opts["end_date"] = now
return provider_id, search_opts
def has_prev_data(self, table):
return self._prev
def has_more_data(self, table):
return self._more
def get_data(self):
prev_marker = self.request.GET.get(
tables.CheckpointsTable._meta.prev_pagination_param, None)
if prev_marker is not None:
marker = prev_marker
else:
marker = self.request.GET.get(
tables.CheckpointsTable._meta.pagination_param, None)
reversed_order = prev_marker is not None
checkpoints = []
try:
# Get provider id and search_opts
provider_id, search_opts = self.get_search_opts()
if provider_id is None:
raise Exception()
checkpoints, self._more, self._prev = \
karborclient.checkpoint_list_paged(
self.request,
provider_id=provider_id,
search_opts=search_opts,
marker=marker,
paginate=True,
sort_dir='asc',
sort_key='id',
reversed_order=reversed_order)
provider = karborclient.provider_get(self.request, provider_id)
for checkpoint in checkpoints:
setattr(checkpoint, "provider_name", provider.name)
setattr(checkpoint, "provider_id", provider_id)
except Exception:
self._prev = False
self._more = False
exceptions.handle(self.request,
_('Unable to retrieve checkpoints list.'))
return checkpoints
def get_table(self):
super(IndexView, self).get_table()
provider_id, _ = self.get_search_opts()
setattr(self.table, 'provider_id', provider_id)
return self.table
class CheckpointsRestoreView(horizon_forms.ModalFormView):
template_name = 'checkpoints/restore.html'
modal_header = _("Restore Checkpoint")
form_id = "restore_checkpoint_form"
form_class = forms.RestoreCheckpointForm
submit_label = _("Restore Checkpoint")
submit_url = 'horizon:karbor:checkpoints:restore'
success_url = reverse_lazy('horizon:karbor:restores:index')
page_title = _("Restore Checkpoint")
def get_initial(self):
return {"provider_id": self.kwargs['provider_id'],
"checkpoint_id": self.kwargs['checkpoint_id']}
def get_context_data(self, **kwargs):
context = super(CheckpointsRestoreView, self). \
get_context_data(**kwargs)
provider_id = self.kwargs['provider_id']
checkpoint_id = self.kwargs['checkpoint_id']
context['provider_id'] = provider_id
context['checkpoint_id'] = checkpoint_id
context["instances"] = self.get_resources()
context['submit_url'] = reverse(self.submit_url,
args=(provider_id, checkpoint_id))
return context
@memoized.memoized_method
def get_resources(self):
results = []
try:
provider_id = self.kwargs['provider_id']
checkpoint_id = self.kwargs['checkpoint_id']
checkpoint = karborclient.checkpoint_get(self.request,
provider_id,
checkpoint_id)
graphnodes = utils.deserialize_resource_graph(
checkpoint.resource_graph)
self.get_results(graphnodes, None, results)
except Exception:
exceptions.handle(
self.request,
_('Unable to retrieve checkpoint details.'),
redirect=reverse("horizon:karbor:checkpoints:index"))
return results
def get_results(self, graphnodes, showparentid, results):
for graphnode in graphnodes:
if graphnode is not None:
# add graph node to results
resource = {}
resource["id"] = graphnode.value.id
resource["type"] = graphnode.value.type
resource["name"] = graphnode.value.name
resource["showid"] = uuidutils.generate_uuid()
resource["showparentid"] = showparentid
result = protectables.Instances(self, resource)
results.append(result)
# add child graph nodes to results
self.get_results(graphnode.child_nodes,
result.showid,
results
)
class DetailView(horizon_tables.DataTableView):
table_class = tables.DetailTable
template_name = 'checkpoints/detail.html'
page_title = _("{{ checkpoint.protection_plan.name }}")
@memoized.memoized_method
def get_checkpoint_data(self):
try:
provider_id = self.kwargs['provider_id']
checkpoint_id = self.kwargs['checkpoint_id']
checkpoint = karborclient.checkpoint_get(self.request,
provider_id,
checkpoint_id)
except Exception:
checkpoint = []
msg = _('checkpoint list can not be retrieved.')
exceptions.handle(self.request, msg)
return checkpoint
def get_context_data(self, **kwargs):
context = super(DetailView, self).get_context_data(**kwargs)
checkpoint = self.get_checkpoint_data()
context["checkpoint"] = checkpoint
provider_id = self.kwargs['provider_id']
provider = karborclient.provider_get(self.request, provider_id)
context["provider_name"] = provider.name
context["resources"] = self.get_resources()
context["url"] = reverse("horizon:karbor:protectionplans:index")
return context
@memoized.memoized_method
def get_resources(self):
results = []
try:
provider_id = self.kwargs['provider_id']
checkpoint_id = self.kwargs['checkpoint_id']
checkpoint = karborclient.checkpoint_get(self.request,
provider_id,
checkpoint_id)
graphnodes = utils.deserialize_resource_graph(
checkpoint.resource_graph)
self.get_results(graphnodes, None, results)
except Exception:
exceptions.handle(
self.request,
_('Unable to retrieve checkpoint details.'),
redirect=reverse("horizon:karbor:checkpoints:index"))
return results
def get_results(self, graphnodes, showparentid, results):
for graphnode in graphnodes:
if graphnode is not None:
# add graph node to results
resource = {}
resource["id"] = graphnode.value.id
resource["type"] = graphnode.value.type
resource["name"] = graphnode.value.name
resource["showid"] = uuidutils.generate_uuid()
resource["showparentid"] = showparentid
result = protectables.Instances(self, resource)
results.append(result)
# add child graph nodes to results
self.get_results(graphnode.child_nodes,
result.showid,
results
)

View File

@ -1,27 +0,0 @@
# Copyright (c) 2016 Huawei, Inc.
#
# 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 horizon
# Load the api rest services into Horizon
import karbor_dashboard.api.rest # noqa
class DataProtection(horizon.Dashboard):
name = "Data Protection"
slug = "karbor"
default_panel = "protectionplans"
horizon.register(DataProtection)

View File

@ -1,27 +0,0 @@
# Copyright (c) 2016 Huawei, Inc.
#
# 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.
# The name of the dashboard to be added to HORIZON['dashboards']. Required.
DASHBOARD = 'karbor'
# If set to True, this dashboard will not be added to the settings.
DISABLED = False
ADD_INSTALLED_APPS = [
'karbor_dashboard',
]
# Automatically discover static resources in installed apps
AUTO_DISCOVER_STATIC_FILES = True

View File

@ -1,21 +0,0 @@
# Copyright (c) 2016 Huawei, Inc.
#
# 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.
PANEL = 'protectionplans'
PANEL_GROUP = 'default'
PANEL_DASHBOARD = 'karbor'
ADD_PANEL = \
'karbor_dashboard.protectionplans.panel.ProtectionPlans'

View File

@ -1,21 +0,0 @@
# Copyright (c) 2016 Huawei, Inc.
#
# 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.
PANEL = 'protectionproviders'
PANEL_GROUP = 'default'
PANEL_DASHBOARD = 'karbor'
ADD_PANEL = \
'karbor_dashboard.protectionproviders.panel.ProtectionProviders'

View File

@ -1,21 +0,0 @@
# Copyright (c) 2016 Huawei, Inc.
#
# 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.
PANEL = 'checkpoints'
PANEL_GROUP = 'default'
PANEL_DASHBOARD = 'karbor'
ADD_PANEL = \
'karbor_dashboard.checkpoints.panel.Checkpoints'

View File

@ -1,21 +0,0 @@
# Copyright (c) 2016 Huawei, Inc.
#
# 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.
PANEL = 'operationlogs'
PANEL_GROUP = 'default'
PANEL_DASHBOARD = 'karbor'
ADD_PANEL = \
'karbor_dashboard.operationlogs.panel.OperationLogs'

View File

@ -1,21 +0,0 @@
# Copyright (c) 2016 Huawei, Inc.
#
# 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.
PANEL = 'triggers'
PANEL_GROUP = 'default'
PANEL_DASHBOARD = 'karbor'
ADD_PANEL = \
'karbor_dashboard.triggers.panel.Triggers'

View File

@ -1,21 +0,0 @@
# Copyright (c) 2016 Huawei, Inc.
#
# 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.
PANEL = 'restores'
PANEL_GROUP = 'default'
PANEL_DASHBOARD = 'karbor'
ADD_PANEL = \
'karbor_dashboard.restores.panel.Restores'

View File

@ -1,21 +0,0 @@
# Copyright (c) 2016 Huawei, Inc.
#
# 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.
PANEL = 'scheduledoperations'
PANEL_GROUP = 'default'
PANEL_DASHBOARD = 'karbor'
ADD_PANEL = \
'karbor_dashboard.scheduledoperations.panel.ScheduledOperations'

View File

@ -1,441 +0,0 @@
# Robert Simai <robert.simai@suse.com>, 2016. #zanata
# Andreas Jaeger <jaegerandi@gmail.com>, 2018. #zanata
# Frank Kloeker <eumel@arcor.de>, 2018. #zanata
msgid ""
msgstr ""
"Project-Id-Version: karbor-dashboard VERSION\n"
"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
"POT-Creation-Date: 2018-07-31 02:17+0000\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"PO-Revision-Date: 2018-08-11 08:44+0000\n"
"Last-Translator: Frank Kloeker <eumel@arcor.de>\n"
"Language-Team: German\n"
"Language: de\n"
"X-Generator: Zanata 4.3.3\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
msgid "Actual Start Time"
msgstr "Tatsächliche Startzeit"
msgid "Associate with Trigger"
msgstr "Verknüpfen mit Trigger"
msgctxt "Task status of an Checkpoint"
msgid "Available"
msgstr "Verfügbar"
msgid "Check Point Details"
msgstr "Kontrollpunkt Details"
msgid "Checkpoint ID"
msgstr "Kontrollpunkt ID"
msgid "Checkpoint restore initiated"
msgstr "Kontrollpunktwiederherstellung initiert"
msgid "Checkpoints"
msgstr "Kontrollpunkte"
msgid "Create Protection Plan"
msgstr "Schutzplan erstellen"
msgid "Create Trigger"
msgstr "Auslöser erstellen"
msgid "Create a new trigger."
msgstr "Neuen Auslöser erstellen."
msgid "Date"
msgstr "Datum"
msgid "Day"
msgstr "Tag"
msgid "Delete Checkpoint"
msgid_plural "Delete Checkpoints"
msgstr[0] "Lösche Kontrollpunkt"
msgstr[1] "Lösche Kontrollpunkt"
msgid "Delete Protection Plan"
msgid_plural "Delete Protection Plans"
msgstr[0] "Lösche Schutzplan"
msgstr[1] "Lösche Schutzpläne"
msgid "Delete Scheduled Operation"
msgid_plural "Delete Scheduled Operations"
msgstr[0] "Lösche geplante Operation"
msgstr[1] "Lösche geplante Operationen"
msgid "Delete Trigger"
msgid_plural "Delete Triggers"
msgstr[0] "Auslöser löschen"
msgstr[1] "Auslöser löschen"
msgctxt "Task status of an Checkpoint"
msgid "Deleted"
msgstr "Gelöscht"
msgid "Deleted Scheduled Operation"
msgid_plural "Deleted Scheduled Operations"
msgstr[0] "Geplante Operation gelöscht"
msgstr[1] "Geplante Operationen gelöscht"
msgid "Deleted Trigger"
msgid_plural "Deleted Triggers"
msgstr[0] "Gelöschter Auslöser"
msgstr[1] "Gelöschte Auslöser"
msgctxt "Task status of an Checkpoint"
msgid "Deleting"
msgstr "Löschen"
msgid "Description"
msgstr "Beschreibung"
msgid "Description:"
msgstr "Beschreibung:"
msgid "Edit Plan"
msgstr "Bearbeite Plan"
msgid "End Time"
msgstr "Endzeit"
msgctxt "Task status of an Checkpoint"
msgid "Error"
msgstr "Fehler"
msgctxt "Task status of an Checkpoint"
msgid "Error Deleting"
msgstr "Fehler beim Löschen"
msgid "Event Trigger"
msgstr "Ereignis-Auslöser"
msgid "Every Day"
msgstr "Jeden Tag"
msgid "Every Month"
msgstr "Jeden Monat"
msgid "Every Week"
msgstr "Jede Woche"
msgid "Execution Interval"
msgstr "Ausführungsinterval"
msgid "Execution Time (HH:MM)"
msgstr "Ausführungszeit (HH:MM)"
msgid "Expect Start Time"
msgstr "Erwartete Startzeit"
msgid "FR"
msgstr "Fr"
msgctxt "Task status of an Restore"
msgid "Fail"
msgstr "Fehlgeschlagen"
msgid "Frequence"
msgstr "Frequenz"
msgid "Friday"
msgstr "Freitag"
msgid "Hour"
msgstr "Stunde"
msgid "ID"
msgstr "ID"
msgctxt "Task status of an Restore"
msgid "In Progress"
msgstr "In Arbeit"
msgid "Lastest one month"
msgstr "Letzter Monat"
msgid "Lastest one week"
msgstr "Letzte Woche"
msgid "Lastest three months"
msgstr "Letzte drei Monate"
msgid "Lastest two weeks"
msgstr "Letzte zwei Wochen"
msgid "MO"
msgstr "Mo"
msgid "Minute"
msgstr "Minute"
msgid "Monday"
msgstr "Montag"
msgid "Name"
msgstr "Name"
msgid "Operation Logs"
msgstr "Betriebsprotokolle"
msgid "Operation Type"
msgstr "Betriebstyp"
msgid "Options Schema"
msgstr "Schemaoptionen"
msgid "Plan Name"
msgstr "Planname"
msgid "Plan Status"
msgstr "Planstatus"
msgid "Plan protection initiated"
msgstr "Schutzplan initiiert"
msgid "Protect Now"
msgstr "Jetzt schützen"
msgid "Protect now successfully."
msgstr "Schutz ist jetzt erfolgreich."
msgctxt "Task status of an Checkpoint"
msgid "Protecting"
msgstr "Schützen"
msgid "Protection Plan"
msgstr "Schutzplan"
msgid "Protection Plan Details"
msgstr "Details des Protektion Plans"
msgid "Protection Plan created successfully."
msgstr "Schutzplan erfolgreich erstellt."
msgid "Protection Plan updated successfully."
msgstr "Schutzplan erfolgreich aktualisiert."
msgid "Protection Plans"
msgstr "Schutzpläne"
msgid "Protection Provider"
msgstr "Schutzanbieter"
msgid "Protection Provider Details"
msgstr "Details der Protektion Provider"
msgid "Protection Providers"
msgstr "Protection Providers"
msgid "Protection Resources"
msgstr "Schutzressourcen"
msgid "Provider Description"
msgstr "Anbieterbeschreibung"
msgid "Provider ID"
msgstr "Anbieter-ID"
msgid "Provider Name"
msgstr "Anbietername"
msgid "Restore Checkpoint"
msgstr "Stelle Kontrolpunkt wieder her"
msgid "Restore From Checkpoint"
msgstr "Stelle Kontrolpunkt wieder her"
msgid "Restore Schema"
msgstr "Stelle Schema wieder her"
msgid "Restore Target"
msgstr "Wiederherstellungsziel"
msgid "Restore Target Password"
msgstr "Ziel-Passwort wiederherstellen"
msgid "Restore Target Username"
msgstr "Ziel-Benutzername wiederherstellen"
msgid ""
"Restore Target, Restore Target Username and Restore Target Password must be "
"assigned at the same time or not assigned."
msgstr ""
"Wiederherstellungsziel, Wiederherstellungszielbenutzername und "
"Wiederherstellungszielkennwort müssen zur gleichen Zeit zugewiesen oder "
"nicht zugewiesen werden."
msgid "Restores"
msgstr "Wiederherstellungen"
msgid "SA"
msgstr "Sa"
msgid "SU"
msgstr "So"
msgid "Saturday"
msgstr "Samstag"
msgid "Saved Info Schema"
msgstr "Gespeicherte Schemainformationen"
msgid "Schedule Protect"
msgstr "Schutzplan"
msgid "Schedule Protect."
msgstr "Schutzplan"
msgid "Schedule protect successfully."
msgstr "Schutzplan erfolgreich."
msgid "Scheduled Operations"
msgstr "Geplante Operationen"
msgid "Scheduled deletion of Checkpoint"
msgid_plural "Scheduled deletion of Checkpoints"
msgstr[0] "Geplante Löschung des Kontrollpunkts"
msgstr[1] "Geplante Löschung von Kontrollpunkten"
msgid "Show Checkpoints"
msgstr "Zeige Kontrollpunkte"
msgid "State"
msgstr "Zustand"
msgid "Status"
msgstr "Status"
msgctxt "Task status of an Restore"
msgid "Success"
msgstr "Erfolg"
msgid "Sunday"
msgstr "Sonntag"
msgid "TH"
msgstr "Do"
msgid "TU"
msgstr "Di"
msgid "TYPE"
msgstr "TYPE"
msgid "Thursday"
msgstr "Donnerstag"
msgid "Time Trigger"
msgstr "Zeit-Auslöser"
msgid "Today"
msgstr "Heute"
msgid "Trigger"
msgstr "Auslöser"
msgid "Trigger Details"
msgstr "Auslöser erstellen"
msgid "Trigger Name"
msgstr "Auslösername"
msgid "Trigger Type"
msgstr "Auslösertyp"
msgid "Trigger created successfully."
msgstr "Auslöser erfolgreich erstellt"
msgid "Triggers"
msgstr "Auslöser"
msgid "Tuesday"
msgstr "Dienstag"
msgid "Type"
msgstr "Typ"
msgid "Unable to create protection plan."
msgstr "Konnte Schutzplan nicht erstellen."
msgid "Unable to create trigger."
msgstr "Auslöser kann nicht erstellt werden."
msgid "Unable to get instances."
msgstr "Instanzen können nicht abgerufen werden."
msgid "Unable to protect now"
msgstr "Konnte jetzt nicht schützen"
msgid "Unable to restore checkpoint."
msgstr "Der Kontrollpunkt kann nicht wiederhergestellt werden."
msgid "Unable to retrieve anyone provider."
msgstr "Kann keinen Anbieter abrufen."
msgid "Unable to retrieve checkpoint details."
msgstr "Die Details des Kontrollpunktes können nicht abgerufen werden."
msgid "Unable to retrieve checkpoints list."
msgstr "Liste der Kontrollpunkte kann nicht abgerufen werden."
msgid "Unable to retrieve protection plan details."
msgstr "Protektion Plan kann nicht abgerufen werden."
msgid "Unable to retrieve protection plans list."
msgstr "Konnte Schutzplanliste nicht abrufen"
msgid "Unable to retrieve protection provider details."
msgstr "Details der Protektion Provider können nicht abgerufen werden."
msgid "Unable to retrieve protection providers list."
msgstr "Die Liste der Protektion Provider kann nicht abgerufen werden."
msgid "Unable to retrieve protection resources."
msgstr "Konnte Schutzplanresourcen nicht abrufen"
msgid "Unable to retrieve provider contents."
msgstr "Anbieterinhalte können nicht abgerufen werden."
msgid "Unable to retrieve provider details."
msgstr "Konnte Schutzanbieterdetails nicht abrufen"
msgid "Unable to retrieve restore list."
msgstr "Wiederherstellungsliste kann nicht abgerufen werden."
msgid "Unable to retrieve scheduled operation list."
msgstr "Die Liste der geplanten Operationen kann nicht abgerufen werden."
msgid "Unable to retrieve trigger details."
msgstr "Auslöserdetails können nicht abgerufen werden."
msgid "Unable to retrieve triggers list."
msgstr "Auslöserliste kann nicht abgerufen werden."
msgid "Unable to schedule protect."
msgstr "Schutzplan nicht erfolgreich."
msgid "Unable to update protection plan. "
msgstr "Konnte Schutzplan nicht aktualisieren."
msgid "Update Protection Plan"
msgstr "Schutzplan aktualisieren"
msgid "Use current session credentials"
msgstr "Benutze aktuelle Session Anmeldeinformationen"
msgid "WE"
msgstr "Mi"
msgid "Wednesday"
msgstr "Mittwoch"
msgid "checkpoint list can not be retrieved."
msgstr "Kontrollpunktliste kann nicht abgerufen werden."
msgid "{{ checkpoint.protection_plan.name }}"
msgstr "{{ checkpoint.protection_plan.name }}"

View File

@ -1,438 +0,0 @@
# Andi Chandler <andi@gowling.com>, 2017. #zanata
msgid ""
msgstr ""
"Project-Id-Version: karbor-dashboard VERSION\n"
"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
"POT-Creation-Date: 2018-01-26 04:03+0000\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"PO-Revision-Date: 2017-12-12 02:32+0000\n"
"Last-Translator: Andi Chandler <andi@gowling.com>\n"
"Language-Team: English (United Kingdom)\n"
"Language: en_GB\n"
"X-Generator: Zanata 4.3.3\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
msgid "Actual Start Time"
msgstr "Actual Start Time"
msgid "Associate with Trigger"
msgstr "Associate with Trigger"
msgctxt "Task status of an Checkpoint"
msgid "Available"
msgstr "Available"
msgid "Check Point Details"
msgstr "Check Point Details"
msgid "Checkpoint ID"
msgstr "Checkpoint ID"
msgid "Checkpoint restore initiated"
msgstr "Checkpoint restore initiated"
msgid "Checkpoints"
msgstr "Checkpoints"
msgid "Create Protection Plan"
msgstr "Create Protection Plan"
msgid "Create Trigger"
msgstr "Create Trigger"
msgid "Create a new trigger."
msgstr "Create a new trigger."
msgid "Date"
msgstr "Date"
msgid "Day"
msgstr "Day"
msgid "Delete Checkpoint"
msgid_plural "Delete Checkpoints"
msgstr[0] "Delete Checkpoint"
msgstr[1] "Delete Checkpoints"
msgid "Delete Protection Plan"
msgid_plural "Delete Protection Plans"
msgstr[0] "Delete Protection Plan"
msgstr[1] "Delete Protection Plans"
msgid "Delete Scheduled Operation"
msgid_plural "Delete Scheduled Operations"
msgstr[0] "Delete Scheduled Operation"
msgstr[1] "Delete Scheduled Operations"
msgid "Delete Trigger"
msgid_plural "Delete Triggers"
msgstr[0] "Delete Trigger"
msgstr[1] "Delete Triggers"
msgctxt "Task status of an Checkpoint"
msgid "Deleted"
msgstr "Deleted"
msgid "Deleted Scheduled Operation"
msgid_plural "Deleted Scheduled Operations"
msgstr[0] "Deleted Scheduled Operation"
msgstr[1] "Deleted Scheduled Operations"
msgid "Deleted Trigger"
msgid_plural "Deleted Triggers"
msgstr[0] "Deleted Trigger"
msgstr[1] "Deleted Triggers"
msgctxt "Task status of an Checkpoint"
msgid "Deleting"
msgstr "Deleting"
msgid "Description"
msgstr "Description"
msgid "Description:"
msgstr "Description:"
msgid "Edit Plan"
msgstr "Edit Plan"
msgid "End Time"
msgstr "End Time"
msgctxt "Task status of an Checkpoint"
msgid "Error"
msgstr "Error"
msgctxt "Task status of an Checkpoint"
msgid "Error Deleting"
msgstr "Error Deleting"
msgid "Event Trigger"
msgstr "Event Trigger"
msgid "Every Day"
msgstr "Every Day"
msgid "Every Month"
msgstr "Every Month"
msgid "Every Week"
msgstr "Every Week"
msgid "Execution Interval"
msgstr "Execution Interval"
msgid "Execution Time (HH:MM)"
msgstr "Execution Time (HH:MM)"
msgid "Expect Start Time"
msgstr "Expect Start Time"
msgid "FR"
msgstr "FR"
msgctxt "Task status of an Restore"
msgid "Fail"
msgstr "Fail"
msgid "Frequence"
msgstr "Frequency"
msgid "Friday"
msgstr "Friday"
msgid "Hour"
msgstr "Hour"
msgid "ID"
msgstr "ID"
msgctxt "Task status of an Restore"
msgid "In Progress"
msgstr "In Progress"
msgid "Lastest one month"
msgstr "Last month"
msgid "Lastest one week"
msgstr "Last one week"
msgid "Lastest three months"
msgstr "Last three months"
msgid "Lastest two weeks"
msgstr "Last two weeks"
msgid "MO"
msgstr "MO"
msgid "Minute"
msgstr "Minute"
msgid "Monday"
msgstr "Monday"
msgid "Name"
msgstr "Name"
msgid "Operation Logs"
msgstr "Operation Logs"
msgid "Operation Type"
msgstr "Operation Type"
msgid "Options Schema"
msgstr "Options Schema"
msgid "Plan Name"
msgstr "Plan Name"
msgid "Plan Status"
msgstr "Plan Status"
msgid "Plan protection initiated"
msgstr "Plan protection initiated"
msgid "Protect Now"
msgstr "Protect Now"
msgid "Protect now successfully."
msgstr "Protect now successfully."
msgctxt "Task status of an Checkpoint"
msgid "Protecting"
msgstr "Protecting"
msgid "Protection Plan"
msgstr "Protection Plan"
msgid "Protection Plan Details"
msgstr "Protection Plan Details"
msgid "Protection Plan created successfully."
msgstr "Protection Plan created successfully."
msgid "Protection Plan updated successfully."
msgstr "Protection Plan updated successfully."
msgid "Protection Plans"
msgstr "Protection Plans"
msgid "Protection Provider"
msgstr "Protection Provider"
msgid "Protection Provider Details"
msgstr "Protection Provider Details"
msgid "Protection Providers"
msgstr "Protection Providers"
msgid "Protection Resources"
msgstr "Protection Resources"
msgid "Provider Description"
msgstr "Provider Description"
msgid "Provider ID"
msgstr "Provider ID"
msgid "Provider Name"
msgstr "Provider Name"
msgid "Restore Checkpoint"
msgstr "Restore Checkpoint"
msgid "Restore From Checkpoint"
msgstr "Restore From Checkpoint"
msgid "Restore Schema"
msgstr "Restore Schema"
msgid "Restore Target"
msgstr "Restore Target"
msgid "Restore Target Password"
msgstr "Restore Target Password"
msgid "Restore Target Username"
msgstr "Restore Target Username"
msgid ""
"Restore Target, Restore Target Username and Restore Target Password must be "
"assigned at the same time or not assigned."
msgstr ""
"Restore Target, Restore Target Username and Restore Target Password must be "
"assigned at the same time or not assigned."
msgid "Restores"
msgstr "Restores"
msgid "SA"
msgstr "SA"
msgid "SU"
msgstr "SU"
msgid "Saturday"
msgstr "Saturday"
msgid "Saved Info Schema"
msgstr "Saved Info Schema"
msgid "Schedule Protect"
msgstr "Schedule Protect"
msgid "Schedule Protect."
msgstr "Schedule Protect."
msgid "Schedule protect successfully."
msgstr "Schedule protect successfully."
msgid "Scheduled Operations"
msgstr "Scheduled Operations"
msgid "Scheduled deletion of Checkpoint"
msgid_plural "Scheduled deletion of Checkpoints"
msgstr[0] "Scheduled deletion of Checkpoint"
msgstr[1] "Scheduled deletion of Checkpoints"
msgid "Show Checkpoints"
msgstr "Show Checkpoints"
msgid "State"
msgstr "State"
msgid "Status"
msgstr "Status"
msgctxt "Task status of an Restore"
msgid "Success"
msgstr "Success"
msgid "Sunday"
msgstr "Sunday"
msgid "TH"
msgstr "TH"
msgid "TU"
msgstr "TU"
msgid "TYPE"
msgstr "TYPE"
msgid "Thursday"
msgstr "Thursday"
msgid "Time Trigger"
msgstr "Time Trigger"
msgid "Today"
msgstr "Today"
msgid "Trigger"
msgstr "Trigger"
msgid "Trigger Details"
msgstr "Trigger Details"
msgid "Trigger Name"
msgstr "Trigger Name"
msgid "Trigger Type"
msgstr "Trigger Type"
msgid "Trigger created successfully."
msgstr "Trigger created successfully."
msgid "Triggers"
msgstr "Triggers"
msgid "Tuesday"
msgstr "Tuesday"
msgid "Type"
msgstr "Type"
msgid "Unable to create protection plan."
msgstr "Unable to create protection plan."
msgid "Unable to create trigger."
msgstr "Unable to create trigger."
msgid "Unable to get instances."
msgstr "Unable to get instances."
msgid "Unable to protect now"
msgstr "Unable to protect now"
msgid "Unable to restore checkpoint."
msgstr "Unable to restore checkpoint."
msgid "Unable to retrieve anyone provider."
msgstr "Unable to retrieve anyone provider."
msgid "Unable to retrieve checkpoint details."
msgstr "Unable to retrieve checkpoint details."
msgid "Unable to retrieve checkpoints list."
msgstr "Unable to retrieve checkpoints list."
msgid "Unable to retrieve protection plan details."
msgstr "Unable to retrieve protection plan details."
msgid "Unable to retrieve protection plans list."
msgstr "Unable to retrieve protection plans list."
msgid "Unable to retrieve protection provider details."
msgstr "Unable to retrieve protection provider details."
msgid "Unable to retrieve protection providers list."
msgstr "Unable to retrieve protection providers list."
msgid "Unable to retrieve protection resources."
msgstr "Unable to retrieve protection resources."
msgid "Unable to retrieve provider contents."
msgstr "Unable to retrieve provider contents."
msgid "Unable to retrieve provider details."
msgstr "Unable to retrieve provider details."
msgid "Unable to retrieve restore list."
msgstr "Unable to retrieve restore list."
msgid "Unable to retrieve scheduled operation list."
msgstr "Unable to retrieve scheduled operation list."
msgid "Unable to retrieve trigger details."
msgstr "Unable to retrieve trigger details."
msgid "Unable to retrieve triggers list."
msgstr "Unable to retrieve triggers list."
msgid "Unable to schedule protect."
msgstr "Unable to schedule protect."
msgid "Unable to update protection plan. "
msgstr "Unable to update protection plan. "
msgid "Update Protection Plan"
msgstr "Update Protection Plan"
msgid "Use current session credentials"
msgstr "Use current session credentials"
msgid "WE"
msgstr "WE"
msgid "Wednesday"
msgstr "Wednesday"
msgid "checkpoint list can not be retrieved."
msgstr "checkpoint list can not be retrieved."
msgid "{{ checkpoint.protection_plan.name }}"
msgstr "{{ checkpoint.protection_plan.name }}"

View File

@ -1,431 +0,0 @@
# suhartono <cloudsuhartono@gmail.com>, 2018. #zanata
msgid ""
msgstr ""
"Project-Id-Version: karbor-dashboard VERSION\n"
"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
"POT-Creation-Date: 2018-04-11 08:40+0000\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"PO-Revision-Date: 2018-05-09 04:27+0000\n"
"Last-Translator: suhartono <cloudsuhartono@gmail.com>\n"
"Language-Team: Indonesian\n"
"Language: id\n"
"X-Generator: Zanata 4.3.3\n"
"Plural-Forms: nplurals=1; plural=0\n"
msgid "Actual Start Time"
msgstr "Actual Start Time"
msgid "Associate with Trigger"
msgstr "Associate with Trigger"
msgctxt "Task status of an Checkpoint"
msgid "Available"
msgstr "Available"
msgid "Check Point Details"
msgstr "Check Point Details"
msgid "Checkpoint ID"
msgstr "Checkpoint ID"
msgid "Checkpoint restore initiated"
msgstr "Checkpoint restore dimulai"
msgid "Checkpoints"
msgstr "Checkpoints"
msgid "Create Protection Plan"
msgstr "Buat Protection Plan"
msgid "Create Trigger"
msgstr "Create Trigger"
msgid "Create a new trigger."
msgstr "Buat pemicu baru."
msgid "Date"
msgstr "Date"
msgid "Day"
msgstr "Day"
msgid "Delete Checkpoint"
msgid_plural "Delete Checkpoints"
msgstr[0] "Delete Checkpoint"
msgid "Delete Protection Plan"
msgid_plural "Delete Protection Plans"
msgstr[0] "Delete Protection Plan"
msgid "Delete Scheduled Operation"
msgid_plural "Delete Scheduled Operations"
msgstr[0] "Delete Scheduled Operation"
msgid "Delete Trigger"
msgid_plural "Delete Triggers"
msgstr[0] "Delete Trigger"
msgctxt "Task status of an Checkpoint"
msgid "Deleted"
msgstr "Deleted"
msgid "Deleted Scheduled Operation"
msgid_plural "Deleted Scheduled Operations"
msgstr[0] "Deleted Scheduled Operation"
msgid "Deleted Trigger"
msgid_plural "Deleted Triggers"
msgstr[0] "Deleted Trigger"
msgctxt "Task status of an Checkpoint"
msgid "Deleting"
msgstr "Deleting"
msgid "Description"
msgstr "Description"
msgid "Description:"
msgstr "Description:"
msgid "Edit Plan"
msgstr "Edit Plan"
msgid "End Time"
msgstr "End Time"
msgctxt "Task status of an Checkpoint"
msgid "Error"
msgstr "Error"
msgctxt "Task status of an Checkpoint"
msgid "Error Deleting"
msgstr "Error Deleting"
msgid "Event Trigger"
msgstr "Event Trigger"
msgid "Every Day"
msgstr "Every Day"
msgid "Every Month"
msgstr "Every Month"
msgid "Every Week"
msgstr "Every Week"
msgid "Execution Interval"
msgstr "Execution Interval"
msgid "Execution Time (HH:MM)"
msgstr "Execution Time (HH:MM)"
msgid "Expect Start Time"
msgstr "Expect Start Time"
msgid "FR"
msgstr "FR"
msgctxt "Task status of an Restore"
msgid "Fail"
msgstr "Fail"
msgid "Frequence"
msgstr "Frequence"
msgid "Friday"
msgstr "Friday"
msgid "Hour"
msgstr "Hour"
msgid "ID"
msgstr "ID"
msgctxt "Task status of an Restore"
msgid "In Progress"
msgstr "In Progress"
msgid "Lastest one month"
msgstr "Satu bulan terakhir"
msgid "Lastest one week"
msgstr "Satu minggu terakhir"
msgid "Lastest three months"
msgstr "Tiga bulan terakhir"
msgid "Lastest two weeks"
msgstr "Dua minggu terakhir"
msgid "MO"
msgstr "MO"
msgid "Minute"
msgstr "Minute"
msgid "Monday"
msgstr "Monday"
msgid "Name"
msgstr "Name"
msgid "Operation Logs"
msgstr "Operation Logs"
msgid "Operation Type"
msgstr "Operation Type"
msgid "Options Schema"
msgstr "Options Schema"
msgid "Plan Name"
msgstr "Plan Name"
msgid "Plan Status"
msgstr "Plan Status"
msgid "Plan protection initiated"
msgstr "Rencana perlindungan dimulai"
msgid "Protect Now"
msgstr "Protect Now"
msgid "Protect now successfully."
msgstr "Lindungi sekarang dengan sukses."
msgctxt "Task status of an Checkpoint"
msgid "Protecting"
msgstr "Protecting"
msgid "Protection Plan"
msgstr "Protection Plan"
msgid "Protection Plan Details"
msgstr "Protection Plan Details"
msgid "Protection Plan created successfully."
msgstr "Protection Plan berhasil dibuat."
msgid "Protection Plan updated successfully."
msgstr "Protection Plan berhasil diperbarui."
msgid "Protection Plans"
msgstr "Protection Plans"
msgid "Protection Provider"
msgstr "Protection Provider"
msgid "Protection Provider Details"
msgstr "Protection Provider Details"
msgid "Protection Providers"
msgstr "Protection Providers"
msgid "Protection Resources"
msgstr "Protection Resources"
msgid "Provider Description"
msgstr "Provider Description"
msgid "Provider ID"
msgstr "Provider ID"
msgid "Provider Name"
msgstr "Provider Name"
msgid "Restore Checkpoint"
msgstr "Kembalikan Checkpoint"
msgid "Restore From Checkpoint"
msgstr "Restore From Checkpoint"
msgid "Restore Schema"
msgstr "Restore Schema"
msgid "Restore Target"
msgstr "Restore Target"
msgid "Restore Target Password"
msgstr "Restore Target Password"
msgid "Restore Target Username"
msgstr "Restore Target Username"
msgid ""
"Restore Target, Restore Target Username and Restore Target Password must be "
"assigned at the same time or not assigned."
msgstr ""
"Restore Target, Restore Target Username dan Restore Target Password harus "
"ditugaskan pada saat bersamaan atau tidak ditugaskan."
msgid "Restores"
msgstr "Restores"
msgid "SA"
msgstr "SA"
msgid "SU"
msgstr "SU"
msgid "Saturday"
msgstr "Saturday"
msgid "Saved Info Schema"
msgstr "Saved Info Schema"
msgid "Schedule Protect"
msgstr "Schedule Protect"
msgid "Schedule Protect."
msgstr "Schedule Protect."
msgid "Schedule protect successfully."
msgstr "Jadwal berhasil dilindungi."
msgid "Scheduled Operations"
msgstr "Scheduled Operations"
msgid "Scheduled deletion of Checkpoint"
msgid_plural "Scheduled deletion of Checkpoints"
msgstr[0] "Scheduled deletion of Checkpoint"
msgid "Show Checkpoints"
msgstr "Show Checkpoints"
msgid "State"
msgstr "State"
msgid "Status"
msgstr "Status"
msgctxt "Task status of an Restore"
msgid "Success"
msgstr "Success"
msgid "Sunday"
msgstr "Sunday"
msgid "TH"
msgstr "TH"
msgid "TU"
msgstr "TU"
msgid "TYPE"
msgstr "TYPE"
msgid "Thursday"
msgstr "Thursday"
msgid "Time Trigger"
msgstr "Time Trigger"
msgid "Today"
msgstr "Today"
msgid "Trigger"
msgstr "Trigger"
msgid "Trigger Details"
msgstr "Trigger Details"
msgid "Trigger Name"
msgstr "Trigger Name"
msgid "Trigger Type"
msgstr "Trigger Type"
msgid "Trigger created successfully."
msgstr "Trigger berhasil dibuat."
msgid "Triggers"
msgstr "Triggers"
msgid "Tuesday"
msgstr "Tuesday"
msgid "Type"
msgstr "Type"
msgid "Unable to create protection plan."
msgstr "Tidak dapat membuat rencana perlindungan."
msgid "Unable to create trigger."
msgstr "Tidak dapat membuat trigger."
msgid "Unable to get instances."
msgstr "Tidak dapat mendapatkan instance."
msgid "Unable to protect now"
msgstr "Tidak dapat melindungi sekarang"
msgid "Unable to restore checkpoint."
msgstr "Tidak dapat restore checkpoint.."
msgid "Unable to retrieve anyone provider."
msgstr "Tidak dapat mengambil penyedia siapa pun."
msgid "Unable to retrieve checkpoint details."
msgstr "Tidak dapat mengambil detail pemeriksaan (checkpoint)"
msgid "Unable to retrieve checkpoints list."
msgstr "Tidak dapat mengambil daftar pemeriksaan (checkpoint)"
msgid "Unable to retrieve protection plan details."
msgstr "Tidak dapat mengambil detail paket perlindungan."
msgid "Unable to retrieve protection plans list."
msgstr "Tidak dapat mengambil daftar rencana perlindungan."
msgid "Unable to retrieve protection provider details."
msgstr "Tidak dapat mengambil detail penyedia perlindungan."
msgid "Unable to retrieve protection providers list."
msgstr "Tidak dapat mengambil daftar penyedia perlindungan."
msgid "Unable to retrieve protection resources."
msgstr "Tidak dapat mengambil sumber daya perlindungan."
msgid "Unable to retrieve provider contents."
msgstr "Tidak dapat mengambil konten penyedia."
msgid "Unable to retrieve provider details."
msgstr "Tidak dapat mengambil detail penyedia."
msgid "Unable to retrieve restore list."
msgstr "Tidak dapat mengambil daftar pulihkan."
msgid "Unable to retrieve scheduled operation list."
msgstr "Tidak dapat mengambil daftar operasi terjadwal."
msgid "Unable to retrieve trigger details."
msgstr "Tidak dapat mengambil detail pemicu."
msgid "Unable to retrieve triggers list."
msgstr "Tidak dapat mengambil daftar pemicu."
msgid "Unable to schedule protect."
msgstr "Tidak dapat dijadwalkan untuk melindungi."
msgid "Unable to update protection plan. "
msgstr "Tidak dapat memperbarui paket perlindungan."
msgid "Update Protection Plan"
msgstr "Memperbarui Protection Plan"
msgid "Use current session credentials"
msgstr "Gunakan kredensial sesi saat ini"
msgid "WE"
msgstr "WE"
msgid "Wednesday"
msgstr "Wednesday"
msgid "checkpoint list can not be retrieved."
msgstr "daftar checkpoint tidak dapat diambil."
msgid "{{ checkpoint.protection_plan.name }}"
msgstr "{{ checkpoint.protection_plan.name }}"

View File

@ -1,431 +0,0 @@
# Sungjin Kang <gang.sungjin@gmail.com>, 2018. #zanata
msgid ""
msgstr ""
"Project-Id-Version: karbor-dashboard VERSION\n"
"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
"POT-Creation-Date: 2018-07-31 02:17+0000\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"PO-Revision-Date: 2018-07-29 06:37+0000\n"
"Last-Translator: Sungjin Kang <gang.sungjin@gmail.com>\n"
"Language-Team: Korean (South Korea)\n"
"Language: ko_KR\n"
"X-Generator: Zanata 4.3.3\n"
"Plural-Forms: nplurals=1; plural=0\n"
msgid "Actual Start Time"
msgstr "실제 시작 시간"
msgid "Associate with Trigger"
msgstr "트리거와 연결"
msgctxt "Task status of an Checkpoint"
msgid "Available"
msgstr "사용 가능"
msgid "Check Point Details"
msgstr "체크포인트 상세 정보"
msgid "Checkpoint ID"
msgstr "Checkpoint ID"
msgid "Checkpoint restore initiated"
msgstr "체크포인트로 복원이 시작됨"
msgid "Checkpoints"
msgstr "체크포인트"
msgid "Create Protection Plan"
msgstr "Protection 계획 생성"
msgid "Create Trigger"
msgstr "트리거 생성"
msgid "Create a new trigger."
msgstr "새로운 트리거를 생성합니다."
msgid "Date"
msgstr "일자"
msgid "Day"
msgstr "일"
msgid "Delete Checkpoint"
msgid_plural "Delete Checkpoints"
msgstr[0] "체크포인트 삭제"
msgid "Delete Protection Plan"
msgid_plural "Delete Protection Plans"
msgstr[0] "Protection 계획 삭제"
msgid "Delete Scheduled Operation"
msgid_plural "Delete Scheduled Operations"
msgstr[0] "예정된 운영 삭제"
msgid "Delete Trigger"
msgid_plural "Delete Triggers"
msgstr[0] "트리거 삭제"
msgctxt "Task status of an Checkpoint"
msgid "Deleted"
msgstr "삭제됨"
msgid "Deleted Scheduled Operation"
msgid_plural "Deleted Scheduled Operations"
msgstr[0] "예정된 운영 삭제됨"
msgid "Deleted Trigger"
msgid_plural "Deleted Triggers"
msgstr[0] "트리거 삭제됨"
msgctxt "Task status of an Checkpoint"
msgid "Deleting"
msgstr "삭제 중"
msgid "Description"
msgstr "설명"
msgid "Description:"
msgstr "설명:"
msgid "Edit Plan"
msgstr "계획 수정"
msgid "End Time"
msgstr "종료 시간"
msgctxt "Task status of an Checkpoint"
msgid "Error"
msgstr "오류"
msgctxt "Task status of an Checkpoint"
msgid "Error Deleting"
msgstr "삭제 중 오류"
msgid "Event Trigger"
msgstr "이벤트 트리거"
msgid "Every Day"
msgstr "매일"
msgid "Every Month"
msgstr "매달"
msgid "Every Week"
msgstr "매주"
msgid "Execution Interval"
msgstr "실행 간격"
msgid "Execution Time (HH:MM)"
msgstr "실행 시간 (HH:MM)"
msgid "Expect Start Time"
msgstr "예상 시작 시간"
msgid "FR"
msgstr "금"
msgctxt "Task status of an Restore"
msgid "Fail"
msgstr "실패"
msgid "Frequence"
msgstr "주기"
msgid "Friday"
msgstr "금요일"
msgid "Hour"
msgstr "시간"
msgid "ID"
msgstr "ID"
msgctxt "Task status of an Restore"
msgid "In Progress"
msgstr "진행중"
msgid "Lastest one month"
msgstr "최근 1달"
msgid "Lastest one week"
msgstr "최근 1주"
msgid "Lastest three months"
msgstr "최근 3달"
msgid "Lastest two weeks"
msgstr "최근 2주"
msgid "MO"
msgstr "월"
msgid "Minute"
msgstr "분"
msgid "Monday"
msgstr "월요일"
msgid "Name"
msgstr "이름"
msgid "Operation Logs"
msgstr "운영 로그"
msgid "Operation Type"
msgstr "운영 타입"
msgid "Options Schema"
msgstr "옵션 Schema"
msgid "Plan Name"
msgstr "계획 이름"
msgid "Plan Status"
msgstr "계획 상태"
msgid "Plan protection initiated"
msgstr "계획된 protection 시작됨"
msgid "Protect Now"
msgstr "지금 protect"
msgid "Protect now successfully."
msgstr "이제 protect를 시작합니다."
msgctxt "Task status of an Checkpoint"
msgid "Protecting"
msgstr "보호중"
msgid "Protection Plan"
msgstr "Protection 계획"
msgid "Protection Plan Details"
msgstr "Protection 계획 상세 정보"
msgid "Protection Plan created successfully."
msgstr "Protection 계획을 성공적으로 생성하였습니다."
msgid "Protection Plan updated successfully."
msgstr "Protection 계획을 성공적으로 업데이트하였습니다."
msgid "Protection Plans"
msgstr "Protection 계획"
msgid "Protection Provider"
msgstr "Protection 프로바이더"
msgid "Protection Provider Details"
msgstr "Protection 프로바이더 상세 정보"
msgid "Protection Providers"
msgstr "Protection 프로바이더"
msgid "Protection Resources"
msgstr "Protection 리소스"
msgid "Provider Description"
msgstr "프로바이더 설명"
msgid "Provider ID"
msgstr "Provider ID"
msgid "Provider Name"
msgstr "프로바이더 이름"
msgid "Restore Checkpoint"
msgstr "체크포인트 복구"
msgid "Restore From Checkpoint"
msgstr "체크포인트로부터 복구"
msgid "Restore Schema"
msgstr "복구 Schema"
msgid "Restore Target"
msgstr "복구 타겟"
msgid "Restore Target Password"
msgstr "복구 타겟 비밀번호"
msgid "Restore Target Username"
msgstr "복구 타겟 사용자명"
msgid ""
"Restore Target, Restore Target Username and Restore Target Password must be "
"assigned at the same time or not assigned."
msgstr ""
"복구 타겟, 복구 타겟 사용자명, 복구 타겟 비밀번호는 동시에 할당되거나 할당되"
"지 않아야합니다."
msgid "Restores"
msgstr "복구"
msgid "SA"
msgstr "토"
msgid "SU"
msgstr "일"
msgid "Saturday"
msgstr "토요일"
msgid "Saved Info Schema"
msgstr "저장된 정보 Schema"
msgid "Schedule Protect"
msgstr "Protect 스케쥴"
msgid "Schedule Protect."
msgstr "예정된 Protect."
msgid "Schedule protect successfully."
msgstr "Protect 스케쥴을 완료하였습니다."
msgid "Scheduled Operations"
msgstr "예정된 운영"
msgid "Scheduled deletion of Checkpoint"
msgid_plural "Scheduled deletion of Checkpoints"
msgstr[0] "체크포인트 삭제 예약"
msgid "Show Checkpoints"
msgstr "체크포인트 확인"
msgid "State"
msgstr "상태"
msgid "Status"
msgstr "상태"
msgctxt "Task status of an Restore"
msgid "Success"
msgstr "완료"
msgid "Sunday"
msgstr "일요일"
msgid "TH"
msgstr "목"
msgid "TU"
msgstr "화"
msgid "TYPE"
msgstr "타입"
msgid "Thursday"
msgstr "목요일"
msgid "Time Trigger"
msgstr "시간 트리거"
msgid "Today"
msgstr "오늘"
msgid "Trigger"
msgstr "트리거"
msgid "Trigger Details"
msgstr "트리거 상세 정보"
msgid "Trigger Name"
msgstr "트리거 이름"
msgid "Trigger Type"
msgstr "트리거 타입"
msgid "Trigger created successfully."
msgstr "트리거를 성공적으로 생성하였습니다."
msgid "Triggers"
msgstr "트리거"
msgid "Tuesday"
msgstr "화요일"
msgid "Type"
msgstr "타입"
msgid "Unable to create protection plan."
msgstr "Protection 계획을 생성할 수 없습니다."
msgid "Unable to create trigger."
msgstr "트리거를 생성할 수 없습니다."
msgid "Unable to get instances."
msgstr "인스턴스를 가져올 수 없습니다."
msgid "Unable to protect now"
msgstr "지금 protect 를 시작할 수 없습니다."
msgid "Unable to restore checkpoint."
msgstr "체크포인트로 복구할 수 없습니다."
msgid "Unable to retrieve anyone provider."
msgstr "어떤 프로바이더도 찾을 수 없습니다."
msgid "Unable to retrieve checkpoint details."
msgstr "체크포인트 상세 정보를 찾을 수 없습니다."
msgid "Unable to retrieve checkpoints list."
msgstr "체크포인트 목록을 찾을 수 없습니다."
msgid "Unable to retrieve protection plan details."
msgstr "Protection 계획 상세 정보를 찾을 수 없습니다."
msgid "Unable to retrieve protection plans list."
msgstr "Protection 계획 목록을 찾을 수 없습니다."
msgid "Unable to retrieve protection provider details."
msgstr "Protection 프로바이더 상세 정보를 찾을 수 없습니다."
msgid "Unable to retrieve protection providers list."
msgstr "Protection 프로바이더 목록을 찾을 수 없습니다."
msgid "Unable to retrieve protection resources."
msgstr "Protection 리소스를 찾을 수 없습니다."
msgid "Unable to retrieve provider contents."
msgstr "Provider 콘텐츠를 찾을 수 없습니다."
msgid "Unable to retrieve provider details."
msgstr "프로바이더 상세 정보를 찾을 수 없습니다."
msgid "Unable to retrieve restore list."
msgstr "복구 목록을 찾을 수 없습니다."
msgid "Unable to retrieve scheduled operation list."
msgstr "예정된 운영 목록을 찾을 수 없습니다."
msgid "Unable to retrieve trigger details."
msgstr "트리거 상세 정보를 찾을 수 없습니다."
msgid "Unable to retrieve triggers list."
msgstr "트리거 목록을 찾을 수 없습니다."
msgid "Unable to schedule protect."
msgstr "Protect 스케쥴을 수행할 수 없습니다."
msgid "Unable to update protection plan. "
msgstr "Protection 계획을 업데이트할 수 없습니다."
msgid "Update Protection Plan"
msgstr "Protection 계획 업데이트"
msgid "Use current session credentials"
msgstr "현재 세션 credentials 사용"
msgid "WE"
msgstr "수"
msgid "Wednesday"
msgstr "수요일"
msgid "checkpoint list can not be retrieved."
msgstr "체크포인트 목록을 검색할 수 없습니다."
msgid "{{ checkpoint.protection_plan.name }}"
msgstr "{{ checkpoint.protection_plan.name }}"

View File

@ -1,26 +0,0 @@
# Copyright (c) 2016 Huawei, Inc.
#
# 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 karbor_dashboard import dashboard
class OperationLogs(horizon.Panel):
name = _("Operation Logs")
slug = 'operationlogs'
dashboard.DataProtection.register(OperationLogs)

View File

@ -1,41 +0,0 @@
# Copyright (c) 2016 Huawei, Inc.
#
# 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 tables
class OperationLogsTable(tables.DataTable):
id = tables.Column('id',
verbose_name=_('ID'))
name = tables.Column('name',
verbose_name=_('Name'))
type = tables.Column('type',
verbose_name=_('Type'))
state = tables.Column('state',
verbose_name=_('State'))
expect_start_time = tables.Column(
'expect_start_time',
verbose_name=_('Expect Start Time'))
actual_start_time = tables.Column(
'actual_start_time',
verbose_name=_('Actual Start Time'))
end_time = tables.Column(
'end_time',
verbose_name=_('End Time'))
class Meta(object):
name = 'operationlogs'
verbose_name = _('Operation Logs')

View File

@ -1,21 +0,0 @@
# Copyright (c) 2016 Huawei, Inc.
#
# 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 url
from karbor_dashboard.operationlogs import views
urlpatterns = [
url(r'^$', views.IndexView.as_view(), name='index'),
]

View File

@ -1,29 +0,0 @@
# Copyright (c) 2016 Huawei, Inc.
#
# 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 tables as horizon_tables
from karbor_dashboard.operationlogs import tables
class IndexView(horizon_tables.DataTableView):
table_class = tables.OperationLogsTable
template_name = 'operationlogs/index.html'
page_title = _("Operation Logs")
def get_data(self):
logs = []
return logs

View File

@ -1,167 +0,0 @@
# Copyright (c) 2016 Huawei, Inc.
#
# 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 import forms
from django.utils.translation import ugettext_lazy as _
from horizon import exceptions
from horizon import forms as horizon_forms
from horizon import messages
from oslo_serialization import jsonutils
from karbor_dashboard.api import karbor as karborclient
STATUS_CHOICE = [("suspended", "suspended"),
("started", "started")]
class CreateProtectionPlanForm(horizon_forms.SelfHandlingForm):
name = forms.CharField(label=_("Name"))
provider_id = forms.ChoiceField(label=_('Protection Provider'),
choices=[],
widget=forms.Select(attrs={
'class': 'switchable'}))
providers = forms.CharField(
widget=forms.HiddenInput(attrs={"class": "providers"}))
actionmode = forms.CharField(
widget=forms.HiddenInput(attrs={"class": "actionmode"}))
resources = forms.CharField(
widget=forms.HiddenInput(attrs={"class": "resources"}))
parameters = forms.CharField(
widget=forms.HiddenInput(attrs={"class": "parameters"}))
def __init__(self, request, *args, **kwargs):
self.next_view = kwargs.pop('next_view')
super(CreateProtectionPlanForm, self).\
__init__(request, *args, **kwargs)
result = []
providers = karborclient.provider_list(request)
self.fields['providers'].initial = \
jsonutils.dumps([f._info for f in providers])
if providers:
result = [(e.id, e.name) for e in providers]
self.fields['provider_id'].choices = result
def handle(self, request, data):
try:
resources = jsonutils.loads(data["resources"])
types = {resource["type"] for resource in resources}
parameters = jsonutils.loads(data["parameters"])
parameters = {k: v for k, v in parameters.items()
if k.split("#")[0] in types}
new_plan = karborclient.plan_create(
request,
data["name"],
data["provider_id"],
resources,
parameters,
)
messages.success(request,
_("Protection Plan created successfully."))
if data["actionmode"] == "schedule":
request.method = 'GET'
return self.next_view.as_view()(request,
plan_id=new_plan.id)
elif data["actionmode"] == "now":
karborclient.checkpoint_create(request, new_plan.provider_id,
new_plan.id)
messages.success(request, _("Protect now successfully."))
return new_plan
except Exception:
exceptions.handle(request, _('Unable to create protection plan.'))
class UpdateProtectionPlanForm(horizon_forms.SelfHandlingForm):
name = forms.CharField(label=_("Name"), max_length=255, required=False)
status = forms.ChoiceField(label=_('Status'),
choices=STATUS_CHOICE,
widget=forms.Select(attrs={
'class': 'switchable'}))
plan = forms.CharField(
widget=forms.HiddenInput(attrs={"class": "plan"}))
provider = forms.CharField(
widget=forms.HiddenInput(attrs={"class": "provider"}))
resources = forms.CharField(
widget=forms.HiddenInput(attrs={"class": "resources"}))
parameters = forms.CharField(
widget=forms.HiddenInput(attrs={"class": "parameters"}))
def handle(self, request, data):
plan_id = self.initial['plan_id']
status = data["status"]
data_ = {"status": status}
name = data["name"]
if name:
data_.update({"name": name})
resources = jsonutils.loads(data["resources"])
if resources:
resources_ = []
for resource in resources:
if resource not in resources_:
resources_.append(resource)
data_.update({"resources": resources_})
try:
new_plan = karborclient.plan_update(request,
plan_id,
data_)
messages.success(request,
_("Protection Plan updated successfully."))
return new_plan
except Exception:
msg = _('Unable to update protection plan.')
exceptions.handle(request, msg)
class ScheduleProtectForm(horizon_forms.SelfHandlingForm):
id = forms.CharField(label=_("ID"), widget=forms.HiddenInput)
name = forms.CharField(label=_("Name"), widget=forms.HiddenInput)
provider_id = forms.CharField(label=_("Provider ID"),
widget=forms.HiddenInput)
trigger_id = horizon_forms.DynamicChoiceField(
label=_("Associate with Trigger"),
add_item_link="horizon:karbor:triggers:create")
def __init__(self, request, *args, **kwargs):
super(ScheduleProtectForm, self).__init__(request, *args, **kwargs)
result = []
triggers = karborclient.trigger_list(request)
if triggers:
result = [(e.id, e.name) for e in triggers]
self.fields['trigger_id'].choices = result
def handle(self, request, data):
try:
operation_definition = dict(provider_id=data["provider_id"],
plan_id=data["id"])
karborclient.scheduled_operation_create(request,
data["name"],
"protect",
data["trigger_id"],
operation_definition)
messages.success(request, _("Schedule protect successfully."))
return True
except Exception:
exceptions.handle(request, _('Unable to schedule protect.'))

View File

@ -1,26 +0,0 @@
# Copyright (c) 2016 Huawei, Inc.
#
# 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 karbor_dashboard import dashboard
class ProtectionPlans(horizon.Panel):
name = _("Protection Plans")
slug = 'protectionplans'
dashboard.DataProtection.register(ProtectionPlans)

View File

@ -1,143 +0,0 @@
# Copyright (c) 2016 Huawei, Inc.
#
# 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 import http
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ungettext_lazy
from horizon import exceptions
from horizon import messages
from horizon import tables
from karbor_dashboard.api import karbor as karborclient
class CreateProtectionPlanLink(tables.LinkAction):
name = "create"
verbose_name = _("Create Protection Plan")
url = "horizon:karbor:protectionplans:create"
classes = ("ajax-modal",)
icon = "plus"
def allowed(self, request, protectionplan):
return True
class ScheduleProtectLink(tables.LinkAction):
name = "scheduleprotect"
verbose_name = _("Schedule Protect")
url = "horizon:karbor:protectionplans:scheduleprotect"
classes = ("ajax-modal",)
def allowed(self, request, plan):
return True
class EditPlanLink(tables.LinkAction):
name = "editplan"
verbose_name = _("Edit Plan")
url = "horizon:karbor:protectionplans:update"
classes = ("ajax-modal",)
def allowed(self, request, protectionplan):
return True
class ProtectNowLink(tables.Action):
name = "protectnow"
verbose_name = _("Protect Now")
def allowed(self, request, protectionplan):
return True
def single(self, table, request, obj_id):
try:
datum = self.table.get_object_by_id(obj_id)
provider_id = datum.provider_id
karborclient.checkpoint_create(request, provider_id, obj_id)
messages.success(request, _("Plan protection initiated"))
redirect = reverse("horizon:karbor:checkpoints:index",
args=(provider_id,))
return http.HttpResponseRedirect(redirect)
except Exception:
exceptions.handle(request, _('Unable to protect now'))
class DeleteProtectionPlansAction(tables.DeleteAction):
@staticmethod
def action_present(count):
return ungettext_lazy(
u"Delete Protection Plan",
u"Delete Protection Plans",
count
)
@staticmethod
def action_past(count):
return ungettext_lazy(
u"Delete Protection Plan",
u"Delete Protection Plans",
count
)
def allowed(self, request, protectionplan):
return True
def delete(self, request, obj_id):
karborclient.plan_delete(request, obj_id)
class ProtectionPlanFilterAction(tables.FilterAction):
def filter(self, table, protectionplans, filter_string):
"""Naive case-insensitive search."""
query = filter_string.lower()
return [protectionplan for protectionplan in protectionplans
if query in protectionplan.name.lower()]
def provider_link(plan):
return reverse('horizon:karbor:protectionproviders:detail',
args=(plan.provider_id, ))
class ProtectionPlansTable(tables.DataTable):
name = tables.Column('name',
link="horizon:karbor:protectionplans:detail",
verbose_name=_('Name'))
provider = tables.Column('provider_name',
link=provider_link,
verbose_name=_('Protection Provider'))
status = tables.Column('status',
verbose_name=_('Status'))
class Meta(object):
name = 'protectionplans'
verbose_name = _('Protection Plans')
row_actions = (ScheduleProtectLink, EditPlanLink, ProtectNowLink,
DeleteProtectionPlansAction)
table_actions = (ProtectionPlanFilterAction, CreateProtectionPlanLink,
DeleteProtectionPlansAction)
class DetailTable(tables.DataTable):
id = tables.Column("id", verbose_name=_("ID"))
type = tables.Column("type", verbose_name=_("TYPE"))
class Meta(object):
name = "protectionresources"
verbose_name = _("Protection Resources")
hidden_title = False

View File

@ -1,28 +0,0 @@
# Copyright (c) 2016 Huawei, Inc.
#
# 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 url
from karbor_dashboard.protectionplans import views
urlpatterns = [
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^create/$', views.CreateView.as_view(), name='create'),
url(r'^(?P<plan_id>[^/]+)/scheduleprotect/$',
views.ScheduleProtectView.as_view(), name='scheduleprotect'),
url(r'^(?P<plan_id>[^/]+)/detail/$',
views.DetailView.as_view(), name='detail'),
url(r'^(?P<plan_id>[^/]+)/update/$',
views.UpdateView.as_view(), name='update'),
]

View File

@ -1,314 +0,0 @@
# Copyright (c) 2016 Huawei, Inc.
#
# 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.core.urlresolvers import reverse_lazy
from django.utils.translation import ugettext_lazy as _
from horizon import exceptions
from horizon import forms as horizon_forms
from horizon import tables as horizon_tables
from horizon.utils import memoized
from horizon import views as horizon_views
from karbor_dashboard.api import karbor as karborclient
from karbor_dashboard.protectionplans import forms
from karbor_dashboard.protectionplans import tables
from karborclient.v1 import protectables
from oslo_serialization import jsonutils
from oslo_utils import uuidutils
class IndexView(horizon_tables.DataTableView):
table_class = tables.ProtectionPlansTable
template_name = 'protectionplans/index.html'
page_title = _("Protection Plans")
def has_prev_data(self, table):
return self._prev
def has_more_data(self, table):
return self._more
def get_data(self):
request = self.request
prev_marker = request.GET.get(
tables.ProtectionPlansTable._meta.prev_pagination_param, None)
if prev_marker is not None:
marker = prev_marker
else:
marker = request.GET.get(
tables.ProtectionPlansTable._meta.pagination_param, None)
reversed_order = prev_marker is not None
plans = []
try:
plans, self._more, self._prev = karborclient.plan_list_paged(
request, None,
marker=marker,
paginate=True,
sort_dir='asc',
sort_key='name',
reversed_order=reversed_order)
except Exception:
self._prev = False
self._more = False
exceptions.handle(self.request,
_('Unable to retrieve protection plans list.'))
providers = {}
try:
providers = {provider.id: provider.name
for provider in karborclient.provider_list(request)}
except Exception:
pass
for plan in plans:
provider_id = plan.provider_id
plan.provider_name = providers.get(provider_id, provider_id)
return plans
class CreateView(horizon_forms.ModalFormView):
template_name = 'protectionplans/create.html'
modal_header = _("Create Protection Plan")
form_id = "create_protectionplan_form"
form_class = forms.CreateProtectionPlanForm
submit_label = _("Create Protection Plan")
submit_url = reverse_lazy("horizon:karbor:protectionplans:create")
success_url = reverse_lazy('horizon:karbor:protectionplans:index')
page_title = _("Create Protection Plan")
def get_context_data(self, **kwargs):
context = super(CreateView, self).get_context_data(**kwargs)
context["instances"] = self.get_object()
return context
def get_form_kwargs(self):
kwargs = super(CreateView, self).get_form_kwargs()
kwargs['next_view'] = ScheduleProtectView
return kwargs
@memoized.memoized_method
def get_object(self):
try:
instances = karborclient.protectable_list_instances(
self.request, "OS::Keystone::Project")
results = []
self.get_results(instances, None, results)
return results
except Exception:
exceptions.handle(
self.request,
_('Unable to create protection plan.'),
redirect=reverse("horizon:karbor:protectionplans:index"))
def get_results(self, instances, showparentid, results):
for instance in instances:
if instance is not None:
resource = {}
resource["id"] = instance.id
resource["type"] = instance.type
resource["name"] = instance.name
resource["showid"] = uuidutils.generate_uuid()
resource["showparentid"] = showparentid
result = protectables.Instances(self, resource)
results.append(result)
for dependent_resource in instance.dependent_resources:
if dependent_resource is not None:
dependent = karborclient.protectable_get_instance(
self.request,
dependent_resource["type"],
dependent_resource["id"])
self.get_results([dependent], result.showid, results)
class UpdateView(horizon_forms.ModalFormView):
template_name = 'protectionplans/update.html'
modal_header = _("Update Protection Plan")
form_id = "update_protectionplan_form"
form_class = forms.UpdateProtectionPlanForm
submit_label = _("Update Protection Plan")
submit_url = "horizon:karbor:protectionplans:update"
success_url = reverse_lazy('horizon:karbor:protectionplans:index')
page_title = _("Update Protection Plan")
def get_context_data(self, **kwargs):
context = super(UpdateView, self).get_context_data(**kwargs)
context["instances"] = self.get_protectable_objects()
args = (self.kwargs['plan_id'],)
context['submit_url'] = reverse(self.submit_url, args=args)
return context
@memoized.memoized_method
def get_protectable_objects(self):
try:
instances = karborclient.protectable_list_instances(
self.request, "OS::Keystone::Project")
results = []
self.get_results(instances, None, results)
return results
except Exception:
exceptions.handle(
self.request,
_('Unable to retrieve protection resources.'),
redirect=reverse("horizon:karbor:protectionplans:index"))
def get_results(self, instances, showparentid, results):
for instance in instances:
if instance is not None:
resource = {}
resource["id"] = instance.id
resource["type"] = instance.type
resource["name"] = instance.name
resource["showid"] = uuidutils.generate_uuid()
resource["showparentid"] = showparentid
result = protectables.Instances(self, resource)
results.append(result)
for dependent_resource in instance.dependent_resources:
if dependent_resource is not None:
dependent = karborclient.protectable_get_instance(
self.request,
dependent_resource["type"],
dependent_resource["id"])
self.get_results([dependent], result.showid, results)
@memoized.memoized_method
def get_plan_object(self, *args, **kwargs):
plan_id = self.kwargs['plan_id']
try:
return karborclient.plan_get(self.request, plan_id)
except Exception:
redirect = reverse("horizon:karbor:protectionplans:index")
msg = _('Unable to retrieve protection plan details.')
exceptions.handle(self.request, msg, redirect=redirect)
@memoized.memoized_method
def get_provider_object(self, provider_id):
try:
return karborclient.provider_get(self.request, provider_id)
except Exception:
redirect = reverse("horizon:karbor:protectionplans:index")
msg = _('Unable to retrieve provider details.')
exceptions.handle(self.request, msg, redirect=redirect)
def get_initial(self):
initial = super(UpdateView, self).get_initial()
plan = self.get_plan_object()
provider = self.get_provider_object(plan.provider_id)
initial.update({'plan_id': self.kwargs['plan_id'],
'name': getattr(plan, 'name', ''),
'plan': jsonutils.dumps(plan._info),
'provider': jsonutils.dumps(provider._info)})
return initial
class ScheduleProtectView(horizon_forms.ModalFormView):
template_name = 'protectionplans/scheduleprotect.html'
modal_header = _("Schedule Protect")
form_id = "scheduleprotect_form"
form_class = forms.ScheduleProtectForm
submit_label = _("Schedule Protect")
submit_url = "horizon:karbor:protectionplans:scheduleprotect"
success_url = reverse_lazy('horizon:karbor:protectionplans:index')
page_title = _("Schedule Protect")
@memoized.memoized_method
def get_object(self):
try:
return karborclient.plan_get(self.request, self.kwargs['plan_id'])
except Exception:
exceptions.handle(
self.request,
_('Unable to schedule protect.'),
redirect=reverse("horizon:karbor:protectionplans:index"))
def get_context_data(self, **kwargs):
context = super(ScheduleProtectView, self).get_context_data(**kwargs)
args = (self.get_object().id,)
context["plan"] = self.get_object()
context['submit_url'] = reverse(self.submit_url, args=args)
return context
def get_initial(self):
plan = self.get_object()
return {'id': plan.id,
'name': plan.name,
'provider_id': plan.provider_id}
class DetailView(horizon_views.HorizonTemplateView):
template_name = 'protectionplans/detail.html'
page_title = "{{ plan.name }}"
def get_context_data(self, **kwargs):
context = super(DetailView, self).get_context_data(**kwargs)
plan = self.get_data()
table = tables.ProtectionPlansTable(self.request)
context["plan"] = plan
context["provider"] = self.get_provider(plan.provider_id)
context["instances"] = self.get_instances(plan.resources)
context["url"] = reverse("horizon:karbor:protectionplans:index")
context["actions"] = table.render_row_actions(plan)
return context
@memoized.memoized_method
def get_data(self):
try:
return karborclient.plan_get(self.request, self.kwargs['plan_id'])
except Exception:
exceptions.handle(
self.request,
_('Unable to retrieve protection plan details.'),
redirect=reverse("horizon:karbor:protectionplans:index"))
@memoized.memoized_method
def get_provider(self, provider_id):
provider = None
if provider_id:
try:
provider = karborclient.provider_get(self.request, provider_id)
except Exception:
exceptions.handle(
self.request,
_('Unable to retrieve protection provider details.'),
redirect=reverse("horizon:karbor:protectionplans:index"))
return provider
@memoized.memoized_method
def get_instances(self, instances):
try:
result = []
for instance in instances:
instance["showid"] = uuidutils.generate_uuid()
result.append(protectables.Instances(self, instance))
detail_instance = karborclient.protectable_get_instance(
self.request,
instance["type"].strip(),
instance["id"].strip())
if detail_instance.dependent_resources:
for dependent in detail_instance.dependent_resources:
dependent["showid"] = uuidutils.generate_uuid()
dependent["showparentid"] = instance["showid"]
result.append(
protectables.Instances(self, dependent))
return result
except Exception:
exceptions.handle(
self.request,
_('Unable to get instances.'),
redirect=reverse("horizon:karbor:protectionplans:index"))

View File

@ -1,26 +0,0 @@
# Copyright (c) 2016 Huawei, Inc.
#
# 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 karbor_dashboard import dashboard
class ProtectionProviders(horizon.Panel):
name = _("Protection Providers")
slug = 'protectionproviders'
dashboard.DataProtection.register(ProtectionProviders)

View File

@ -1,56 +0,0 @@
# Copyright (c) 2016 Huawei, Inc.
#
# 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 import http
from django.utils.translation import ugettext_lazy as _
from horizon import tables
class ShowCheckpointsAction(tables.Action):
name = "checkpoints"
verbose_name = _("Show Checkpoints")
def allowed(self, request, provider):
return True
def single(self, table, request, obj_id):
redirect = reverse("horizon:karbor:checkpoints:index",
args=(obj_id,))
return http.HttpResponseRedirect(redirect)
class ProtectionProviderFilterAction(tables.FilterAction):
def filter(self, table, protectionproviders, filter_string):
"""Naive case-insensitive search."""
query = filter_string.lower()
return [protectionprovider
for protectionprovider in protectionproviders
if query in protectionprovider.name.lower()]
class ProtectionProvidersTable(tables.DataTable):
name = tables.Column('name',
link="horizon:karbor:protectionproviders:detail",
verbose_name=_('Name'))
description = tables.Column('description',
verbose_name=_('Description'))
class Meta(object):
name = 'protectionproviders'
verbose_name = _('Protection Providers')
row_actions = (ShowCheckpointsAction,)
table_actions = (ProtectionProviderFilterAction,)
multi_select = False

View File

@ -1,91 +0,0 @@
# Copyright (c) 2016 Huawei, Inc.
#
# 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 tabs
from karbor_dashboard.api import karbor as karborclient
import simplejson as json
class OptionsSchemaTab(tabs.Tab):
name = _("Options Schema")
slug = "optionsschema"
template_name = "protectionproviders/_schema_contents.html"
def get_context_data(self, request):
try:
provider_id = self.tab_group.kwargs['provider_id']
provider = karborclient.provider_get(request, provider_id)
schema = {}
if provider is not None:
if 'options_schema' in provider.extended_info_schema:
schema = provider.extended_info_schema['options_schema']
return {"schema_contents": json.dumps(schema, indent=4)}
except Exception:
msg = _('Unable to retrieve provider contents.')
exceptions.handle(request, msg)
return None
class RestoreSchemaTab(tabs.Tab):
name = _("Restore Schema")
slug = "restoreschema"
template_name = "protectionproviders/_schema_contents.html"
def get_context_data(self, request):
try:
provider_id = self.tab_group.kwargs['provider_id']
provider = karborclient.provider_get(request, provider_id)
schema = {}
if provider is not None:
if 'restore_schema' in provider.extended_info_schema:
schema = provider.extended_info_schema['restore_schema']
return {"schema_contents": json.dumps(schema, indent=4)}
except Exception:
msg = _('Unable to retrieve provider contents.')
exceptions.handle(request, msg)
return None
class SavedInfoSchemaTab(tabs.Tab):
name = _("Saved Info Schema")
slug = "savedinfoschema"
template_name = "protectionproviders/_schema_contents.html"
def get_context_data(self, request):
try:
provider_id = self.tab_group.kwargs['provider_id']
provider = karborclient.provider_get(request, provider_id)
schema = {}
if provider is not None:
if 'saved_info_schema' in provider.extended_info_schema:
schema = provider.extended_info_schema['saved_info_schema']
return {"schema_contents": json.dumps(schema, indent=4)}
except Exception:
msg = _('Unable to retrieve provider contents.')
exceptions.handle(request, msg)
return None
class ProviderDetailTabs(tabs.TabGroup):
slug = "provider_details"
tabs = (OptionsSchemaTab, RestoreSchemaTab, SavedInfoSchemaTab)

View File

@ -1,23 +0,0 @@
# Copyright (c) 2016 Huawei, Inc.
#
# 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 url
from karbor_dashboard.protectionproviders import views
urlpatterns = [
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^(?P<provider_id>[^/]+)/detail/$',
views.DetailView.as_view(), name='detail'),
]

View File

@ -1,94 +0,0 @@
# Copyright (c) 2016 Huawei, Inc.
#
# 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 exceptions
from horizon import tables as horizon_tables
from horizon import tabs as horizon_tabs
from horizon.utils import memoized
from karbor_dashboard.api import karbor as karborclient
from karbor_dashboard.protectionproviders import tables
from karbor_dashboard.protectionproviders import tabs
class IndexView(horizon_tables.DataTableView):
table_class = tables.ProtectionProvidersTable
template_name = 'protectionproviders/index.html'
page_title = _("Protection Providers")
def has_prev_data(self, table):
return self._prev
def has_more_data(self, table):
return self._more
def get_data(self):
request = self.request
prev_marker = request.GET.get(
tables.ProtectionProvidersTable._meta.prev_pagination_param, None)
if prev_marker is not None:
marker = prev_marker
else:
marker = request.GET.get(
tables.ProtectionProvidersTable._meta.pagination_param, None)
reversed_order = prev_marker is not None
providers = []
try:
providers, self._more, self._prev = \
karborclient.provider_list_paged(
request, None,
marker=marker,
paginate=True,
sort_dir='asc',
sort_key='name',
reversed_order=reversed_order)
except Exception:
self._prev = False
self._more = False
exceptions.handle(
self.request,
_('Unable to retrieve protection providers list.'))
return providers
class DetailView(horizon_tabs.TabView):
redirect_url = "horizon:karbor:protectionproviders:index"
tab_group_class = tabs.ProviderDetailTabs
template_name = 'protectionproviders/detail.html'
page_title = "{{ provider.name }}"
def get_context_data(self, **kwargs):
context = super(DetailView, self).get_context_data(**kwargs)
context["provider"] = self.get_data()
return context
@memoized.memoized_method
def get_data(self):
try:
provider_id = self.kwargs['provider_id']
provider = karborclient.provider_get(self.request, provider_id)
except Exception:
exceptions.handle(
self.request,
_('Unable to retrieve protection provider details.'),
redirect=reverse("horizon:karbor:protectionproviders:index"))
return provider
def get_tabs(self, request, *args, **kwargs):
provider = self.get_data()
return self.tab_group_class(request, provider=provider, **kwargs)

View File

@ -1,26 +0,0 @@
# Copyright (c) 2016 Huawei, Inc.
#
# 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 karbor_dashboard import dashboard
class Restores(horizon.Panel):
name = _("Restores")
slug = 'restores'
dashboard.DataProtection.register(Restores)

View File

@ -1,77 +0,0 @@
# Copyright (c) 2016 Huawei, Inc.
#
# 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 pgettext_lazy
from django.utils.translation import ugettext_lazy as _
from horizon import tables
from karbor_dashboard.api import karbor as karborclient
TASK_DISPLAY_CHOICES = (
("fail", pgettext_lazy("Task status of an Restore", u"Fail")),
("in_progress", pgettext_lazy("Task status of an Restore",
u"In Progress")),
("success", pgettext_lazy("Task status of an Restore", u"Success")),
)
class UpdateRow(tables.Row):
ajax = True
def get_data(self, request, obj_id):
restore = karborclient.restore_get(request, obj_id)
checkpoint = karborclient.checkpoint_get(request,
restore.provider_id,
restore.checkpoint_id)
provider = karborclient.provider_get(request,
restore.provider_id)
setattr(restore, "name", checkpoint.protection_plan["name"])
setattr(restore, "provider_name", provider.name)
return restore
class RestoresTable(tables.DataTable):
TASK_STATUS_CHOICES = (
("fail", False),
("success", True),
)
id = tables.Column(
'id',
verbose_name=_('ID'))
name = tables.Column(
'name',
verbose_name=_('Protection Plan'))
status = tables.Column(
'status',
verbose_name=_('Status'),
status=True,
status_choices=TASK_STATUS_CHOICES,
display_choices=TASK_DISPLAY_CHOICES)
restore_from_checkpoint = tables.Column(
'checkpoint_id',
verbose_name=_('Restore From Checkpoint'))
restore_target = tables.Column(
'restore_target',
verbose_name=_('Restore Target'))
protection_provider = tables.Column(
'provider_name',
verbose_name=_('Protection Provider'))
class Meta(object):
name = 'restores'
verbose_name = _('Restores')
status_columns = ["status", ]
row_class = UpdateRow

View File

@ -1,21 +0,0 @@
# Copyright (c) 2016 Huawei, Inc.
#
# 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 url
from karbor_dashboard.restores import views
urlpatterns = [
url(r'^$', views.IndexView.as_view(), name='index'),
]

View File

@ -1,76 +0,0 @@
# Copyright (c) 2016 Huawei, Inc.
#
# 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 tables as horizon_tables
from karbor_dashboard.api import karbor as karborclient
from karbor_dashboard.restores import tables
class IndexView(horizon_tables.DataTableView):
table_class = tables.RestoresTable
template_name = 'restores/index.html'
page_title = _("Restores")
def has_prev_data(self, table):
return self._prev
def has_more_data(self, table):
return self._more
def get_data(self):
request = self.request
prev_marker = request.GET.get(
tables.RestoresTable._meta.prev_pagination_param, None)
if prev_marker is not None:
marker = prev_marker
else:
marker = request.GET.get(
tables.RestoresTable._meta.pagination_param, None)
reversed_order = prev_marker is not None
restores = []
try:
restores, self._more, self._prev = \
karborclient.restore_list_paged(
self.request,
marker=marker,
paginate=True,
sort_dir='asc',
sort_key='id',
reversed_order=reversed_order)
for restore in restores:
try:
checkpoint = karborclient.checkpoint_get(
self.request,
restore.provider_id,
restore.checkpoint_id)
plan_name = checkpoint.protection_plan["name"]
except Exception:
plan_name = "Not Found"
provider = karborclient.provider_get(self.request,
restore.provider_id)
setattr(restore, "name", plan_name)
setattr(restore, "provider_name", provider.name)
except Exception:
self._prev = False
self._more = False
exceptions.handle(self.request,
_('Unable to retrieve restore list.'))
return restores

View File

@ -1,26 +0,0 @@
# Copyright (c) 2016 Huawei, Inc.
#
# 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 karbor_dashboard import dashboard
class ScheduledOperations(horizon.Panel):
name = _("Scheduled Operations")
slug = 'scheduledoperations'
dashboard.DataProtection.register(ScheduledOperations)

View File

@ -1,77 +0,0 @@
# Copyright (c) 2016 Huawei, Inc.
#
# 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 django.utils.translation import ungettext_lazy
from horizon import tables
from karbor_dashboard.api import karbor as karborclient
class ScheduledOperationFilterAction(tables.FilterAction):
def filter(self, table, scheduledoperations, filter_string):
"""Naive case-insensitive search."""
query = filter_string.lower()
return [scheduledoperation
for scheduledoperation in scheduledoperations
if query in scheduledoperation.name.lower()]
class DeleteScheduledOperationsAction(tables.DeleteAction):
@staticmethod
def action_present(count):
return ungettext_lazy(u"Delete Scheduled Operation",
u"Delete Scheduled Operations",
count)
@staticmethod
def action_past(count):
return ungettext_lazy(u"Deleted Scheduled Operation",
u"Deleted Scheduled Operations",
count)
def allowed(self, request, scheduledoperation):
return True
def delete(self, request, obj_id):
karborclient.scheduled_operation_delete(request, obj_id)
class ScheduledOperationsTable(tables.DataTable):
id = tables.Column(
'id',
verbose_name=_('ID'))
name = tables.Column(
'name',
verbose_name=_('Name'))
operation_type = tables.Column(
'operation_type',
verbose_name=_('Operation Type'))
plan_name = tables.Column(
'plan_name',
verbose_name=_('Protection Plan'))
provider_name = tables.Column(
'provider_name',
verbose_name=_('Protection Provider'))
trigger_name = tables.Column(
'trigger_name',
verbose_name=_('Trigger'))
class Meta(object):
name = 'scheduledoperations'
verbose_name = _('Scheduled Operations')
row_actions = (DeleteScheduledOperationsAction,)
table_actions = (ScheduledOperationFilterAction,
DeleteScheduledOperationsAction)

View File

@ -1,21 +0,0 @@
# Copyright (c) 2016 Huawei, Inc.
#
# 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 url
from karbor_dashboard.scheduledoperations import views
urlpatterns = [
url(r'^$', views.IndexView.as_view(), name='index'),
]

View File

@ -1,91 +0,0 @@
# Copyright (c) 2016 Huawei, Inc.
#
# 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 tables as horizon_tables
from karbor_dashboard.api import karbor as karborclient
from karbor_dashboard.scheduledoperations import tables
class IndexView(horizon_tables.DataTableView):
table_class = tables.ScheduledOperationsTable
template_name = 'scheduledoperations/index.html'
page_title = _("Scheduled Operations")
def has_prev_data(self, table):
return self._prev
def has_more_data(self, table):
return self._more
def get_data(self):
request = self.request
prev_marker = request.GET.get(
tables.ScheduledOperationsTable._meta.prev_pagination_param, None)
if prev_marker is not None:
marker = prev_marker
else:
marker = request.GET.get(
tables.ScheduledOperationsTable._meta.pagination_param, None)
reversed_order = prev_marker is not None
scheduledoperations = []
try:
scheduledoperations, self._more, self._prev = \
karborclient.scheduled_operation_list_paged(
self.request,
marker=marker,
paginate=True,
sort_dir='asc',
sort_key='name',
reversed_order=reversed_order)
for scheduledoperation in scheduledoperations:
plan_name, provider_name, trigger_name = '', '', ''
operation_definition = scheduledoperation.operation_definition
if "plan_id" in operation_definition.keys():
plan = karborclient.plan_get(
self.request,
operation_definition["plan_id"])
if plan:
plan_name = plan.name
if "provider_id" in operation_definition.keys():
provider = karborclient.provider_get(
self.request,
operation_definition["provider_id"])
if provider:
provider_name = provider.name
trigger = karborclient.trigger_get(
self.request,
scheduledoperation.trigger_id)
if trigger:
trigger_name = trigger.name
setattr(scheduledoperation, "plan_name", plan_name)
setattr(scheduledoperation, "provider_name", provider_name)
setattr(scheduledoperation, "trigger_name", trigger_name)
except Exception:
self._prev = False
self._more = False
exceptions.handle(
self.request,
_('Unable to retrieve scheduled operation list.'))
return scheduledoperations

View File

@ -1,45 +0,0 @@
table.treetable span.indenter {
display: inline-block;
margin: 0;
padding: 0;
text-align: right;
user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-o-user-select: none;
-webkit-user-select: none;
width: 19px;
}
table.treetable span.indenter a {
background-position: left center;
background-repeat: no-repeat;
display: inline-block;
text-decoration: none;
width: 19px;
}
table.treetable span {
background-position: center left;
background-repeat: no-repeat;
}
table.treetable tr.collapsed span.indenter a {
background-image: url('../images/expand.png');
}
table.treetable tr.expanded span.indenter a {
background-image: url('../images/collapse.png');
}
table.treetable span.logoresource {
background-image: url('../images/logoicon.png');
display: inline-block;
width:16px;
height:16px;
vertical-align: middle;
}
table.treetable span.spanresource {
vertical-align: middle;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 850 B

View File

@ -1,21 +0,0 @@
/* Copyright (c) 2016 Huawei, Inc.
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.
*/
horizon.checkpoints_detail = {
init: function() {
/* init resource tree */
$("#checkpointDetailResource").treetable({ expandable: true });
}
};

View File

@ -1,144 +0,0 @@
/* Copyright (c) 2016 Huawei, Inc.
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.
*/
/* set the choose resources */
function setRestoredResource() {
var trResources = $("#checkpointRestoreResource tr[resource-id]");
var provider = $.parseJSON($(".provider").val());
var parameters = $.Karbor.getResourceDefaultParameters(provider, "restore_schema");
if(trResources != null) {
trResources.each(function() {
var trResource = $(this);
var resourceid = trResource.attr("resource-id");
var parameterbtn = trResource.find(".editparameters");
var resourcetype =parameterbtn.attr("resourcetype");
var userdata = parameterbtn.data("userdata");
if(userdata!=null) {
parameters[resourcetype + "#" + resourceid] = userdata;
}
});
}
$(".parameters").val(angular.toJson(parameters));
}
horizon.checkpoints_restore = {
/* init create plan dialog */
init: function(){
/* init resource tree */
$("#checkpointRestoreResource").treetable({ expandable: true });
/* init protection provider */
(function() {
var provider = $.parseJSON($(".provider").val());
if(provider != null) {
if(provider.extended_info_schema != null) {
var result = provider.extended_info_schema['restore_schema'];
for(var r in result) {
$("#checkpointRestoreResource").find("input[resourcetype='" + r + "']").data("schema", result[r]);
$("#checkpointRestoreResource").find("input[resourcetype='" + r + "']").data("userdata", null);
}
}
}
})();
/* bind create button event */
$(".btn-primary").bind("click", function() {
setRestoredResource();
return true;
});
/* live resource parameters event */
$(document).on('click', ".editparameters", function(){
var schema = $(this).data("schema");
var userdata = $(this).data("userdata");
var resourceid = $(this).closest("tr").attr("resource-id");
if(schema != null) {
var exist_ui_dialogs = $("body").has(".ui-dialog");
if(exist_ui_dialogs.length == 0){
var dialog_data = $.Karbor.createDialog(schema, userdata, resourceid);
$.Karbor.openDialog(dialog_data, "#parametersdialog", "div.dialog_wrapper");
}
}
});
/* bind parameters dialog save button event */
$(document).on('click', "#parametersdialog .btn.btn-primary", function() {
var flag = $.Karbor.check_required($("#parametersdialog"));
if(flag) {
var resourceid = $("#parametersdialog .modal-body").attr("resourceid");
var form_controls = $("#parametersdialog .modal-body .form-control");
var userdata = $.Karbor.getDynamicValue(form_controls);
$("#checkpointRestoreResource").find("tr[resource-id='" + resourceid + "']")
.find(".editparameters")
.data("userdata", userdata);
$.Karbor.closeDialog("#parametersdialog");
}
});
/* bind parameters dialog cancel button event */
$(document).on('click', "#parametersdialog .btn.cancel", function() {
$.Karbor.closeDialog("#parametersdialog");
});
/* bind parameters dialog close button event */
$(document).on('click', "#parametersdialog a.close", function() {
$.Karbor.closeDialog("#parametersdialog");
});
$(document).on('change', "input.disable_input", function (evt) {
var $fieldset = $(evt.target).closest('fieldset'),
$disable_inputs = $fieldset.find('input.disable_input');
$disable_inputs.each(function(index, disable_input){
var $disable_input = $(disable_input),
visible = $disable_input.parent().hasClass('themable-checkbox') ? $disable_input.siblings('label').is(':visible') : $disable_input.is(':visible'),
slug = $disable_input.data('slug'),
disabled = $disable_input.prop('checked'),
disable_on = $disable_input.data('disableOnChecked');
// If checkbox is hidden then do not apply any further logic
if (!visible) return;
function handle_disabled_field(index, input){
var $input = $(input);
if (disabled != disable_on) {
$input.val("");
$input.attr("disabled", false);
if ($input.attr('id') == "id_restore_target_password"){
$input.closest('.form-group').removeClass("hide");
}
} else {
if ($input.attr('id') == 'id_restore_target'){
$input.val("Target: local host");
}
if ($input.attr('id') == 'id_restore_target_username'){
$input.val("Target username: current project");
}
if ($input.attr('id') == 'id_restore_target_password'){
$input.closest('.form-group').addClass("hide");
}
$input.attr("disabled", true);
}
}
$fieldset.find('.disabled_input[data-disable-on*="' + slug + '"]').each(handle_disabled_field);
$fieldset.siblings().find('.disabled_input[data-disable-on*="' + slug + '"]').each(handle_disabled_field);
});
});
$("input[name='restore_target_password']").closest('.form-group').addClass("hide");
}
};

View File

@ -1,311 +0,0 @@
/*
* jQuery Karbor Function
*/
(function ($) {
/* add warning span */
function add_warning_span(cur_node) {
var warning_span = $(cur_node).has("span.help-block");
if( warning_span.length == 0) {
var warning_info = $("<span/>").addClass("help-block")
.html("This field is required");
cur_node.append(warning_info);
}
$(cur_node).closest(".form-group.required").addClass("has-error");
}
/* remove warning span */
function remove_warning_span(cur_node) {
var warning_spans = $(cur_node).has("span.help-block");
if( warning_spans.length > 0) {
warning_spans.each(function(){
$(this).children("span").remove();
});
}
$(cur_node).closest(".form-group.required").removeClass("has-error");
}
/* create dynamic field */
function createDynamicField(schema, userdata, modal_body) {
if(schema!=null) {
for(var p in schema.properties) {
var property = schema.properties[p];
/* confirm whether the field is required */
var required = false;
if($.inArray(p, schema.required) >= 0) {
required = true;
}
/* form group */
var form_group = $("<div/>").addClass("form-group");
if(required) {
form_group.addClass("required");
}
/* control label */
var control_label = $("<label/>").addClass("control-label")
.attr("for", "id_"+p)
.html(property.title);
if(required) {
control_label.addClass("required");
}
form_group.append(control_label);
/* icon required */
if(required) {
var icon_required = $("<span/>").addClass("hz-icon-required")
.addClass("fa")
.addClass("fa-asterisk");
form_group.append(icon_required);
}
/* help icon */
if(property.hasOwnProperty("description")) {
var help_icon = $("<span/>").addClass("help-icon")
.attr("data-toggle", "tooltip")
.attr("data-placement", "top")
.attr("title", "")
.attr("data-original-title", property.description);
var question_circle = $("<span/>").addClass("fa")
.addClass("fa-question-circle");
help_icon.append(question_circle);
form_group.append(help_icon);
}
/* control wrapper */
var control_wrapper = $("<div/>");
if(property.hasOwnProperty("eumn")) {
//drop down list
var dropdownlist_control = $("<select/>");
dropdownlist_control.addClass("form-control");
dropdownlist_control.attr("id", "id_"+p);
dropdownlist_control.attr("name", p);
//get drop down list options
for(option in property.enum) {
var option_control = $("<option/>").attr('value', property.enum[option])
.html(property.enum[option]);
dropdownlist_control.append(option_control);
}
//default value
if(property.hasOwnProperty("default")) {
if(property.default != null) {
dropdownlist_control.val(property.default);
}
}
//user value
if(userdata != null) {
if(userdata.hasOwnProperty(p)) {
dropdownlist_control.val(userdata[p]);
}
}
control_wrapper.append(dropdownlist_control);
}
else {
switch(property.type) {
case "string": {
//text box
var text_control = $("<input type='text'/>");
text_control.addClass("form-control");
text_control.attr("id", "id_"+p);
text_control.attr("name", p);
//default value
if(property.hasOwnProperty("default")) {
if(property.default != null) {
text_control.val(property.default);
}
}
//user value
if(userdata != null) {
if(userdata.hasOwnProperty(p)) {
text_control.val(userdata[p]);
}
}
control_wrapper.append(text_control);
break;
}
case "boolean": {
//check box
var checkbox_control = $("<input type='checkbox'/>");
checkbox_control.addClass("form-control");
checkbox_control.attr("id", "id_"+p);
checkbox_control.attr("name", p);
//default value
if(property.hasOwnProperty("default")) {
if(property.default&&eval(property.default)) {
checkbox_control.attr("checked",true);
}
}
//user value
if(userdata != null) {
if(userdata.hasOwnProperty(p)) {
if(userdata[p]) {
checkbox_control.attr("checked", true);
}
else {
checkbox_control.removeAttr("checked");
}
}
}
control_wrapper.append(checkbox_control);
break;
}
default: {
break;
}
}
}
/* add control to body */
form_group.append(control_wrapper);
modal_body.append(form_group);
}
}
}
$.Karbor = {
/* get the default resources parameters */
getResourceDefaultParameters: function(provider, schemaname) {
var parameters = {};
if(provider != null) {
if(provider.extended_info_schema != null) {
var result = provider.extended_info_schema[schemaname];
for(var r in result) {
parameters[r] = {};
var schema = result[r];
if(schema!=null) {
for(var p in schema.properties) {
var property = schema.properties[p];
if(property.hasOwnProperty("default")) {
parameters[r][p] = property.default;
}
}
}
}
}
}
return parameters;
},
/* check html control required */
check_required: function(div_id){
var flag = true;
var required_node = div_id.find(".form-group.required").find(".form-control");
for(var i = 0; i<required_node.length; i++) {
var cur_node = required_node[i];
var parent_node = $(cur_node).closest("div");
var node_value = eval(cur_node).value;
if(node_value == "" || node_value == null)
{
add_warning_span(parent_node);
flag = false;
}
else
{
remove_warning_span(parent_node);
}
}
return flag;
},
/* Get dynamic field value */
getDynamicValue: function(form_controls) {
var data = null;
if(form_controls!=null&&form_controls.length>0) {
data = {};
for(var i = 0; i<form_controls.length; i++) {
var form_control = $(form_controls[i]);
if(form_control!=null) {
var form_control_name = form_control.attr("name");
if(form_control.is("input[type='text']")) {
data[form_control_name] = form_control.val();
}
else if(form_control.is("input[type='checkbox']")) {
data[form_control_name] = (form_control.is(":checked") ? true : false);
}
else if(form_control.is("select")) {
data[form_control_name] = form_control.val();
}
else {
continue;
}
}
}
}
return data;
},
/* create parameters dialog */
createDialog(schema, userdata, resourceid) {
var modal = $("<div/>").attr("id", "parametersdialog").addClass("modal");
var modal_dialog = $("<div/>").addClass("modal-dialog");
var modal_content = $("<div/>").addClass("modal-content");
//modal header
var modal_header = $("<div/>").addClass("modal-header");
modal_header.append("<a class='close' data-dismiss='modal'>&times;</a>");
modal_header.append("<h3 class='modal-title'>"
+(schema.title || "Edit Parameters")
+"</h3>");
//modal body
var modal_body = $("<div/>").addClass("modal-body").attr("resourceid", resourceid);
createDynamicField(schema, userdata, modal_body);
//modal footer
var modal_footer = $("<div/>").addClass("modal-footer");
var cancel = $("<a/>").attr("href", "#")
.addClass("btn")
.addClass("btn-default")
.addClass("cancel")
.attr("data-dismiss", "modal")
.html("Cancel");
var save = $("<a/>").attr("href", "#")
.attr("type", "submit")
.addClass("btn")
.addClass("btn-primary")
.html("Save");
modal_footer.append(cancel);
modal_footer.append(save);
//append children
modal_content.append(modal_header);
modal_content.append(modal_body);
modal_content.append(modal_footer);
modal_dialog.append(modal_content);
modal.append(modal_dialog);
return modal;
},
/* open parameters dialog */
openDialog: function(dialog_data,dialog_element,dialog_parent) {
$(dialog_parent).append(dialog_data);
$(dialog_element).dialog({
autoOpen: true,
modal: true,
open: function(event, ui) {
$(dialog_element + " .modal-content").draggable({handle: ".modal-header"});
},
close: function(event, ui) {
$(dialog_element).dialog('destroy');
$(dialog_parent).empty();
}
});
},
/* close parameters dialog */
closeDialog: function(dialog_element) {
$(dialog_element).dialog("close");
}
};
})(jQuery);

View File

@ -1,418 +0,0 @@
/*
* jQuery treeTable Plugin
*/
(function() {
var $, Node, Tree, methods;
$ = jQuery;
Node = (function() {
function Node(row, tree, settings) {
var parentId;
this.row = row;
this.tree = tree;
this.settings = settings;
this.id = this.row.data(this.settings.nodeIdAttr);
parentId = this.row.data(this.settings.parentIdAttr);
if (parentId != null && parentId !== "") {
this.parentId = parentId;
}
this.treeCell = $(this.row.children(this.settings.columnElType)[this.settings.column]);
this.expander = $(this.settings.expanderTemplate);
this.indenter = $(this.settings.indenterTemplate);
this.children = [];
this.initialized = false;
this.treeCell.prepend(this.indenter);
}
Node.prototype.addChild = function(child) {
return this.children.push(child);
};
Node.prototype.ancestors = function() {
var ancestors, node;
node = this;
ancestors = [];
while (node = node.parentNode()) {
ancestors.push(node);
}
return ancestors;
};
Node.prototype.collapse = function() {
this._hideChildren();
this.row.removeClass("expanded").addClass("collapsed");
this.expander.attr("title", this.settings.stringExpand);
if (this.initialized && this.settings.onNodeCollapse != null) {
this.settings.onNodeCollapse.apply(this);
}
return this;
};
Node.prototype.expand = function() {
if (this.initialized && this.settings.onNodeExpand != null) {
this.settings.onNodeExpand.apply(this);
}
this.row.removeClass("collapsed").addClass("expanded");
this._showChildren();
this.expander.attr("title", this.settings.stringCollapse);
return this;
};
Node.prototype.expanded = function() {
return this.row.hasClass("expanded");
};
Node.prototype.hide = function() {
this._hideChildren();
this.row.hide();
return this;
};
Node.prototype.isBranchNode = function() {
if(this.children.length > 0 || this.row.data(this.settings.branchAttr) === true) {
return true;
} else {
return false;
}
};
Node.prototype.level = function() {
return this.ancestors().length;
};
Node.prototype.parentNode = function() {
if (this.parentId != null) {
return this.tree[this.parentId];
} else {
return null;
}
};
Node.prototype.removeChild = function(child) {
var i = $.inArray(child, this.children);
return this.children.splice(i, 1)
};
Node.prototype.render = function() {
var settings = this.settings, target;
if (settings.expandable === true && this.isBranchNode()) {
this.indenter.html(this.expander);
target = settings.clickableNodeNames === true ? this.treeCell : this.expander;
target.unbind("click.treetable").bind("click.treetable", function(event) {
$(this).parents("table").treetable("node", $(this).parents("tr").data(settings.nodeIdAttr)).toggle();
return event.preventDefault();
});
}
if (settings.expandable === true && settings.initialState === "collapsed") {
this.collapse();
} else {
this.expand();
}
this.indenter[0].style.marginLeft = "" + (this.level() * settings.indent) + "px";
return this;
};
Node.prototype.reveal = function() {
if (this.parentId != null) {
this.parentNode().reveal();
}
return this.expand();
};
Node.prototype.setParent = function(node) {
if (this.parentId != null) {
this.tree[this.parentId].removeChild(this);
}
this.parentId = node.id;
this.row.data(this.settings.parentIdAttr, node.id);
return node.addChild(this);
};
Node.prototype.show = function() {
if (!this.initialized) {
this._initialize();
}
this.row.show();
if (this.expanded()) {
this._showChildren();
}
return this;
};
Node.prototype.toggle = function() {
if (this.expanded()) {
this.collapse();
} else {
this.expand();
}
return this;
};
Node.prototype._hideChildren = function() {
var child, _i, _len, _ref, _results;
_ref = this.children;
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
child = _ref[_i];
_results.push(child.hide());
}
return _results;
};
Node.prototype._initialize = function() {
this.render();
if (this.settings.onNodeInitialized != null) {
this.settings.onNodeInitialized.apply(this);
}
return this.initialized = true;
};
Node.prototype._showChildren = function() {
var child, _i, _len, _ref, _results;
_ref = this.children;
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
child = _ref[_i];
_results.push(child.show());
}
return _results;
};
return Node;
})();
Tree = (function() {
function Tree(table, settings) {
this.table = table;
this.settings = settings;
this.tree = {};
// Cache the nodes and roots in simple arrays for quick access/iteration
this.nodes = [];
this.roots = [];
}
Tree.prototype.collapseAll = function() {
var node, _i, _len, _ref, _results;
_ref = this.nodes;
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
node = _ref[_i];
_results.push(node.collapse());
}
return _results;
};
Tree.prototype.expandAll = function() {
var node, _i, _len, _ref, _results;
_ref = this.nodes;
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
node = _ref[_i];
_results.push(node.expand());
}
return _results;
};
Tree.prototype.loadRows = function(rows) {
var node, row, i;
if (rows != null) {
for (i = 0; i < rows.length; i++) {
row = $(rows[i]);
if (row.data(this.settings.nodeIdAttr) != null) {
node = new Node(row, this.tree, this.settings);
this.nodes.push(node);
this.tree[node.id] = node;
if (node.parentId != null) {
this.tree[node.parentId].addChild(node);
} else {
this.roots.push(node);
}
}
}
}
return this;
};
Tree.prototype.render = function() {
var root, _i, _len, _ref;
_ref = this.roots;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
root = _ref[_i];
root.show();
}
return this;
};
Tree.prototype.unloadBranch = function(node) {
var child, children, i;
for (i = 0; i < node.children.length; i++) {
child = node.children[i];
// Recursively remove all descendants of +node+
this.unloadBranch(child);
// Remove child from DOM (<tr>)
child.row.remove();
// Clean up Tree object (so Node objects are GC-ed)
delete this.tree[child.id];
this.nodes.splice($.inArray(child, this.nodes), 1)
}
// Reset node's collection of children
node.children = [];
return this;
};
return Tree;
})();
// jQuery Plugin
methods = {
init: function(options) {
var settings;
settings = $.extend({
branchAttr: "ttBranch",
clickableNodeNames: false,
column: 0,
columnElType: "td", // i.e. 'td', 'th' or 'td,th'
expandable: false,
expanderTemplate: "<a href='#'>&nbsp;</a>",
indent: 19,
indenterTemplate: "<span class='indenter'></span>",
initialState: "collapsed",
nodeIdAttr: "ttId", // maps to data-tt-id
parentIdAttr: "ttParentId", // maps to data-tt-parent-id
stringExpand: "Expand",
stringCollapse: "Collapse",
// Events
onInitialized: null,
onNodeCollapse: null,
onNodeExpand: null,
onNodeInitialized: null
}, options);
return this.each(function() {
var el, tree;
tree = new Tree(this, settings);
tree.loadRows(this.rows).render();
el = $(this).addClass("treetable").data("treetable", tree);
if (settings.onInitialized != null) {
settings.onInitialized.apply(tree);
}
return el;
});
},
destroy: function() {
return this.each(function() {
return $(this).removeData("treetable").removeClass("treetable");
});
},
collapseAll: function() {
this.data("treetable").collapseAll();
return this;
},
collapseNode: function(id) {
var node = this.data("treetable").tree[id];
if (node) {
node.collapse();
} else {
throw new Error("Unknown node '" + id + "'");
}
return this;
},
expandAll: function() {
this.data("treetable").expandAll();
return this;
},
expandNode: function(id) {
var node = this.data("treetable").tree[id];
if (node) {
node.expand();
} else {
throw new Error("Unknown node '" + id + "'");
}
return this;
},
loadBranch: function(node, rows) {
rows = $(rows);
rows.insertAfter(node.row);
this.data("treetable").loadRows(rows);
return this;
},
node: function(id) {
return this.data("treetable").tree[id];
},
reveal: function(id) {
var node = this.data("treetable").tree[id];
if (node) {
node.reveal();
} else {
throw new Error("Unknown node '" + id + "'");
}
return this;
},
unloadBranch: function(node) {
this.data("treetable").unloadBranch(node);
return this;
}
};
$.fn.treetable = function(method) {
if (methods[method]) {
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
} else if (typeof method === 'object' || !method) {
return methods.init.apply(this, arguments);
} else {
return $.error("Method " + method + " does not exist on jQuery.treetable");
}
};
// Expose classes to world
this.TreeTable || (this.TreeTable = {});
this.TreeTable.Node = Node;
this.TreeTable.Tree = Tree;
}).call(this);

View File

@ -1,165 +0,0 @@
/* Copyright (c) 2016 Huawei, Inc.
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.
*/
/* set the children check */
function setChecked(node, isChecked) {
if(isChecked) {
node.row.find("input[type=checkbox]").attr("checked", true);
}
else {
node.row.find("input[type=checkbox]").removeAttr("checked");
}
for(var i = 0; i<node.children.length;i++) {
var resourceChild = node.children[i];
setChecked(resourceChild, isChecked);
}
}
/* set the choose resources */
function setProtectedResource() {
var resources = [];
var cbResources = $(".cbresource:checked");
var provider = getProvider($("select[name='provider_id']").val());
var parameters = $.Karbor.getResourceDefaultParameters(provider, "options_schema");
if(cbResources != null) {
cbResources.each(function() {
var cbResource = $(this);
var resource = {};
resource.id = cbResource.closest("tr").attr("resource-id");
resource.type = cbResource.closest("td").next().find("span").html();
resource.name = cbResource.closest("span").nextAll("span.spanresource").eq(0).html();
resources.push(resource);
var parameterbtn = cbResource.closest("tr").find(".editparameters");
var userdata = parameterbtn.data("userdata");
if(userdata!=null) {
parameters[resource.type + "#" + resource.id] = userdata;
}
});
}
$(".resources").val(angular.toJson(resources));
$(".parameters").val(angular.toJson(parameters));
}
/* Get Provider */
function getProvider(v) {
var providers = $(".providers").val();
var provider = null;
if(providers != null) {
var providers_array = $.parseJSON(providers);
$(providers_array).each(function() {
if(this.id == v) {
provider=this;
return false;
}
});
}
return provider;
}
horizon.protectionplans_create = {
/* init create plan dialog */
init: function(){
/* init resource tree */
$("#protectionplanCreateResource").treetable({ expandable: true });
/* init protection provider */
$("select[name='provider_id']").change(function(evt) {
var v = $(this).val();
provider = getProvider(v);
$("#protectionplanCreateResource").find("input[resourcetype]").data("schema", null);
$("#protectionplanCreateResource").find("input[resourcetype]").data("userdata", null);
if(provider != null) {
if(provider.extended_info_schema != null) {
//var result = provider.extended_info_schema;
var result = provider.extended_info_schema['options_schema'];
for(var r in result) {
$("#protectionplanCreateResource").find("input[resourcetype='" + r + "']").data("schema", result[r]);
$("#protectionplanCreateResource").find("input[resourcetype='" + r + "']").data("userdata", null);
}
}
}
});
/* trigger protection provider */
$("select[name='provider_id']").trigger('change');
/* bind create button event */
$(".btn-primary.create").bind("click", function() {
$(".actionmode").val("create");
setProtectedResource();
return true;
});
/* bind schedule button event */
$(".btn-primary.schedule").bind("click", function() {
$(".actionmode").val("schedule");
setProtectedResource();
return true;
});
/* bind now button event */
$(".btn-primary.now").bind("click", function () {
$(".actionmode").val("now");
setProtectedResource();
return true;
});
/* live resource check event */
$(document).on('click', ".cbresource", function() {
var tr = $(this).closest("tr");
var node = $("#protectionplanCreateResource").treetable("node", tr.attr("data-tt-id"));
setChecked(node, $(this).is(":checked"));
});
/* live resource parameters event */
$(document).on('click',".editparameters", function() {
var schema = $(this).data("schema");
var userdata = $(this).data("userdata");
var resourceid = $(this).closest("tr").attr("resource-id");
if(schema != null) {
var exist_ui_dialogs = $("body").has(".ui-dialog");
if(exist_ui_dialogs.length == 0){
var dialog_data = $.Karbor.createDialog(schema, userdata, resourceid);
$.Karbor.openDialog(dialog_data, "#parametersdialog", "div.dialog_wrapper");
}
}
});
/* bind parameters dialog save button event */
$(document).on('click', "#parametersdialog .btn.btn-primary", function() {
var flag = $.Karbor.check_required($("#parametersdialog"));
if(flag) {
var resourceid = $("#parametersdialog .modal-body").attr("resourceid");
var form_controls = $("#parametersdialog .modal-body .form-control");
var userdata = $.Karbor.getDynamicValue(form_controls);
$("#protectionplanCreateResource").find("tr[resource-id='" + resourceid + "']")
.find(".editparameters")
.data("userdata", userdata);
$.Karbor.closeDialog("#parametersdialog");
}
});
/* bind parameters dialog cancel button event */
$(document).on('click', "#parametersdialog .btn.cancel", function() {
$.Karbor.closeDialog("#parametersdialog");
});
/* bind parameters dialog close button event */
$(document).on('click', "#parametersdialog a.close", function() {
$.Karbor.closeDialog("#parametersdialog");
});
}
};

View File

@ -1,21 +0,0 @@
/* Copyright (c) 2016 Huawei, Inc.
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.
*/
horizon.protectionplans_detail = {
init: function() {
/* init resource tree */
$("#protectionplanDetailResource").treetable({ expandable: true });
}
};

View File

@ -1,143 +0,0 @@
/* Copyright (c) 2016 Huawei, Inc.
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.
*/
/* set the children check */
function setChecked(node, isChecked) {
if(isChecked) {
node.row.find("input[type=checkbox]").prop("checked", true);
}
else {
node.row.find("input[type=checkbox]").removeAttr("checked");
}
for(var i = 0; i<node.children.length;i++) {
var resourceChild = node.children[i];
setChecked(resourceChild, isChecked);
}
}
/* set the choose resources */
function setProtectedResource() {
var resources = [];
var cbResources = $(".cbresource:checked");
var provider = getProvider($("select[name='provider_id']").val());
var parameters = $.Karbor.getResourceDefaultParameters(provider, "options_schema");
if(cbResources != null) {
cbResources.each(function() {
var cbResource = $(this);
var resource = {};
resource.id = cbResource.closest("tr").attr("resource-id");
resource.type = cbResource.closest("td").next().find("span").html();
resource.name = cbResource.closest("span").nextAll("span.spanresource").eq(0).html();
resources.push(resource);
var parameterbtn = cbResource.closest("tr").find(".editparameters");
var userdata = parameterbtn.data("userdata");
if(userdata!=null) {
parameters[resource.type + "#" + resource.id] = userdata;
}
});
}
$(".resources").val(angular.toJson(resources));
$(".parameters").val(angular.toJson(parameters));
}
horizon.protectionplans_update = {
/* init create plan dialog */
init: function(){
/* init resource tree */
$("#protectionplanUpdateResource").treetable({ expandable: true });
/* init plan resources*/
(function(){
plan = $.parseJSON($(".plan").val());
if(plan.resources != null){
resources = plan.resources
$(resources).each(function() {
resource_id = this.id
node = $("#protectionplanUpdateResource").find("tr[resource-id='"+ resource_id +"']");
node.find("input[type=checkbox]").prop("checked", true);
});
}
})();
/* init protection provider */
(function() {
provider = $.parseJSON($(".provider").val());
$("#protectionplanUpdateResource").find("input[resourcetype]").data("schema", null);
$("#protectionplanUpdateResource").find("input[resourcetype]").data("userdata", null);
if(provider != null) {
if(provider.extended_info_schema != null) {
var result = provider.extended_info_schema['options_schema'];
for(var r in result) {
$("#protectionplanUpdateResource").find("input[resourcetype='" + r + "']").data("schema", result[r]);
$("#protectionplanUpdateResource").find("input[resourcetype='" + r + "']").data("userdata", null);
}
}
}
})();
/* live resource check event */
$(document).on('click', ".cbresource", function() {
var tr = $(this).closest("tr");
var node = $("#protectionplanUpdateResource").treetable("node", tr.attr("data-tt-id"));
setChecked(node, $(this).is(":checked"));
});
/* live resource parameters event */
$(document).on('click',".editparameters", function() {
var schema = $(this).data("schema");
var userdata = $(this).data("userdata");
var resourceid = $(this).closest("tr").attr("resource-id");
if(schema != null) {
var exist_ui_dialogs = $("body").has(".ui-dialog");
if(exist_ui_dialogs.length == 0){
var dialog_data = $.Karbor.createDialog(schema, userdata, resourceid);
$.Karbor.openDialog(dialog_data, "#parametersdialog", "div.dialog_wrapper");
}
}
});
/* bind parameters dialog save button event */
$(document).on('click', "#parametersdialog .btn.btn-primary", function() {
var flag = $.Karbor.check_required($("#parametersdialog"));
if(flag) {
var resourceid = $("#parametersdialog .modal-body").attr("resourceid");
var form_controls = $("#parametersdialog .modal-body .form-control");
var userdata = $.Karbor.getDynamicValue(form_controls);
$("#protectionplanUpdateResource").find("tr[resource-id='" + resourceid + "']")
.find(".editparameters")
.data("userdata", userdata);
$.Karbor.closeDialog("#parametersdialog");
}
});
/* bind create button event */
$(".btn-primary.save").bind("click", function() {
setProtectedResource();
return true;
});
/* bind parameters dialog cancel button event */
$(document).on('click', "#parametersdialog .btn.cancel", function() {
$.Karbor.closeDialog("#parametersdialog");
});
/* bind parameters dialog close button event */
$(document).on('click', "#parametersdialog a.close", function() {
$.Karbor.closeDialog("#parametersdialog");
});
}
};

View File

@ -1,62 +0,0 @@
{% load i18n %}
{% load static %}
{% load compress %}
{% block css %}
{% compress css %}
<link rel="stylesheet" href="{% static 'karbordashboard/css/jquery.treetable.css' %}">
{% endcompress %}
{% endblock %}
<div class="detail">
<dl class="dl-horizontal">
<dt>{% trans "Protection Provider" %}:</dt>
<dd>{{ provider_name }}</dd>
<dt>{% trans "Protection Plan" %}:</dt>
<dd>{{ checkpoint.protection_plan.name }}</dd>
<dt>{% trans "Status" %}:</dt>
<dd>{{ checkpoint.status }}</dd>
</dl>
</div>
<div class="table_wrapper">
<table id="checkpointDetailResource"
class="{% block table_css_classes %}
table table-striped datatable {{ table.css_classes }}
{% endblock %}">
<thead>
<tr class="table_column_header">
<th {{ column.attr_string|safe }}>
Resource Name
</th>
<th {{ column.attr_string|safe }}>
Resource Type
</th>
</tr>
</thead>
<tbody>
{% for resource in resources %}
<tr data-tt-id="{{ resource.showid }}"
resource-id="{{ resource.id }}"
{% if resource.showparentid != None %}
data-tt-parent-id="{{ resource.showparentid }}"
{% endif %}>
<td>
<span class="logoresource"></span>
<span class="spanresource">{{ resource.name }}</span>
</td>
<td>
<span class="spanresource">{{ resource.type }}</span>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<script type="text/javascript">
$(function() {
"use strict";
horizon.checkpoints_detail.init();
});
</script>

View File

@ -1,32 +0,0 @@
{% load i18n %}
<form action="{{ url }}" method="post" class="pristine ng-valid">
{% csrf_token %}
<caption>
<div class="table_actions clearfix">
<div class="table_search">
<span style="font-size: 13px;vertical-align: middle">By Provider:</span>
<select class="form-control" name="provider_filter" style="width: auto;min-width: 160px">
{% for provider in provider_list %}
<option value={{ provider.id }} {% ifequal provider_filter provider.id %} selected {% endifequal %}>{{ provider.name }}</option>
{% endfor %}
</select>
<span style="font-size: 13px;vertical-align: middle">By Plan:</span>
<select class="form-control" name="plan_filter" style="width: auto;min-width: 160px">
<option {% ifequal plan_id "All" %} selected {% endifequal %}>All</option>
{% for plan in plan_list %}
<option value={{ plan.id }} {% ifequal plan_filter plan.id %} selected {% endifequal %}>{{ plan.name }}</option>
{% endfor %}
</select>
<span style="font-size: 13px;">By Date:</span>
<select class="form-control" name="date_filter" style="width: auto;min-width: 160px">
<option {% ifequal date_filter "All" %} selected {% endifequal %}>All</option>
{% for date in date_list %}
<option value={{ date.0 }} {% ifequal date_filter date.0 %} selected {% endifequal %}>{{ date.1 }}</option>
{% endfor %}
</select>
<button type="submit" class="btn btn-default" id="checkpoint_list_action_filter">Filter</button>
</div>
</div>
</caption>
</form>

View File

@ -1,65 +0,0 @@
{% extends "horizon/common/_modal_form.html" %}
{% load i18n %}
{% load static %}
{% load compress %}
{% block modal-body %}
{% block css %}
{% compress css %}
<link rel="stylesheet" href="{% static 'karbordashboard/css/jquery.treetable.css' %}">
{% endcompress %}
{% endblock %}
<div class="left" style="width:100%">
<fieldset>
{% include "horizon/common/_form_fields.html" %}
</fieldset>
<span class="table-title" style="font-size: 23px;">
Parameters
</span>
<div class="table_wrapper">
<table id="checkpointRestoreResource" class="{% block table_css_classes %}table table-striped datatable {{ table.css_classes }}{% endblock %}">
<thead>
<tr class="table_column_header">
<th {{ column.attr_string|safe }}>
Resource Name
</th>
<th {{ column.attr_string|safe }}>
Resource Type
</th>
<th {{ column.attr_string|safe }}>
Actions
</th>
</tr>
</thead>
<tbody>
{% for instance in instances %}
<tr data-tt-id="{{instance.showid}}"
resource-id="{{ instance.id }}"
{% if instance.showparentid != None %}
data-tt-parent-id="{{instance.showparentid}}"
{% endif %}>
<td>
<span class="logoresource"></span>
<span class="spanresource">{{instance.name}}</span>
</td>
<td>
<span class="spanresource">{{instance.type}}</span>
</td>
<td>
<input type="button" class="btn btn-default editparameters" value="Edit Parameters" resourcetype="{{instance.type}}">
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="dialog_wrapper"></div>
</div>
<script type="text/javascript">
(window.$ || window.addHorizonLoadEvent)(function () {
horizon.checkpoints_restore.init();
});
</script>
{% endblock %}

View File

@ -1,16 +0,0 @@
{% extends 'base.html' %}
{% load i18n %}
{% block title %}{% trans "Check Point Details" %}{% endblock %}
{% block page_header %}
{% include 'horizon/common/_detail_header.html' %}
{% endblock %}
{% block main %}
<div class="row">
<div class="col-sm-12">
{% include 'checkpoints/_detail.html' %}
</div>
</div>
{% endblock %}

View File

@ -1,11 +0,0 @@
{% extends 'base.html' %}
{% load i18n %}
{% block title %}
{% trans "Checkpoints" %}
{% endblock %}
{% block main %}
{% include "checkpoints/_index.html" %}
{{ table.render }}
{% endblock %}

View File

@ -1,10 +0,0 @@
{% extends 'base.html' %}
{% load i18n %}
{% block title %}
{% trans "Restore Checkpoint" %}
{% endblock %}
{% block main %}
{% include 'checkpoints/_restore.html' %}
{% endblock %}

View File

@ -1,10 +0,0 @@
{% extends 'base.html' %}
{% load i18n %}
{% block title %}
{% trans "Operation Logs" %}
{% endblock %}
{% block main %}
{{ table.render }}
{% endblock %}

View File

@ -1,69 +0,0 @@
{% extends "horizon/common/_modal_form.html" %}
{% load i18n %}
{% load static %}
{% load compress %}
{% block modal-body %}
{% block css %}
{% compress css %}
<link rel="stylesheet" href="{% static 'karbordashboard/css/jquery.treetable.css' %}">
{% endcompress %}
{% endblock %}
<div class="left" style="width:100%">
<fieldset>
{% include "horizon/common/_form_fields.html" %}
</fieldset>
<div class="table_wrapper">
<table id="protectionplanCreateResource" class="{% block table_css_classes %}table table-striped datatable {{ table.css_classes }}{% endblock %}">
<thead>
<tr class="table_column_header">
<th {{ column.attr_string|safe }}>
Resource Name
</th>
<th {{ column.attr_string|safe }}>
Resource Type
</th>
<th {{ column.attr_string|safe }}>
Actions
</th>
</tr>
</thead>
<tbody>
{% for instance in instances %}
<tr data-tt-id="{{ instance.showid }}"
resource-id="{{ instance.id }}"
{% if instance.showparentid != None %}
data-tt-parent-id="{{ instance.showparentid }}"
{% endif %}>
<td>
<span class="spanresource"><input type="checkbox" class="cbresource"/></span>
<span class="logoresource"></span>
<span class="spanresource">{{instance.name}}</span>
</td>
<td>
<span class="spanresource">{{instance.type}}</span>
</td>
<td>
<input type="button" class="btn btn-default editparameters" value="Edit Parameters" resourcetype="{{instance.type}}">
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="dialog_wrapper"></div>
</div>
<script type="text/javascript">
(window.$ || window.addHorizonLoadEvent)(function () {
horizon.protectionplans_create.init();
});
</script>
{% endblock %}
{% block modal-footer %}
<input class="btn btn-primary create" type="submit" value='{% trans "Create Protection Plan" %}' />
<input class="btn btn-primary schedule" type="submit" value='{% trans "Schedule Protect" %}' />
<input class="btn btn-primary now" type="submit" value='{% trans "Protect Now" %}' />
{% endblock %}

View File

@ -1,59 +0,0 @@
{% load i18n %}
{% load static %}
{% load compress %}
{% block css %}
{% compress css %}
<link rel="stylesheet" href="{% static 'karbordashboard/css/jquery.treetable.css' %}">
{% endcompress %}
{% endblock %}
<div class="detail">
<dl class="dl-horizontal">
<dt>{% trans "Plan Name" %}</dt>
<dd>{{ plan.name }}</dd>
<dt>{% trans "Plan Status" %}</dt>
<dd>{{ plan.status }}</dd>
<dt>{% trans "Protection Provider" %}</dt>
<dd>{{ provider.name }}</dd>
</dl>
</div>
<div class="table_wrapper">
<table id="protectionplanDetailResource" class="{% block table_css_classes %}table table-striped datatable {{ table.css_classes }}{% endblock %}">
<thead>
<tr class="table_column_header">
<th {{ column.attr_string|safe }}>
Resource Name
</th>
<th {{ column.attr_string|safe }}>
Resource Type
</th>
</tr>
</thead>
<tbody>
{% for instance in instances %}
<tr data-tt-id="{{ instance.showid }}"
resource-id="{{ instance.id }}"
{% if instance.showparentid != None %}
data-tt-parent-id="{{ instance.showparentid }}"
{% endif %}>
<td>
<span class="logoresource"></span>
<span class="spanresource">{{instance.name}}</span>
</td>
<td>
<span class="spanresource">{{instance.type}}</span>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<script type="text/javascript">
$(function() {
"use strict";
horizon.protectionplans_detail.init();
});
</script>

View File

@ -1,20 +0,0 @@
{% extends "horizon/common/_modal_form.html" %}
{% load i18n %}
{% block modal-body %}
<div class="left">
<div class="form-group">
<label class="control-label">Plan Name</label>
<div>
{{ plan.name }}
</div>
</div>
<fieldset>
{% include "horizon/common/_form_fields.html" %}
</fieldset>
</div>
<div class="right">
<h3>{% trans "Description:" %}</h3>
<p>{% trans "Schedule Protect." %}</p>
</div>
{% endblock %}

View File

@ -1,69 +0,0 @@
{% extends "horizon/common/_modal_form.html" %}
{% load i18n %}
{% load static %}
{% load compress %}
{% block modal-body %}
{% block css %}
{% compress css %}
<link rel="stylesheet" href="{% static 'karbordashboard/css/jquery.treetable.css' %}">
{% endcompress %}
{% endblock %}
<div class="left" style="width:100%">
<fieldset>
{% include "horizon/common/_form_fields.html" %}
</fieldset>
<div class="table_wrapper">
<table id="protectionplanUpdateResource" class="{% block table_css_classes %}table table-striped datatable {{ table.css_classes }}{% endblock %}">
<thead>
<tr class="table_column_header">
<th {{ column.attr_string|safe }}>
Resource Name
</th>
<th {{ column.attr_string|safe }}>
Resource Type
</th>
<th {{ column.attr_string|safe }}>
Actions
</th>
</tr>
</thead>
<tbody>
{% for instance in instances %}
<tr data-tt-id="{{ instance.showid }}"
resource-id="{{ instance.id }}"
{% if instance.showparentid != None %}
data-tt-parent-id="{{ instance.showparentid }}"
{% endif %}>
<td>
<span class="spanresource"><input type="checkbox" class="cbresource"/></span>
<span class="logoresource"></span>
<span class="spanresource">{{instance.name}}</span>
</td>
<td>
<span class="spanresource">{{instance.type}}</span>
</td>
<td>
<input type="button" class="btn btn-default editparameters" value="Edit Parameters" resourcetype="{{instance.type}}">
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="dialog_wrapper"></div>
</div>
<script type="text/javascript">
(window.$ || window.addHorizonLoadEvent)(function () {
horizon.protectionplans_update.init();
});
</script>
{% endblock %}
{% block modal-footer %}
<a class="btn btn-default cancel">Cancel</a>
<input class="btn btn-primary save" type="submit" value="Save">
{% endblock %}

View File

@ -1,10 +0,0 @@
{% extends 'base.html' %}
{% load i18n %}
{% block title %}
{% trans "Create Protection Plan" %}
{% endblock %}
{% block main %}
{% include 'protectionplans/_create.html' %}
{% endblock %}

View File

@ -1,16 +0,0 @@
{% extends 'base.html' %}
{% load i18n %}
{% block title %}{% trans "Protection Plan Details" %}{% endblock %}
{% block page_header %}
{% include 'horizon/common/_detail_header.html' %}
{% endblock %}
{% block main %}
<div class="row">
<div class="col-sm-12">
{% include "protectionplans/_detail.html" %}
</div>
</div>
{% endblock %}

View File

@ -1,10 +0,0 @@
{% extends 'base.html' %}
{% load i18n %}
{% block title %}
{% trans "Protection Plans" %}
{% endblock %}
{% block main %}
{{ table.render }}
{% endblock %}

View File

@ -1,7 +0,0 @@
{% extends 'base.html' %}
{% load i18n %}
{% block title %}{% trans "Schedule Protect" %}{% endblock %}
{% block main %}
{% include "protectionplans/_scheduleprotect.html" %}
{% endblock %}

View File

@ -1,10 +0,0 @@
{% extends 'base.html' %}
{% load i18n %}
{% block title %}
{% trans "Update Protection Plan" %}
{% endblock %}
{% block main %}
{% include 'protectionplans/_update.html' %}
{% endblock %}

View File

@ -1,10 +0,0 @@
{% load i18n %}
<div class="detail">
<dl class="dl-horizontal">
<dt>{% trans "Provider Name" %}</dt>
<dd>{{ provider.name }}</dd>
<dt>{% trans "Provider Description" %}</dt>
<dd>{{ provider.description }}</dd>
</dl>
</div>

View File

@ -1,5 +0,0 @@
{% load i18n %}
<div class="pre_scrollable">
<pre class="data">{{ schema_contents }}</pre>
</div>

View File

@ -1,21 +0,0 @@
{% extends 'base.html' %}
{% load i18n %}
{% block title %}{% trans "Protection Provider Details" %}{% endblock %}
{% block page_header %}
{% include 'horizon/common/_detail_header.html' %}
{% endblock %}
{% block main %}
<div class="row">
<div class="col-sm-12">
{% include "protectionproviders/_detail.html" %}
</div>
</div>
<div class="row">
<div class="col-sm-12">
{{ tab_group.render }}
</div>
</div>
{% endblock %}

View File

@ -1,8 +0,0 @@
{% extends 'base.html' %}
{% load i18n %}
{% block title %}{% trans "Protection Providers" %}{% endblock %}
{% block main %}
{{ table.render }}
{% endblock %}

View File

@ -1,10 +0,0 @@
{% extends 'base.html' %}
{% load i18n %}
{% block title %}
{% trans "Restores" %}
{% endblock %}
{% block main %}
{{ table.render }}
{% endblock %}

View File

@ -1,10 +0,0 @@
{% extends 'base.html' %}
{% load i18n %}
{% block title %}
{% trans "Scheduled Operations" %}
{% endblock %}
{% block main %}
{{ table.render }}
{% endblock %}

View File

@ -1,7 +0,0 @@
{% extends "horizon/common/_modal_form.html" %}
{% load i18n %}
{% block modal-body-right %}
<h3>{% trans "Description:" %}</h3>
<p>{% trans "Create a new trigger." %}</p>
{% endblock %}

View File

@ -1,38 +0,0 @@
{% load i18n %}
<div class="detail">
<dl class="dl-horizontal">
<dt>{% trans "Trigger Name" %}</dt>
<dd>{{ trigger.name }}</dd>
<dt>{% trans "Trigger Type" %}</dt>
<dd>{{ trigger.type }}</dd>
{% if trigger.frequence %}
<dt>{% trans "Frequence" %}</dt>
<dd>{{ trigger.frequence }}</dd>
{% endif %}
{% if trigger.day %}
<dt>{% trans "Day" %}</dt>
<dd>{{ trigger.day }}</dd>
{% endif %}
{% if trigger.date %}
<dt>{% trans "Date" %}</dt>
<dd>{{ trigger.date }}</dd>
{% endif %}
{% if trigger.time %}
<dt>{% trans "Execution Time (HH:MM)" %}</dt>
<dd>{{ trigger.time }}</dd>
{% endif %}
{% if trigger.hour %}
<dt>{% trans "Hour" %}</dt>
<dd>{{ trigger.hour }}</dd>
{% endif %}
{% if trigger.minute %}
<dt>{% trans "Minute" %}</dt>
<dd>{{ trigger.minute }}</dd>
{% endif %}
{% if trigger.interval %}
<dt>{% trans "Execution Interval" %}</dt>
<dd>{{ trigger.interval }}</dd>
{% endif %}
</dl>
</div>

View File

@ -1,10 +0,0 @@
{% extends 'base.html' %}
{% load i18n %}
{% block title %}
{% trans "Create Trigger" %}
{% endblock %}
{% block main %}
{% include 'triggers/_create.html' %}
{% endblock %}

View File

@ -1,16 +0,0 @@
{% extends 'base.html' %}
{% load i18n %}
{% block title %}{% trans "Trigger Details" %}{% endblock %}
{% block page_header %}
{% include 'horizon/common/_detail_header.html' %}
{% endblock %}
{% block main %}
<div class="row">
<div class="col-sm-12">
{% include "triggers/_detail.html" %}
</div>
</div>
{% endblock %}

Some files were not shown because too many files have changed in this diff Show More