stripping out user/project stuff, step 1
This commit is contained in:
parent
c31843c743
commit
82d6c943fb
@ -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.
|
||||
|
@ -1,38 +0,0 @@
|
||||
OpenStack Django-Nova-Syspanel
|
||||
------------------------------
|
||||
|
||||
The Django-Nova-Syspanel package provides a django app that interacts
|
||||
with the OpenStack Nova cloud controller to view the health of a
|
||||
running OpenStack installation.
|
||||
|
||||
This is packaged, and intended to be used inside of, OpenStack
|
||||
Dashboard, which is located at
|
||||
|
||||
http://launchpad.net/openstack-dashboard
|
||||
|
||||
Development against this application is best done inside this reference
|
||||
implementation, though in practice any django app can install this
|
||||
application.
|
||||
|
||||
|
||||
Getting Started
|
||||
---------------
|
||||
|
||||
Django-Nova-Syspanel uses Buildout (http://www.buildout.org/) to
|
||||
manage local development. To configure your local Buildout
|
||||
environment:
|
||||
|
||||
$ python bootstrap.py
|
||||
$ bin/buildout
|
||||
|
||||
This will install all the dependencies of django-nova-syspanel and
|
||||
provide some useful scripts in the bin/ directory:
|
||||
|
||||
bin/python provides a python shell for the current buildout.
|
||||
bin/django provides django functions for the current buildout.
|
||||
|
||||
|
||||
You should now be able to run unit tests as follows:
|
||||
|
||||
$ bin/django test
|
||||
|
@ -1,260 +0,0 @@
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2006 Zope Foundation and Contributors.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# This software is subject to the provisions of the Zope Public License,
|
||||
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
|
||||
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
|
||||
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE.
|
||||
#
|
||||
##############################################################################
|
||||
"""Bootstrap a buildout-based project
|
||||
|
||||
Simply run this script in a directory containing a buildout.cfg.
|
||||
The script accepts buildout command-line options, so you can
|
||||
use the -c option to specify an alternate configuration file.
|
||||
"""
|
||||
|
||||
import os, shutil, sys, tempfile, textwrap, urllib, urllib2, subprocess
|
||||
from optparse import OptionParser
|
||||
|
||||
if sys.platform == 'win32':
|
||||
def quote(c):
|
||||
if ' ' in c:
|
||||
return '"%s"' % c # work around spawn lamosity on windows
|
||||
else:
|
||||
return c
|
||||
else:
|
||||
quote = str
|
||||
|
||||
# See zc.buildout.easy_install._has_broken_dash_S for motivation and comments.
|
||||
stdout, stderr = subprocess.Popen(
|
||||
[sys.executable, '-Sc',
|
||||
'try:\n'
|
||||
' import ConfigParser\n'
|
||||
'except ImportError:\n'
|
||||
' print 1\n'
|
||||
'else:\n'
|
||||
' print 0\n'],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
|
||||
has_broken_dash_S = bool(int(stdout.strip()))
|
||||
|
||||
# In order to be more robust in the face of system Pythons, we want to
|
||||
# run without site-packages loaded. This is somewhat tricky, in
|
||||
# particular because Python 2.6's distutils imports site, so starting
|
||||
# with the -S flag is not sufficient. However, we'll start with that:
|
||||
if not has_broken_dash_S and 'site' in sys.modules:
|
||||
# We will restart with python -S.
|
||||
args = sys.argv[:]
|
||||
args[0:0] = [sys.executable, '-S']
|
||||
args = map(quote, args)
|
||||
os.execv(sys.executable, args)
|
||||
# Now we are running with -S. We'll get the clean sys.path, import site
|
||||
# because distutils will do it later, and then reset the path and clean
|
||||
# out any namespace packages from site-packages that might have been
|
||||
# loaded by .pth files.
|
||||
clean_path = sys.path[:]
|
||||
import site
|
||||
sys.path[:] = clean_path
|
||||
for k, v in sys.modules.items():
|
||||
if k in ('setuptools', 'pkg_resources') or (
|
||||
hasattr(v, '__path__') and
|
||||
len(v.__path__)==1 and
|
||||
not os.path.exists(os.path.join(v.__path__[0],'__init__.py'))):
|
||||
# This is a namespace package. Remove it.
|
||||
sys.modules.pop(k)
|
||||
|
||||
is_jython = sys.platform.startswith('java')
|
||||
|
||||
setuptools_source = 'http://peak.telecommunity.com/dist/ez_setup.py'
|
||||
distribute_source = 'http://python-distribute.org/distribute_setup.py'
|
||||
|
||||
# parsing arguments
|
||||
def normalize_to_url(option, opt_str, value, parser):
|
||||
if value:
|
||||
if '://' not in value: # It doesn't smell like a URL.
|
||||
value = 'file://%s' % (
|
||||
urllib.pathname2url(
|
||||
os.path.abspath(os.path.expanduser(value))),)
|
||||
if opt_str == '--download-base' and not value.endswith('/'):
|
||||
# Download base needs a trailing slash to make the world happy.
|
||||
value += '/'
|
||||
else:
|
||||
value = None
|
||||
name = opt_str[2:].replace('-', '_')
|
||||
setattr(parser.values, name, value)
|
||||
|
||||
usage = '''\
|
||||
[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options]
|
||||
|
||||
Bootstraps a buildout-based project.
|
||||
|
||||
Simply run this script in a directory containing a buildout.cfg, using the
|
||||
Python that you want bin/buildout to use.
|
||||
|
||||
Note that by using --setup-source and --download-base to point to
|
||||
local resources, you can keep this script from going over the network.
|
||||
'''
|
||||
|
||||
parser = OptionParser(usage=usage)
|
||||
parser.add_option("-v", "--version", dest="version",
|
||||
help="use a specific zc.buildout version")
|
||||
parser.add_option("-d", "--distribute",
|
||||
action="store_true", dest="use_distribute", default=False,
|
||||
help="Use Distribute rather than Setuptools.")
|
||||
parser.add_option("--setup-source", action="callback", dest="setup_source",
|
||||
callback=normalize_to_url, nargs=1, type="string",
|
||||
help=("Specify a URL or file location for the setup file. "
|
||||
"If you use Setuptools, this will default to " +
|
||||
setuptools_source + "; if you use Distribute, this "
|
||||
"will default to " + distribute_source +"."))
|
||||
parser.add_option("--download-base", action="callback", dest="download_base",
|
||||
callback=normalize_to_url, nargs=1, type="string",
|
||||
help=("Specify a URL or directory for downloading "
|
||||
"zc.buildout and either Setuptools or Distribute. "
|
||||
"Defaults to PyPI."))
|
||||
parser.add_option("--eggs",
|
||||
help=("Specify a directory for storing eggs. Defaults to "
|
||||
"a temporary directory that is deleted when the "
|
||||
"bootstrap script completes."))
|
||||
parser.add_option("-t", "--accept-buildout-test-releases",
|
||||
dest='accept_buildout_test_releases',
|
||||
action="store_true", default=False,
|
||||
help=("Normally, if you do not specify a --version, the "
|
||||
"bootstrap script and buildout gets the newest "
|
||||
"*final* versions of zc.buildout and its recipes and "
|
||||
"extensions for you. If you use this flag, "
|
||||
"bootstrap and buildout will get the newest releases "
|
||||
"even if they are alphas or betas."))
|
||||
parser.add_option("-c", None, action="store", dest="config_file",
|
||||
help=("Specify the path to the buildout configuration "
|
||||
"file to be used."))
|
||||
|
||||
options, args = parser.parse_args()
|
||||
|
||||
# if -c was provided, we push it back into args for buildout's main function
|
||||
if options.config_file is not None:
|
||||
args += ['-c', options.config_file]
|
||||
|
||||
if options.eggs:
|
||||
eggs_dir = os.path.abspath(os.path.expanduser(options.eggs))
|
||||
else:
|
||||
eggs_dir = tempfile.mkdtemp()
|
||||
|
||||
if options.setup_source is None:
|
||||
if options.use_distribute:
|
||||
options.setup_source = distribute_source
|
||||
else:
|
||||
options.setup_source = setuptools_source
|
||||
|
||||
if options.accept_buildout_test_releases:
|
||||
args.append('buildout:accept-buildout-test-releases=true')
|
||||
args.append('bootstrap')
|
||||
|
||||
try:
|
||||
import pkg_resources
|
||||
import setuptools # A flag. Sometimes pkg_resources is installed alone.
|
||||
if not hasattr(pkg_resources, '_distribute'):
|
||||
raise ImportError
|
||||
except ImportError:
|
||||
ez_code = urllib2.urlopen(
|
||||
options.setup_source).read().replace('\r\n', '\n')
|
||||
ez = {}
|
||||
exec ez_code in ez
|
||||
setup_args = dict(to_dir=eggs_dir, download_delay=0)
|
||||
if options.download_base:
|
||||
setup_args['download_base'] = options.download_base
|
||||
if options.use_distribute:
|
||||
setup_args['no_fake'] = True
|
||||
ez['use_setuptools'](**setup_args)
|
||||
if 'pkg_resources' in sys.modules:
|
||||
reload(sys.modules['pkg_resources'])
|
||||
import pkg_resources
|
||||
# This does not (always?) update the default working set. We will
|
||||
# do it.
|
||||
for path in sys.path:
|
||||
if path not in pkg_resources.working_set.entries:
|
||||
pkg_resources.working_set.add_entry(path)
|
||||
|
||||
cmd = [quote(sys.executable),
|
||||
'-c',
|
||||
quote('from setuptools.command.easy_install import main; main()'),
|
||||
'-mqNxd',
|
||||
quote(eggs_dir)]
|
||||
|
||||
if not has_broken_dash_S:
|
||||
cmd.insert(1, '-S')
|
||||
|
||||
find_links = options.download_base
|
||||
if not find_links:
|
||||
find_links = os.environ.get('bootstrap-testing-find-links')
|
||||
if find_links:
|
||||
cmd.extend(['-f', quote(find_links)])
|
||||
|
||||
if options.use_distribute:
|
||||
setup_requirement = 'distribute'
|
||||
else:
|
||||
setup_requirement = 'setuptools'
|
||||
ws = pkg_resources.working_set
|
||||
setup_requirement_path = ws.find(
|
||||
pkg_resources.Requirement.parse(setup_requirement)).location
|
||||
env = dict(
|
||||
os.environ,
|
||||
PYTHONPATH=setup_requirement_path)
|
||||
|
||||
requirement = 'zc.buildout'
|
||||
version = options.version
|
||||
if version is None and not options.accept_buildout_test_releases:
|
||||
# Figure out the most recent final version of zc.buildout.
|
||||
import setuptools.package_index
|
||||
_final_parts = '*final-', '*final'
|
||||
def _final_version(parsed_version):
|
||||
for part in parsed_version:
|
||||
if (part[:1] == '*') and (part not in _final_parts):
|
||||
return False
|
||||
return True
|
||||
index = setuptools.package_index.PackageIndex(
|
||||
search_path=[setup_requirement_path])
|
||||
if find_links:
|
||||
index.add_find_links((find_links,))
|
||||
req = pkg_resources.Requirement.parse(requirement)
|
||||
if index.obtain(req) is not None:
|
||||
best = []
|
||||
bestv = None
|
||||
for dist in index[req.project_name]:
|
||||
distv = dist.parsed_version
|
||||
if _final_version(distv):
|
||||
if bestv is None or distv > bestv:
|
||||
best = [dist]
|
||||
bestv = distv
|
||||
elif distv == bestv:
|
||||
best.append(dist)
|
||||
if best:
|
||||
best.sort()
|
||||
version = best[-1].version
|
||||
if version:
|
||||
requirement = '=='.join((requirement, version))
|
||||
cmd.append(requirement)
|
||||
|
||||
if is_jython:
|
||||
import subprocess
|
||||
exitcode = subprocess.Popen(cmd, env=env).wait()
|
||||
else: # Windows prefers this, apparently; otherwise we would prefer subprocess
|
||||
exitcode = os.spawnle(*([os.P_WAIT, sys.executable] + cmd + [env]))
|
||||
if exitcode != 0:
|
||||
sys.stdout.flush()
|
||||
sys.stderr.flush()
|
||||
print ("An error occurred when trying to install zc.buildout. "
|
||||
"Look above this message for any errors that "
|
||||
"were output by easy_install.")
|
||||
sys.exit(exitcode)
|
||||
|
||||
ws.add_entry(eggs_dir)
|
||||
ws.require(requirement)
|
||||
import zc.buildout.buildout
|
||||
zc.buildout.buildout.main(args)
|
||||
if not options.eggs: # clean up temporary egg directory
|
||||
shutil.rmtree(eggs_dir)
|
@ -1,19 +0,0 @@
|
||||
[buildout]
|
||||
parts = python django
|
||||
develop = .
|
||||
eggs = django-nova-syspanel
|
||||
|
||||
[python]
|
||||
recipe = zc.recipe.egg
|
||||
interpreter = python
|
||||
eggs = ${buildout:eggs}
|
||||
|
||||
[django]
|
||||
recipe = djangorecipe
|
||||
version = 1.2.4
|
||||
project = django_nova_syspanel
|
||||
projectegg = django_nova_syspanel
|
||||
settings = testsettings
|
||||
test = django_nova_syspanel
|
||||
eggs = ${buildout:eggs}
|
||||
|
@ -1,32 +0,0 @@
|
||||
import os
|
||||
from setuptools import setup, find_packages, findall
|
||||
|
||||
def read(fname):
|
||||
return open(os.path.join(os.path.dirname(__file__), fname)).read()
|
||||
|
||||
setup(
|
||||
name = "django-nova-syspanel",
|
||||
version = "0.1",
|
||||
url = 'https://launchpad.net/openstack-dashboard/',
|
||||
license = 'Apache 2.0',
|
||||
description = "A Django interface for OpenStack Nova.",
|
||||
long_description = read('README'),
|
||||
author = 'Todd Willey',
|
||||
author_email = 'xtoddx@gmail.com',
|
||||
packages = find_packages('src'),
|
||||
package_dir = {'': 'src'},
|
||||
package_data = {'django_nova_syspanel':
|
||||
[s[len('src/django_nova_syspanel/'):] for s in
|
||||
findall('src/django_nova_syspanel/templates')]},
|
||||
install_requires = ['setuptools', 'boto==1.9b', 'mox>=0.5.0'],
|
||||
classifiers = [
|
||||
'Development Status :: 4 - Beta',
|
||||
'Framework :: Django',
|
||||
'Intended Audience :: Developers',
|
||||
'License :: OSI Approved :: Apache License',
|
||||
'Operating System :: OS Independent',
|
||||
'Programming Language :: Python',
|
||||
'Topic :: Internet :: WWW/HTTP',
|
||||
]
|
||||
)
|
||||
|
Binary file not shown.
@ -1,239 +0,0 @@
|
||||
# Translations of Dashboard for OpenStack User Interface.
|
||||
# Copyright 2011 Midokura KK
|
||||
# This file is distributed under the same license as the Dashboard for OpenStack.
|
||||
# FIRST AUTHOR Jeffrey Wilcox, 2011.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openstack-dashboard\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2011-06-08 14:02+0900\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: models.py:24 models.py:25
|
||||
msgid "Forbidden"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:39
|
||||
msgid "An unexpected error occurred. Please try your request again."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/index.html:9
|
||||
msgid ""
|
||||
"View all running instances other than VPNs. Schedule instances for\treboot "
|
||||
"or termination. Download logs."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/index.html:15
|
||||
#: templates/django_nova_syspanel/volumes/index.html:24
|
||||
msgid ""
|
||||
"View all volumes. See size, status, and mount point. Detach and destroy "
|
||||
"volumes."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/index.html:21
|
||||
#: templates/django_nova_syspanel/vpns/index.html:25
|
||||
msgid ""
|
||||
"View all projects VPN status. Schedule launch, termination, and reboot. Send "
|
||||
"credentials."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/index.html:27
|
||||
msgid ""
|
||||
"View servers that participate in your cloud. See statistics about\trunning "
|
||||
"services and served objects."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/index.html:33
|
||||
msgid ""
|
||||
"Perform operations to deal with rogue users, limit or prevent compromise, "
|
||||
"and deal with external threats."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/cloudview/index.html:9
|
||||
msgid ""
|
||||
"View servers that participate in your cloud. See statistics about running "
|
||||
"services and served objects."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/instances/index.html:23
|
||||
msgid "Manage Instances"
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/instances/index.html:24
|
||||
msgid ""
|
||||
"View all running instances other than VPNs. Schedule instances for reboot or "
|
||||
"termination. Download logs."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/instances/index.html:36
|
||||
msgid "Refresh List"
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/instances/index.html:66
|
||||
msgid "Console Log"
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/disable_project_credentials.html:9
|
||||
msgid ""
|
||||
"\n"
|
||||
" If a user's credentials were comprimised, you will need to use \n"
|
||||
" `nova-manage user revoke USERNAME`, and the restart all VPNs for "
|
||||
"projects\n"
|
||||
" they are a member of. "
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/disable_project_credentials.html:15
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\n"
|
||||
" The VPN for %(project)s is currently offline. You can turn it back on\n"
|
||||
" using "
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:7
|
||||
msgid "Security"
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:9
|
||||
msgid "Use the following tools to secure the cloud during a security event"
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:14
|
||||
msgid ""
|
||||
"<strong>Scenario:</strong> Project account credentials have been compromised."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:15
|
||||
msgid ""
|
||||
"<strong>Action:</strong> Disable the user or project. This should invalidate "
|
||||
"the credentials, also deny the specific port assigned to the user."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:34
|
||||
msgid ""
|
||||
"<strong>Scenario:</strong> The issue pin points to be coming in from a "
|
||||
"specific external ip or ip range."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:35
|
||||
msgid ""
|
||||
"<strong>Action:</strong> Block the IP or IP range. This should manipulate ip "
|
||||
"tables to block the ip or ip range."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:55
|
||||
msgid ""
|
||||
"<strong>Scenario:</strong> Issues affecting multiple public entry points or "
|
||||
"could not determine to be a specific one."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:56
|
||||
msgid ""
|
||||
"<strong>Action:</strong> Disable all public IPs on all VMs. This should "
|
||||
"unplumb the device the public ip was on."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:69
|
||||
msgid ""
|
||||
"<strong>Scenario:</strong> Issue related to VPN service affecting multiple "
|
||||
"customers."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:70
|
||||
msgid ""
|
||||
"<strong>Action:</strong> Disable VPN service. This should turn off the VPN "
|
||||
"ip."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/volumes/index.html:23
|
||||
msgid "Manage Volumes"
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/vpns/index.html:24
|
||||
msgid "Manage VPNs"
|
||||
msgstr ""
|
||||
|
||||
#: views/instances.py:44
|
||||
#, python-format
|
||||
msgid "Instance %s has been scheduled for termination."
|
||||
msgstr ""
|
||||
|
||||
#: views/instances.py:48
|
||||
#, python-format
|
||||
msgid "There were issues trying to terminate instance %s. Please try again."
|
||||
msgstr ""
|
||||
|
||||
#: views/instances.py:79
|
||||
#, python-format
|
||||
msgid "Instance %s has been scheduled for reboot."
|
||||
msgstr ""
|
||||
|
||||
#: views/instances.py:83
|
||||
#, python-format
|
||||
msgid "There were issues trying to reboot instance %s. Please try again."
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:41
|
||||
#, python-format
|
||||
msgid "Unable to disable project %(name)s: %(code)s - %(msg)s"
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:46
|
||||
#, python-format
|
||||
msgid "Project %s has been successfully disabled."
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:52
|
||||
msgid "Invalid form data"
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:68
|
||||
#, python-format
|
||||
msgid "Unable to block IPs range %(cidr)s: %(code)s %(msg)s"
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:74
|
||||
#, python-format
|
||||
msgid "IPs range %shas been successfully blocked"
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:88
|
||||
#, python-format
|
||||
msgid "Unable to shut off public IPs: %(code)s - %(msg)s"
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:91
|
||||
msgid "Public IPs have been turned off."
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:114
|
||||
#, python-format
|
||||
msgid "Unable to shut off all VPNs: %(code)s - %(msg)s"
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:118
|
||||
msgid "VPNs have been successfully turned off."
|
||||
msgstr ""
|
||||
|
||||
#: views/volumes.py:44
|
||||
#, python-format
|
||||
msgid "Volume %s has been scheduled to be detached."
|
||||
msgstr ""
|
||||
|
||||
#: views/volumes.py:57
|
||||
#, python-format
|
||||
msgid "Unable to delete volume %(vol)s: %(msg)s"
|
||||
msgstr ""
|
||||
|
||||
#: views/volumes.py:61
|
||||
#, python-format
|
||||
msgid "Volume %s has been successfully deleted."
|
||||
msgstr ""
|
Binary file not shown.
@ -1,240 +0,0 @@
|
||||
# Translations of Dashboard for OpenStack User Interface.
|
||||
# Copyright 2011 Midokura KK
|
||||
# This file is distributed under the same license as the Dashboard for OpenStack.
|
||||
# FIRST AUTHOR Jeffrey Wilcox, 2011.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openstack-dashboard\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2011-06-08 14:02+0900\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: models.py:24 models.py:25
|
||||
msgid "Forbidden"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:39
|
||||
msgid "An unexpected error occurred. Please try your request again."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/index.html:9
|
||||
msgid ""
|
||||
"View all running instances other than VPNs. Schedule instances for\treboot "
|
||||
"or termination. Download logs."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/index.html:15
|
||||
#: templates/django_nova_syspanel/volumes/index.html:24
|
||||
msgid ""
|
||||
"View all volumes. See size, status, and mount point. Detach and destroy "
|
||||
"volumes."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/index.html:21
|
||||
#: templates/django_nova_syspanel/vpns/index.html:25
|
||||
msgid ""
|
||||
"View all projects VPN status. Schedule launch, termination, and reboot. Send "
|
||||
"credentials."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/index.html:27
|
||||
msgid ""
|
||||
"View servers that participate in your cloud. See statistics about\trunning "
|
||||
"services and served objects."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/index.html:33
|
||||
msgid ""
|
||||
"Perform operations to deal with rogue users, limit or prevent compromise, "
|
||||
"and deal with external threats."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/cloudview/index.html:9
|
||||
msgid ""
|
||||
"View servers that participate in your cloud. See statistics about running "
|
||||
"services and served objects."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/instances/index.html:23
|
||||
msgid "Manage Instances"
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/instances/index.html:24
|
||||
msgid ""
|
||||
"View all running instances other than VPNs. Schedule instances for reboot or "
|
||||
"termination. Download logs."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/instances/index.html:36
|
||||
msgid "Refresh List"
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/instances/index.html:66
|
||||
msgid "Console Log"
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/disable_project_credentials.html:9
|
||||
msgid ""
|
||||
"\n"
|
||||
" If a user's credentials were comprimised, you will need to use \n"
|
||||
" `nova-manage user revoke USERNAME`, and the restart all VPNs for "
|
||||
"projects\n"
|
||||
" they are a member of. "
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/disable_project_credentials.html:15
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\n"
|
||||
" The VPN for %(project)s is currently offline. You can turn it back on\n"
|
||||
" using "
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:7
|
||||
msgid "Security"
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:9
|
||||
msgid "Use the following tools to secure the cloud during a security event"
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:14
|
||||
msgid ""
|
||||
"<strong>Scenario:</strong> Project account credentials have been compromised."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:15
|
||||
msgid ""
|
||||
"<strong>Action:</strong> Disable the user or project. This should invalidate "
|
||||
"the credentials, also deny the specific port assigned to the user."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:34
|
||||
msgid ""
|
||||
"<strong>Scenario:</strong> The issue pin points to be coming in from a "
|
||||
"specific external ip or ip range."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:35
|
||||
msgid ""
|
||||
"<strong>Action:</strong> Block the IP or IP range. This should manipulate ip "
|
||||
"tables to block the ip or ip range."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:55
|
||||
msgid ""
|
||||
"<strong>Scenario:</strong> Issues affecting multiple public entry points or "
|
||||
"could not determine to be a specific one."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:56
|
||||
msgid ""
|
||||
"<strong>Action:</strong> Disable all public IPs on all VMs. This should "
|
||||
"unplumb the device the public ip was on."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:69
|
||||
msgid ""
|
||||
"<strong>Scenario:</strong> Issue related to VPN service affecting multiple "
|
||||
"customers."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:70
|
||||
msgid ""
|
||||
"<strong>Action:</strong> Disable VPN service. This should turn off the VPN "
|
||||
"ip."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/volumes/index.html:23
|
||||
msgid "Manage Volumes"
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/vpns/index.html:24
|
||||
msgid "Manage VPNs"
|
||||
msgstr ""
|
||||
|
||||
#: views/instances.py:44
|
||||
#, python-format
|
||||
msgid "Instance %s has been scheduled for termination."
|
||||
msgstr ""
|
||||
|
||||
#: views/instances.py:48
|
||||
#, python-format
|
||||
msgid "There were issues trying to terminate instance %s. Please try again."
|
||||
msgstr ""
|
||||
|
||||
#: views/instances.py:79
|
||||
#, python-format
|
||||
msgid "Instance %s has been scheduled for reboot."
|
||||
msgstr ""
|
||||
|
||||
#: views/instances.py:83
|
||||
#, python-format
|
||||
msgid "There were issues trying to reboot instance %s. Please try again."
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:41
|
||||
#, python-format
|
||||
msgid "Unable to disable project %(name)s: %(code)s - %(msg)s"
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:46
|
||||
#, python-format
|
||||
msgid "Project %s has been successfully disabled."
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:52
|
||||
msgid "Invalid form data"
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:68
|
||||
#, python-format
|
||||
msgid "Unable to block IPs range %(cidr)s: %(code)s %(msg)s"
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:74
|
||||
#, python-format
|
||||
msgid "IPs range %shas been successfully blocked"
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:88
|
||||
#, python-format
|
||||
msgid "Unable to shut off public IPs: %(code)s - %(msg)s"
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:91
|
||||
msgid "Public IPs have been turned off."
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:114
|
||||
#, python-format
|
||||
msgid "Unable to shut off all VPNs: %(code)s - %(msg)s"
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:118
|
||||
msgid "VPNs have been successfully turned off."
|
||||
msgstr ""
|
||||
|
||||
#: views/volumes.py:44
|
||||
#, python-format
|
||||
msgid "Volume %s has been scheduled to be detached."
|
||||
msgstr ""
|
||||
|
||||
#: views/volumes.py:57
|
||||
#, python-format
|
||||
msgid "Unable to delete volume %(vol)s: %(msg)s"
|
||||
msgstr ""
|
||||
|
||||
#: views/volumes.py:61
|
||||
#, python-format
|
||||
msgid "Volume %s has been successfully deleted."
|
||||
msgstr ""
|
Binary file not shown.
@ -1,240 +0,0 @@
|
||||
# Translations of Dashboard for OpenStack User Interface.
|
||||
# Copyright 2011 Midokura KK
|
||||
# This file is distributed under the same license as the Dashboard for OpenStack.
|
||||
# FIRST AUTHOR Jeffrey Wilcox, 2011.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openstack-dashboard\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2011-06-08 14:02+0900\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n>1;\n"
|
||||
|
||||
#: models.py:24 models.py:25
|
||||
msgid "Forbidden"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:39
|
||||
msgid "An unexpected error occurred. Please try your request again."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/index.html:9
|
||||
msgid ""
|
||||
"View all running instances other than VPNs. Schedule instances for\treboot "
|
||||
"or termination. Download logs."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/index.html:15
|
||||
#: templates/django_nova_syspanel/volumes/index.html:24
|
||||
msgid ""
|
||||
"View all volumes. See size, status, and mount point. Detach and destroy "
|
||||
"volumes."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/index.html:21
|
||||
#: templates/django_nova_syspanel/vpns/index.html:25
|
||||
msgid ""
|
||||
"View all projects VPN status. Schedule launch, termination, and reboot. Send "
|
||||
"credentials."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/index.html:27
|
||||
msgid ""
|
||||
"View servers that participate in your cloud. See statistics about\trunning "
|
||||
"services and served objects."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/index.html:33
|
||||
msgid ""
|
||||
"Perform operations to deal with rogue users, limit or prevent compromise, "
|
||||
"and deal with external threats."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/cloudview/index.html:9
|
||||
msgid ""
|
||||
"View servers that participate in your cloud. See statistics about running "
|
||||
"services and served objects."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/instances/index.html:23
|
||||
msgid "Manage Instances"
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/instances/index.html:24
|
||||
msgid ""
|
||||
"View all running instances other than VPNs. Schedule instances for reboot or "
|
||||
"termination. Download logs."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/instances/index.html:36
|
||||
msgid "Refresh List"
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/instances/index.html:66
|
||||
msgid "Console Log"
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/disable_project_credentials.html:9
|
||||
msgid ""
|
||||
"\n"
|
||||
" If a user's credentials were comprimised, you will need to use \n"
|
||||
" `nova-manage user revoke USERNAME`, and the restart all VPNs for "
|
||||
"projects\n"
|
||||
" they are a member of. "
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/disable_project_credentials.html:15
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\n"
|
||||
" The VPN for %(project)s is currently offline. You can turn it back on\n"
|
||||
" using "
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:7
|
||||
msgid "Security"
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:9
|
||||
msgid "Use the following tools to secure the cloud during a security event"
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:14
|
||||
msgid ""
|
||||
"<strong>Scenario:</strong> Project account credentials have been compromised."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:15
|
||||
msgid ""
|
||||
"<strong>Action:</strong> Disable the user or project. This should invalidate "
|
||||
"the credentials, also deny the specific port assigned to the user."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:34
|
||||
msgid ""
|
||||
"<strong>Scenario:</strong> The issue pin points to be coming in from a "
|
||||
"specific external ip or ip range."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:35
|
||||
msgid ""
|
||||
"<strong>Action:</strong> Block the IP or IP range. This should manipulate ip "
|
||||
"tables to block the ip or ip range."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:55
|
||||
msgid ""
|
||||
"<strong>Scenario:</strong> Issues affecting multiple public entry points or "
|
||||
"could not determine to be a specific one."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:56
|
||||
msgid ""
|
||||
"<strong>Action:</strong> Disable all public IPs on all VMs. This should "
|
||||
"unplumb the device the public ip was on."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:69
|
||||
msgid ""
|
||||
"<strong>Scenario:</strong> Issue related to VPN service affecting multiple "
|
||||
"customers."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:70
|
||||
msgid ""
|
||||
"<strong>Action:</strong> Disable VPN service. This should turn off the VPN "
|
||||
"ip."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/volumes/index.html:23
|
||||
msgid "Manage Volumes"
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/vpns/index.html:24
|
||||
msgid "Manage VPNs"
|
||||
msgstr ""
|
||||
|
||||
#: views/instances.py:44
|
||||
#, python-format
|
||||
msgid "Instance %s has been scheduled for termination."
|
||||
msgstr ""
|
||||
|
||||
#: views/instances.py:48
|
||||
#, python-format
|
||||
msgid "There were issues trying to terminate instance %s. Please try again."
|
||||
msgstr ""
|
||||
|
||||
#: views/instances.py:79
|
||||
#, python-format
|
||||
msgid "Instance %s has been scheduled for reboot."
|
||||
msgstr ""
|
||||
|
||||
#: views/instances.py:83
|
||||
#, python-format
|
||||
msgid "There were issues trying to reboot instance %s. Please try again."
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:41
|
||||
#, python-format
|
||||
msgid "Unable to disable project %(name)s: %(code)s - %(msg)s"
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:46
|
||||
#, python-format
|
||||
msgid "Project %s has been successfully disabled."
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:52
|
||||
msgid "Invalid form data"
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:68
|
||||
#, python-format
|
||||
msgid "Unable to block IPs range %(cidr)s: %(code)s %(msg)s"
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:74
|
||||
#, python-format
|
||||
msgid "IPs range %shas been successfully blocked"
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:88
|
||||
#, python-format
|
||||
msgid "Unable to shut off public IPs: %(code)s - %(msg)s"
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:91
|
||||
msgid "Public IPs have been turned off."
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:114
|
||||
#, python-format
|
||||
msgid "Unable to shut off all VPNs: %(code)s - %(msg)s"
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:118
|
||||
msgid "VPNs have been successfully turned off."
|
||||
msgstr ""
|
||||
|
||||
#: views/volumes.py:44
|
||||
#, python-format
|
||||
msgid "Volume %s has been scheduled to be detached."
|
||||
msgstr ""
|
||||
|
||||
#: views/volumes.py:57
|
||||
#, python-format
|
||||
msgid "Unable to delete volume %(vol)s: %(msg)s"
|
||||
msgstr ""
|
||||
|
||||
#: views/volumes.py:61
|
||||
#, python-format
|
||||
msgid "Volume %s has been successfully deleted."
|
||||
msgstr ""
|
Binary file not shown.
@ -1,282 +0,0 @@
|
||||
# Translations of Dashboard for OpenStack User Interface.
|
||||
# Copyright 2011 Midokura KK
|
||||
# This file is distributed under the same license as the Dashboard for OpenStack.
|
||||
# FIRST AUTHOR Jeffrey Wilcox, 2011.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openstack-dashboard\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2011-06-08 14:02+0900\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: Takeshi Nakajima <tnakaji@midokura.jp>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: Japanese\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
|
||||
#: models.py:24 models.py:25
|
||||
msgid "Forbidden"
|
||||
msgstr "アクセスを許可されていません。"
|
||||
|
||||
#: models.py:39
|
||||
msgid "An unexpected error occurred. Please try your request again."
|
||||
msgstr ""
|
||||
"予期しないエラーが発生しました。もう一度リクエストを試してみてください。"
|
||||
|
||||
#: templates/django_nova_syspanel/index.html:9
|
||||
msgid ""
|
||||
"View all running instances other than VPNs. Schedule instances for\treboot "
|
||||
"or termination. Download logs."
|
||||
msgstr ""
|
||||
"VPN以外で実行中のすべてのインスタンスを表示。再起動または終了のインスタンスス"
|
||||
"ケジュールを設定。ログをダウンロード。"
|
||||
|
||||
#: templates/django_nova_syspanel/index.html:15
|
||||
#: templates/django_nova_syspanel/volumes/index.html:24
|
||||
msgid ""
|
||||
"View all volumes. See size, status, and mount point. Detach and destroy "
|
||||
"volumes."
|
||||
msgstr ""
|
||||
"すべてのボリュームを表示。サイズ、ステータスおよびマウントポイントを参照。ボ"
|
||||
"リュームを取り外して破棄。"
|
||||
|
||||
#: templates/django_nova_syspanel/index.html:21
|
||||
#: templates/django_nova_syspanel/vpns/index.html:25
|
||||
msgid ""
|
||||
"View all projects VPN status. Schedule launch, termination, and reboot. Send "
|
||||
"credentials."
|
||||
msgstr ""
|
||||
"すべてのプロジェクトのVPNステータスを表示。起動、終了、再起動のスケジュールを"
|
||||
"設定。認証情報を送信。"
|
||||
|
||||
#: templates/django_nova_syspanel/index.html:27
|
||||
msgid ""
|
||||
"View servers that participate in your cloud. See statistics about\trunning "
|
||||
"services and served objects."
|
||||
msgstr ""
|
||||
"クラウドに参加しているサーバーを表示。実行中のサービスと提供オブジェクトに関"
|
||||
"する統計情報を参照してください。"
|
||||
|
||||
#: templates/django_nova_syspanel/index.html:33
|
||||
msgid ""
|
||||
"Perform operations to deal with rogue users, limit or prevent compromise, "
|
||||
"and deal with external threats."
|
||||
msgstr ""
|
||||
"不正なユーザーへの対応する操作を実行し、情報漏洩の制限または防止し、外部から"
|
||||
"の脅威に対処する。"
|
||||
|
||||
#: templates/django_nova_syspanel/cloudview/index.html:9
|
||||
msgid ""
|
||||
"View servers that participate in your cloud. See statistics about running "
|
||||
"services and served objects."
|
||||
msgstr ""
|
||||
"クラウドに参加しているサーバーを表示。実行中のサービスと提供オブジェクトに関"
|
||||
"する統計情報を参照してください。"
|
||||
|
||||
#: templates/django_nova_syspanel/instances/index.html:23
|
||||
msgid "Manage Instances"
|
||||
msgstr "インスタンスを管理する。"
|
||||
|
||||
#: templates/django_nova_syspanel/instances/index.html:24
|
||||
msgid ""
|
||||
"View all running instances other than VPNs. Schedule instances for reboot or "
|
||||
"termination. Download logs."
|
||||
msgstr ""
|
||||
"VPN以外で実行中のすべてのインスタンスを表示。再起動または終了のインスタンスス"
|
||||
"ケジュールを設定。ログをダウンロード。"
|
||||
|
||||
#: templates/django_nova_syspanel/instances/index.html:36
|
||||
msgid "Refresh List"
|
||||
msgstr "リストを再読み込みする。"
|
||||
|
||||
#: templates/django_nova_syspanel/instances/index.html:66
|
||||
msgid "Console Log"
|
||||
msgstr "ログをコンソールする。"
|
||||
|
||||
#: templates/django_nova_syspanel/security/disable_project_credentials.html:9
|
||||
msgid ""
|
||||
"\n"
|
||||
" If a user's credentials were comprimised, you will need to use \n"
|
||||
" `nova-manage user revoke USERNAME`, and the restart all VPNs for "
|
||||
"projects\n"
|
||||
" they are a member of. "
|
||||
msgstr ""
|
||||
"\n"
|
||||
" ユーザーの認証情報が漏洩していた場合には、USERNAMEを取り消すことができる"
|
||||
"nova-manage userを利用し、\n"
|
||||
" 参加している全てのVPNを再起動してください。"
|
||||
|
||||
#: templates/django_nova_syspanel/security/disable_project_credentials.html:15
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\n"
|
||||
" The VPN for %(project)s is currently offline. You can turn it back on\n"
|
||||
" using "
|
||||
msgstr ""
|
||||
"\n"
|
||||
" 現在、%(project)sのVPNはオフラインになっています。あなたが使用していたも"
|
||||
"のを元に戻すことができます"
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:7
|
||||
msgid "Security"
|
||||
msgstr "セキュリティ"
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:9
|
||||
msgid "Use the following tools to secure the cloud during a security event"
|
||||
msgstr ""
|
||||
"セキュリティイベント中にクラウドのセキュリティを確保するために、次のツールを"
|
||||
"使用してください。"
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:14
|
||||
msgid ""
|
||||
"<strong>Scenario:</strong> Project account credentials have been compromised."
|
||||
msgstr ""
|
||||
"<strong>シナリオ:</strong>プロジェクトアカウントの認証情報が漏洩しています。"
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:15
|
||||
msgid ""
|
||||
"<strong>Action:</strong> Disable the user or project. This should invalidate "
|
||||
"the credentials, also deny the specific port assigned to the user."
|
||||
msgstr ""
|
||||
"<strong>アクション:</strong>ユーザーまはたプロジェクトを無効にする。これは認"
|
||||
"証情報を無効にし、ユーザーに割り当てられている特定のポートを拒否します。"
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:34
|
||||
msgid ""
|
||||
"<strong>Scenario:</strong> The issue pin points to be coming in from a "
|
||||
"specific external ip or ip range."
|
||||
msgstr ""
|
||||
"<strong>シナリオ:</strong>この問題は特定の範囲の外部IPアドレスから来ているこ"
|
||||
"とを示しています。"
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:35
|
||||
msgid ""
|
||||
"<strong>Action:</strong> Block the IP or IP range. This should manipulate ip "
|
||||
"tables to block the ip or ip range."
|
||||
msgstr ""
|
||||
"<strong>アクション:</strong>そのIPアドレスの範囲をブロックします。IPアドレス"
|
||||
"範囲をブロックするには、IPアドレステーブルを操作する必要があります。"
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:55
|
||||
msgid ""
|
||||
"<strong>Scenario:</strong> Issues affecting multiple public entry points or "
|
||||
"could not determine to be a specific one."
|
||||
msgstr ""
|
||||
"<strong>シナリオ:</strong>やポイントに影響を及ぼす複数のパブリックエントリの"
|
||||
"問題は、1つ具体的にできなかった決定します。"
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:56
|
||||
msgid ""
|
||||
"<strong>Action:</strong> Disable all public IPs on all VMs. This should "
|
||||
"unplumb the device the public ip was on."
|
||||
msgstr ""
|
||||
"<strong>アクション:</strong>全てのVM上の全てのパブリックIPアドレスを無効にし"
|
||||
"ます。この操作には、パブリックIPアドレスが付与されたデバイスを取り外す必要が"
|
||||
"あります。"
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:69
|
||||
msgid ""
|
||||
"<strong>Scenario:</strong> Issue related to VPN service affecting multiple "
|
||||
"customers."
|
||||
msgstr ""
|
||||
"<strong>シナリオ:</strong>複数の顧客に影響を与えるVPNサービスに関連する問題"
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:70
|
||||
msgid ""
|
||||
"<strong>Action:</strong> Disable VPN service. This should turn off the VPN "
|
||||
"ip."
|
||||
msgstr ""
|
||||
"<strong>アクション:</strong>VPNサービスを無効にする。この操作には、VPNのIPを"
|
||||
"オフにする必要があります。"
|
||||
|
||||
#: templates/django_nova_syspanel/volumes/index.html:23
|
||||
msgid "Manage Volumes"
|
||||
msgstr "ボリュームを管理する。"
|
||||
|
||||
#: templates/django_nova_syspanel/vpns/index.html:24
|
||||
msgid "Manage VPNs"
|
||||
msgstr "VPNを管理する。"
|
||||
|
||||
#: views/instances.py:44
|
||||
#, python-format
|
||||
msgid "Instance %s has been scheduled for termination."
|
||||
msgstr "インスタンス%sは終了処理されます。"
|
||||
|
||||
#: views/instances.py:48
|
||||
#, python-format
|
||||
msgid "There were issues trying to terminate instance %s. Please try again."
|
||||
msgstr ""
|
||||
"インスタンス%sの終了処理中に問題が生じています。もう一度やり直してください。"
|
||||
|
||||
#: views/instances.py:79
|
||||
#, python-format
|
||||
msgid "Instance %s has been scheduled for reboot."
|
||||
msgstr "インスタンス%sは再起動されます。"
|
||||
|
||||
#: views/instances.py:83
|
||||
#, python-format
|
||||
msgid "There were issues trying to reboot instance %s. Please try again."
|
||||
msgstr ""
|
||||
"インスタンス%sの再起動中に問題が生じています。もう一度やり直してください。"
|
||||
|
||||
#: views/security.py:41
|
||||
#, python-format
|
||||
msgid "Unable to disable project %(name)s: %(code)s - %(msg)s"
|
||||
msgstr "プロジェクト%(name)sを無効にすることができません。: %(code)s - %(msg)s"
|
||||
|
||||
#: views/security.py:46
|
||||
#, python-format
|
||||
msgid "Project %s has been successfully disabled."
|
||||
msgstr "プロジェクト%sが無効になりました。"
|
||||
|
||||
#: views/security.py:52
|
||||
msgid "Invalid form data"
|
||||
msgstr "無効なフォームデータ"
|
||||
|
||||
#: views/security.py:68
|
||||
#, python-format
|
||||
msgid "Unable to block IPs range %(cidr)s: %(code)s %(msg)s"
|
||||
msgstr ""
|
||||
"IPアドレス範囲%(cidr)sをブロックすることができません。: %(code)s %(msg)s"
|
||||
|
||||
#: views/security.py:74
|
||||
#, python-format
|
||||
msgid "IPs range %shas been successfully blocked"
|
||||
msgstr "IPアドレス範囲%sは、正常にブロックされました。"
|
||||
|
||||
#: views/security.py:88
|
||||
#, python-format
|
||||
msgid "Unable to shut off public IPs: %(code)s - %(msg)s"
|
||||
msgstr "パブリックIPアドレスを遮断することができません。: %(code)s - %(msg)s"
|
||||
|
||||
#: views/security.py:91
|
||||
msgid "Public IPs have been turned off."
|
||||
msgstr "パブリックIPアドレスがオフになっています。"
|
||||
|
||||
#: views/security.py:114
|
||||
#, python-format
|
||||
msgid "Unable to shut off all VPNs: %(code)s - %(msg)s"
|
||||
msgstr "全てのVPNを遮断することができません。: %(code)s - %(msg)s"
|
||||
|
||||
#: views/security.py:118
|
||||
msgid "VPNs have been successfully turned off."
|
||||
msgstr "VPNは正常にオフになりました。"
|
||||
|
||||
#: views/volumes.py:44
|
||||
#, python-format
|
||||
msgid "Volume %s has been scheduled to be detached."
|
||||
msgstr "ボリューム%s取り外されます。"
|
||||
|
||||
#: views/volumes.py:57
|
||||
#, python-format
|
||||
msgid "Unable to delete volume %(vol)s: %(msg)s"
|
||||
msgstr "ボリューム%(vol)sを削除することができません。%(msg)s"
|
||||
|
||||
#: views/volumes.py:61
|
||||
#, python-format
|
||||
msgid "Volume %s has been successfully deleted."
|
||||
msgstr "ボリューム%sが正常に削除されました。"
|
Binary file not shown.
@ -1,239 +0,0 @@
|
||||
# Translations of Dashboard for OpenStack User Interface.
|
||||
# Copyright 2011 Midokura KK
|
||||
# This file is distributed under the same license as the Dashboard for OpenStack.
|
||||
# FIRST AUTHOR Jeffrey Wilcox, 2011.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openstack-dashboard\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2011-06-08 14:02+0900\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: models.py:24 models.py:25
|
||||
msgid "Forbidden"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:39
|
||||
msgid "An unexpected error occurred. Please try your request again."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/index.html:9
|
||||
msgid ""
|
||||
"View all running instances other than VPNs. Schedule instances for\treboot "
|
||||
"or termination. Download logs."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/index.html:15
|
||||
#: templates/django_nova_syspanel/volumes/index.html:24
|
||||
msgid ""
|
||||
"View all volumes. See size, status, and mount point. Detach and destroy "
|
||||
"volumes."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/index.html:21
|
||||
#: templates/django_nova_syspanel/vpns/index.html:25
|
||||
msgid ""
|
||||
"View all projects VPN status. Schedule launch, termination, and reboot. Send "
|
||||
"credentials."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/index.html:27
|
||||
msgid ""
|
||||
"View servers that participate in your cloud. See statistics about\trunning "
|
||||
"services and served objects."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/index.html:33
|
||||
msgid ""
|
||||
"Perform operations to deal with rogue users, limit or prevent compromise, "
|
||||
"and deal with external threats."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/cloudview/index.html:9
|
||||
msgid ""
|
||||
"View servers that participate in your cloud. See statistics about running "
|
||||
"services and served objects."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/instances/index.html:23
|
||||
msgid "Manage Instances"
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/instances/index.html:24
|
||||
msgid ""
|
||||
"View all running instances other than VPNs. Schedule instances for reboot or "
|
||||
"termination. Download logs."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/instances/index.html:36
|
||||
msgid "Refresh List"
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/instances/index.html:66
|
||||
msgid "Console Log"
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/disable_project_credentials.html:9
|
||||
msgid ""
|
||||
"\n"
|
||||
" If a user's credentials were comprimised, you will need to use \n"
|
||||
" `nova-manage user revoke USERNAME`, and the restart all VPNs for "
|
||||
"projects\n"
|
||||
" they are a member of. "
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/disable_project_credentials.html:15
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\n"
|
||||
" The VPN for %(project)s is currently offline. You can turn it back on\n"
|
||||
" using "
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:7
|
||||
msgid "Security"
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:9
|
||||
msgid "Use the following tools to secure the cloud during a security event"
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:14
|
||||
msgid ""
|
||||
"<strong>Scenario:</strong> Project account credentials have been compromised."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:15
|
||||
msgid ""
|
||||
"<strong>Action:</strong> Disable the user or project. This should invalidate "
|
||||
"the credentials, also deny the specific port assigned to the user."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:34
|
||||
msgid ""
|
||||
"<strong>Scenario:</strong> The issue pin points to be coming in from a "
|
||||
"specific external ip or ip range."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:35
|
||||
msgid ""
|
||||
"<strong>Action:</strong> Block the IP or IP range. This should manipulate ip "
|
||||
"tables to block the ip or ip range."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:55
|
||||
msgid ""
|
||||
"<strong>Scenario:</strong> Issues affecting multiple public entry points or "
|
||||
"could not determine to be a specific one."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:56
|
||||
msgid ""
|
||||
"<strong>Action:</strong> Disable all public IPs on all VMs. This should "
|
||||
"unplumb the device the public ip was on."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:69
|
||||
msgid ""
|
||||
"<strong>Scenario:</strong> Issue related to VPN service affecting multiple "
|
||||
"customers."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:70
|
||||
msgid ""
|
||||
"<strong>Action:</strong> Disable VPN service. This should turn off the VPN "
|
||||
"ip."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/volumes/index.html:23
|
||||
msgid "Manage Volumes"
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/vpns/index.html:24
|
||||
msgid "Manage VPNs"
|
||||
msgstr ""
|
||||
|
||||
#: views/instances.py:44
|
||||
#, python-format
|
||||
msgid "Instance %s has been scheduled for termination."
|
||||
msgstr ""
|
||||
|
||||
#: views/instances.py:48
|
||||
#, python-format
|
||||
msgid "There were issues trying to terminate instance %s. Please try again."
|
||||
msgstr ""
|
||||
|
||||
#: views/instances.py:79
|
||||
#, python-format
|
||||
msgid "Instance %s has been scheduled for reboot."
|
||||
msgstr ""
|
||||
|
||||
#: views/instances.py:83
|
||||
#, python-format
|
||||
msgid "There were issues trying to reboot instance %s. Please try again."
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:41
|
||||
#, python-format
|
||||
msgid "Unable to disable project %(name)s: %(code)s - %(msg)s"
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:46
|
||||
#, python-format
|
||||
msgid "Project %s has been successfully disabled."
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:52
|
||||
msgid "Invalid form data"
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:68
|
||||
#, python-format
|
||||
msgid "Unable to block IPs range %(cidr)s: %(code)s %(msg)s"
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:74
|
||||
#, python-format
|
||||
msgid "IPs range %shas been successfully blocked"
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:88
|
||||
#, python-format
|
||||
msgid "Unable to shut off public IPs: %(code)s - %(msg)s"
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:91
|
||||
msgid "Public IPs have been turned off."
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:114
|
||||
#, python-format
|
||||
msgid "Unable to shut off all VPNs: %(code)s - %(msg)s"
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:118
|
||||
msgid "VPNs have been successfully turned off."
|
||||
msgstr ""
|
||||
|
||||
#: views/volumes.py:44
|
||||
#, python-format
|
||||
msgid "Volume %s has been scheduled to be detached."
|
||||
msgstr ""
|
||||
|
||||
#: views/volumes.py:57
|
||||
#, python-format
|
||||
msgid "Unable to delete volume %(vol)s: %(msg)s"
|
||||
msgstr ""
|
||||
|
||||
#: views/volumes.py:61
|
||||
#, python-format
|
||||
msgid "Volume %s has been successfully deleted."
|
||||
msgstr ""
|
Binary file not shown.
@ -1,239 +0,0 @@
|
||||
# Translations of Dashboard for OpenStack User Interface.
|
||||
# Copyright 2011 Midokura KK
|
||||
# This file is distributed under the same license as the Dashboard for OpenStack.
|
||||
# FIRST AUTHOR Jeffrey Wilcox, 2011.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openstack-dashboard\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2011-06-08 14:02+0900\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: models.py:24 models.py:25
|
||||
msgid "Forbidden"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:39
|
||||
msgid "An unexpected error occurred. Please try your request again."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/index.html:9
|
||||
msgid ""
|
||||
"View all running instances other than VPNs. Schedule instances for\treboot "
|
||||
"or termination. Download logs."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/index.html:15
|
||||
#: templates/django_nova_syspanel/volumes/index.html:24
|
||||
msgid ""
|
||||
"View all volumes. See size, status, and mount point. Detach and destroy "
|
||||
"volumes."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/index.html:21
|
||||
#: templates/django_nova_syspanel/vpns/index.html:25
|
||||
msgid ""
|
||||
"View all projects VPN status. Schedule launch, termination, and reboot. Send "
|
||||
"credentials."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/index.html:27
|
||||
msgid ""
|
||||
"View servers that participate in your cloud. See statistics about\trunning "
|
||||
"services and served objects."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/index.html:33
|
||||
msgid ""
|
||||
"Perform operations to deal with rogue users, limit or prevent compromise, "
|
||||
"and deal with external threats."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/cloudview/index.html:9
|
||||
msgid ""
|
||||
"View servers that participate in your cloud. See statistics about running "
|
||||
"services and served objects."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/instances/index.html:23
|
||||
msgid "Manage Instances"
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/instances/index.html:24
|
||||
msgid ""
|
||||
"View all running instances other than VPNs. Schedule instances for reboot or "
|
||||
"termination. Download logs."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/instances/index.html:36
|
||||
msgid "Refresh List"
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/instances/index.html:66
|
||||
msgid "Console Log"
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/disable_project_credentials.html:9
|
||||
msgid ""
|
||||
"\n"
|
||||
" If a user's credentials were comprimised, you will need to use \n"
|
||||
" `nova-manage user revoke USERNAME`, and the restart all VPNs for "
|
||||
"projects\n"
|
||||
" they are a member of. "
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/disable_project_credentials.html:15
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\n"
|
||||
" The VPN for %(project)s is currently offline. You can turn it back on\n"
|
||||
" using "
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:7
|
||||
msgid "Security"
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:9
|
||||
msgid "Use the following tools to secure the cloud during a security event"
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:14
|
||||
msgid ""
|
||||
"<strong>Scenario:</strong> Project account credentials have been compromised."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:15
|
||||
msgid ""
|
||||
"<strong>Action:</strong> Disable the user or project. This should invalidate "
|
||||
"the credentials, also deny the specific port assigned to the user."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:34
|
||||
msgid ""
|
||||
"<strong>Scenario:</strong> The issue pin points to be coming in from a "
|
||||
"specific external ip or ip range."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:35
|
||||
msgid ""
|
||||
"<strong>Action:</strong> Block the IP or IP range. This should manipulate ip "
|
||||
"tables to block the ip or ip range."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:55
|
||||
msgid ""
|
||||
"<strong>Scenario:</strong> Issues affecting multiple public entry points or "
|
||||
"could not determine to be a specific one."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:56
|
||||
msgid ""
|
||||
"<strong>Action:</strong> Disable all public IPs on all VMs. This should "
|
||||
"unplumb the device the public ip was on."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:69
|
||||
msgid ""
|
||||
"<strong>Scenario:</strong> Issue related to VPN service affecting multiple "
|
||||
"customers."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:70
|
||||
msgid ""
|
||||
"<strong>Action:</strong> Disable VPN service. This should turn off the VPN "
|
||||
"ip."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/volumes/index.html:23
|
||||
msgid "Manage Volumes"
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/vpns/index.html:24
|
||||
msgid "Manage VPNs"
|
||||
msgstr ""
|
||||
|
||||
#: views/instances.py:44
|
||||
#, python-format
|
||||
msgid "Instance %s has been scheduled for termination."
|
||||
msgstr ""
|
||||
|
||||
#: views/instances.py:48
|
||||
#, python-format
|
||||
msgid "There were issues trying to terminate instance %s. Please try again."
|
||||
msgstr ""
|
||||
|
||||
#: views/instances.py:79
|
||||
#, python-format
|
||||
msgid "Instance %s has been scheduled for reboot."
|
||||
msgstr ""
|
||||
|
||||
#: views/instances.py:83
|
||||
#, python-format
|
||||
msgid "There were issues trying to reboot instance %s. Please try again."
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:41
|
||||
#, python-format
|
||||
msgid "Unable to disable project %(name)s: %(code)s - %(msg)s"
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:46
|
||||
#, python-format
|
||||
msgid "Project %s has been successfully disabled."
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:52
|
||||
msgid "Invalid form data"
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:68
|
||||
#, python-format
|
||||
msgid "Unable to block IPs range %(cidr)s: %(code)s %(msg)s"
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:74
|
||||
#, python-format
|
||||
msgid "IPs range %shas been successfully blocked"
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:88
|
||||
#, python-format
|
||||
msgid "Unable to shut off public IPs: %(code)s - %(msg)s"
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:91
|
||||
msgid "Public IPs have been turned off."
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:114
|
||||
#, python-format
|
||||
msgid "Unable to shut off all VPNs: %(code)s - %(msg)s"
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:118
|
||||
msgid "VPNs have been successfully turned off."
|
||||
msgstr ""
|
||||
|
||||
#: views/volumes.py:44
|
||||
#, python-format
|
||||
msgid "Volume %s has been scheduled to be detached."
|
||||
msgstr ""
|
||||
|
||||
#: views/volumes.py:57
|
||||
#, python-format
|
||||
msgid "Unable to delete volume %(vol)s: %(msg)s"
|
||||
msgstr ""
|
||||
|
||||
#: views/volumes.py:61
|
||||
#, python-format
|
||||
msgid "Volume %s has been successfully deleted."
|
||||
msgstr ""
|
Binary file not shown.
@ -1,239 +0,0 @@
|
||||
# Translations of Dashboard for OpenStack User Interface.
|
||||
# Copyright 2011 Midokura KK
|
||||
# This file is distributed under the same license as the Dashboard for OpenStack.
|
||||
# FIRST AUTHOR Jeffrey Wilcox, 2011.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openstack-dashboard\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2011-06-08 14:02+0900\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: models.py:24 models.py:25
|
||||
msgid "Forbidden"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:39
|
||||
msgid "An unexpected error occurred. Please try your request again."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/index.html:9
|
||||
msgid ""
|
||||
"View all running instances other than VPNs. Schedule instances for\treboot "
|
||||
"or termination. Download logs."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/index.html:15
|
||||
#: templates/django_nova_syspanel/volumes/index.html:24
|
||||
msgid ""
|
||||
"View all volumes. See size, status, and mount point. Detach and destroy "
|
||||
"volumes."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/index.html:21
|
||||
#: templates/django_nova_syspanel/vpns/index.html:25
|
||||
msgid ""
|
||||
"View all projects VPN status. Schedule launch, termination, and reboot. Send "
|
||||
"credentials."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/index.html:27
|
||||
msgid ""
|
||||
"View servers that participate in your cloud. See statistics about\trunning "
|
||||
"services and served objects."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/index.html:33
|
||||
msgid ""
|
||||
"Perform operations to deal with rogue users, limit or prevent compromise, "
|
||||
"and deal with external threats."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/cloudview/index.html:9
|
||||
msgid ""
|
||||
"View servers that participate in your cloud. See statistics about running "
|
||||
"services and served objects."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/instances/index.html:23
|
||||
msgid "Manage Instances"
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/instances/index.html:24
|
||||
msgid ""
|
||||
"View all running instances other than VPNs. Schedule instances for reboot or "
|
||||
"termination. Download logs."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/instances/index.html:36
|
||||
msgid "Refresh List"
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/instances/index.html:66
|
||||
msgid "Console Log"
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/disable_project_credentials.html:9
|
||||
msgid ""
|
||||
"\n"
|
||||
" If a user's credentials were comprimised, you will need to use \n"
|
||||
" `nova-manage user revoke USERNAME`, and the restart all VPNs for "
|
||||
"projects\n"
|
||||
" they are a member of. "
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/disable_project_credentials.html:15
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\n"
|
||||
" The VPN for %(project)s is currently offline. You can turn it back on\n"
|
||||
" using "
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:7
|
||||
msgid "Security"
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:9
|
||||
msgid "Use the following tools to secure the cloud during a security event"
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:14
|
||||
msgid ""
|
||||
"<strong>Scenario:</strong> Project account credentials have been compromised."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:15
|
||||
msgid ""
|
||||
"<strong>Action:</strong> Disable the user or project. This should invalidate "
|
||||
"the credentials, also deny the specific port assigned to the user."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:34
|
||||
msgid ""
|
||||
"<strong>Scenario:</strong> The issue pin points to be coming in from a "
|
||||
"specific external ip or ip range."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:35
|
||||
msgid ""
|
||||
"<strong>Action:</strong> Block the IP or IP range. This should manipulate ip "
|
||||
"tables to block the ip or ip range."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:55
|
||||
msgid ""
|
||||
"<strong>Scenario:</strong> Issues affecting multiple public entry points or "
|
||||
"could not determine to be a specific one."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:56
|
||||
msgid ""
|
||||
"<strong>Action:</strong> Disable all public IPs on all VMs. This should "
|
||||
"unplumb the device the public ip was on."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:69
|
||||
msgid ""
|
||||
"<strong>Scenario:</strong> Issue related to VPN service affecting multiple "
|
||||
"customers."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/security/index.html:70
|
||||
msgid ""
|
||||
"<strong>Action:</strong> Disable VPN service. This should turn off the VPN "
|
||||
"ip."
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/volumes/index.html:23
|
||||
msgid "Manage Volumes"
|
||||
msgstr ""
|
||||
|
||||
#: templates/django_nova_syspanel/vpns/index.html:24
|
||||
msgid "Manage VPNs"
|
||||
msgstr ""
|
||||
|
||||
#: views/instances.py:44
|
||||
#, python-format
|
||||
msgid "Instance %s has been scheduled for termination."
|
||||
msgstr ""
|
||||
|
||||
#: views/instances.py:48
|
||||
#, python-format
|
||||
msgid "There were issues trying to terminate instance %s. Please try again."
|
||||
msgstr ""
|
||||
|
||||
#: views/instances.py:79
|
||||
#, python-format
|
||||
msgid "Instance %s has been scheduled for reboot."
|
||||
msgstr ""
|
||||
|
||||
#: views/instances.py:83
|
||||
#, python-format
|
||||
msgid "There were issues trying to reboot instance %s. Please try again."
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:41
|
||||
#, python-format
|
||||
msgid "Unable to disable project %(name)s: %(code)s - %(msg)s"
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:46
|
||||
#, python-format
|
||||
msgid "Project %s has been successfully disabled."
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:52
|
||||
msgid "Invalid form data"
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:68
|
||||
#, python-format
|
||||
msgid "Unable to block IPs range %(cidr)s: %(code)s %(msg)s"
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:74
|
||||
#, python-format
|
||||
msgid "IPs range %shas been successfully blocked"
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:88
|
||||
#, python-format
|
||||
msgid "Unable to shut off public IPs: %(code)s - %(msg)s"
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:91
|
||||
msgid "Public IPs have been turned off."
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:114
|
||||
#, python-format
|
||||
msgid "Unable to shut off all VPNs: %(code)s - %(msg)s"
|
||||
msgstr ""
|
||||
|
||||
#: views/security.py:118
|
||||
msgid "VPNs have been successfully turned off."
|
||||
msgstr ""
|
||||
|
||||
#: views/volumes.py:44
|
||||
#, python-format
|
||||
msgid "Volume %s has been scheduled to be detached."
|
||||
msgstr ""
|
||||
|
||||
#: views/volumes.py:57
|
||||
#, python-format
|
||||
msgid "Unable to delete volume %(vol)s: %(msg)s"
|
||||
msgstr ""
|
||||
|
||||
#: views/volumes.py:61
|
||||
#, python-format
|
||||
msgid "Volume %s has been successfully deleted."
|
||||
msgstr ""
|
@ -1,418 +0,0 @@
|
||||
import sys
|
||||
import boto
|
||||
import boto.exception
|
||||
import boto.s3
|
||||
from boto.ec2.volume import Volume
|
||||
from xml.dom import minidom
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import User
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django.db.models.signals import post_save
|
||||
from django.shortcuts import render_to_response
|
||||
from django.template import RequestContext
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
from nova_adminclient import NovaAdminClient
|
||||
|
||||
project_permissions = ('admin',)
|
||||
|
||||
|
||||
class NovaResponseError(Exception):
|
||||
def __init__(self, ec2error):
|
||||
if ec2error.reason == 'Forbidden':
|
||||
self.code = _('Forbidden')
|
||||
self.message = _('Forbidden')
|
||||
return
|
||||
|
||||
dom = minidom.parseString(ec2error.body)
|
||||
err = dom.getElementsByTagName('Errors')[0]
|
||||
|
||||
try:
|
||||
self.code = err.getElementsByTagName('Code')[0].childNodes[0].data
|
||||
except IndexError:
|
||||
self.code = 'Unknown'
|
||||
|
||||
try:
|
||||
self.message = err.getElementsByTagName('Message')[0].childNodes[0].data
|
||||
except IndexError:
|
||||
self.message = _('An unexpected error occurred. Please try your request again.')
|
||||
|
||||
dom.unlink()
|
||||
|
||||
def __str__(self):
|
||||
return '%s (%s)' % (self.message, self.code)
|
||||
|
||||
|
||||
def handle_nova_error(fn):
|
||||
def decorator(view_func):
|
||||
def wrapper(*args, **kwargs):
|
||||
try:
|
||||
return view_func(*args, **kwargs)
|
||||
except boto.exception.EC2ResponseError, e:
|
||||
if e.reason == 'Forbidden':
|
||||
raise PermissionDenied()
|
||||
else:
|
||||
raise NovaResponseError(e)
|
||||
return wrapper
|
||||
return decorator(fn)
|
||||
|
||||
|
||||
def get_nova_admin_connection():
|
||||
"""
|
||||
Returns a Nova administration connection.
|
||||
"""
|
||||
return NovaAdminClient(
|
||||
clc_url=settings.NOVA_DEFAULT_ENDPOINT,
|
||||
region=settings.NOVA_DEFAULT_REGION,
|
||||
access_key=settings.NOVA_ACCESS_KEY,
|
||||
secret_key=settings.NOVA_SECRET_KEY)
|
||||
|
||||
|
||||
class VolumeInfo(object):
|
||||
"""Foo"""
|
||||
|
||||
def __init__(self, connection=None, username=None, endpoint=None):
|
||||
self.connection = connection
|
||||
self.username = username
|
||||
self.endpoint = endpoint
|
||||
|
||||
self.id = None
|
||||
self.create_time = None
|
||||
self.status = None
|
||||
self.size = None
|
||||
self.snapshot_id = None
|
||||
self.attach_data = None
|
||||
self.zone = None
|
||||
|
||||
self.display_name = None
|
||||
self.display_description = None
|
||||
|
||||
def startElement(self, name, attrs, connection):
|
||||
return None
|
||||
|
||||
def endElement(self, name, value, connection):
|
||||
if name == 'volumeId':
|
||||
self.id = str(value)
|
||||
elif name == 'size':
|
||||
self.size = int(value)
|
||||
elif name == 'status':
|
||||
self.status = str(value)
|
||||
elif name == 'displayName':
|
||||
self.display_name = str(value)
|
||||
elif name == 'displayDescription':
|
||||
self.display_description = str(value)
|
||||
else:
|
||||
setattr(self, name, str(value))
|
||||
|
||||
|
||||
class ProjectManager(object):
|
||||
def __init__(self, username, project, region):
|
||||
self.username = username
|
||||
self.projectname = project.projectname
|
||||
self.projectManagerId = project.projectManagerId
|
||||
self.region = region
|
||||
|
||||
def get_nova_connection(self):
|
||||
"""
|
||||
Returns a boto connection for a user's project.
|
||||
"""
|
||||
nova = get_nova_admin_connection()
|
||||
return nova.connection_for(self.username,
|
||||
self.projectname,
|
||||
clc_url=self.region['endpoint'],
|
||||
region=self.region['name'])
|
||||
|
||||
def get_zip(self):
|
||||
"""
|
||||
Returns a buffer of a zip file containing signed credentials
|
||||
for the project's Nova user.
|
||||
"""
|
||||
nova = get_nova_admin_connection()
|
||||
return nova.get_zip(self.username, self.projectname)
|
||||
|
||||
def get_images(self, image_ids=None):
|
||||
conn = self.get_nova_connection()
|
||||
images = conn.get_all_images(image_ids=image_ids)
|
||||
sorted_images = [i for i in images if i.ownerId == self.username] + \
|
||||
[i for i in images if i.ownerId != self.username]
|
||||
|
||||
return [i for i in sorted_images
|
||||
if i.type == 'machine' and i.location.split('/')[0] != 'nova']
|
||||
|
||||
def get_image(self, image_id):
|
||||
try:
|
||||
return self.get_images(image_ids=[image_id, ])[0]
|
||||
except IndexError:
|
||||
return None
|
||||
|
||||
@handle_nova_error
|
||||
def deregister_image(self, image_id):
|
||||
"""
|
||||
Removes the image's listing but leaves the image
|
||||
and manifest in the object store in tact.
|
||||
"""
|
||||
conn = self.get_nova_connection()
|
||||
return conn.deregister_image(image_id)
|
||||
|
||||
@handle_nova_error
|
||||
def update_image(self, image_id, display_name=None, description=None):
|
||||
conn = self.get_nova_connection()
|
||||
params = {'ImageId': image_id,
|
||||
'DisplayName': display_name,
|
||||
'Description': description}
|
||||
return conn.get_object('UpdateImage', params, boto.ec2.image.Image)
|
||||
|
||||
@handle_nova_error
|
||||
def run_instances(self, image_id, **kwargs):
|
||||
"""
|
||||
Runs instances of the specified image id.
|
||||
"""
|
||||
conn = self.get_nova_connection()
|
||||
return conn.run_instances(image_id, **kwargs)
|
||||
|
||||
def get_instance_count(self):
|
||||
"""
|
||||
Returns the number of active instances in this project
|
||||
or None if unknown.
|
||||
"""
|
||||
try:
|
||||
return len(self.get_instances())
|
||||
except:
|
||||
return None
|
||||
|
||||
@handle_nova_error
|
||||
def get_instances(self):
|
||||
"""
|
||||
Returns all instances in this project.
|
||||
"""
|
||||
conn = self.get_nova_connection()
|
||||
reservations = conn.get_all_instances()
|
||||
instances = []
|
||||
for reservation in reservations:
|
||||
for instance in reservation.instances:
|
||||
instances.append(instance)
|
||||
return instances
|
||||
|
||||
@handle_nova_error
|
||||
def get_instance(self, instance_id):
|
||||
"""
|
||||
Returns detail about the specified instance.
|
||||
"""
|
||||
conn = self.get_nova_connection()
|
||||
# TODO: Refactor this once nova's describe_instances filters by instance_id.
|
||||
reservations = conn.get_all_instances()
|
||||
for reservation in reservations:
|
||||
for instance in reservation.instances:
|
||||
if instance.id == instance_id:
|
||||
return instance
|
||||
return None
|
||||
|
||||
@handle_nova_error
|
||||
def update_instance(self, instance_id, updates):
|
||||
conn = self.get_nova_connection()
|
||||
params = {'InstanceId': instance_id,
|
||||
'DisplayName': updates['nickname'],
|
||||
'DisplayDescription': updates['description']}
|
||||
return conn.get_object('UpdateInstance', params,
|
||||
boto.ec2.instance.Instance)
|
||||
|
||||
def get_instance_graph(self, region, instance_id, graph_name):
|
||||
# TODO(devcamcar): Need better support for multiple regions.
|
||||
# Need a way to get object store by region.
|
||||
s3 = boto.s3.connection.S3Connection(
|
||||
aws_access_key_id=settings.NOVA_ACCESS_KEY,
|
||||
aws_secret_access_key=settings.NOVA_SECRET_KEY,
|
||||
is_secure=False,
|
||||
calling_format=boto.s3.connection.OrdinaryCallingFormat(),
|
||||
port=3333,
|
||||
host=settings.NOVA_CLC_IP)
|
||||
key = '_%s.monitor' % instance_id
|
||||
|
||||
try:
|
||||
bucket = s3.get_bucket(key, validate=False)
|
||||
except S3ResponseError, e:
|
||||
if e.code == "NoSuchBucket":
|
||||
return None
|
||||
else:
|
||||
raise e
|
||||
|
||||
key = bucket.get_key(graph_name)
|
||||
|
||||
return key.read()
|
||||
|
||||
@handle_nova_error
|
||||
def terminate_instance(self, instance_id):
|
||||
""" Terminates the specified instance within this project. """
|
||||
conn = self.get_nova_connection()
|
||||
conn.terminate_instances([instance_id])
|
||||
|
||||
@handle_nova_error
|
||||
def get_security_groups(self):
|
||||
"""
|
||||
Returns all security groups associated with this project.
|
||||
"""
|
||||
conn = self.get_nova_connection()
|
||||
groups = []
|
||||
|
||||
for g in conn.get_all_security_groups():
|
||||
# Do not show vpn group.
|
||||
#if g.name != 'vpn-secgroup':
|
||||
groups.append(g)
|
||||
|
||||
return groups
|
||||
|
||||
@handle_nova_error
|
||||
def get_security_group(self, name):
|
||||
"""
|
||||
Returns the specified security group for this project.
|
||||
"""
|
||||
conn = self.get_nova_connection()
|
||||
|
||||
try:
|
||||
return conn.get_all_security_groups(groupnames=name.encode('ASCII'))[0]
|
||||
except IndexError:
|
||||
return None
|
||||
|
||||
@handle_nova_error
|
||||
def has_security_group(self, name):
|
||||
"""
|
||||
Indicates whether a security group with the specified name
|
||||
exists in this project.
|
||||
"""
|
||||
return self.get_security_group(name) != None
|
||||
|
||||
@handle_nova_error
|
||||
def create_security_group(self, name, description):
|
||||
"""
|
||||
Creates a new security group in this project.
|
||||
"""
|
||||
conn = self.get_nova_connection()
|
||||
return conn.create_security_group(name, description)
|
||||
|
||||
@handle_nova_error
|
||||
def delete_security_group(self, name):
|
||||
"""
|
||||
Deletes a security group from the project.
|
||||
"""
|
||||
conn = self.get_nova_connection()
|
||||
return conn.delete_security_group(name=name)
|
||||
|
||||
@handle_nova_error
|
||||
def authorize_security_group(self, group_name, ip_protocol, from_port, to_port):
|
||||
"""
|
||||
Authorizes a rule for the specified security group.
|
||||
"""
|
||||
conn = self.get_nova_connection()
|
||||
return conn.authorize_security_group(
|
||||
group_name=group_name,
|
||||
ip_protocol=ip_protocol,
|
||||
from_port=from_port,
|
||||
to_port=to_port,
|
||||
cidr_ip='0.0.0.0/0')
|
||||
|
||||
@handle_nova_error
|
||||
def revoke_security_group(self, group_name, ip_protocol, from_port, to_port):
|
||||
"""
|
||||
Revokes a rule for the specified security group.
|
||||
"""
|
||||
conn = self.get_nova_connection()
|
||||
return conn.revoke_security_group(
|
||||
group_name=group_name,
|
||||
ip_protocol=ip_protocol,
|
||||
from_port=from_port,
|
||||
to_port=to_port,
|
||||
cidr_ip='0.0.0.0/0')
|
||||
|
||||
@handle_nova_error
|
||||
def get_key_pairs(self):
|
||||
"""
|
||||
Returns all key pairs associated with this project.
|
||||
"""
|
||||
conn = self.get_nova_connection()
|
||||
keys = []
|
||||
|
||||
for k in conn.get_all_key_pairs():
|
||||
# Do not show vpn key.
|
||||
if k.name != 'vpn-key':
|
||||
keys.append(k)
|
||||
|
||||
return keys
|
||||
|
||||
@handle_nova_error
|
||||
def get_key_pair(self, name):
|
||||
"""
|
||||
Returns the specified security group for this project.
|
||||
"""
|
||||
conn = self.get_nova_connection()
|
||||
|
||||
try:
|
||||
return conn.get_all_key_pairs(keynames=name.encode('ASCII'))[0]
|
||||
except IndexError:
|
||||
return None
|
||||
|
||||
@handle_nova_error
|
||||
def has_key_pair(self, name):
|
||||
"""
|
||||
Indicates whether a key pair with the specified name
|
||||
exists in this project.
|
||||
"""
|
||||
return self.get_key_pair(name) != None
|
||||
|
||||
@handle_nova_error
|
||||
def create_key_pair(self, name):
|
||||
"""
|
||||
Creates a new key pair for this project.
|
||||
"""
|
||||
conn = self.get_nova_connection()
|
||||
return conn.create_key_pair(name)
|
||||
|
||||
@handle_nova_error
|
||||
def delete_key_pair(self, name):
|
||||
"""
|
||||
Deletes a new key pair from this project.
|
||||
"""
|
||||
conn = self.get_nova_connection()
|
||||
conn.delete_key_pair(name)
|
||||
|
||||
@handle_nova_error
|
||||
def get_volumes(self):
|
||||
"""
|
||||
Returns all volumes in this project.
|
||||
"""
|
||||
conn = self.get_nova_connection()
|
||||
return conn.get_all_volumes()
|
||||
|
||||
@handle_nova_error
|
||||
def create_volume(self, size, display_name=None, display_description=None,
|
||||
snapshot=None):
|
||||
conn = self.get_nova_connection()
|
||||
params = {'Size': size, 'DisplayName': display_name,
|
||||
'DisplayDescription': display_description}
|
||||
return conn.get_object('CreateVolume', params, boto.ec2.volume.Volume)
|
||||
|
||||
@handle_nova_error
|
||||
def delete_volume(self, volume_id):
|
||||
conn = self.get_nova_connection()
|
||||
return conn.delete_volume(volume_id)
|
||||
|
||||
@handle_nova_error
|
||||
def attach_volume(self, volume_id, instance_id, device):
|
||||
conn = self.get_nova_connection()
|
||||
return conn.attach_volume(volume_id, instance_id, device)
|
||||
|
||||
@handle_nova_error
|
||||
def detach_volume(self, volume_id):
|
||||
conn = self.get_nova_connection()
|
||||
return conn.detach_volume(volume_id)
|
||||
|
||||
|
||||
def user_post_save(sender, instance, created, *args, **kwargs):
|
||||
"""
|
||||
Creates a Nova User when a new Django User is created.
|
||||
"""
|
||||
if created:
|
||||
nova = get_nova_admin_connection()
|
||||
if not nova.has_user(instance.username):
|
||||
nova.create_user(instance.username)
|
||||
post_save.connect(user_post_save, User, dispatch_uid='django.contrib.auth.models.User.post_save')
|
@ -1,20 +0,0 @@
|
||||
{% extends "base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block breadcrumb %}{{ block.super }}<li><a href="{% url syspanel_security %}">Security</a></li>{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h2 class="page_heading">{{project}} Disabled</h2>
|
||||
|
||||
<p>{%blocktrans%}
|
||||
If a user's credentials were comprimised, you will need to use
|
||||
`nova-manage user revoke USERNAME`, and the restart all VPNs for projects
|
||||
they are a member of. {%endblocktrans%}
|
||||
</p>
|
||||
|
||||
<p>{%blocktrans%}
|
||||
The VPN for {{project}} is currently offline. You can turn it back on
|
||||
using {%endblocktrans%}<a href="{% url syspanel_vpns %}">VPN overview</a>.
|
||||
</p>
|
||||
|
||||
{% endblock %}
|
@ -1,81 +0,0 @@
|
||||
{% extends "base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block breadcrumb %}{{ block.super }}<li><a href="{% url syspanel_security %}">Security</a></li>{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h2 class="page_heading">{% trans "Security" %}</h2>
|
||||
|
||||
<h2>{% trans "Use the following tools to secure the cloud during a security event" %}</h2>
|
||||
|
||||
<div id="scenerios">
|
||||
<div class="scenerio">
|
||||
<div class="description">
|
||||
<p>{% trans "<strong>Scenario:</strong> Project account credentials have been compromised." %}</p>
|
||||
<p>{% trans "<strong>Action:</strong> Disable the user or project. This should invalidate the credentials, also deny the specific port assigned to the user." %}</p>
|
||||
</div>
|
||||
|
||||
<form id="disable_project_credentials" action="{% url syspanel_security_disable_project_credentials %}" method="post" accept-charset="utf-8">
|
||||
{% csrf_token %}
|
||||
<fieldset>
|
||||
{% for field in project_form %}
|
||||
{{ field.label_tag }}
|
||||
{% if field.errors %}{{ field.errors }}{% endif %}
|
||||
{{ field }}
|
||||
{% endfor %}
|
||||
|
||||
<input type="submit" value="Turn off user/project" />
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="scenerio">
|
||||
<div class="description">
|
||||
<p>{% trans "<strong>Scenario:</strong> The issue pin points to be coming in from a specific external ip or ip range." %}</p>
|
||||
<p>{% trans "<strong>Action:</strong> Block the IP or IP range. This should manipulate ip tables to block the ip or ip range." %}</p>
|
||||
</div>
|
||||
|
||||
<form id="disable_ip_range" action="{% url syspanel_security_disable_ip_range %}" method="post" accept-charset="utf-8">
|
||||
{% csrf_token %}
|
||||
<fieldset>
|
||||
{% for field in ip_form %}
|
||||
{{ field.label_tag }}
|
||||
{% if field.errors %}{{ field.errors }}{% endif %}
|
||||
{{ field }}
|
||||
{% endfor %}
|
||||
|
||||
<input type="submit" value="Block IP Range" />
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="scenerio">
|
||||
<div class="description">
|
||||
<p>{% trans "<strong>Scenario:</strong> Issues affecting multiple public entry points or could not determine to be a specific one." %}</p>
|
||||
<p>{% trans "<strong>Action:</strong> Disable all public IPs on all VMs. This should unplumb the device the public ip was on." %}</p>
|
||||
</div>
|
||||
|
||||
<form action="{% url syspanel_security_disable_public_ips %}" method="post" accept-charset="utf-8">
|
||||
{% csrf_token %}
|
||||
<fieldset>
|
||||
<input name="turn_off_ips" type="submit" value="Turn off Public IPs" />
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="scenerio">
|
||||
<div class="description">
|
||||
<p>{% trans "<strong>Scenario:</strong> Issue related to VPN service affecting multiple customers." %}</p>
|
||||
<p>{% trans "<strong>Action:</strong> Disable VPN service. This should turn off the VPN ip." %}</p>
|
||||
</div>
|
||||
|
||||
<form action="{% url syspanel_security_disable_vpn %}" method="post" accept-charset="utf-8">
|
||||
{% csrf_token %}
|
||||
<fieldset>
|
||||
<input name="block_vpn" type="submit" value="Turn off VPNs" />
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
@ -1,32 +0,0 @@
|
||||
from django.conf.urls.defaults import *
|
||||
from django.conf import settings
|
||||
from django.contrib import admin
|
||||
|
||||
admin.autodiscover()
|
||||
|
||||
urlpatterns = patterns('',
|
||||
url(r'^$', 'django_nova_syspanel.views.home.index', name='syspanel_index'),
|
||||
url(r'^instances/$', 'django_nova_syspanel.views.instances.index', name='syspanel_instances'),
|
||||
url(r'^instances/(?P<instance_id>[^/]+)/terminate$', 'django_nova_syspanel.views.instances.terminate', name='syspanel_instance_terminate'),
|
||||
url(r'^instances/(?P<instance_id>[^/]+)/restart$', 'django_nova_syspanel.views.instances.restart', name='syspanel_instance_restart'),
|
||||
url(r'^instances/(?P<instance_id>[^/]+)/console_log$', 'django_nova_syspanel.views.instances.console', name='syspanel_instance_console'),
|
||||
|
||||
url(r'^volumes/$', 'django_nova_syspanel.views.volumes.index', name='syspanel_volumes'),
|
||||
url(r'^volumes/(?P<volume_id>[^/]+)/delete$', 'django_nova_syspanel.views.volumes.delete', name='syspanel_delete_volume'),
|
||||
url(r'^volumes/(?P<volume_id>[^/]+)/detach$', 'django_nova_syspanel.views.volumes.detach', name='syspanel_detach_volume'),
|
||||
|
||||
url(r'^security/$', 'django_nova_syspanel.views.security.index', name='syspanel_security'),
|
||||
url(r'^security/disable_project_credentials/$', 'django_nova_syspanel.views.security.disable_project_credentials', name='syspanel_security_disable_project_credentials'),
|
||||
url(r'^security/disable_ip_range/$', 'django_nova_syspanel.views.security.disable_ip', name='syspanel_security_disable_ip_range'),
|
||||
url(r'^security/disable_public_ips/$', 'django_nova_syspanel.views.security.disable_public_ips', name='syspanel_security_disable_public_ips'),
|
||||
url(r'^security/disable_vpn/$', 'django_nova_syspanel.views.security.disable_vpn', name='syspanel_security_disable_vpn'),
|
||||
|
||||
url(r'^vpns/$', 'django_nova_syspanel.views.vpns.index', name='syspanel_vpns'),
|
||||
url(r'^vpns/(?P<project_id>[^/]+)/launch$', 'django_nova_syspanel.views.vpns.launch', name='syspanel_vpn_launch'),
|
||||
url(r'^vpns/(?P<project_id>[^/]+)/send_credentials$', 'django_nova_syspanel.views.vpns.send_credentials', name='syspanel_vpn_send_credentials'),
|
||||
url(r'^vpns/(?P<project_id>[^/]+)/terminate$', 'django_nova_syspanel.views.vpns.terminate', name='syspanel_vpn_terminate'),
|
||||
url(r'^vpns/(?P<project_id>[^/]+)/restart$', 'django_nova_syspanel.views.vpns.restart', name='syspanel_vpn_restart'),
|
||||
url(r'^vpns/(?P<project_id>[^/]+)/console_log$', 'django_nova_syspanel.views.vpns.console', name='syspanel_vpn_console'),
|
||||
|
||||
url(r'^cloudview/$', 'django_nova_syspanel.views.cloud.index', name='syspanel_cloudview'),
|
||||
)
|
@ -1,121 +0,0 @@
|
||||
from django import template
|
||||
from django.conf import settings
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.shortcuts import redirect, render_to_response
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
from django_nova_syspanel.forms import DisableProject
|
||||
from django_nova_syspanel.forms import DisableIpAddress
|
||||
from django_nova_syspanel.models import NovaResponseError, get_nova_admin_connection
|
||||
|
||||
|
||||
@login_required
|
||||
def index(request):
|
||||
disable_project_form = DisableProject()
|
||||
disable_ip_form = DisableIpAddress()
|
||||
return render_to_response('django_nova_syspanel/security/index.html',
|
||||
{'project_form': disable_project_form,
|
||||
'ip_form': disable_ip_form, },
|
||||
context_instance=template.RequestContext(request))
|
||||
|
||||
|
||||
@login_required
|
||||
def disable_project_credentials(request):
|
||||
if request.method == "POST":
|
||||
nova = get_nova_admin_connection()
|
||||
form = DisableProject(request.POST)
|
||||
if form.is_valid():
|
||||
name = form.cleaned_data['project_name']
|
||||
conn = nova.connection_for(settings.NOVA_ADMIN_USER, name)
|
||||
vpn = [x for x in nova.get_vpns() if x.project_id == name]
|
||||
if vpn:
|
||||
# NOTE(todd): Check, because it could already be shut-off
|
||||
vpn = vpn[0]
|
||||
try:
|
||||
nova.disable_project_credentials(name)
|
||||
if vpn and vpn.instance_id:
|
||||
conn.terminate_instances([vpn.instance_id])
|
||||
except NovaResponseError, e:
|
||||
messages.error(request,
|
||||
_('Unable to disable project %(name)s: %(code)s - %(msg)s') %
|
||||
{'name': name, 'code': e.code, 'msg': e.message})
|
||||
return redirect('syspanel_security')
|
||||
else:
|
||||
messages.success(request,
|
||||
_('Project %s has been successfully disabled.') %
|
||||
form.cleaned_data['project_name'])
|
||||
return render_to_response(
|
||||
'django_nova_syspanel/security/disable_project_credentials.html',
|
||||
context_instance=template.RequestContext(request))
|
||||
else:
|
||||
messages.error(request, _('Invalid form data'))
|
||||
return redirect('syspanel_security')
|
||||
else:
|
||||
return redirect('syspanel_security')
|
||||
|
||||
|
||||
@login_required
|
||||
def disable_ip(request):
|
||||
if request.method == "POST":
|
||||
conn = get_nova_admin_connection()
|
||||
form = DisableIpAddress(request.POST)
|
||||
if form.is_valid():
|
||||
try:
|
||||
conn.block_ips(form.cleaned_data['cidr'])
|
||||
except NovaResponseError, e:
|
||||
messages.error(request,
|
||||
_('Unable to block IPs range %(cidr)s: %(code)s %(msg)s') %
|
||||
{'cidr': form.cleaned_data['cidr'],
|
||||
'code': e.code,
|
||||
'msg': e.message})
|
||||
else:
|
||||
messages.success(request,
|
||||
_('IPs range %shas been successfully blocked') %
|
||||
form.cleaned_data['cidr'])
|
||||
|
||||
return redirect('syspanel_security')
|
||||
|
||||
|
||||
@login_required
|
||||
def disable_public_ips(request):
|
||||
if request.method == "POST":
|
||||
try:
|
||||
nova = get_nova_admin_connection()
|
||||
nova.disable_all_floating_ips()
|
||||
except NovaResponseError, e:
|
||||
messages.error(request,
|
||||
_('Unable to shut off public IPs: %(code)s - %(msg)s') %
|
||||
{'code': e.code, 'msg': e.message, })
|
||||
else:
|
||||
messages.success(request, _('Public IPs have been turned off.'))
|
||||
return redirect('syspanel_security')
|
||||
|
||||
|
||||
@login_required
|
||||
def disable_vpn(request):
|
||||
if request.method == "POST":
|
||||
nova = get_nova_admin_connection()
|
||||
conn = nova.connection_for(settings.NOVA_ADMIN_USER,
|
||||
settings.NOVA_PROJECT)
|
||||
try:
|
||||
collector = []
|
||||
for vpn in nova.get_vpns():
|
||||
if not vpn.instance_id:
|
||||
continue
|
||||
collector.append(vpn)
|
||||
if len(collector) >= 5:
|
||||
conn.terminate_instances([x.instance_id for x in collector])
|
||||
collector = []
|
||||
if collector:
|
||||
conn.terminate_instances([x.instance_id for x in collector])
|
||||
except NovaResponseError, e:
|
||||
messages.error(request,
|
||||
_('Unable to shut off all VPNs: %(code)s - %(msg)s') %
|
||||
{'code': e.code, 'msg': e.message, })
|
||||
else:
|
||||
messages.success(request,
|
||||
_('VPNs have been successfully turned off.'))
|
||||
return redirect('syspanel_security')
|
||||
else:
|
||||
return redirect('syspanel_security')
|
@ -1,34 +0,0 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2010 United States Government as represented by the
|
||||
# Administrator of the National Aeronautics and Space Administration.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
"""
|
||||
Manage connections to Nova's admin API.
|
||||
"""
|
||||
|
||||
import nova_adminclient as adminclient
|
||||
from django.conf import settings
|
||||
|
||||
|
||||
def get_nova_admin_connection():
|
||||
"""
|
||||
Returns a Nova administration connection.
|
||||
"""
|
||||
return adminclient.NovaAdminClient(
|
||||
clc_url=settings.NOVA_DEFAULT_ENDPOINT,
|
||||
region=settings.NOVA_DEFAULT_REGION,
|
||||
access_key=settings.NOVA_ACCESS_KEY,
|
||||
secret_key=settings.NOVA_SECRET_KEY)
|
@ -1,16 +0,0 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
'''
|
||||
django_openstack logging functions Currently does nothing useful, but if
|
||||
everything already points here, makes adding more complex logging simpler in
|
||||
the future
|
||||
'''
|
||||
|
||||
import logging
|
||||
|
||||
|
||||
def getLogger(name):
|
||||
'''
|
||||
Returns a python logger
|
||||
'''
|
||||
return logging.getLogger(name)
|
@ -1,40 +0,0 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2010 United States Government as represented by the
|
||||
# Administrator of the National Aeronautics and Space Administration.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
"""
|
||||
Management commands for synchronizing the Django auth database and Nova
|
||||
users database.
|
||||
"""
|
||||
|
||||
from django.core.management.base import NoArgsCommand
|
||||
from django.contrib.auth.models import User
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
from django_nova.connection import get_nova_admin_connection
|
||||
|
||||
|
||||
class Command(NoArgsCommand):
|
||||
help = _('Creates nova users for all users in the django auth database.')
|
||||
|
||||
def handle_noargs(self, **options):
|
||||
nova = get_nova_admin_connection()
|
||||
users = User.objects.all()
|
||||
for user in users:
|
||||
if not nova.has_user(user.username):
|
||||
self.stdout.write(_('creating user %s... ') % user.username)
|
||||
nova.create_user(user.username)
|
||||
self.stdout.write('ok\n')
|
@ -1,131 +0,0 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2010 United States Government as represented by the
|
||||
# Administrator of the National Aeronautics and Space Administration.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
"""
|
||||
Database models for authorization credentials and synchronizing Nova users.
|
||||
"""
|
||||
|
||||
import datetime
|
||||
import random
|
||||
import re
|
||||
import sha
|
||||
from django.conf import settings
|
||||
from django.contrib.auth import models as auth_models
|
||||
from django.contrib.sites import models as site_models
|
||||
from django.core import mail
|
||||
from django.db import models
|
||||
from django.db.models.signals import post_save
|
||||
from django.template.loader import render_to_string
|
||||
from django_openstack import log as logging
|
||||
from django_openstack.core.connection import get_nova_admin_connection
|
||||
|
||||
|
||||
LOG = logging.getLogger('django_openstack')
|
||||
|
||||
|
||||
SHA1_RE = re.compile('^[a-f0-9]{40}$')
|
||||
|
||||
|
||||
class CredentialsAuthorization(models.Model):
|
||||
username = models.CharField(max_length=128)
|
||||
project = models.CharField(max_length=128)
|
||||
auth_token = models.CharField(max_length=40)
|
||||
auth_date = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
def __str__(self):
|
||||
return '%s/%s:%s' % (self.username, self.project, self.auth_token)
|
||||
|
||||
@classmethod
|
||||
def get_by_token(cls, token):
|
||||
if SHA1_RE.search(token):
|
||||
try:
|
||||
credentials = cls.objects.get(auth_token=token)
|
||||
except cls.DoesNotExist:
|
||||
return None
|
||||
if not credentials.auth_token_expired():
|
||||
return credentials
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def authorize(cls, username, project):
|
||||
return cls.objects.create(username=username,
|
||||
project=project,
|
||||
auth_token=cls.create_auth_token(username))
|
||||
|
||||
@staticmethod
|
||||
def create_auth_token(username):
|
||||
salt = sha.new(str(random.random())).hexdigest()[:5]
|
||||
return sha.new(salt + username).hexdigest()
|
||||
|
||||
def auth_token_expired(self):
|
||||
expiration_date = datetime.timedelta(
|
||||
days=int(settings.CREDENTIAL_AUTHORIZATION_DAYS))
|
||||
|
||||
return self.auth_date + expiration_date <= datetime.datetime.now()
|
||||
|
||||
def get_download_url(self):
|
||||
return settings.CREDENTIAL_DOWNLOAD_URL + self.auth_token
|
||||
|
||||
def get_zip(self):
|
||||
nova = get_nova_admin_connection()
|
||||
self.delete()
|
||||
return nova.get_zip(self.username, self.project)
|
||||
|
||||
|
||||
def credentials_post_save(sender, instance, created, *args, **kwargs):
|
||||
"""
|
||||
Creates a Nova User when a new Django User is created.
|
||||
"""
|
||||
if created:
|
||||
site = site_models.Site.objects.get_current()
|
||||
user = auth_models.User.objects.get(username=instance.username)
|
||||
context = {
|
||||
'user': user,
|
||||
'download_url': instance.get_download_url(),
|
||||
'dashboard_url': 'http://%s/' % site.domain
|
||||
}
|
||||
subject = render_to_string('credentials/credentials_email_subject.txt')
|
||||
body = render_to_string('credentials/credentials_email.txt', context)
|
||||
|
||||
message = mail.EmailMessage(subject=subject.strip(),
|
||||
body=body,
|
||||
to=[user.email])
|
||||
message.send(fail_silently=False)
|
||||
LOG.info('Credentials sent to user "%s" at "%s"' %
|
||||
(instance.name, user.email))
|
||||
post_save.connect(credentials_post_save,
|
||||
CredentialsAuthorization,
|
||||
dispatch_uid='django_openstack.CredentialsAuthorization.post_save')
|
||||
|
||||
|
||||
def user_post_save(sender, instance, created, *args, **kwargs):
|
||||
"""
|
||||
Creates a Nova User when a new Django User is created.
|
||||
"""
|
||||
|
||||
# NOTE(devcamcar): If running unit tests, don't use a real endpoint.
|
||||
if settings.NOVA_DEFAULT_ENDPOINT == 'none':
|
||||
return
|
||||
|
||||
if created:
|
||||
nova = get_nova_admin_connection()
|
||||
if not nova.has_user(instance.username):
|
||||
nova.create_user(instance.username)
|
||||
LOG.info('User "%s" created in Nova' % instance.username)
|
||||
post_save.connect(user_post_save,
|
||||
auth_models.User,
|
||||
dispatch_uid='django_openstack.User.post_save')
|
@ -26,7 +26,6 @@ from django import forms
|
||||
from django.contrib.auth import models as auth_models
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
from django_openstack.core.connection import get_nova_admin_connection
|
||||
from django_openstack.nova.exceptions import wrap_nova_error
|
||||
|
||||
|
||||
@ -86,44 +85,6 @@ def get_protocols():
|
||||
)
|
||||
|
||||
|
||||
@wrap_nova_error
|
||||
def get_roles(project_roles=True):
|
||||
nova = get_nova_admin_connection()
|
||||
roles = nova.get_roles(project_roles=project_roles)
|
||||
return [(role.role, role.role) for role in roles]
|
||||
|
||||
|
||||
@wrap_nova_error
|
||||
def get_members(project):
|
||||
nova = get_nova_admin_connection()
|
||||
members = nova.get_project_members(project)
|
||||
return [str(user.memberId) for user in members]
|
||||
|
||||
|
||||
@wrap_nova_error
|
||||
def set_project_roles(projectname, username, roles):
|
||||
nova = get_nova_admin_connection()
|
||||
# hacky work around to interface correctly with multiple select form
|
||||
_remove_roles(projectname, username)
|
||||
|
||||
for role in roles:
|
||||
nova.add_user_role(username, str(role), projectname)
|
||||
|
||||
|
||||
def _remove_roles(project, username):
|
||||
nova = get_nova_admin_connection()
|
||||
userroles = nova.get_user_roles(username, project)
|
||||
roles = [str(role.role) for role in userroles]
|
||||
|
||||
for role in roles:
|
||||
if role == "developer":
|
||||
nova.remove_user_role(username, "developer", project)
|
||||
if role == "sysadmin":
|
||||
nova.remove_user_role(username, "sysadmin", project)
|
||||
if role == "netadmin":
|
||||
nova.remove_user_role(username, "netadmin", project)
|
||||
|
||||
|
||||
class ProjectFormBase(forms.Form):
|
||||
def __init__(self, project, *args, **kwargs):
|
||||
self.project = project
|
||||
@ -171,39 +132,6 @@ class UpdateImageForm(forms.Form):
|
||||
self.fields['description'].initial = image.description
|
||||
|
||||
|
||||
class CreateKeyPairForm(ProjectFormBase):
|
||||
name = forms.RegexField(regex=alphanumeric_re)
|
||||
|
||||
def clean_name(self):
|
||||
name = self.cleaned_data['name']
|
||||
|
||||
if self.project.has_key_pair(name):
|
||||
raise forms.ValidationError(
|
||||
_('A key named %s already exists.') % name)
|
||||
|
||||
return name
|
||||
|
||||
|
||||
class CreateSecurityGroupForm(ProjectFormBase):
|
||||
name = forms.RegexField(regex=alphanumeric_re)
|
||||
description = forms.CharField()
|
||||
|
||||
def clean_name(self):
|
||||
name = self.cleaned_data['name']
|
||||
|
||||
if self.project.has_security_group(name):
|
||||
raise forms.ValidationError(
|
||||
_('A security group named %s already exists.') % name)
|
||||
|
||||
return name
|
||||
|
||||
|
||||
class AuthorizeSecurityGroupRuleForm(forms.Form):
|
||||
protocol = forms.ChoiceField(choices=get_protocols())
|
||||
from_port = forms.IntegerField(min_value=1, max_value=65535)
|
||||
to_port = forms.IntegerField(min_value=1, max_value=65535)
|
||||
|
||||
|
||||
class CreateVolumeForm(forms.Form):
|
||||
size = forms.IntegerField(label='Size (in GB)',
|
||||
min_value=1,
|
||||
@ -221,61 +149,3 @@ class AttachVolumeForm(ProjectFormBase):
|
||||
super(AttachVolumeForm, self).__init__(project, *args, **kwargs)
|
||||
self.fields['volume'].choices = get_available_volume_choices(project)
|
||||
self.fields['instance'].choices = get_instance_choices(project)
|
||||
|
||||
|
||||
class ProjectForm(forms.Form):
|
||||
projectname = forms.CharField(label="Project Name", max_length=20)
|
||||
description = forms.CharField(label="Description",
|
||||
widget=forms.widgets.Textarea())
|
||||
manager = forms.ModelChoiceField(queryset=auth_models.User.objects.all(),
|
||||
label="Project Manager")
|
||||
|
||||
|
||||
class GlobalRolesForm(forms.Form):
|
||||
role = forms.MultipleChoiceField(label='Roles', required=False)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(GlobalRolesForm, self).__init__(*args, **kwargs)
|
||||
self.fields['role'].choices = get_roles(project_roles=False)
|
||||
|
||||
|
||||
class ProjectUserForm(forms.Form):
|
||||
role = forms.MultipleChoiceField(label='Roles', required=False)
|
||||
|
||||
def __init__(self, project, user, *args, **kwargs):
|
||||
super(ProjectUserForm, self).__init__(*args, **kwargs)
|
||||
self.project = project
|
||||
self.user = user
|
||||
self.fields['role'].choices = get_roles()
|
||||
|
||||
def save(self):
|
||||
set_project_roles(self.project.projectname,
|
||||
self.user.username,
|
||||
self.cleaned_data['role'])
|
||||
|
||||
|
||||
class AddProjectUserForm(forms.Form):
|
||||
username = forms.ModelChoiceField(queryset='',
|
||||
label='Username',
|
||||
empty_label='Select a Username')
|
||||
role = forms.MultipleChoiceField(label='Roles')
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
project = kwargs.pop('project')
|
||||
super(AddProjectUserForm, self).__init__(*args, **kwargs)
|
||||
members = get_members(project)
|
||||
|
||||
self.fields['username'].queryset = \
|
||||
auth_models.User.objects.exclude(username__in=members)
|
||||
self.fields['role'].choices = get_roles()
|
||||
|
||||
|
||||
class SendCredentialsForm(forms.Form):
|
||||
users = forms.MultipleChoiceField(label='Users', required=True)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
query_list = kwargs.pop('query_list')
|
||||
super(SendCredentialsForm, self).__init__(*args, **kwargs)
|
||||
|
||||
self.fields['users'].choices = \
|
||||
[(choices, choices) for choices in query_list]
|
||||
|
@ -24,7 +24,6 @@ import boto.ec2.volume
|
||||
import boto.exception
|
||||
import boto.s3
|
||||
from django.conf import settings
|
||||
from django_openstack.core.connection import get_nova_admin_connection
|
||||
from django_openstack.nova.exceptions import wrap_nova_error
|
||||
|
||||
|
||||
|
@ -26,7 +26,6 @@ from django.core.exceptions import PermissionDenied
|
||||
from django.http import Http404
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
from django_openstack.core.connection import get_nova_admin_connection
|
||||
from django_openstack.nova import manager
|
||||
from django_openstack.nova.exceptions import wrap_nova_error
|
||||
|
||||
|
@ -1,55 +0,0 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2010 United States Government as represented by the
|
||||
# Administrator of the National Aeronautics and Space Administration.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
"""
|
||||
URL patterns for managing Nova projects through the Django admin interface.
|
||||
"""
|
||||
|
||||
from django.conf.urls.defaults import *
|
||||
|
||||
|
||||
#TODO(devcamcar): Standardize url names admin_project_*.
|
||||
|
||||
urlpatterns = patterns('',
|
||||
url(r'^$',
|
||||
'django_openstack.nova.views.admin.projects_list',
|
||||
name='admin_projects'),
|
||||
url(r'^add/$',
|
||||
'django_openstack.nova.views.admin.add_project',
|
||||
name='add_project'),
|
||||
url(r'^(?P<project_name>[^/]+)/$',
|
||||
'django_openstack.nova.views.admin.project_view',
|
||||
name='admin_project'),
|
||||
url(r'^(?P<project_name>[^/]+)/user/(?P<project_user>[^/]+)/delete/',
|
||||
'django_openstack.nova.views.admin.delete_project_user',
|
||||
name='admin_project_delete_user'),
|
||||
url(r'^(?P<project_name>[^/]+)/delete/$',
|
||||
'django_openstack.nova.views.admin.delete_project',
|
||||
name='delete_project'),
|
||||
url(r'^(?P<project_name>[^/]+)/user/add/$',
|
||||
'django_openstack.nova.views.admin.add_project_user',
|
||||
name='add_project_user'),
|
||||
url(r'^(?P<project_name>[^/]+)/user/(?P<project_user>[^/]+)/$',
|
||||
'django_openstack.nova.views.admin.project_user',
|
||||
name='project_user'),
|
||||
url(r'^(?P<project_id>[^/]+)/sendcredentials/$',
|
||||
'django_openstack.nova.views.admin.project_sendcredentials',
|
||||
name='admin_project_sendcredentials'),
|
||||
url(r'^(?P<project_id>[^/]+)/start_vpn/$',
|
||||
'django_openstack.nova.views.admin.project_start_vpn',
|
||||
name='admin_project_start_vpn'),
|
||||
)
|
@ -1,32 +0,0 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2010 United States Government as represented by the
|
||||
# Administrator of the National Aeronautics and Space Administration.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
"""
|
||||
URL patterns for managing Nova user roles through the Django admin interface.
|
||||
"""
|
||||
|
||||
from django.conf.urls.defaults import *
|
||||
|
||||
|
||||
urlpatterns = patterns('',
|
||||
url(r'^(?P<user_id>[^/]+)/$',
|
||||
'django_openstack.nova.views.admin.user_roles',
|
||||
name='admin_user_roles'),
|
||||
url(r'^$',
|
||||
'django_openstack.nova.views.admin.users_list',
|
||||
name='admin_users_list'),
|
||||
)
|
@ -27,15 +27,14 @@ urlpatterns = patterns('',
|
||||
url(r'^(?P<project_id>[^/]+)/$',
|
||||
'django_openstack.nova.views.projects.detail',
|
||||
name='nova_project'),
|
||||
url(r'^(?P<project_id>[^/]+)/manage/(?P<username>[^/]+)/',
|
||||
'django_openstack.nova.views.projects.edit_user',
|
||||
name='nova_project_edit_user'),
|
||||
url(r'^(?P<project_id>[^/]+)/manage$',
|
||||
'django_openstack.nova.views.projects.manage',
|
||||
name='nova_project_manage'),
|
||||
url(r'^(?P<project_id>[^/]+)/download/credentials$',
|
||||
'django_openstack.nova.views.projects.download_credentials',
|
||||
name='nova_download_credentials'),
|
||||
#url(r'^(?P<project_id>[^/]+)/manage/(?P<username>[^/]+)/',
|
||||
# 'django_openstack.nova.views.projects.edit_user',
|
||||
# name='nova_project_edit_user'),
|
||||
#url(r'^(?P<project_id>[^/]+)/manage$',
|
||||
# 'django_openstack.nova.views.projects.manage',
|
||||
# name='nova_project_manage'),
|
||||
|
||||
# images
|
||||
url(r'^(?P<project_id>[^/]+)/images$',
|
||||
'django_openstack.nova.views.images.index',
|
||||
name='nova_images'),
|
||||
@ -57,6 +56,8 @@ urlpatterns = patterns('',
|
||||
url(r'^(?P<project_id>[^/]+)/instances$',
|
||||
'django_openstack.nova.views.instances.index',
|
||||
name='nova_instances'),
|
||||
|
||||
# instances
|
||||
url(r'^(?P<project_id>[^/]+)/instances/refresh$',
|
||||
'django_openstack.nova.views.instances.refresh',
|
||||
name='nova_instances_refresh'),
|
||||
@ -84,49 +85,21 @@ urlpatterns = patterns('',
|
||||
url(r'^(?P<project_id>[^/]+)/instances/(?P<instance_id>[^/]+)/graph/(?P<graph_name>[^/]+)$',
|
||||
'django_openstack.nova.views.instances.graph',
|
||||
name='nova_instances_graph'),
|
||||
url(r'^(?P<project_id>[^/]+)/keys$',
|
||||
'django_openstack.nova.views.keypairs.index',
|
||||
name='nova_keypairs'),
|
||||
url(r'^(?P<project_id>[^/]+)/keys/add$',
|
||||
'django_openstack.nova.views.keypairs.add',
|
||||
name='nova_keypairs_add'),
|
||||
url(r'^(?P<project_id>[^/]+)/keys/delete$',
|
||||
'django_openstack.nova.views.keypairs.delete',
|
||||
name='nova_keypairs_delete'),
|
||||
url(r'^(?P<project_id>[^/]+)/keys/(?P<key_name>.*)/download$',
|
||||
'django_openstack.nova.views.keypairs.download',
|
||||
name='nova_keypairs_download'),
|
||||
#url(r'^(?P<project_id>[^/]+)/securitygroups/$',
|
||||
# 'django_openstack.nova.views.securitygroups.index',
|
||||
# name='nova_securitygroups'),
|
||||
#url(r'^(?P<project_id>[^/]+)/securitygroups/add$',
|
||||
# 'django_openstack.nova.views.securitygroups.add',
|
||||
# name='nova_securitygroups_add'),
|
||||
#url(r'^(?P<project_id>[^/]+)/securitygroups/(?P<group_name>[^/]+)$',
|
||||
# 'django_openstack.nova.views.securitygroups.detail',
|
||||
# name='nova_securitygroups_detail'),
|
||||
#url(r'^(?P<project_id>[^/]+)/securitygroups/(?P<group_name>[^/]+)/authorize/$',
|
||||
# 'django_openstack.nova.views.securitygroups.authorize',
|
||||
# name='nova_securitygroups_authorize'),
|
||||
#url(r'^(?P<project_id>[^/]+)/securitygroups/(?P<group_name>[^/]+)/delete/$',
|
||||
# 'django_openstack.nova.views.securitygroups.delete',
|
||||
# name='nova_securitygroups_delete'),
|
||||
#url(r'^(?P<project_id>[^/]+)/securitygroups/(?P<group_name>.*)/revoke/$',
|
||||
# 'django_openstack.nova.views.securitygroups.revoke',
|
||||
# name='nova_securitygroups_revoke'),
|
||||
url(r'^(?P<project_id>[^/]+)/volumes/$',
|
||||
'django_openstack.nova.views.volumes.index',
|
||||
name='nova_volumes'),
|
||||
url(r'^(?P<project_id>[^/]+)/volumes/add$',
|
||||
'django_openstack.nova.views.volumes.add',
|
||||
name='nova_volumes_add'),
|
||||
url(r'^(?P<project_id>[^/]+)/volumes/attach$',
|
||||
'django_openstack.nova.views.volumes.attach',
|
||||
name='nova_volumes_attach'),
|
||||
url(r'^(?P<project_id>[^/]+)/volumes/(?P<volume_id>[^/]+)/detach$',
|
||||
'django_openstack.nova.views.volumes.detach',
|
||||
name='nova_volumes_detach'),
|
||||
url(r'^(?P<project_id>[^/]+)/volumes/(?P<volume_id>[^/]+)/delete$',
|
||||
'django_openstack.nova.views.volumes.delete',
|
||||
name='nova_volumes_delete'),
|
||||
|
||||
# volumes
|
||||
#url(r'^(?P<project_id>[^/]+)/volumes/$',
|
||||
# 'django_openstack.nova.views.volumes.index',
|
||||
# name='nova_volumes'),
|
||||
#url(r'^(?P<project_id>[^/]+)/volumes/add$',
|
||||
# 'django_openstack.nova.views.volumes.add',
|
||||
# name='nova_volumes_add'),
|
||||
#url(r'^(?P<project_id>[^/]+)/volumes/attach$',
|
||||
# 'django_openstack.nova.views.volumes.attach',
|
||||
# name='nova_volumes_attach'),
|
||||
#url(r'^(?P<project_id>[^/]+)/volumes/(?P<volume_id>[^/]+)/detach$',
|
||||
# 'django_openstack.nova.views.volumes.detach',
|
||||
# name='nova_volumes_detach'),
|
||||
#url(r'^(?P<project_id>[^/]+)/volumes/(?P<volume_id>[^/]+)/delete$',
|
||||
# 'django_openstack.nova.views.volumes.delete',
|
||||
# name='nova_volumes_delete'),
|
||||
)
|
||||
|
@ -20,6 +20,8 @@
|
||||
Views for managing Nova through the Django admin interface.
|
||||
"""
|
||||
|
||||
import logging
|
||||
|
||||
import boto.exception
|
||||
|
||||
from django import http
|
||||
@ -29,9 +31,7 @@ from django.contrib.admin.views.decorators import staff_member_required
|
||||
from django.contrib.auth import models as auth_models
|
||||
from django.shortcuts import redirect, render_to_response
|
||||
from django.utils.translation import ugettext as _
|
||||
from django_openstack import log as logging
|
||||
from django_openstack import models
|
||||
from django_openstack.core.connection import get_nova_admin_connection
|
||||
from django_openstack.nova import forms
|
||||
|
||||
|
||||
|
@ -1,52 +0,0 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2010 United States Government as represented by the
|
||||
# Administrator of the National Aeronautics and Space Administration.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""
|
||||
Views for downloading X509 credentials. Useful when using an invitation
|
||||
style system for configuring first time users.
|
||||
"""
|
||||
|
||||
from django import http
|
||||
from django.conf import settings
|
||||
from django.shortcuts import render_to_response
|
||||
from django_openstack import log as logging
|
||||
from django_openstack import models
|
||||
|
||||
|
||||
LOG = logging.getLogger('django_openstack.nova')
|
||||
|
||||
|
||||
def authorize_credentials(request, auth_token):
|
||||
"""Sends X509 credentials to user if their auth token is valid."""
|
||||
auth_token = auth_token.lower()
|
||||
credentials = models.CredentialsAuthorization.get_by_token(auth_token)
|
||||
|
||||
# NOTE(devcamcar): If nothing returned, then token was bad or has expired.
|
||||
if not credentials:
|
||||
LOG.info("Credentials token bad or expired for user %s" %
|
||||
str(request.user))
|
||||
return render_to_response(
|
||||
'django_openstack/nova/credentials/expired.html')
|
||||
|
||||
response = http.HttpResponse(mimetype='application/zip')
|
||||
response['Content-Disposition'] = \
|
||||
'attachment; filename=%s-%s-%s-x509.zip' % \
|
||||
(settings.SITE_NAME, credentials.project, credentials.username)
|
||||
response.write(credentials.get_zip())
|
||||
|
||||
return response
|
@ -20,6 +20,7 @@
|
||||
Views for managing Nova images.
|
||||
"""
|
||||
|
||||
import logging
|
||||
import re
|
||||
|
||||
from django import http
|
||||
@ -29,7 +30,6 @@ from django.contrib import messages
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.shortcuts import redirect, render_to_response
|
||||
from django.utils.translation import ugettext as _
|
||||
from django_openstack import log as logging
|
||||
from django_openstack.nova import exceptions
|
||||
from django_openstack.nova import forms
|
||||
from django_openstack.nova import shortcuts
|
||||
|
@ -20,6 +20,8 @@
|
||||
Views for managing Nova instances.
|
||||
"""
|
||||
|
||||
import logging
|
||||
|
||||
from django import http
|
||||
from django import template
|
||||
from django.conf import settings
|
||||
@ -27,7 +29,6 @@ from django.contrib import messages
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.shortcuts import redirect, render_to_response
|
||||
from django.utils.translation import ugettext as _
|
||||
from django_openstack import log as logging
|
||||
from django_openstack.nova import exceptions
|
||||
from django_openstack.nova import forms as nova_forms
|
||||
from django_openstack.nova import shortcuts
|
||||
|
@ -1,139 +0,0 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2010 United States Government as represented by the
|
||||
# Administrator of the National Aeronautics and Space Administration.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""
|
||||
Views for managing Nova keypairs.
|
||||
"""
|
||||
|
||||
from django import http
|
||||
from django import template
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.shortcuts import redirect, render_to_response
|
||||
from django.utils.translation import ugettext as _
|
||||
from django_openstack import log as logging
|
||||
from django_openstack.nova import exceptions
|
||||
from django_openstack.nova import forms
|
||||
from django_openstack.nova import shortcuts
|
||||
from django_openstack.nova.exceptions import handle_nova_error
|
||||
|
||||
|
||||
LOG = logging.getLogger('django_openstack.nova')
|
||||
|
||||
|
||||
@login_required
|
||||
@handle_nova_error
|
||||
def index(request, project_id, download_key=None):
|
||||
project = shortcuts.get_project_or_404(request, project_id)
|
||||
keypairs = project.get_key_pairs()
|
||||
|
||||
return render_to_response('django_openstack/nova/keypairs/index.html', {
|
||||
'create_form': forms.CreateKeyPairForm(project),
|
||||
'region': project.region,
|
||||
'project': project,
|
||||
'keypairs': keypairs,
|
||||
'download_key': download_key
|
||||
}, context_instance=template.RequestContext(request))
|
||||
|
||||
|
||||
@login_required
|
||||
@handle_nova_error
|
||||
def add(request, project_id):
|
||||
project = shortcuts.get_project_or_404(request, project_id)
|
||||
|
||||
if request.method == 'POST':
|
||||
form = forms.CreateKeyPairForm(project, request.POST)
|
||||
|
||||
if form.is_valid():
|
||||
try:
|
||||
keypair = project.create_key_pair(form.cleaned_data['name'])
|
||||
except exceptions.NovaApiError, e:
|
||||
messages.error(request,
|
||||
_('Unable to create key: %s') % e.message)
|
||||
LOG.error('Unable to create key for user "%s" on project "%s".'
|
||||
' Exception: "%s"' %
|
||||
(str(request.user), project_id, e.message))
|
||||
else:
|
||||
LOG.info('Keypair "%s" for project "%s" created successfully' %
|
||||
(keypair.name, project_id))
|
||||
if request.POST['js'] == '1':
|
||||
request.session['key.%s' % keypair.name] = keypair.material
|
||||
return index(request,
|
||||
project_id,
|
||||
download_key=keypair.name)
|
||||
else:
|
||||
response = http.HttpResponse(mimetype='application/binary')
|
||||
response['Content-Disposition'] = \
|
||||
'attachment; filename=%s.pem' % \
|
||||
form.cleaned_data['name']
|
||||
response.write(keypair.material)
|
||||
return response
|
||||
else:
|
||||
keypairs = project.get_key_pairs()
|
||||
|
||||
return render_to_response(
|
||||
'django_openstack/nova/keypairs/index.html',
|
||||
{'create_form': form,
|
||||
'region': project.region,
|
||||
'project': project,
|
||||
'keypairs': keypairs},
|
||||
context_instance=template.RequestContext(request))
|
||||
|
||||
return redirect('nova_keypairs', project_id)
|
||||
|
||||
|
||||
@login_required
|
||||
@handle_nova_error
|
||||
def delete(request, project_id):
|
||||
project = shortcuts.get_project_or_404(request, project_id)
|
||||
|
||||
if request.method == 'POST':
|
||||
key_name = request.POST['key_name']
|
||||
|
||||
try:
|
||||
project.delete_key_pair(key_name)
|
||||
except exceptions.NovaApiError, e:
|
||||
messages.error(request,
|
||||
_('Unable to delete key: %s') % e.message)
|
||||
LOG.error('Unable to delete key "%s". Exception: "%s"' %
|
||||
(key_name, e.message_))
|
||||
else:
|
||||
messages.success(request,
|
||||
_('Key %s has been successfully deleted.') % \
|
||||
key_name)
|
||||
LOG.info('Key "%s" successfully deleted' % key_name)
|
||||
|
||||
return redirect('nova_keypairs', project_id)
|
||||
|
||||
|
||||
@login_required
|
||||
@handle_nova_error
|
||||
def download(request, project_id, key_name):
|
||||
# Ensure the project exists.
|
||||
shortcuts.get_project_or_404(request, project_id)
|
||||
|
||||
try:
|
||||
material = request.session.pop('key.%s' % key_name)
|
||||
except KeyError:
|
||||
return redirect('nova_keypairs', project_id)
|
||||
|
||||
response = http.HttpResponse(mimetype='application/binary')
|
||||
response['Content-Disposition'] = 'attachment; filename=%s.pem' % key_name
|
||||
response.write(material)
|
||||
|
||||
return response
|
@ -19,14 +19,13 @@
|
||||
"""
|
||||
Views for managing Nova projects.
|
||||
"""
|
||||
import logging
|
||||
|
||||
from django import http
|
||||
from django import template
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.shortcuts import redirect, render_to_response
|
||||
from django_openstack.core.connection import get_nova_admin_connection
|
||||
from django_openstack import log as logging
|
||||
from django_openstack.nova import forms as nova_forms
|
||||
from django_openstack.nova.exceptions import handle_nova_error
|
||||
from django_openstack.nova.shortcuts import get_project_or_404
|
||||
|
@ -1,41 +0,0 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2010 United States Government as represented by the
|
||||
# Administrator of the National Aeronautics and Space Administration.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""
|
||||
Views for managing Nova regions.
|
||||
"""
|
||||
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.shortcuts import redirect
|
||||
from django.utils.translation import ugettext as _
|
||||
from django_openstack import log as logging
|
||||
from django_openstack.nova.shortcuts import set_current_region
|
||||
|
||||
|
||||
LOG = logging.getLogger('django_openstack.nova')
|
||||
|
||||
|
||||
@login_required
|
||||
def change(request):
|
||||
region = request.POST['region']
|
||||
redirect_url = request.POST['redirect_url']
|
||||
set_current_region(request, region)
|
||||
messages.success(request, _('You are now using the region "%s".') % region)
|
||||
LOG.info('User "%s" changed to region "%s"' % (str(request.user), region))
|
||||
return redirect(redirect_url)
|
@ -1,220 +0,0 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2010 United States Government as represented by the
|
||||
# Administrator of the National Aeronautics and Space Administration.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""
|
||||
Views for managing Nova security groups.
|
||||
"""
|
||||
|
||||
from django import http
|
||||
from django import template
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.shortcuts import redirect, render_to_response
|
||||
from django.utils.translation import ugettext as _
|
||||
from django_openstack import log as logging
|
||||
from django_openstack.nova import exceptions
|
||||
from django_openstack.nova import forms
|
||||
from django_openstack.nova.exceptions import handle_nova_error
|
||||
from django_openstack.nova.shortcuts import get_project_or_404
|
||||
|
||||
|
||||
LOG = logging.getLogger('django_openstack.nova')
|
||||
|
||||
|
||||
@login_required
|
||||
@handle_nova_error
|
||||
def index(request, project_id):
|
||||
project = get_project_or_404(request, project_id)
|
||||
securitygroups = project.get_security_groups()
|
||||
|
||||
return render_to_response(
|
||||
'django_openstack/nova/securitygroups/index.html',
|
||||
{'create_form': forms.CreateSecurityGroupForm(project),
|
||||
'project': project,
|
||||
'securitygroups': securitygroups},
|
||||
context_instance=template.RequestContext(request))
|
||||
|
||||
|
||||
@login_required
|
||||
@handle_nova_error
|
||||
def detail(request, project_id, group_name):
|
||||
project = get_project_or_404(request, project_id)
|
||||
securitygroup = project.get_security_group(group_name)
|
||||
|
||||
if not securitygroup:
|
||||
raise http.Http404
|
||||
|
||||
return render_to_response(
|
||||
'django_openstack/nova/securitygroups/detail.html',
|
||||
{'authorize_form': forms.AuthorizeSecurityGroupRuleForm(),
|
||||
'project': project,
|
||||
'securitygroup': securitygroup},
|
||||
context_instance=template.RequestContext(request))
|
||||
|
||||
|
||||
@login_required
|
||||
@handle_nova_error
|
||||
def add(request, project_id):
|
||||
project = get_project_or_404(request, project_id)
|
||||
|
||||
if request.method == 'POST':
|
||||
form = forms.CreateSecurityGroupForm(project, request.POST)
|
||||
if form.is_valid():
|
||||
try:
|
||||
project.create_security_group(
|
||||
form.cleaned_data['name'],
|
||||
form.cleaned_data['description'])
|
||||
except exceptions.NovaApiError, e:
|
||||
messages.error(
|
||||
request,
|
||||
_('Unable to create security group: %s') % e.message)
|
||||
LOG.error('Unable to create security group "%s" on project'
|
||||
' "%s". Exception "%s"' % (form.cleaned_data['name'],
|
||||
project_id, e.message))
|
||||
else:
|
||||
messages.success(
|
||||
request,
|
||||
_('Security Group %s has been succesfully created.') % \
|
||||
form.cleaned_data['name'])
|
||||
LOG.info('Security Group "%s" created on project "%s"' %
|
||||
(form.cleaned_data['name'], project_id))
|
||||
else:
|
||||
securitygroups = project.get_security_groups()
|
||||
|
||||
return render_to_response(
|
||||
'django_openstack/nova/securitygroups/index.html',
|
||||
{'create_form': form,
|
||||
'project': project,
|
||||
'securitygroups': securitygroups},
|
||||
context_instance=template.RequestContext(request))
|
||||
|
||||
return redirect('nova_securitygroups', project_id)
|
||||
|
||||
|
||||
@login_required
|
||||
@handle_nova_error
|
||||
def authorize(request, project_id, group_name):
|
||||
project = get_project_or_404(request, project_id)
|
||||
|
||||
if request.method == 'POST':
|
||||
form = forms.AuthorizeSecurityGroupRuleForm(request.POST)
|
||||
if form.is_valid():
|
||||
try:
|
||||
project.authorize_security_group(
|
||||
group_name=group_name,
|
||||
ip_protocol=form.cleaned_data['protocol'],
|
||||
from_port=form.cleaned_data['from_port'],
|
||||
to_port=form.cleaned_data['to_port'])
|
||||
except exceptions.NovaApiError, e:
|
||||
messages.error(request,
|
||||
_('Unable to authorize: %s') % e.message)
|
||||
LOG.error('Unable to authorize access for protocol "%s" for'
|
||||
' ports %d-%d on group "%s" in project "%s".'
|
||||
' Exception: "%s"' %
|
||||
(form.cleaned_data['protocol'],
|
||||
form.cleaned_data['from_port'],
|
||||
form.cleaned_data['to_port'],
|
||||
group_name, project_id, e.message))
|
||||
else:
|
||||
messages.success(
|
||||
request,
|
||||
_('Security Group %(grp)s: Access to %(proto)s ports %(fr)d - %(to)d has been authorized.') %
|
||||
{'grp': group_name,
|
||||
'proto': form.cleaned_data['protocol'],
|
||||
'fr': form.cleaned_data['from_port'],
|
||||
'to': form.cleaned_data['to_port']})
|
||||
LOG.info('Access to group "%s" in project "%s" granted'
|
||||
' for "%s" ports %d-%d' %
|
||||
(group_name, project_id,
|
||||
form.cleaned_data['protocol'],
|
||||
form.cleaned_data['from_port'],
|
||||
form.cleaned_data['to_port']))
|
||||
|
||||
else:
|
||||
securitygroup = project.get_security_group(group_name)
|
||||
|
||||
if not securitygroup:
|
||||
raise http.Http404
|
||||
|
||||
return render_to_response(
|
||||
'django_openstack/nova/securitygroups/detail.html',
|
||||
{'authorize_form': form,
|
||||
'project': project,
|
||||
'securitygroup': securitygroup},
|
||||
context_instance=template.RequestContext(request))
|
||||
|
||||
return redirect('nova_securitygroups_detail', project_id, group_name)
|
||||
|
||||
|
||||
@login_required
|
||||
@handle_nova_error
|
||||
def revoke(request, project_id, group_name):
|
||||
project = get_project_or_404(request, project_id)
|
||||
|
||||
if request.method == 'POST':
|
||||
try:
|
||||
project.revoke_security_group(
|
||||
group_name=group_name,
|
||||
ip_protocol=request.POST['protocol'],
|
||||
from_port=request.POST['from_port'],
|
||||
to_port=request.POST['to_port'])
|
||||
except exceptions.NovaApiError, e:
|
||||
messages.error(request, _('Unable to revoke: %s') % e.message)
|
||||
LOG.error('Unable to revoke access to group "%s" in project "%s"'
|
||||
' for "%s" ports %d-%d. Exception: "%s"' %
|
||||
(group_name, project_id, request.POST['protocol'],
|
||||
request.POST['from_port'], request.POST['to_port'],
|
||||
e.message))
|
||||
else:
|
||||
messages.success(
|
||||
request,
|
||||
_('Security Group %(grp)s: Access to %(proto)s ports %(fr)d - %(to)d has been revoked.') %
|
||||
{'grp': group_name,
|
||||
'proto': form.cleaned_data['protocol'],
|
||||
'fr': form.cleaned_data['from_port'],
|
||||
'to': form.cleaned_data['to_port']})
|
||||
LOG.info('Access to group "%s" granted on project "%s" for'
|
||||
' "%s" ports %d-%d' %
|
||||
(group_name, project_id, request.POST['protocol'],
|
||||
request.POST['from_port'], request.POST['to_port']))
|
||||
|
||||
return redirect('nova_securitygroups_detail', project_id, group_name)
|
||||
|
||||
|
||||
@login_required
|
||||
@handle_nova_error
|
||||
def delete(request, project_id, group_name):
|
||||
project = get_project_or_404(request, project_id)
|
||||
|
||||
if request.method == 'POST':
|
||||
try:
|
||||
project.delete_security_group(name=group_name)
|
||||
except exceptions.NovaApiError, e:
|
||||
messages.error(
|
||||
request,
|
||||
_('Unable to delete security group: %s') % e.message)
|
||||
LOG.error('Unable to delete security group "%s" on project "%s".'
|
||||
' Exception: "%s"' % (group_name, project_id, e.message))
|
||||
else:
|
||||
messages.success(request,
|
||||
_('Security Group %s was successfully deleted.') %
|
||||
group_name)
|
||||
LOG.info('Security group "%s" deleted from project "%s"' %
|
||||
(group_name, project_id))
|
||||
|
||||
return redirect('nova_securitygroups', project_id)
|
@ -19,13 +19,13 @@
|
||||
"""
|
||||
Views for managing Nova volumes.
|
||||
"""
|
||||
import logging
|
||||
|
||||
from django import template
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.shortcuts import redirect, render_to_response
|
||||
from django.utils.translation import ugettext as _
|
||||
from django_openstack import log as logging
|
||||
from django_openstack.nova import exceptions
|
||||
from django_openstack.nova import forms
|
||||
from django_openstack.nova import shortcuts
|
||||
|
31
django-openstack/src/django_openstack/syspanel/urls.py
Normal file
31
django-openstack/src/django_openstack/syspanel/urls.py
Normal file
@ -0,0 +1,31 @@
|
||||
from django.conf.urls.defaults import *
|
||||
from django.conf import settings
|
||||
from django.contrib import admin
|
||||
|
||||
admin.autodiscover()
|
||||
|
||||
urlpatterns = patterns('',
|
||||
url(r'^$', 'django_openstack.syspanel.views.home.index', name='syspanel_index'),
|
||||
|
||||
# instances
|
||||
url(r'^instances/$', 'django_openstack.syspanel.views.instances.index', name='syspanel_instances'),
|
||||
url(r'^instances/(?P<instance_id>[^/]+)/terminate$', 'django_openstack.syspanel.views.instances.terminate', name='syspanel_instance_terminate'),
|
||||
url(r'^instances/(?P<instance_id>[^/]+)/restart$', 'django_openstack.syspanel.views.instances.restart', name='syspanel_instance_restart'),
|
||||
url(r'^instances/(?P<instance_id>[^/]+)/console_log$', 'django_openstack.syspanel.views.instances.console', name='syspanel_instance_console'),
|
||||
|
||||
# volumes
|
||||
#url(r'^volumes/$', 'django_openstack.syspanel.views.volumes.index', name='syspanel_volumes'),
|
||||
#url(r'^volumes/(?P<volume_id>[^/]+)/delete$', 'django_openstack.syspanel.views.volumes.delete', name='syspanel_delete_volume'),
|
||||
#url(r'^volumes/(?P<volume_id>[^/]+)/detach$', 'django_openstack.syspanel.views.volumes.detach', name='syspanel_detach_volume'),
|
||||
|
||||
# vpns
|
||||
url(r'^vpns/$', 'django_openstack.syspanel.views.vpns.index', name='syspanel_vpns'),
|
||||
url(r'^vpns/(?P<project_id>[^/]+)/launch$', 'django_openstack.syspanel.views.vpns.launch', name='syspanel_vpn_launch'),
|
||||
url(r'^vpns/(?P<project_id>[^/]+)/send_credentials$', 'django_openstack.syspanel.views.vpns.send_credentials', name='syspanel_vpn_send_credentials'),
|
||||
url(r'^vpns/(?P<project_id>[^/]+)/terminate$', 'django_openstack.syspanel.views.vpns.terminate', name='syspanel_vpn_terminate'),
|
||||
url(r'^vpns/(?P<project_id>[^/]+)/restart$', 'django_openstack.syspanel.views.vpns.restart', name='syspanel_vpn_restart'),
|
||||
url(r'^vpns/(?P<project_id>[^/]+)/console_log$', 'django_openstack.syspanel.views.vpns.console', name='syspanel_vpn_console'),
|
||||
|
||||
# cloudview
|
||||
url(r'^cloudview/$', 'django_openstack.syspanel.views.cloud.index', name='syspanel_cloudview'),
|
||||
)
|
@ -2,8 +2,6 @@ from django import template
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.shortcuts import render_to_response
|
||||
|
||||
from django_nova_syspanel.models import get_nova_admin_connection
|
||||
|
||||
|
||||
@login_required
|
||||
def index(request):
|
@ -5,8 +5,6 @@ from django.contrib.auth.decorators import login_required
|
||||
from django.shortcuts import render_to_response
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
from django_nova_syspanel.models import *
|
||||
|
||||
|
||||
def _reservations_to_instances(reservation_list):
|
||||
rv = []
|
@ -6,8 +6,6 @@ from django.contrib.auth.decorators import login_required
|
||||
from django.shortcuts import redirect, render_to_response
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
from django_nova_syspanel.models import *
|
||||
|
||||
|
||||
@login_required
|
||||
def index(request):
|
@ -3,7 +3,6 @@ from django import template
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.shortcuts import redirect, render_to_response
|
||||
from django_nova_syspanel.models import get_nova_admin_connection
|
||||
|
||||
|
||||
@login_required
|
@ -1,45 +0,0 @@
|
||||
{% extends "admin/django_openstack/nova/project/base_projects.html" %}
|
||||
{% load admin_modify adminmedia %}
|
||||
|
||||
{% block extrahead %}
|
||||
{{ block.super }}
|
||||
{{ media }}
|
||||
{% endblock %}
|
||||
|
||||
{% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% admin_media_prefix %}css/forms.css" />{% endblock %}
|
||||
|
||||
{% block coltype %}colMS{% endblock %}
|
||||
|
||||
{% block bodyclass %} change-form{% endblock %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
<div class="breadcrumbs">
|
||||
<a href="/admin">Home</a> ›
|
||||
<a href="../../projects">Projects</a> ›
|
||||
Add Project
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div id="content-main">
|
||||
{% block object-tools %}
|
||||
{% endblock %}
|
||||
<form action="." method="post" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
<fieldset class="module aligned {{ fieldset.classes }}">
|
||||
{% for field in form.visible_fields %}
|
||||
<div class="form-row">
|
||||
{{ field.errors }}
|
||||
{{ field.label_tag }}{{ field }}
|
||||
{% if field.field.help_text %}<p class="help">{{ field.field.help_text|safe }}</p>{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% for field in form.hidden_fields %}
|
||||
{{ field }}
|
||||
{% endfor %}
|
||||
|
||||
</fieldset>
|
||||
<input type="submit" value="Save" />
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
@ -1,69 +0,0 @@
|
||||
{% extends "admin/django_openstack/nova/project/base_projects.html" %}
|
||||
{% load admin_modify adminmedia %}
|
||||
|
||||
{% block extrahead %}
|
||||
{{ block.super }}
|
||||
{{ media }}
|
||||
|
||||
<script type="text/javascript" src="/media/admin/js/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="/media/admin/js/jquery.init.js"></script>
|
||||
|
||||
<script type="text/javascript" src="/media/dashboard/js/django-admin.multiselect.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/media/dashboard/css/django-admin-widgets.css" />
|
||||
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
django.jQuery(function(){
|
||||
django.jQuery.each(django.jQuery(".edit_user_roles select[multiple]"), function () {
|
||||
// "Locations" can be any label you want
|
||||
SelectFilter.init(this.id, "Roles", 0, "/media/admin/");
|
||||
});
|
||||
})
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
{% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% admin_media_prefix %}css/forms.css" />{% endblock %}
|
||||
|
||||
{% block coltype %}colMS{% endblock %}
|
||||
|
||||
{% block bodyclass %} change-form{% endblock %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
<div class="breadcrumbs">
|
||||
<a href="/admin">Home</a> ›
|
||||
<a href="{% url admin_projects %}">Projects</a> ›
|
||||
<a href="{% url admin_project project.projectname %}">{{project.projectname}}</a> ›
|
||||
User
|
||||
{{form.ProjectUserForm}}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div id="content-main">
|
||||
{% block object-tools %}
|
||||
{% endblock %}
|
||||
<form class="edit_user_roles" action="." method="post" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
<fieldset class="module aligned {{ fieldset.classes }}">
|
||||
<input type="hidden" name="username" value="{{user.id}}" id="username" />
|
||||
{% for field in form.visible_fields %}
|
||||
<div class="form-row">
|
||||
{{ field.errors }}
|
||||
{{ field.label_tag }}{{ field }}
|
||||
{% if field.field.help_text %}<p class="help">{{ field.field.help_text|safe }}</p>{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% for field in form.hidden_fields %}
|
||||
{{ field }}
|
||||
{% endfor %}
|
||||
|
||||
</fieldset>
|
||||
<div class="submit-row">
|
||||
<p class="deletelink-box">
|
||||
<a href="{% url admin_project_delete_user project.projectname user.username %}" class="deletelink">Delete</a>
|
||||
</p>
|
||||
<input type="submit" value="Save" class="default" />
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
@ -1,17 +0,0 @@
|
||||
{% extends "admin/change_list.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block extrastyle %}
|
||||
{{block.super}}
|
||||
<link rel="stylesheet" type="text/css" href="{{settings.MEDIA_URL}}/stylesheets/extra_admin.css" />
|
||||
{% endblock %}
|
||||
{% block breadcrumbs %}<div class="breadcrumbs"><a href="/admin/">Home</a> › Projects</div>{% endblock %}
|
||||
{% block content %}
|
||||
<div id="content-main">
|
||||
<div class="module filtered" id="changelist">
|
||||
<div id="toolbartable">
|
||||
{% block innercontent %}{% endblock %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
@ -1,3 +0,0 @@
|
||||
{% extends "admin/change_list.html" %}
|
||||
{% load admin_extras %}
|
||||
{% block result_list %}{% project_result_list cl %}{% endblock %}
|
@ -1,26 +0,0 @@
|
||||
{% extends "admin/change_list.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block extrastyle %}
|
||||
{{block.super}}
|
||||
<link rel="stylesheet" type="text/css" href="{{settings.MEDIA_URL}}/stylesheets/extra_admin.css" />
|
||||
{% endblock %}
|
||||
{% block breadcrumbs %}<div class="breadcrumbs"><a href="/admin/">Home</a> › <a href="/admin/projects">Projects</a> › <a href="{% url admin_project project.projectname %}">{{project.projectname}}</a> › Delete</div>{% endblock %}
|
||||
{% block content %}
|
||||
<div id="content-main">
|
||||
<div class="module filtered" id="changelist">
|
||||
<div id="toolbartable">
|
||||
<h1>{% trans "Delete Project" %}</h1>
|
||||
<p>{% trans "Do you really want to delete this project?<" %}/p>
|
||||
<ul>
|
||||
<li><a href="{% url admin_project project.projectname %}">{{project.projectname}}</a></li>
|
||||
</ul>
|
||||
|
||||
<form action="." method="post">
|
||||
{% csrf_token %}
|
||||
<p><input type="submit" value="Delete"></p>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
@ -1,26 +0,0 @@
|
||||
{% extends "admin/change_list.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block extrastyle %}
|
||||
{{block.super}}
|
||||
<link rel="stylesheet" type="text/css" href="{{settings.MEDIA_URL}}/stylesheets/extra_admin.css" />
|
||||
{% endblock %}
|
||||
{% block breadcrumbs %}<div class="breadcrumbs"><a href="/admin/">Home</a> › <a href="/admin/projects">Projects</a> › <a href="{% url admin_project project.projectname %}">{{project.projectname}}</a> › {% trans "Delete"%}</div>{% endblock %}
|
||||
{% block content %}
|
||||
<div id="content-main">
|
||||
<div class="module filtered" id="changelist">
|
||||
<div id="toolbartable">
|
||||
<h1>{% trans "Remove User From Project" %}</h1>
|
||||
<p>{% trans "Do you really want to remove this user from project?" %}</p>
|
||||
<ul>
|
||||
<li><a href="{% url project_user project.projectname user.username %}">{{user.username}}</a> from <a href="{% url admin_project project.projectname %}">{{project.projectname}}</a></li>
|
||||
</ul>
|
||||
|
||||
<form action="." method="post">
|
||||
{% csrf_token %}
|
||||
<p><input type="submit" value="Delete"></p>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
@ -1,84 +0,0 @@
|
||||
{% extends "admin/django_openstack/nova/project/base_projects.html" %}
|
||||
{% load admin_modify adminmedia %}
|
||||
|
||||
{% block extrahead %}
|
||||
{{ block.super }}
|
||||
{{ media }}
|
||||
{% endblock %}
|
||||
|
||||
{% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% admin_media_prefix %}css/forms.css" />{% endblock %}
|
||||
|
||||
{% block coltype %}colMS{% endblock %}
|
||||
|
||||
{% block bodyclass %} change-form{% endblock %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
<div class="breadcrumbs">
|
||||
<a href="/admin">Home</a> ›
|
||||
<a href="{% url admin_projects %}">Projects</a> ›
|
||||
<a href="{% url admin_project project.projectname %}">{{project.projectname}}</a> ›
|
||||
Edit Project
|
||||
{{form.ProjectEditForm}}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div id="content-main">
|
||||
{% block object-tools %}
|
||||
{% endblock %}
|
||||
|
||||
<form action="." method="post" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
<fieldset class="module aligned {{ fieldset.classes }}">
|
||||
{% for field in form.visible_fields %}
|
||||
<div class="form-row">
|
||||
{{ field.errors }}
|
||||
{{ field.label_tag }}{{ field }}
|
||||
{% if field.field.help_text %}<p class="help">{{ field.field.help_text|safe }}</p>{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% for field in form.hidden_fields %}
|
||||
{{ field }}
|
||||
{% endfor %}
|
||||
</fieldset>
|
||||
<div class="submit-row">
|
||||
<p class="deletelink-box">
|
||||
<a href="{% url delete_project project.projectname %}" class="deletelink">Delete Project</a>
|
||||
</p>
|
||||
<input type="submit" value="Save" class="default" />
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
|
||||
<table cellspacing="0" style="margin-top: 20px;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Username</th>
|
||||
<th>Project Roles</th>
|
||||
<th>Global Roles</th>
|
||||
</tr>
|
||||
</thead>
|
||||
{% for user in users %}
|
||||
<tr class="{% cycle 'row1' 'row2' %}">
|
||||
<td>
|
||||
<a href="{%url project_user project.projectname user.memberId %}">{{user.memberId}} {% if user.memberId == project.projectManagerId %}(<em>project manager</em>){%endif %}</a>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
{{user.project_roles}}
|
||||
</td>
|
||||
<td>
|
||||
{{user.global_roles}}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
<ul class="object-tools">
|
||||
<li>
|
||||
<a class="addlink" href="{% url add_project_user project.projectname %}">Add User</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
{% endblock %}
|
@ -1,71 +0,0 @@
|
||||
{% extends "admin/django_openstack/nova/project/base_projects.html" %}
|
||||
{% load admin_modify adminmedia %}
|
||||
|
||||
{% block extrahead %}
|
||||
{{ block.super }}
|
||||
{{ media }}
|
||||
|
||||
<script type="text/javascript" src="/media/admin/js/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="/media/admin/js/jquery.init.js"></script>
|
||||
|
||||
<script type="text/javascript" src="/media/dashboard/js/django-admin.multiselect.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/media/dashboard/css/django-admin-widgets.css" />
|
||||
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
django.jQuery(function(){
|
||||
django.jQuery.each(django.jQuery("#global_users select"), function () {
|
||||
// "Locations" can be any label you want
|
||||
SelectFilter.init(this.id, "Roles", 0, "/media/admin/");
|
||||
});
|
||||
})
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
{% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% admin_media_prefix %}css/forms.css" />{% endblock %}
|
||||
|
||||
{% block coltype %}colMS{% endblock %}
|
||||
|
||||
{% block bodyclass %} change-form{% endblock %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
<div class="breadcrumbs">
|
||||
<a href="/admin">Home</a> ›
|
||||
<a href="{% url admin_users_list %}">Global Roles</a> ›
|
||||
{{user.username}}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div id="content-main">
|
||||
{% block object-tools %}
|
||||
{% endblock %}
|
||||
<form action="." method="post" enctype="multipart/form-data" id="global_users">
|
||||
{% csrf_token %}
|
||||
<fieldset class="module aligned {{ fieldset.classes }}">
|
||||
<div class="form-row">
|
||||
<label for="id_username">Username</label>
|
||||
<span>{{user.username}}</span>
|
||||
</div>
|
||||
<input type="hidden" name="username" value="{{user.id}}" id="username" />
|
||||
{% for field in form.visible_fields %}
|
||||
<div class="form-row">
|
||||
{{ field.errors }}
|
||||
{{ field.label_tag }}{{ field }}
|
||||
{% if field.field.help_text %}<p class="help">{{ field.field.help_text|safe }}</p>{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% for field in form.hidden_fields %}
|
||||
{{ field }}
|
||||
{% endfor %}
|
||||
|
||||
</fieldset>
|
||||
<div class="submit-row">
|
||||
<p class="deletelink-box">
|
||||
{# <a href="{% url admin_project_delete_user project.projectname user.username %}" class="deletelink">Delete</a> #}
|
||||
</p>
|
||||
<input type="submit" value="Save" class="default" />
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
@ -1,42 +0,0 @@
|
||||
{% extends "admin/django_openstack/nova/project/base_projects.html" %}
|
||||
{% block extrahead %}
|
||||
{{ block.super }}
|
||||
{% endblock %}
|
||||
{% block innercontent %}
|
||||
<ul class="object-tools">
|
||||
<li>
|
||||
<a class="addlink" href="{% url add_project %}">Add Project</a>
|
||||
</li>
|
||||
</ul>
|
||||
<table cellspacing="0" style="margin-top: 20px;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Description</th>
|
||||
<th>Project Manager</th>
|
||||
<th>Send Credentials</th>
|
||||
<th>Start VPN</th>
|
||||
</tr>
|
||||
</thead>
|
||||
{% for project in projects %}
|
||||
<tr class="{% cycle 'row1' 'row2' %}">
|
||||
<td>
|
||||
<a href="{%url admin_project project.projectname %}">{{project.projectname}}</a>
|
||||
</td>
|
||||
<td>
|
||||
{{project.description}}
|
||||
</td>
|
||||
<td>
|
||||
{{project.projectManagerId}}
|
||||
</td>
|
||||
<td>
|
||||
<a href="{% url admin_project_sendcredentials project.projectname %}">Send Credentials</a>
|
||||
</td>
|
||||
<td>
|
||||
<a href="{% url admin_project_start_vpn project.projectname %}">Start VPN</a>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endblock %}
|
@ -1,76 +0,0 @@
|
||||
{% extends "admin/django_openstack/nova/project/base_projects.html" %}
|
||||
{% load admin_modify adminmedia i18n %}
|
||||
|
||||
{% block extrahead %}
|
||||
{{ block.super }}
|
||||
{{ media }}
|
||||
|
||||
<script type="text/javascript" src="/media/admin/js/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="/media/admin/js/jquery.init.js"></script>
|
||||
|
||||
<script type="text/javascript" src="/media/dashboard/js/django-admin.multiselect.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/media/dashboard/css/django-admin-widgets.css" />
|
||||
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
django.jQuery(function(){
|
||||
django.jQuery.each(django.jQuery(".edit_user_roles select[multiple]"), function () {
|
||||
// "Locations" can be any label you want
|
||||
SelectFilter.init(this.id, "Roles", 0, "/media/admin/");
|
||||
});
|
||||
})
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
{% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% admin_media_prefix %}css/forms.css" />{% endblock %}
|
||||
|
||||
{% block coltype %}colMS{% endblock %}
|
||||
|
||||
{% block bodyclass %} change-form{% endblock %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
<div class="breadcrumbs">
|
||||
<a href="/admin">Home</a> ›
|
||||
<a href="{% url admin_projects %}">Projects</a> ›
|
||||
<a href="{% url admin_project project.projectname %}">{{project.projectname}}</a> ›
|
||||
User
|
||||
{{form.ProjectUserForm}}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div id="content-main">
|
||||
{% block object-tools %}
|
||||
{% endblock %}
|
||||
<form class="edit_user_roles" action="." method="post" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
<fieldset class="module aligned {{ fieldset.classes }}">
|
||||
<div class="form-row">
|
||||
<label for="id_username">Username</label>
|
||||
<span>{{user.username}}</span>
|
||||
</div>
|
||||
<input type="hidden" name="username" value="{{user.id}}" id="username" />
|
||||
{% for field in form.visible_fields %}
|
||||
<div class="form-row">
|
||||
{{ field.errors }}
|
||||
{{ field.label_tag }}{{ field }}
|
||||
{% if field.field.help_text %}<p class="help">{{ field.field.help_text|safe }}</p>{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% for field in form.hidden_fields %}
|
||||
{{ field }}
|
||||
{% endfor %}
|
||||
|
||||
</fieldset>
|
||||
<div class="submit-row">
|
||||
{% if project.projectManagerId != user.username %}
|
||||
<p class="deletelink-box">
|
||||
<a href="{% url admin_project_delete_user project.projectname user.username %}" class="deletelink">{% trans "Remove User From Project" %}</a>
|
||||
</p>
|
||||
{% endif %}
|
||||
|
||||
<input type="submit" value="Save" class="default" />
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
@ -1,87 +0,0 @@
|
||||
{% extends "admin/base_site.html" %}
|
||||
{% load i18n admin_modify adminmedia %}
|
||||
|
||||
{% block title %}Send project credentials{{ block.super }}{% endblock %}
|
||||
|
||||
{% block extrahead %}
|
||||
{{ block.super }}
|
||||
{{ media }}
|
||||
|
||||
<script type="text/javascript" src="/media/admin/js/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="/media/admin/js/jquery.init.js"></script>
|
||||
|
||||
<script type="text/javascript" src="/media/dashboard/js/django-admin.multiselect.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/media/dashboard/css/django-admin-widgets.css" />
|
||||
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
django.jQuery(function(){
|
||||
django.jQuery.each(django.jQuery("#send_credentials select"), function () {
|
||||
// "Locations" can be any label you want
|
||||
SelectFilter.init(this.id, "Users", 0, "/media/admin/");
|
||||
});
|
||||
})
|
||||
</script>
|
||||
|
||||
<style type="text/css" media="screen">
|
||||
.errorlist, .successlist {background:#fcc;border:1px solid #c66;color:#600;list-style:none; padding: 10px 5px; margin: 25px 0 25px 0; float: left; width: 100%;}
|
||||
.successlist {background: #CBFBD7; color: #1E5024; border-color: #6FBA5C;}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block breadcrumbs %}
|
||||
<div class="breadcrumbs">
|
||||
<a href="/admin">Home</a> ›
|
||||
<a href="{% url admin_projects %}">Projects</a> ›
|
||||
<a href="{% url admin_project project.projectname %}">{{project.projectname}}</a> ›
|
||||
Send Credentials
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div id="content-main">
|
||||
|
||||
|
||||
{% if not success %}
|
||||
<h1>{% trans "Send Credentials"%}</h1>
|
||||
<h3>{%blocktrans with proj=project.projectname%}"Select which users you would like to send credentials to from the '{{proj}}' project."{%endblocktrans%}</h3>
|
||||
{% else %}
|
||||
<h1>{% trans "Credentials sent successfully"%}</h1>
|
||||
{% endif %}
|
||||
|
||||
<div class="status">
|
||||
{% if error %}
|
||||
<span class="errorlist">{{ error }}</span>
|
||||
{% endif %}
|
||||
|
||||
{% if success %}
|
||||
<span class="successlist">{{ success }}</span>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
|
||||
{% if not success %}
|
||||
<form id="send_credentials" action="{% url admin_project_sendcredentials project.projectname %}" method="post">
|
||||
{% csrf_token %}
|
||||
<fieldset class="module aligned">
|
||||
|
||||
{% for field in form.visible_fields %}
|
||||
<div class="form-row">
|
||||
{{ field.errors }}
|
||||
{{ field }}
|
||||
{% if field.field.help_text %}<p class="help">{{ field.field.help_text|safe }}</p>{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% for field in form.hidden_fields %}
|
||||
{{ field }}
|
||||
{% endfor %}
|
||||
|
||||
</fieldset>
|
||||
<div class="submit-row">
|
||||
<input style="margin-top:20px; margin-left:10px;" type="submit" value="{% trans "Send Credentials"%}" />
|
||||
</div>
|
||||
|
||||
</form>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
@ -1,39 +0,0 @@
|
||||
{% extends "admin/django_openstack/nova/project/base_projects.html" %}
|
||||
{% block extrahead %}
|
||||
{{ block.super }}
|
||||
{% endblock %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
<div class="breadcrumbs">
|
||||
<a href="/admin">Home</a> ›
|
||||
Global Roles
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block innercontent %}
|
||||
<h1>Select a User</h1>
|
||||
|
||||
<table cellspacing="0" style="margin-top: 20px;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Username</th>
|
||||
<th>Global Roles</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
{% for user in users %}
|
||||
<tr class="{% cycle 'row1' 'row2' %}">
|
||||
<td>
|
||||
{{user.username}}
|
||||
</td>
|
||||
<td>
|
||||
(temporarily hidden)
|
||||
{#user.roles#}
|
||||
</td>
|
||||
<td>
|
||||
<a href="{%url admin_user_roles user.username %}">Edit</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endblock %}
|
@ -1,17 +0,0 @@
|
||||
{% load django_nova_tags %}
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" xml:lang="en">
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<title>Expired Token</title>
|
||||
</head>
|
||||
<body>
|
||||
<center>
|
||||
<h1>The link you clicked has expired.</h1>
|
||||
<p style="width:460px;">This credentials download link you have reached
|
||||
is either invalid or has expired. Each link is only good for one use. If
|
||||
you need to download your credentials again, please contact the
|
||||
{% site_branding %} support team.</p>
|
||||
</center>
|
||||
</body>
|
||||
</html>
|
@ -1,5 +0,0 @@
|
||||
{% for field in create_form %}
|
||||
{{ field.label_tag }}
|
||||
{% if field.errors %}{{ field.errors }}{% endif %}
|
||||
{{ field }}
|
||||
{% endfor %}
|
@ -1,31 +0,0 @@
|
||||
{% if keypairs %}
|
||||
<table style="width: 100%">
|
||||
<tr>
|
||||
<th>Key Pair Name</th>
|
||||
<th>Fingerprint</th>
|
||||
<th> </th>
|
||||
</tr>
|
||||
{% for keypair in keypairs %}
|
||||
<tr class="{% cycle 'odd' 'even' %}">
|
||||
<td>{{ keypair.name }}</td>
|
||||
<td class="odd">{{ keypair.fingerprint }}</td>
|
||||
<td>
|
||||
<form id="form_key_delete_{{keypair.name}}" class="form-key-delete" method="post" action="{% url nova_keypairs_delete project.projectname %}">
|
||||
<input name="key_name" type="hidden" value="{{ keypair.name }}" />
|
||||
<input id="keypair_delete_{{keypair.name}}" class="delete" type="submit" value="Delete" />
|
||||
{% csrf_token %}
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% else %}
|
||||
<div class="ui-widget">
|
||||
<div class="ui-state-highlight ui-corner-all">
|
||||
<p>
|
||||
<span class="ui-icon ui-icon-info"></span>
|
||||
No key pairs currently exist.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
@ -1,7 +0,0 @@
|
||||
{% extends "django_nova/base.html" %}
|
||||
{% load sidebar_tags %}
|
||||
|
||||
{% block nav_projects %}
|
||||
{% sidebar_select keys %}
|
||||
{{ block.super }}
|
||||
{% endblock %}
|
@ -1,77 +0,0 @@
|
||||
{% extends "django_nova/keypairs/base.html" %}
|
||||
|
||||
{% block title %} - Cloud Computing{% endblock %}
|
||||
|
||||
{% block headerjs %}
|
||||
{{ block.super }}
|
||||
<script type="text/javascript" src="/media/dashboard/js/jquery.form.js"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div id="page_head">
|
||||
<h2 id="page_heading">Keys</h2>
|
||||
<p id="page_description">Key pairs are ssh credentials which are injected into images when they are launched. Creating a new key pair registers the public key and downloads the private key (a pem file). <em>Protect and use the key as a normal private key.</em></p>
|
||||
</div>
|
||||
|
||||
{% include "django_nova/_messages.html" %}
|
||||
|
||||
<div id="instances">
|
||||
{% include "django_nova/keypairs/_list.html" %}
|
||||
</div>
|
||||
|
||||
<div class="dash_block first">
|
||||
<form id="frm_key_create" action="{% url nova_keypairs_add project.projectname %}" method="post">
|
||||
{% csrf_token %}
|
||||
<input id="js" name="js" type="hidden" value="0" />
|
||||
<fieldset>
|
||||
<h3>Create New Keypair</h3>
|
||||
{% include "django_nova/keypairs/_create_form.html" %}
|
||||
<input id="keypair_create" class="create" type="submit" value="Create" />
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id="dlg_confirm" title="Confirm Termination">
|
||||
<p>Are you sure you wish to delete key <span id="spn_delete_key_name"></span>?</p>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block footerjs %}
|
||||
{{ block.super }}
|
||||
<script type="text/javascript">
|
||||
$(function() { $('#js').val('1'); });
|
||||
|
||||
{% if download_key %}
|
||||
$(function() { window.location = '{% url nova_keypairs_download project.projectname download_key %}'; });
|
||||
{% endif %}
|
||||
|
||||
$(function() {
|
||||
$('.form-key-delete').submit(function() {
|
||||
_key_name = $(this).children(':first').val()
|
||||
$('#spn_delete_key_name').text(_key_name);
|
||||
$('#dlg_confirm').dialog('open');
|
||||
return false;
|
||||
});
|
||||
|
||||
$('#dlg_confirm').dialog({
|
||||
buttons: {
|
||||
'Ok': onConfirmOK,
|
||||
'Cancel': function() { $(this).dialog('close'); }
|
||||
},
|
||||
autoOpen: false,
|
||||
resizable: false,
|
||||
width: 500,
|
||||
height: 200
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
var _terminateID = null;
|
||||
|
||||
function onConfirmOK() {
|
||||
$(this).dialog('close');
|
||||
form = document.getElementById('form_key_delete_' + _key_name);
|
||||
if(form) form.submit();
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
@ -1,5 +0,0 @@
|
||||
{% for field in authorize_form %}
|
||||
{{ field.label_tag }}
|
||||
{% if field.errors %}{{ field.errors }}{% endif %}
|
||||
{{ field }}
|
||||
{% endfor %}
|
@ -1,5 +0,0 @@
|
||||
{% for field in create_form %}
|
||||
{{ field.label_tag }}
|
||||
{% if field.errors %}{{ field.errors }}{% endif %}
|
||||
{{ field }}
|
||||
{% endfor %}
|
@ -1,3 +0,0 @@
|
||||
<input type="hidden" name="protocol" value="{{ rule.ip_protocol }}" />
|
||||
<input type="hidden" name="from_port" value="{{ rule.from_port}}" />
|
||||
<input type="hidden" name="to_port" value="{{ rule.to_port }}" />
|
@ -1,7 +0,0 @@
|
||||
{% extends "django_nova/base.html" %}
|
||||
{% load sidebar_tags %}
|
||||
|
||||
{% block nav_projects %}
|
||||
{% sidebar_select securitygroups %}
|
||||
{{ block.super }}
|
||||
{% endblock %}
|
@ -1,62 +0,0 @@
|
||||
{% extends "django_nova/securitygroups/base.html" %}
|
||||
|
||||
{% block title %} - Cloud Computing{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div id="dashboard_tabs">
|
||||
<div id="tabs-1" class="ui-tabs-panel ui-widget-content ui-corner-bottom dash-wrap" style="margin-left:0;min-height:300px;">
|
||||
<ul id="dashboard_nav">
|
||||
<li><a id="lnk_overview" href="{% url dashboard_project project.projectname %}">Overview</a></li>
|
||||
<li><a id="lnk_instances" href="{% url dashboard_instances project.projectname %}">Instances</a></li>
|
||||
<li><a id="lnk_images" href="{% url dashboard_images project.projectname %}">Images</a></li>
|
||||
<li><a id="lnk_keypairs" href="{% url dashboard_keypairs project.projectname %}">Keys</a></li>
|
||||
<li class="active"><a id="lnk_securitygroups" href="{% url dashboard_securitygroups project.projectname %}">Security Groups</a></li>
|
||||
<li><a id="lnk_volumes" href="{% url dashboard_volumes project.projectname %}">Volumes</a></li>
|
||||
</ul>
|
||||
<div id="right_content">
|
||||
<div id="page_head">
|
||||
<h2>Security Group: {{ securitygroup.name }}</h2>
|
||||
<p>Add and remove protocols to the security group by authorizing and revoking port forwarding. For instance<br /> [tcp, 80, 80] will allow access to HTTP from devices outside this security group.</p>
|
||||
</div>
|
||||
|
||||
{% include "django_nova/_messages.html" %}
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>Protocol</th>
|
||||
<th>From Port</th>
|
||||
<th>To Port</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
{% for rule in securitygroup.rules %}
|
||||
<tr class="{% cycle 'odd' 'even' %}">
|
||||
<td>{{ rule.ip_protocol }}</td>
|
||||
<td class="odd">{{ rule.from_port }}</td>
|
||||
<td>{{ rule.to_port }}</td>
|
||||
<td class="odd">
|
||||
<form id="security_groups" method="post" action="{% url dashboard_securitygroups_revoke project.projectname securitygroup.name %}">
|
||||
{% csrf_token %}
|
||||
{% include "django_nova/securitygroups/_revoke_form.html" %}
|
||||
<input class="ui-state-default ui-corner-all" type="submit" value="Revoke" />
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
||||
<div class="block">
|
||||
<h3>Authorize</h3>
|
||||
<form id="authorize" method="post" action="{% url dashboard_securitygroups_authorize project.projectname securitygroup.name %}">
|
||||
{% csrf_token %}
|
||||
<fieldset>
|
||||
<input type="hidden" name="group" value="{{ securitygroup.name }}" />
|
||||
{% include "django_nova/securitygroups/_authorize_form.html" %}
|
||||
<input class="ui-state-default ui-corner-all" type="submit" value="Authorize">
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clr"></div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
@ -1,59 +0,0 @@
|
||||
{% extends "django_nova/securitygroups/base.html" %}
|
||||
|
||||
{% block title %} - Cloud Computing{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div id="dashboard_tabs">
|
||||
<div id="tabs-1" class="ui-tabs-panel ui-widget-content ui-corner-bottom dash-wrap" style="margin-left:0px;min-height:300px;">
|
||||
<ul id="dashboard_nav">
|
||||
<li><a id="lnk_overview" href="{% url dashboard_project project.projectname %}">Overview</a></li>
|
||||
<li><a id="lnk_instances" href="{% url dashboard_instances project.projectname %}">Instances</a></li>
|
||||
<li><a id="lnk_images" href="{% url dashboard_images project.projectname %}">Images</a></li>
|
||||
<li><a id="lnk_keypairs" href="{% url dashboard_keypairs project.projectname %}">Keys</a></li>
|
||||
<li class="active"><a id="lnk_securitygroups" href="{% url dashboard_securitygroups project.projectname %}">Security Groups</a></li>
|
||||
<li><a id="lnk_volumes" href="{% url dashboard_volumes project.projectname %}">Volumes</a></li>
|
||||
</ul>
|
||||
<div id="right_content">
|
||||
<div id="page_head">
|
||||
<h2 id="page_heading">Security Groups</h2>
|
||||
<p id="page_description">Security groups are firewall rules which allow access to your instances from other groups as well as the internet. All ports/protocols are denied by default.</p>
|
||||
</div>
|
||||
|
||||
{% include "django_nova/_messages.html" %}
|
||||
|
||||
<table style="width:100%;">
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th style="min-width:60%;">Description</th>
|
||||
<th>Rules</th>
|
||||
<th> </th>
|
||||
</tr>
|
||||
{% for securitygroup in securitygroups %}
|
||||
<tr class="{% cycle 'odd' 'even' %}">
|
||||
<td id="group_{{ securitygroup.id }}"><a href="{% url dashboard_securitygroups_detail project.projectname securitygroup.name %}">{{ securitygroup.name }}</a></td>
|
||||
<td id="group_{{ securitygroup.id }}_description" class="odd">{{ securitygroup.description }}</td>
|
||||
<td id="group_{{ securitygroup.id }}_rules">{{ securitygroup.rules|length }}</td>
|
||||
<td class="odd">
|
||||
<form id="delete_group_{{ securitygroup.id }}" method="post" action="{% url dashboard_securitygroups_delete project.projectname securitygroup.name %}">
|
||||
{% csrf_token %}
|
||||
<input class="ui-state-default ui-corner-all" type="submit" value="Delete">
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
<div class="block">
|
||||
<form id="add_group_form" method="post" action="{% url dashboard_securitygroups_add project.projectname %}">
|
||||
{% csrf_token %}
|
||||
<fieldset>
|
||||
<h3>New Group</h3>
|
||||
{% include "django_nova/securitygroups/_create_form.html" %}
|
||||
<label> </label><input class="ui-state-default ui-corner-all" type="submit" value="Create" />
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clr"></div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
@ -21,14 +21,13 @@ URL patterns for testing django-openstack views.
|
||||
"""
|
||||
|
||||
from django.conf.urls.defaults import *
|
||||
from django.conf.urls.defaults import *
|
||||
|
||||
|
||||
urlpatterns = patterns('',
|
||||
url(r'^projects/', include('django_openstack.nova.urls.project')),
|
||||
url(r'^region/', include('django_openstack.nova.urls.region')),
|
||||
url(r'^admin/projects/', include('django_openstack.nova.urls.admin_project')),
|
||||
url(r'^admin/roles/', include('django_openstack.nova.urls.admin_roles')),
|
||||
#url(r'^admin/projects/', include('django_openstack.nova.urls.admin_project')),
|
||||
#url(r'^admin/roles/', include('django_openstack.nova.urls.admin_roles')),
|
||||
url(r'^credentials/download/(?P<auth_token>\w+)/$',
|
||||
'django_openstack.nova.views.credentials.authorize_credentials',
|
||||
name='nova_credentials_authorize'),
|
||||
|
@ -70,7 +70,7 @@ INSTALLED_APPS = (
|
||||
'django_openstack',
|
||||
'django_openstack.nova',
|
||||
'django_openstack.templatetags',
|
||||
'django_nova_syspanel',
|
||||
'django_openstack.syspanel',
|
||||
'registration',
|
||||
)
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
{% extends "admin/base_site.html" %}
|
||||
{% load django_openstack_tags i18n %}
|
||||
{% load branding i18n %}
|
||||
|
||||
{% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% load adminmedia %}{% admin_media_prefix %}css/dashboard.css" />{% endblock %}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
{% load django_openstack_tags i18n %}
|
||||
{% load branding i18n %}
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" xml:lang="en">
|
||||
<head>
|
||||
|
@ -1,5 +1,5 @@
|
||||
{% extends "base.html" %}
|
||||
{% load django_openstack_tags i18n %}
|
||||
{% load branding i18n %}
|
||||
|
||||
{% block headercss %}
|
||||
{% endblock %}
|
||||
|
@ -1,5 +1,5 @@
|
||||
{% extends "base.html" %}
|
||||
{% load django_openstack_tags %}
|
||||
{% load branding %}
|
||||
|
||||
{% block region %}{% endblock %}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
{% load i18n %}{% load django_openstack_tags %}
|
||||
{% load i18n %}{% load branding %}
|
||||
{% autoescape off %}
|
||||
You're receiving this e-mail because you requested a password reset for your
|
||||
user account at {% site_branding %}.
|
||||
|
@ -33,17 +33,8 @@ admin.autodiscover()
|
||||
urlpatterns = patterns('',
|
||||
url(r'^$', 'dashboard.views.index', name='index'),
|
||||
url(r'^i18n/setlang', django.views.i18n.set_language),
|
||||
url(r'^accounts/register/$',
|
||||
'registration.views.register',
|
||||
{'form_class': reg_forms.RegistrationFormUniqueEmail},
|
||||
name='registration_register'),
|
||||
url(r'^accounts/', include('registration.urls')),
|
||||
url(r'^project/', include('django_openstack.nova.urls.project')),
|
||||
url(r'^region/', include('django_openstack.nova.urls.region')),
|
||||
url(r'^admin/project/', include('django_openstack.nova.urls.admin_project')),
|
||||
url(r'^admin/roles/', include('django_openstack.nova.urls.admin_roles')),
|
||||
url(r'^admin/', include(admin.site.urls)),
|
||||
url(r'^syspanel/', include('django_nova_syspanel.urls')),
|
||||
url(r'^syspanel/', include('django_openstack.syspanel.urls')),
|
||||
)
|
||||
|
||||
urlpatterns += patterns('',
|
||||
|
@ -122,12 +122,6 @@ def install_django_openstack():
|
||||
run_command([WITH_VENV, 'python', 'setup.py', 'develop'], cwd=path)
|
||||
|
||||
|
||||
def install_django_nova_syspanel():
|
||||
print 'Installing django_nova_syspanel in development mode...'
|
||||
path = os.path.join(ROOT, '..', 'django-nova-syspanel')
|
||||
run_command([WITH_VENV, 'python', 'setup.py', 'develop'], cwd=path)
|
||||
|
||||
|
||||
def print_summary():
|
||||
summary = """
|
||||
OpenStack Dashboard development environment setup is complete.
|
||||
@ -145,7 +139,6 @@ def main():
|
||||
create_virtualenv()
|
||||
install_dependencies()
|
||||
install_django_openstack()
|
||||
install_django_nova_syspanel()
|
||||
print_summary()
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
Loading…
x
Reference in New Issue
Block a user