Depends-On: https://review.opendev.org/#/c/658493/ Change-Id: I3e2e42efc30eced5abb6c8fff0d0fc974fc9722bchanges/95/658495/2
@ -1,7 +0,0 @@ | |||
[run] | |||
branch = True | |||
source = neutron_lbaas_dashboard | |||
omit = neutron_lbaas_dashboard/openstack/* | |||
[report] | |||
ignore_errors = True |
@ -1,52 +0,0 @@ | |||
# Set up globals | |||
globals: | |||
angular: false | |||
extends: openstack | |||
# Most environment options are not explicitly enabled or disabled, only | |||
# included here for completeness' sake. They are commented out, because the | |||
# global updates.py script would otherwise override them during a global | |||
# requirements synchronization. | |||
# | |||
# Individual projects should choose which platforms they deploy to. | |||
env: | |||
# browser global variables. | |||
browser: true | |||
# Adds all of the Jasmine testing global variables for version 1.3 and 2.0. | |||
jasmine: true | |||
# Enable eslint-plugin-angular | |||
plugins: | |||
- angular | |||
# Below we adjust rules specific to horizon's usage of openstack's linting | |||
# rules, and its own plugin inclusions. | |||
rules: | |||
############################################################################# | |||
# Disabled Rules from eslint-config-openstack | |||
############################################################################# | |||
valid-jsdoc: 1 | |||
brace-style: 1 | |||
no-extra-parens: 1 | |||
consistent-return: 1 | |||
callback-return: 1 | |||
guard-for-in: 1 | |||
block-scoped-var: 1 | |||
semi-spacing: 1 | |||
no-redeclare: 1 | |||
no-new: 1 | |||
############################################################################# | |||
# Angular Plugin Customization | |||
############################################################################# | |||
angular/controller-as-vm: | |||
- 1 | |||
- "ctrl" | |||
# Remove after migrating to angular 1.4 or later. | |||
angular/no-cookiestore: | |||
- 1 |
@ -1,61 +0,0 @@ | |||
*.py[cod] | |||
# C extensions | |||
*.so | |||
# Packages | |||
*.egg | |||
*.egg-info | |||
dist | |||
build | |||
.eggs | |||
eggs | |||
parts | |||
bin | |||
var | |||
sdist | |||
develop-eggs | |||
.installed.cfg | |||
lib | |||
lib64 | |||
# Installer logs | |||
pip-log.txt | |||
# Unit test / coverage reports | |||
.coverage | |||
*.lock | |||
.tox | |||
nosetests.xml | |||
.secret_key_store | |||
.testrepository | |||
node_modules | |||
coverage* | |||
test-shim.js | |||
# Translations | |||
*.mo | |||
.zanata-cache/ | |||
# Mr Developer | |||
.mr.developer.cfg | |||
.project | |||
.pydevproject | |||
# Complexity | |||
output/*.html | |||
output/*/index.html | |||
# Sphinx | |||
doc/build | |||
doc/source/contributor/modules | |||
# pbr generates these | |||
AUTHORS | |||
ChangeLog | |||
# Editors | |||
*~ | |||
.*.swp | |||
.*sw? | |||
.ropeproject/ |
@ -1,3 +0,0 @@ | |||
# Format is: | |||
# <preferred e-mail> <other e-mail 1> | |||
# <preferred e-mail> <other e-mail 2> |
@ -1,8 +0,0 @@ | |||
- project: | |||
templates: | |||
- check-requirements | |||
- horizon-nodejs10-jobs | |||
- openstack-lower-constraints-jobs | |||
- openstack-python-jobs-horizon | |||
- openstack-python3-train-jobs-horizon | |||
- publish-openstack-docs-pti |
@ -1,21 +0,0 @@ | |||
.. warning:: | |||
Neutron-lbaas-dashboard is now deprecated. Please see the FAQ: https://wiki.openstack.org/wiki/Neutron/LBaaS/Deprecation | |||
If you would like to contribute to the development of OpenStack, you must | |||
follow the steps in this page: | |||
http://docs.openstack.org/infra/manual/developers.html | |||
If you already have a good understanding of how the system works and your | |||
OpenStack accounts are set up, you can skip to the development workflow | |||
section of this documentation to learn how changes to OpenStack should be | |||
submitted for review via the Gerrit tool: | |||
http://docs.openstack.org/infra/manual/developers.html#development-workflow | |||
Pull requests submitted through GitHub will be ignored. | |||
Bugs should be filed on Launchpad, not GitHub: | |||
https://storyboard.openstack.org/#!/project/907 |
@ -1,4 +0,0 @@ | |||
neutron-lbaas-dashboard Style Commandments | |||
========================================== | |||
Read the OpenStack Style Commandments https://docs.openstack.org/hacking/latest/ |
@ -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. | |||
@ -0,0 +1,15 @@ | |||
This project is no longer maintained. | |||
The contents of this repository are still available in the Git | |||
source code management system. To see the contents of this | |||
repository before it reached its end of life, please check out the | |||
previous commit with "git checkout HEAD^1". | |||
The new official OpenStack LBaaS project is Octavia. See the following | |||
resources for more details: | |||
https://wiki.openstack.org/wiki/Neutron/LBaaS/Deprecation | |||
https://governance.openstack.org/tc/reference/projects/octavia.html | |||
For any further questions, please email | |||
openstack-discuss@lists.openstack.org or join #openstack-dev on | |||
Freenode. |
@ -1,101 +0,0 @@ | |||
======================== | |||
Team and repository tags | |||
======================== | |||
.. image:: https://governance.openstack.org/tc/badges/neutron-lbaas-dashboard.svg | |||
:target: https://governance.openstack.org/tc/reference/tags/index.html | |||
.. Change things from this point on | |||
.. warning:: | |||
Neutron-lbaas-dashboard is now deprecated. Please see the FAQ: https://wiki.openstack.org/wiki/Neutron/LBaaS/Deprecation | |||
======================= | |||
neutron-lbaas-dashboard | |||
======================= | |||
Horizon panels for Neutron LBaaS v2 | |||
* Free software: Apache license | |||
* Documentation: https://docs.openstack.org/neutron-lbaas-dashboard/latest/ | |||
* Source: https://opendev.org/openstack/neutron-lbaas-dashboard | |||
* Bugs: https://storyboard.openstack.org/#!/project/907 | |||
Features | |||
-------- | |||
* Please see neutron-lbaas repository | |||
Howto | |||
----- | |||
1. Package the neutron_lbaas_dashboard by running:: | |||
python setup.py sdist | |||
This will create a python egg in the dist folder, which can be used to | |||
install on the horizon machine or within horizon's python virtual | |||
environment. | |||
2. Copy ``_1481_project_ng_loadbalancersv2_panel.py`` in | |||
``neutron_lbaas_dashboard/enabled`` directory | |||
to ``openstack_dashboard/local/enabled``. | |||
3. (Optional) Copy the policy file into horizon's policy files folder, and | |||
add this config ``POLICY_FILES``:: | |||
'neutron_lbaas': 'neutron_lbaas_policy.json', | |||
4. Django has a compressor feature that performs many enhancements for the | |||
delivery of static files. If the compressor feature is enabled in your | |||
environment (``COMPRESS_OFFLINE = True``), run the following commands:: | |||
$ ./manage.py collectstatic | |||
$ ./manage.py compress | |||
5. Finally restart your web server to enable neutron-lbaas-dashboard | |||
in your Horizon:: | |||
$ sudo service apache2 restart | |||
Enabling neutron-lbaas-dashboard and octavia-dashboard | |||
------------------------------------------------------ | |||
In general we advise against having both dashboards running at the same | |||
time to avoid confusing users, which is exaggerated since the dashboards | |||
will have the same label. | |||
In rare circumstances, e.g. as part of a migration strategy, it might be | |||
necessary to do so. The main issue to watch out for is to avoid neutron-lbaas | |||
and Octavia getting out of sync and neutron-lbaas-dashboard showing phantom | |||
load balancers - this can be avoided if the sync between Octavia and | |||
neutron-lbaas is fully enabled. | |||
Here is a table to show some cases: | |||
+---------------+-----------------+----------------+-----------+--------------+ | |||
| Configuration | Configuration | neutron-lbaas- | octavia- | Notes | | |||
| neutron-lbaas | Octavia | dashboard | dashboard | | | |||
| | | enabled | enabled | | | |||
+---------------+-----------------+----------------+-----------+--------------+ | |||
| not installed | v2 API enabled | not supported | preferred | | | |||
+---------------+-----------------+----------------+-----------+--------------+ | |||
| octavia-driver| v2 API disabled | supported | not | sync | | |||
| | v1 API enabled | | supported | required | | |||
+---------------+-----------------+----------------+-----------+--------------+ | |||
| octavia-driver| v2 API enabled | supported | preferred | sync | | |||
| | v1 API enabled | | | required | | |||
+---------------+-----------------+----------------+-----------+--------------+ | |||
| octavia-proxy | v1 API disabled | Supported (but | preferred | | | |||
| plugin | v2 API enabled | not | | | | |||
| | | recommended) | | | | |||
+---------------+-----------------+----------------+-----------+--------------+ | |||
| no octavia | not installed | preferred | not | | | |||
| driver but | | | supported | | | |||
| other drivers | | | | | | |||
+---------------+-----------------+----------------+-----------+--------------+ | |||
| no octavia | v2 API enabled | preferred | preferred | independent | | |||
| driver but | v1 API disabled | | | services | | |||
| other drivers | | | | | | |||
+---------------+-----------------+----------------+-----------+--------------+ |
@ -1,6 +0,0 @@ | |||
[extractors] | |||
django = django_babel.extract:extract_django | |||
[python: **.py] | |||
[django: templates/**.html] | |||
[django: **/templates/**.csv] |
@ -1,14 +0,0 @@ | |||
[extractors] | |||
# We use a custom extractor to find translatable strings in AngularJS | |||
# templates. The extractor is included in horizon.utils for now. | |||
# See http://babel.pocoo.org/docs/messages/#referencing-extraction-methods for | |||
# details on how this works. | |||
angular = horizon.utils.babel_extract_angular:extract_angular | |||
[javascript: **.js] | |||
# We need to look into all static folders for HTML files. | |||
# The **/static ensures that we also search within | |||
# .../dashboards/XYZ/static which will ensure | |||
# that plugins are also translated. | |||
[angular: **/static/**.html] |
@ -1,22 +0,0 @@ | |||
========================================== | |||
Neutron LBaaS v2 dashboard devstack plugin | |||
========================================== | |||
This directory contains the neutron-lbaas-dashboard devstack plugin. | |||
To enable the plugin, add the following to your local.conf: | |||
enable_plugin neutron-lbaas-dashboard <neutron-lbaas-dashboard GITURL> [GITREF] | |||
where | |||
<neutron-lbaas-dashboard GITURL> is the URL of a neutron-lbaas-dashboard repository | |||
[GITREF] is an optional git ref (branch/ref/tag). The default is master. | |||
For example: | |||
enable_plugin neutron-lbaas-dashboard https://opendev.org/openstack/neutron-lbaas-dashboard | |||
Once you enable the plugin in your local.conf, ensure ``horizon`` and | |||
``q-lbaasv2`` services are enabled. If both of them are enabled, | |||
neutron-lbaas-dashboard will be enabled automatically |
@ -1,35 +0,0 @@ | |||
function neutron_lbaas_dashboard_install { | |||
setup_develop $NEUTRON_LBAAS_DASHBOARD_DIR | |||
} | |||
function neutron_lbaas_dashboard_configure { | |||
cp $NEUTRON_LBAAS_DASHBOARD_ENABLE_FILE_PATH \ | |||
$HORIZON_DIR/openstack_dashboard/local/enabled/ | |||
} | |||
if is_service_enabled horizon && is_service_enabled q-lbaasv2; then | |||
if [[ "$1" == "stack" && "$2" == "install" ]]; then | |||
# Perform installation of service source | |||
echo_summary "Installing neutron-lbaas-dashboard" | |||
neutron_lbaas_dashboard_install | |||
elif [[ "$1" == "stack" && "$2" == "post-config" ]]; then | |||
echo_summary "Configuring neutron-lbaas-dashboard" | |||
neutron_lbaas_dashboard_configure | |||
elif [[ "$1" == "stack" && "$2" == "extra" ]]; then | |||
# Initialize and start the LBaaS service | |||
echo_summary "Initializing neutron-lbaas-dashboard" | |||
fi | |||
fi | |||
if [[ "$1" == "unstack" ]]; then | |||
# Shut down LBaaS dashboard services | |||
: | |||
fi | |||
if [[ "$1" == "clean" ]]; then | |||
# Remove state and transient data | |||
# Remember clean.sh first calls unstack.sh | |||
# Remove lbaas-dashboard enabled file and pyc | |||
rm -f "$HORIZON_DIR"/openstack_dashboard/local/enabled/"$NEUTRON_LBAAS_DASHBOARD_ENABLE_FILE_NAME"* | |||
fi |
@ -1,5 +0,0 @@ | |||
NEUTRON_LBAAS_DASHBOARD_DIR=$DEST/neutron-lbaas-dashboard | |||
NEUTRON_LBAAS_DASHBOARD_ENABLE_FILE_NAME=_1481_project_ng_loadbalancersv2_panel.py | |||
NEUTRON_LBAAS_DASHBOARD_ENABLE_FILE_PATH=$NEUTRON_LBAAS_DASHBOARD_DIR/neutron_lbaas_dashboard/enabled/$NEUTRON_LBAAS_DASHBOARD_ENABLE_FILE_NAME |
@ -1,6 +0,0 @@ | |||
# The order of packages is significant, because pip processes them in the order | |||
# of appearance. Changing the order has an impact on the overall integration | |||
# process, which may cause wedges in the gate later. | |||
openstackdocstheme>=1.18.1 # Apache-2.0 | |||
sphinx!=1.6.6,!=1.6.7,>=1.6.2 # BSD | |||
sphinxcontrib-apidoc>=0.2.1 # BSD |
@ -1,115 +0,0 @@ | |||
# -*- coding: utf-8 -*- | |||
# Licensed under the Apache License, Version 2.0 (the "License"); | |||
# you may not use this file except in compliance with the License. | |||
# You may obtain a copy of the License at | |||
# | |||
# http://www.apache.org/licenses/LICENSE-2.0 | |||
# | |||
# Unless required by applicable law or agreed to in writing, software | |||
# distributed under the License is distributed on an "AS IS" BASIS, | |||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | |||
# implied. | |||
# See the License for the specific language governing permissions and | |||
# limitations under the License. | |||
import logging | |||
import os | |||
import sys | |||
import django | |||
sys.path.insert(0, os.path.abspath('../..')) | |||
sys.path.insert(0, os.path.abspath('.')) | |||
logging.getLogger('openstack_dashboard.settings').setLevel(logging.ERROR) | |||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'openstack_dashboard.settings') | |||
django.setup() | |||
# -- General configuration ---------------------------------------------------- | |||
# Add any Sphinx extension module names here, as strings. They can be | |||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones. | |||
extensions = [ | |||
'openstackdocstheme', | |||
'sphinx.ext.autodoc', | |||
'sphinx.ext.coverage', | |||
# 'sphinx.ext.intersphinx', | |||
'sphinx.ext.todo', | |||
'sphinx.ext.viewcode', | |||
'sphinxcontrib.apidoc' | |||
] | |||
# autodoc generation is a bit aggressive and a nuisance when doing heavy | |||
# text edit cycles. | |||
# execute "export SPHINX_DEBUG=1" in your terminal to disable | |||
# The suffix of source filenames. | |||
source_suffix = '.rst' | |||
# The master toctree document. | |||
master_doc = 'index' | |||
# General information about the project. | |||
project = u'neutron-lbaas-dashboard' | |||
copyright = u'2013, OpenStack Foundation' | |||
# If true, '()' will be appended to :func: etc. cross-reference text. | |||
add_function_parentheses = True | |||
# If true, the current module name will be prepended to all description | |||
# unit titles (such as .. function::). | |||
add_module_names = True | |||
# The name of the Pygments (syntax highlighting) style to use. | |||
pygments_style = 'sphinx' | |||
# -- Options for HTML output -------------------------------------------------- | |||
# The theme to use for HTML and HTML Help pages. Major themes that come with | |||
# Sphinx are currently 'default' and 'sphinxdoc'. | |||
# html_theme_path = ["."] | |||
# html_theme = '_theme' | |||
# html_static_path = ['static'] | |||
html_theme = 'openstackdocs' | |||
html_theme_options = { | |||
'display_toc': False | |||
} | |||
html_static_path = [] | |||
# Output file base name for HTML help builder. | |||
htmlhelp_basename = '%sdoc' % project | |||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, | |||
# using the given strftime format. | |||
html_last_updated_fmt = '%Y-%m-%d %H:%M' | |||
# Grouping the document tree into LaTeX files. List of tuples | |||
# (source start file, target name, title, author, documentclass | |||
# [howto/manual]). | |||
latex_documents = [ | |||
('index', | |||
'%s.tex' % project, | |||
u'%s Documentation' % project, | |||
u'OpenStack Foundation', 'manual'), | |||
] | |||
# Example configuration for intersphinx: refer to the Python standard library. | |||
# intersphinx_mapping = {'http://docs.python.org/': None} | |||
# A list of ignored prefixes for module index sorting. | |||
modindex_common_prefix = ['neutron-lbaas-dashboard.'] | |||
apidoc_output_dir = 'contributor/modules' | |||
apidoc_module_dir = '../../neutron_lbaas_dashboard' | |||
apidoc_excluded_paths = [ | |||
'tests', | |||
'enabled', | |||
'locale', | |||
'static', | |||
'post_install.sh' | |||
'karma.conf.js' | |||
] |
@ -1,4 +0,0 @@ | |||
============ | |||
Contributing | |||
============ | |||
.. include:: ../../CONTRIBUTING.rst |
@ -1,21 +0,0 @@ | |||
.. neutron-lbaas-dashboard documentation master file, created by | |||
sphinx-quickstart on Tue Jul 9 22:26:36 2013. | |||
You can adapt this file completely to your liking, but it should at least | |||
contain the root `toctree` directive. | |||
Welcome to neutron-lbaas-dashboard's documentation! | |||
======================================================== | |||
.. warning:: | |||
Neutron-lbaas-dashboard is now deprecated. Please see the FAQ: https://wiki.openstack.org/wiki/Neutron/LBaaS/Deprecation | |||
Contents: | |||
.. toctree:: | |||
:maxdepth: 2 | |||
readme | |||
installation | |||
usage | |||
contributing | |||
reference |
@ -1,28 +0,0 @@ | |||
============ | |||
Installation | |||
============ | |||
.. warning:: | |||
Neutron-lbaas-dashboard is now deprecated. Please see the FAQ: https://wiki.openstack.org/wiki/Neutron/LBaaS/Deprecation | |||
At the command line:: | |||
$ sudo pip install neutron-lbaas-dashboard | |||
Enable the plugin:: | |||
$ cp /usr/local/lib/python2.7/dist-packages/neutron_lbaas_dashboard/enabled/_1481_project_ng_loadbalancersv2_panel.py /opt/stack/horizon/openstack_dashboard/enabled/ | |||
Note: This file may have installed in a different location depending on your | |||
host configuration. For example, on CentOS it may be in | |||
/usr/lib/python2.7/site-packages. | |||
Run the Django update commands (answer 'yes'):: | |||
$ /opt/stack/horizon/manage.py collectstatic | |||
$ /opt/stack/horizon/manage.py compress | |||
Restart Apache:: | |||
$ sudo service apache2 restart |
@ -1 +0,0 @@ | |||
.. include:: ../../README.rst |
@ -1,16 +0,0 @@ | |||
========= | |||
Reference | |||
========= | |||
Indices and search | |||
------------------ | |||
.. toctree:: | |||
:hidden: | |||
contributor/modules/modules | |||
* :ref:`genindex` | |||
* :ref:`modindex` | |||
* :ref:`search` | |||
@ -1,87 +0,0 @@ | |||
========== | |||
User Guide | |||
========== | |||
.. warning:: | |||
Neutron-lbaas-dashboard is now deprecated. Please see the FAQ: https://wiki.openstack.org/wiki/Neutron/LBaaS/Deprecation | |||
Load-Balancer-as-a-Service (LBaaS) enables networking to distribute incoming | |||
requests evenly among designated instances. This distribution ensures that | |||
the workload is shared predictably among instances and enables more effective | |||
use of system resources. Use one of these load-balancing methods to distribute | |||
incoming requests: | |||
* Round robin: Rotates requests evenly between multiple instances. | |||
* Source IP: Requests from a unique source IP address are consistently | |||
directed to the same instance. | |||
* Least connections: Allocates requests to the instance with the | |||
least number of active connections. | |||
As an end user, you can create and manage load balancers and related | |||
objects for users in various projects. You can also delete load balancers | |||
and related objects. | |||
LBaaS v2 has several new concepts to understand: | |||
Load balancer | |||
The load balancer occupies a neutron network port and | |||
has an IP address assigned from a subnet. | |||
Listener | |||
Each port that listens for traffic on a particular load balancer is | |||
configured separately and tied to the load balancer. Multiple listeners can | |||
be associated with the same load balancer. | |||
Pool | |||
A pool is a group of hosts that sits behind the load balancer and | |||
serves traffic through the load balancer. | |||
Member | |||
Members are the actual IP addresses that receive traffic from | |||
the load balancer. Members are associated with pools. | |||
Health monitor | |||
Members may go offline from time to time and health monitors | |||
diverts traffic away from members that are not responding properly. | |||
Health monitors are associated with pools. | |||
View existing load balancers | |||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |||
#. Log in to the OpenStack dashboard. | |||
#. On the :guilabel:`Project` tab, open the | |||
:guilabel:`Network` tab, and click the | |||
:guilabel:`Load Balancers` category. | |||
This view shows the list of existing load balancers. To view details | |||
of any of the load balancers, click on the specific load balancer. | |||
Create a load balancer | |||
~~~~~~~~~~~~~~~~~~~~~~ | |||
#. Log in to the OpenStack dashboard. | |||
#. On the :guilabel:`Project` tab, open the | |||
:guilabel:`Network` tab, and click the | |||
:guilabel:`Load Balancers` category. | |||
#. Click the :guilabel:`Create Load Balancer` button. | |||
Use the concepts described in the overview section to fill in | |||
the necessary information about the load balancer you want to create. | |||
Keep in mind, the health checks routinely run against each instance | |||
within a target load balancer and the result of the health check is | |||
used to determine if the instance receives new connections. | |||
.. note:: | |||
A message indicates whether the action succeeded. | |||
Delete a load balancer | |||
~~~~~~~~~~~~~~~~~~~~~~ | |||
#. Select the load balancer you want to delete | |||
and click the :guilabel:`Delete Load Balancer` button. | |||
To be deleted successfully, a load balancer must not | |||
have any listeners or pools associated with | |||
it. The delete action is also available in the | |||
:guilabel:`Actions` column for the individual load balancers. |
@ -1,147 +0,0 @@ | |||
amqp==2.1.1 | |||
appdirs==1.3.0 | |||
asn1crypto==0.23.0 | |||
Babel==2.3.4 | |||
cachetools==2.0.0 | |||
cffi==1.7.0 | |||
cliff==2.8.0 | |||
cmd2==0.8.0 | |||
contextlib2==0.4.0 | |||
coverage==4.0 | |||
cryptography==2.1 | |||
ddt==1.0.1 | |||
debtcollector==1.2.0 | |||
decorator==3.4.0 | |||
deprecation==1.0 | |||
Django==1.8 | |||
django-appconf==1.0.2 | |||
django-babel==0.5.1 | |||
django-compressor==2.0 | |||
django-pyscss==2.0.2 | |||
dogpile.cache==0.6.2 | |||
eventlet==0.18.2 | |||
extras==1.0.0 | |||
fasteners==0.7.0 | |||
fixtures==3.0.0 | |||
flake8==2.5.5 | |||
futurist==1.2.0 | |||
greenlet==0.4.10 | |||
hacking==0.12.0 | |||
horizon==14.0.0.0b3 | |||
idna==2.6 | |||
iso8601==0.1.11 | |||
Jinja2==2.10 | |||
jmespath==0.9.0 | |||
jsonpatch==1.16 | |||
jsonpointer==1.13 | |||
jsonschema==2.6.0 | |||
keystoneauth1==3.4.0 | |||
kombu==4.0.0 | |||
linecache2==1.0.0 | |||
MarkupSafe==1.0 | |||
mccabe==0.2.1 | |||
mock==2.0.0 | |||
monotonic==0.6 | |||
mox3==0.20.0 | |||
msgpack-python==0.4.0 | |||
munch==2.1.0 | |||
netaddr==0.7.18 | |||
netifaces==0.10.4 | |||
openstacksdk==0.11.2 | |||
os-client-config==1.28.0 | |||
os-service-types==1.2.0 | |||
osc-lib==1.8.0 | |||
oslo.concurrency==3.25.0 | |||
oslo.config==5.2.0 | |||
oslo.context==2.19.2 | |||
oslo.i18n==3.15.3 | |||
oslo.log==3.36.0 | |||
oslo.messaging==5.29.0 | |||
oslo.middleware==3.31.0 | |||
oslo.policy==1.30.0 | |||
oslo.serialization==2.18.0 | |||
oslo.service==1.24.0 | |||
oslo.utils==3.33.0 | |||
oslotest==3.2.0 | |||
osprofiler==1.4.0 | |||
Paste==2.0.2 | |||
PasteDeploy==1.5.0 | |||
pbr==2.0.0 | |||
pep8==1.5.7 | |||
pika==0.10.0 | |||
pika-pool==0.1.3 | |||
Pint==0.5 | |||
positional==1.2.1 | |||
prettytable==0.7.2 | |||
pycparser==2.18 | |||
pyflakes==0.8.1 | |||
pyinotify==0.9.6 | |||
pymongo==3.0.2 | |||
pyOpenSSL==17.1.0 | |||
pyparsing==2.1.0 | |||
pyperclip==1.5.27 | |||
pyScss==1.3.4 | |||
python-barbicanclient==4.5.2 | |||
python-cinderclient==3.3.0 | |||
python-dateutil==2.5.3 | |||
python-glanceclient==2.8.0 | |||
python-keystoneclient==3.8.0 | |||
python-mimeparse==1.6.0 | |||
python-neutronclient==6.7.0 | |||
python-novaclient==9.1.0 | |||
python-subunit==1.0.0 | |||
python-swiftclient==3.2.0 | |||
pytz==2013.6 | |||
PyYAML==3.12 | |||
rcssmin==1.0.6 | |||
repoze.lru==0.7 | |||
requests==2.14.2 | |||
requestsexceptions==1.2.0 | |||
rfc3986==0.3.1 | |||
rjsmin==1.0.12 | |||
Routes==2.3.1 | |||
selenium==2.50.1 | |||
semantic-version==2.3.1 | |||
simplejson==3.5.1 | |||
six==1.10.0 | |||
sphinxcontrib-apidoc===0.2.1 | |||
statsd==3.2.1 | |||
stevedore==1.20.0 | |||
tenacity==3.2.1 | |||
testscenarios==0.4 | |||
testtools==2.2.0 | |||
traceback2==1.4.0 | |||
unittest2==1.1.0 | |||
vine==1.1.4 | |||
warlock==1.2.0 | |||
WebOb==1.7.1 | |||
wrapt==1.7.0 | |||
XStatic==1.0.0 | |||
XStatic-Angular==1.5.8.0 | |||
XStatic-Angular-Bootstrap==2.2.0.0 | |||
XStatic-Angular-FileUpload==12.0.4.0 | |||
XStatic-Angular-Gettext==2.3.8.0 | |||
XStatic-Angular-lrdragndrop==1.0.2.2 | |||
XStatic-Angular-Schema-Form==0.8.13.0 | |||
XStatic-Bootstrap-Datepicker==1.3.1.0 | |||
XStatic-Bootstrap-SCSS==3.3.7.1 | |||
XStatic-bootswatch==3.3.7.0 | |||
XStatic-D3==3.5.17.0 | |||
XStatic-Font-Awesome==4.7.0.0 | |||
XStatic-Hogan==2.0.0.2 | |||
XStatic-Jasmine==2.4.1.1 | |||
XStatic-jQuery==1.8.2.1 | |||
XStatic-JQuery-Migrate==1.2.1.1 | |||
XStatic-jquery-ui==1.10.4.1 | |||
XStatic-JQuery.quicksearch==2.0.3.1 | |||
XStatic-JQuery.TableSorter==2.14.5.1 | |||
XStatic-JSEncrypt==2.3.1.1 | |||
XStatic-mdi==1.4.57.0 | |||
XStatic-objectpath==1.2.1.0 | |||
XStatic-Rickshaw==1.5.0.0 | |||
XStatic-roboto-fontface==0.5.0.0 | |||
XStatic-smart-table==1.4.13.2 | |||
XStatic-Spin==1.2.5.2 | |||
XStatic-term.js==0.0.7.0 | |||
XStatic-tv4==1.2.7.0 | |||
xvfbwrapper==0.1.3 |
@ -1,23 +0,0 @@ | |||
#!/usr/bin/env python | |||
# Licensed under the Apache License, Version 2.0 (the "License"); you may | |||
# not use this file except in compliance with the License. You may obtain | |||
# a copy of the License at | |||
# | |||
# http://www.apache.org/licenses/LICENSE-2.0 | |||
# | |||
# Unless required by applicable law or agreed to in writing, software | |||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||
# License for the specific language governing permissions and limitations | |||
# under the License. | |||
import os | |||
import sys | |||
from django.core.management import execute_from_command_line # noqa | |||
if __name__ == "__main__": | |||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", | |||
"openstack_dashboard.settings") | |||
execute_from_command_line(sys.argv) |
@ -1,16 +0,0 @@ | |||
# Licensed under the Apache License, Version 2.0 (the "License"); you may | |||
# not use this file except in compliance with the License. You may obtain | |||
# a copy of the License at | |||
# | |||
# http://www.apache.org/licenses/LICENSE-2.0 | |||
# | |||
# Unless required by applicable law or agreed to in writing, software | |||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||
# License for the specific language governing permissions and limitations | |||
# under the License. | |||
import pbr.version | |||
__version__ = pbr.version.VersionInfo( | |||
'neutron_lbaas_dashboard').version_string() |
@ -1,26 +0,0 @@ | |||
# Copyright 2015 IBM Corp. | |||
# | |||
# 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. | |||
"""This package holds the REST API that supports the LBaaS v2 dashboard | |||
Javascript code. | |||
It is not intended to be used outside of Horizon, and makes no promises of | |||
stability or fitness for purpose outside of that scope. | |||
It does not promise to adhere to the general OpenStack API Guidelines set out | |||
in https://wiki.openstack.org/wiki/APIChangeGuidelines. | |||
""" | |||
# import REST API modules here | |||
from neutron_lbaas_dashboard.api.rest import barbican # noqa | |||
from neutron_lbaas_dashboard.api.rest import nlbaasv2 # noqa |
@ -1,95 +0,0 @@ | |||
# Copyright 2016 IBM Corp. | |||
# | |||
# 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. | |||
"""API over the barbican service. | |||
""" | |||
from barbicanclient import client as barbican_client | |||
from django.conf import settings | |||
from django.views import generic | |||
from keystoneclient.auth.identity import v2 as auth_v2 | |||
from keystoneclient.auth.identity import v3 as auth_v3 | |||
from keystoneclient import session | |||
from horizon.utils.memoized import memoized # noqa | |||
from openstack_dashboard.api import base | |||
from openstack_dashboard.api import keystone | |||
from openstack_dashboard.api.rest import urls | |||
from openstack_dashboard.api.rest import utils as rest_utils | |||
@memoized | |||
def barbicanclient(request): | |||
project_id = request.user.project_id | |||
region = request.user.services_region | |||
endpoint = base.url_for(request, 'key-manager') | |||
if keystone.get_version() < 3: | |||
auth = auth_v2.Token(settings.OPENSTACK_KEYSTONE_URL, | |||
request.user.token.id, | |||
tenant_id=project_id) | |||
else: | |||
domain_id = request.session.get('domain_context') | |||
auth = auth_v3.Token(settings.OPENSTACK_KEYSTONE_URL, | |||
request.user.token.id, | |||
project_id=project_id, | |||
project_domain_id=domain_id) | |||
insecure = getattr(settings, 'OPENSTACK_SSL_NO_VERIFY', False) | |||
cacert = getattr(settings, 'OPENSTACK_SSL_CACERT', None) | |||
# If 'insecure' is True, 'verify' is False in all cases; otherwise | |||
# pass the cacert path if it is present, or True if no cacert. | |||
verify = not insecure and (cacert or True) | |||
return barbican_client.Client(session=session.Session(auth=auth, | |||
verify=verify), | |||
endpoint=endpoint, | |||
region_name=region) | |||
@urls.register | |||
class SSLCertificates(generic.View): | |||
"""API for working with SSL certificate containers. | |||
""" | |||
url_regex = r'barbican/certificates/$' | |||
@rest_utils.ajax() | |||
def get(self, request): | |||
"""List certificate containers. | |||
The listing result is an object with property "items". | |||
""" | |||
limit = getattr(settings, 'API_RESULT_LIMIT', 1000) | |||
containers = barbicanclient(request).containers | |||
params = {'limit': limit, 'type': 'certificate'} | |||
result = containers._api.get('containers', params=params) | |||
return {'items': result.get('containers')} | |||
@urls.register | |||
class Secrets(generic.View): | |||
"""API for working with secrets. | |||
""" | |||
url_regex = r'barbican/secrets/$' | |||
@rest_utils.ajax() | |||
def get(self, request): | |||
"""List secrets. | |||
The listing result is an object with property "items". | |||
""" | |||
limit = getattr(settings, 'API_RESULT_LIMIT', 1000) | |||
secrets = barbicanclient(request).secrets | |||
params = {'limit': limit} | |||
result = secrets._api.get('secrets', params=params) | |||
return {'items': result.get('secrets')} |
@ -1,780 +0,0 @@ | |||
# Copyright 2015 IBM Corp. | |||
# | |||
# 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. | |||
"""API over the neutron LBaaS v2 service. | |||
""" | |||
from six.moves import _thread as thread | |||
from time import sleep | |||
from django.views import generic | |||
from horizon import conf | |||
from openstack_dashboard.api import neutron | |||
from openstack_dashboard.api.rest import urls | |||
from openstack_dashboard.api.rest import utils as rest_utils | |||
neutronclient = neutron.neutronclient | |||
def poll_loadbalancer_status(request, loadbalancer_id, callback, | |||
from_state='PENDING_UPDATE', to_state='ACTIVE', | |||
callback_kwargs=None): | |||
"""Poll for the status of the load balancer. | |||
Polls for the status of the load balancer and calls a function when the | |||
status changes to a specified state. | |||
:param request: django request object | |||
:param loadbalancer_id: id of the load balancer to poll | |||
:param callback: function to call when polling is complete | |||
:param from_state: initial expected state of the load balancer | |||
:param to_state: state to check for | |||
:param callback_kwargs: kwargs to pass into the callback function | |||
""" | |||
interval = conf.HORIZON_CONFIG['ajax_poll_interval'] / 1000.0 | |||
status = from_state | |||
while status == from_state: | |||
sleep(interval) | |||
lb = neutronclient(request).show_loadbalancer( | |||
loadbalancer_id).get('loadbalancer') | |||
status = lb['provisioning_status'] | |||
if status == to_state: | |||
kwargs = {'loadbalancer_id': loadbalancer_id} | |||
if callback_kwargs: | |||
kwargs.update(callback_kwargs) | |||
callback(request, **kwargs) | |||
def create_loadbalancer(request): | |||
data = request.DATA | |||
spec = { | |||
'vip_subnet_id': data['loadbalancer']['subnet'] | |||
} | |||
if data['loadbalancer'].get('name'): | |||
spec['name'] = data['loadbalancer']['name'] | |||
if data['loadbalancer'].get('description'): | |||
spec['description'] = data['loadbalancer']['description'] | |||
if data['loadbalancer'].get('ip'): | |||
spec['vip_address'] = data['loadbalancer']['ip'] | |||
loadbalancer = neutronclient(request).create_loadbalancer( | |||
{'loadbalancer': spec}).get('loadbalancer') | |||
if data.get('listener'): | |||
# There is work underway to add a new API to LBaaS v2 that will | |||
# allow us to pass in all information at once. Until that is | |||
# available we use a separate thread to poll for the load | |||
# balancer status and create the other resources when it becomes | |||
# active. | |||
args = (request, loadbalancer['id'], create_listener) | |||
kwargs = {'from_state': 'PENDING_CREATE'} | |||
thread.start_new_thread(poll_loadbalancer_status, args, kwargs) | |||
return loadbalancer | |||
def create_listener(request, **kwargs): | |||
"""Create a new listener. | |||
""" | |||
data = request.DATA | |||
listenerSpec = { | |||
'protocol': data['listener']['protocol'], | |||
'protocol_port': data['listener']['port'], | |||
'loadbalancer_id': kwargs['loadbalancer_id'] | |||
} | |||
if data['listener'].get('name'): | |||
listenerSpec['name'] = data['listener']['name'] | |||
if data['listener'].get('description'): | |||
listenerSpec['description'] = data['listener']['description'] | |||
if data.get('certificates'): | |||
listenerSpec['default_tls_container_ref'] = data['certificates'][0] | |||
listenerSpec['sni_container_refs'] = data['certificates'] | |||
listener = neutronclient(request).create_listener( | |||
{'listener': listenerSpec}).get('listener') | |||
if data.get('pool'): | |||
args = (request, kwargs['loadbalancer_id'], create_pool) | |||
kwargs = {'callback_kwargs': {'listener_id': listener['id']}} | |||
thread.start_new_thread(poll_loadbalancer_status, args, kwargs) | |||
return listener | |||
def create_pool(request, **kwargs): | |||
"""Create a new pool. | |||
""" | |||
data = request.DATA | |||
poolSpec = { | |||
'protocol': data['pool']['protocol'], | |||
'lb_algorithm': data['pool']['method'], | |||
'listener_id': kwargs['listener_id'] | |||
} | |||
if data['pool'].get('name'): | |||
poolSpec['name'] = data['pool']['name'] | |||
if data['pool'].get('description'): | |||
poolSpec['description'] = data['pool']['description'] | |||
pool = neutronclient(request).create_lbaas_pool( | |||
{'pool': poolSpec}).get('pool') | |||
if data.get('members'): | |||
args = (request, kwargs['loadbalancer_id'], add_member) | |||
kwargs = {'callback_kwargs': {'pool_id': pool['id'], | |||
'index': 0}} | |||
thread.start_new_thread(poll_loadbalancer_status, args, kwargs) | |||
elif data.get('monitor'): | |||
args = (request, kwargs['loadbalancer_id'], create_health_monitor) | |||
kwargs = {'callback_kwargs': {'pool_id': pool['id']}} | |||
thread.start_new_thread(poll_loadbalancer_status, args, kwargs) | |||
return pool | |||
def create_health_monitor(request, **kwargs): | |||
"""Create a new health monitor for a pool. | |||
""" | |||
data = request.DATA | |||
monitorSpec = { | |||
'type': data['monitor']['type'], | |||
'delay': data['monitor']['interval'], | |||
'timeout': data['monitor']['timeout'], | |||
'max_retries': data['monitor']['retry'], | |||
'pool_id': kwargs['pool_id'] | |||
} | |||
if data['monitor'].get('method'): | |||
monitorSpec['http_method'] = data['monitor']['method'] | |||
if data['monitor'].get('path'): | |||
monitorSpec['url_path'] = data['monitor']['path'] | |||
if data['monitor'].get('status'): | |||
monitorSpec['expected_codes'] = data['monitor']['status'] | |||
return neutronclient(request).create_lbaas_healthmonitor( | |||
{'healthmonitor': monitorSpec}).get('healthmonitor') | |||
def add_member(request, **kwargs): | |||
"""Add a member to a pool. | |||
""" | |||
data = request.DATA | |||
members = data.get('members') | |||
pool_id = kwargs.get('pool_id') | |||
if kwargs.get('members_to_add'): | |||
members_to_add = kwargs['members_to_add'] | |||
index = [members.index(member) for member in members | |||
if member['id'] == members_to_add[0]][0] | |||
loadbalancer_id = data.get('loadbalancer_id') | |||
else: | |||
index = kwargs.get('index') | |||
loadbalancer_id = kwargs.get('loadbalancer_id') | |||
member = members[index] | |||
memberSpec = { | |||
'address': member['address'], | |||
'protocol_port': member['port'], | |||
'subnet_id': member['subnet'] | |||
} | |||
if member.get('weight'): | |||
memberSpec['weight'] = member['weight'] | |||
member = neutronclient(request).create_lbaas_member( | |||
pool_id, {'member': memberSpec}).get('member') | |||
index += 1 | |||
if kwargs.get('members_to_add'): | |||
args = (request, loadbalancer_id, update_member_list) | |||
members_to_add = kwargs['members_to_add'] | |||
members_to_add.pop(0) | |||
kwargs = {'callback_kwargs': { | |||
'existing_members': kwargs.get('existing_members'), | |||
'members_to_add': members_to_add, | |||
'members_to_delete': kwargs.get('members_to_delete'), | |||
'pool_id': pool_id}} | |||
thread.start_new_thread(poll_loadbalancer_status, args, kwargs) | |||
elif len(members) > index: | |||
args = (request, loadbalancer_id, add_member) | |||
kwargs = {'callback_kwargs': {'pool_id': pool_id, | |||
'index': index}} | |||
thread.start_new_thread(poll_loadbalancer_status, args, kwargs) | |||
elif data.get('monitor'): | |||
args = (request, loadbalancer_id, create_health_monitor) | |||
kwargs = {'callback_kwargs': {'pool_id': pool_id}} | |||
thread.start_new_thread(poll_loadbalancer_status, args, kwargs) | |||
return member | |||
def remove_member(request, **kwargs): | |||
"""Remove a member from the pool. | |||
""" | |||
data = request.DATA | |||
loadbalancer_id = data.get('loadbalancer_id') | |||
pool_id = kwargs.get('pool_id') | |||
if kwargs.get('members_to_delete'): | |||
members_to_delete = kwargs['members_to_delete'] | |||
member_id = members_to_delete.pop(0) | |||
neutronclient(request).delete_lbaas_member(member_id, pool_id) | |||
args = (request, loadbalancer_id, update_member_list) | |||
kwargs = {'callback_kwargs': { | |||
'existing_members': kwargs.get('existing_members'), | |||
'members_to_add': kwargs.get('members_to_add'), | |||
'members_to_delete': members_to_delete}} | |||
thread.start_new_thread(poll_loadbalancer_status, args, kwargs) | |||
def update_loadbalancer(request, **kwargs): | |||
"""Update a load balancer. | |||
""" | |||
data = request.DATA | |||
spec = {} | |||
loadbalancer_id = kwargs.get('loadbalancer_id') | |||
if data['loadbalancer'].get('name'): | |||
spec['name'] = data['loadbalancer']['name'] | |||
if data['loadbalancer'].get('description'): | |||
spec['description'] = data['loadbalancer']['description'] | |||
return neutronclient(request).update_loadbalancer( | |||
loadbalancer_id, {'loadbalancer': spec}).get('loadbalancer') | |||
def update_listener(request, **kwargs): | |||
"""Update a listener. | |||
""" | |||
data = request.DATA | |||
listener_spec = {} | |||
listener_id = data['listener'].get('id') | |||
loadbalancer_id = data.get('loadbalancer_id') | |||
if data['listener'].get('name'): | |||
listener_spec['name'] = data['listener']['name'] | |||
if data['listener'].get('description'): | |||
listener_spec['description'] = data['listener']['description'] | |||
if data.get('certificates'): | |||
listener_spec['default_tls_container_ref'] = data['certificates'][0] | |||
listener_spec['sni_container_refs'] = data['certificates'] | |||
listener = neutronclient(request).update_listener( | |||
listener_id, {'listener': listener_spec}).get('listener') | |||
if data.get('pool'): | |||
args = (request, loadbalancer_id, update_pool) | |||
thread.start_new_thread(poll_loadbalancer_status, args) | |||
return listener | |||
def update_pool(request, **kwargs): | |||
"""Update a pool. | |||
""" | |||
data = request.DATA | |||
pool_spec = {} | |||
pool_id = data['pool'].get('id') | |||
loadbalancer_id = data.get('loadbalancer_id') | |||
if data['pool'].get('name'): | |||
pool_spec['name'] = data['pool']['name'] | |||
if data['pool'].get('description'): | |||
pool_spec['description'] = data['pool']['description'] | |||
pools = neutronclient(request).update_lbaas_pool( | |||
pool_id, {'pool': pool_spec}).get('pools') | |||
# Assemble the lists of member id's to add and remove, if any exist | |||
tenant_id = request.user.project_id | |||
request_member_data = data.get('members', []) | |||
existing_members = neutronclient(request).list_lbaas_members( | |||
pool_id, tenant_id=tenant_id).get('members') | |||
(members_to_add, members_to_delete) = get_members_to_add_remove( | |||
request_member_data, existing_members) | |||
if members_to_add or members_to_delete: | |||
args = (request, loadbalancer_id, update_member_list) | |||
kwargs = {'callback_kwargs': {'existing_members': existing_members, | |||
'members_to_add': members_to_add, | |||
'members_to_delete': members_to_delete, | |||
'pool_id': pool_id}} | |||
thread.start_new_thread(poll_loadbalancer_status, args, kwargs) | |||
elif data.get('monitor'): | |||
args = (request, loadbalancer_id, update_monitor) | |||
thread.start_new_thread(poll_loadbalancer_status, args) | |||
return pools | |||
def update_monitor(request, **kwargs): | |||
"""Update a health monitor. | |||
""" | |||
data = request.DATA | |||
monitor_spec = {} | |||
monitor_id = data['monitor']['id'] | |||
if data['monitor'].get('interval'): | |||
monitor_spec['delay'] = data['monitor']['interval'] | |||
if data['monitor'].get('timeout'): | |||
monitor_spec['timeout'] = data['monitor']['timeout'] | |||
if data['monitor'].get('retry'): | |||
monitor_spec['max_retries'] = data['monitor']['retry'] | |||
if data['monitor'].get('method'): | |||
monitor_spec['http_method'] = data['monitor']['method'] | |||
if data['monitor'].get('path'): | |||
monitor_spec['url_path'] = data['monitor']['path'] | |||
if data['monitor'].get('status'): | |||
monitor_spec['expected_codes'] = data['monitor']['status'] | |||
healthmonitor = neutronclient(request).update_lbaas_healthmonitor( | |||
monitor_id, {'healthmonitor': monitor_spec}).get('healthmonitor') | |||
return healthmonitor | |||
def update_member_list(request, **kwargs): | |||
"""Update the list of members by adding or removing the necessary members. | |||
""" | |||
data = request.DATA | |||
loadbalancer_id = data.get('loadbalancer_id') | |||
pool_id = kwargs.get('pool_id') | |||
existing_members = kwargs.get('existing_members') | |||
members_to_add = kwargs.get('members_to_add') | |||
members_to_delete = kwargs.get('members_to_delete') | |||
if members_to_delete: | |||
kwargs = {'existing_members': existing_members, | |||
'members_to_add': members_to_add, | |||
'members_to_delete': members_to_delete, | |||
'pool_id': pool_id} | |||
remove_member(request, **kwargs) | |||
elif members_to_add: | |||
kwargs = {'existing_members': existing_members, | |||
'members_to_add': members_to_add, | |||
'members_to_delete': members_to_delete, | |||
'pool_id': pool_id} | |||
add_member(request, **kwargs) | |||
elif data.get('monitor'): | |||
args = (request, loadbalancer_id, update_monitor) | |||
thread.start_new_thread(poll_loadbalancer_status, args) | |||
def get_members_to_add_remove(request_member_data, existing_members): | |||
new_member_ids = [member['id'] for member in request_member_data] | |||
existing_member_ids = [member['id'] for member in existing_members] | |||
members_to_add = [member_id for member_id in new_member_ids | |||
if member_id not in existing_member_ids] | |||
members_to_delete = [member_id for member_id in existing_member_ids | |||
if member_id not in new_member_ids] | |||
return members_to_add, members_to_delete | |||
def add_floating_ip_info(request, loadbalancers): | |||
"""Add floating IP address info to each load balancer. | |||
""" | |||
floating_ips = neutron.tenant_floating_ip_list(request) | |||
for lb in loadbalancers: | |||
floating_ip = {} | |||
associated_ip = next((fip for fip in floating_ips | |||
if fip['fixed_ip'] == lb['vip_address']), None) | |||
if associated_ip is not None: | |||
floating_ip['id'] = associated_ip['id'] | |||
floating_ip['ip'] = associated_ip['ip'] | |||
lb['floating_ip'] = floating_ip | |||
@urls.register | |||
class LoadBalancers(generic.View): | |||
"""API for load balancers. | |||
""" | |||
url_regex = r'nlbaas/loadbalancers/$' | |||
@rest_utils.ajax() | |||
def get(self, request): | |||
"""List load balancers for current project. | |||
The listing result is an object with property "items". | |||
""" | |||
tenant_id = request.user.project_id | |||
loadbalancers = neutronclient(request).list_loadbalancers( | |||
tenant_id=tenant_id).get('loadbalancers') | |||
if request.GET.get('full') and neutron.floating_ip_supported(request): | |||
add_floating_ip_info(request, loadbalancers) | |||
return {'items': loadbalancers} | |||
@rest_utils.ajax() | |||
def post(self, request): | |||
"""Create a new load balancer. | |||
Creates a new load balancer as well as other optional resources such as | |||
a listener, pool, monitor, etc. | |||
""" | |||
return create_loadbalancer(request) | |||
@urls.register | |||
class LoadBalancerStatusTree(generic.View): | |||
"""API for retrieving the resource status tree for a single load balancer. | |||
""" | |||
url_regex = r'nlbaas/loadbalancers/(?P<loadbalancer_id>[^/]+)/statuses/$' | |||
@rest_utils.ajax() | |||
def get(self, request, loadbalancer_id): | |||
"""Get the status tree for a specific load balancer. | |||
http://localhost/api/nlbaas/loadbalancers/cc758c90-3d98-4ea1-af44-aab405c9c915/statuses | |||
""" | |||
return neutronclient(request).retrieve_loadbalancer_status( | |||
loadbalancer_id) | |||
@urls.register | |||
class LoadBalancer(generic.View): | |||
"""API for retrieving, updating, and deleting a single load balancer. | |||
""" | |||
url_regex = r'nlbaas/loadbalancers/(?P<loadbalancer_id>[^/]+)/$' | |||
@rest_utils.ajax() | |||
def get(self, request, loadbalancer_id): | |||
"""Get a specific load balancer. | |||
http://localhost/api/nlbaas/loadbalancers/cc758c90-3d98-4ea1-af44-aab405c9c915 | |||
""" | |||
loadbalancer = neutronclient(request).show_loadbalancer( | |||
loadbalancer_id).get('loadbalancer') | |||
if request.GET.get('full') and neutron.floating_ip_supported(request): | |||
add_floating_ip_info(request, [loadbalancer]) | |||
return loadbalancer | |||
@rest_utils.ajax() | |||
def put(self, request, loadbalancer_id): | |||
"""Edit a load balancer. | |||
""" | |||
kwargs = {'loadbalancer_id': loadbalancer_id} | |||
update_loadbalancer(request, **kwargs) | |||
@rest_utils.ajax() | |||
def delete(self, request, loadbalancer_id): | |||
"""Delete a specific load balancer. | |||
http://localhost/api/nlbaas/loadbalancers/cc758c90-3d98-4ea1-af44-aab405c9c915 | |||
""" | |||
neutronclient(request).delete_loadbalancer(loadbalancer_id) | |||
@urls.register | |||
class Listeners(generic.View) |