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:
parent
06e52e5126
commit
1d52e37d0a
|
@ -1,11 +0,0 @@
|
|||
AUTHORS
|
||||
ChangeLog
|
||||
build
|
||||
doc/source/sourcecode
|
||||
.secret_key_store
|
||||
.venv
|
||||
.tox
|
||||
*.pyc
|
||||
*.lock
|
||||
*.egg*
|
||||
*.swp
|
|
@ -1,5 +0,0 @@
|
|||
- project:
|
||||
templates:
|
||||
- horizon-non-primary-django-jobs
|
||||
- openstack-python3-victoria-jobs
|
||||
- check-requirements
|
|
@ -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
|
|
@ -1,4 +0,0 @@
|
|||
karbor-dashboard Style Commandments
|
||||
===================================
|
||||
|
||||
Read the OpenStack Style Commandments https://docs.openstack.org/hacking/latest/
|
176
LICENSE
176
LICENSE
|
@ -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.
|
||||
|
66
README.rst
66
README.rst
|
@ -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.
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
[python: **.py]
|
||||
[django: **/templates/**.html]
|
|
@ -1,2 +0,0 @@
|
|||
[javascript: **.js]
|
||||
[angular: **/static/**.html]
|
|
@ -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
|
|
@ -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}
|
|
@ -1 +0,0 @@
|
|||
.. include:: ../../README.rst
|
|
@ -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()
|
|
@ -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)
|
|
@ -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.'))
|
|
@ -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)
|
|
@ -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
|
|
@ -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'),
|
||||
]
|
|
@ -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
|
|
@ -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
|
||||
)
|
|
@ -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)
|
|
@ -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
|
|
@ -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'
|
|
@ -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'
|
|
@ -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'
|
|
@ -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'
|
|
@ -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'
|
|
@ -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'
|
|
@ -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'
|
|
@ -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 }}"
|
|
@ -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 }}"
|
|
@ -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 }}"
|
|
@ -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 }}"
|
|
@ -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)
|
|
@ -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')
|
|
@ -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'),
|
||||
]
|
|
@ -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
|
|
@ -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.'))
|
|
@ -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)
|
|
@ -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
|
|
@ -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'),
|
||||
]
|
|
@ -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"))
|
|
@ -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)
|
|
@ -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
|
|
@ -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)
|
|
@ -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'),
|
||||
]
|
|
@ -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)
|
|
@ -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)
|
|
@ -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
|
|
@ -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'),
|
||||
]
|
|
@ -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
|
|
@ -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)
|
|
@ -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)
|
|
@ -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'),
|
||||
]
|
|
@ -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
|
|
@ -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 |
|
@ -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 });
|
||||
}
|
||||
};
|
|
@ -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");
|
||||
}
|
||||
};
|
|
@ -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'>×</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);
|
|
@ -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='#'> </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);
|
|
@ -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");
|
||||
});
|
||||
}
|
||||
};
|
|
@ -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 });
|
||||
}
|
||||
};
|
|
@ -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");
|
||||
});
|
||||
|
||||
}
|
||||
};
|
|
@ -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>
|
|
@ -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>
|
|
@ -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 %}
|
|
@ -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 %}
|
|
@ -1,11 +0,0 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}
|
||||
{% trans "Checkpoints" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{% include "checkpoints/_index.html" %}
|
||||
{{ table.render }}
|
||||
{% endblock %}
|
|
@ -1,10 +0,0 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}
|
||||
{% trans "Restore Checkpoint" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{% include 'checkpoints/_restore.html' %}
|
||||
{% endblock %}
|
|
@ -1,10 +0,0 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}
|
||||
{% trans "Operation Logs" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{{ table.render }}
|
||||
{% endblock %}
|
|
@ -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 %}
|
|
@ -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>
|
|
@ -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 %}
|
|
@ -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 %}
|
|
@ -1,10 +0,0 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}
|
||||
{% trans "Create Protection Plan" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{% include 'protectionplans/_create.html' %}
|
||||
{% endblock %}
|
|
@ -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 %}
|
|
@ -1,10 +0,0 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}
|
||||
{% trans "Protection Plans" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{{ table.render }}
|
||||
{% endblock %}
|
|
@ -1,7 +0,0 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Schedule Protect" %}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{% include "protectionplans/_scheduleprotect.html" %}
|
||||
{% endblock %}
|
|
@ -1,10 +0,0 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}
|
||||
{% trans "Update Protection Plan" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{% include 'protectionplans/_update.html' %}
|
||||
{% endblock %}
|
|
@ -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>
|
|
@ -1,5 +0,0 @@
|
|||
{% load i18n %}
|
||||
|
||||
<div class="pre_scrollable">
|
||||
<pre class="data">{{ schema_contents }}</pre>
|
||||
</div>
|
|
@ -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 %}
|
|
@ -1,8 +0,0 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}{% trans "Protection Providers" %}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{{ table.render }}
|
||||
{% endblock %}
|
|
@ -1,10 +0,0 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}
|
||||
{% trans "Restores" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{{ table.render }}
|
||||
{% endblock %}
|
|
@ -1,10 +0,0 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}
|
||||
{% trans "Scheduled Operations" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{{ table.render }}
|
||||
{% endblock %}
|
|
@ -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 %}
|
|
@ -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>
|
|
@ -1,10 +0,0 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}
|
||||
{% trans "Create Trigger" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{% include 'triggers/_create.html' %}
|
||||
{% endblock %}
|
|
@ -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
Loading…
Reference in New Issue