Merge topic 'lbaas_python'

* changes:
  Fixing LBaaS package issues
  Fixing F5 package issue
  Adding F5 based LBaaS murano app
This commit is contained in:
Sergey Kraynev 2016-04-22 15:54:17 +04:00 committed by Gerrit Code Review
commit 7b44f31f44
36 changed files with 992 additions and 5 deletions

1
murano-apps/F5-based-LBaaS/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
F5_based_LBaaS.zip

View File

@ -0,0 +1,36 @@
# Stop the script if an error occurs.
set -e
function cleanup {
cd $SCRIPTPATH
rm -rf tmp
}
# In case if script is running not where it is located.
cd $(dirname $0)
SCRIPTPATH=`pwd`
# Cleanup tmp dir on script exit.
trap 'cleanup' EXIT
mkdir tmp
pushd package
cp -v -r Classes Resources UI manifest.yaml logo.png ../tmp/
popd
archive_name=f5-lbaas-driver.tar.gz
f5_directory_name=f5_lbaas_driver-0.0.1
# Pack python tarball.
pushd tmp/Resources/scripts
tar -czvf $archive_name $f5_directory_name/*
base64 $archive_name > $archive_name.bs64
rm -rf $f5_directory_name
rm -rf $archive_name
popd
# Make murano package.
pushd tmp
zip -r ../F5_based_LBaaS.zip .
popd

View File

@ -0,0 +1,61 @@
# 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.
Namespaces:
=: io.murano.apps.lbaas
std: io.murano
sys: io.murano.system
Name: F5BigIPLTM
Extends: LBaaS
Properties:
host:
Contract: $.string().notNull()
username:
Contract: $.string().notNull()
password:
Contract: $.string().notNull()
Methods:
.init:
Body:
- $.implementation: f5ltm
installLBaaS:
Body:
- $lbaas: $.cast(LBaaS).installLBaaS()
- $resources: new(sys:Resources)
- $template: $resources.yaml('DeployF5Driver.template')
- $.environment.reporter.report($this, 'Installing F5 driver for LBaaS...')
- $.instance.agent.call($template, $resources)
- $.environment.reporter.report($this, 'F5 driver is installed.')
- Return: $lbaas
getOptionalConfig:
Body:
- Return:
- section: lbaas_f5
key: host
value: $.host
- section: lbaas_f5
key: username
value: $.username
- section: lbaas_f5
key: password
value: $.password

View File

@ -0,0 +1,18 @@
FormatVersion: 2.0.0
Version: 1.0.0
Name: Deploy F5 Driver
Body: |
return F5DriverDeploy().stdout
Scripts:
F5DriverDeploy:
Type: Application
Version: 1.0.0
EntryPoint: deployF5Driver.sh
Files:
- <f5-lbaas-driver.tar.gz.bs64>
- f5-lbaas-append.conf.sample
Options:
captureStdout: true
captureStderr: true

View File

@ -0,0 +1,13 @@
# Fail script if an error occurs.
set -e
# TODO(nmakhotkin): It should be removed in the future after fixing the bug:
# TODO(nmakhotkin): https://bugs.launchpad.net/murano/+bug/1561522
# TODO(nmakhotkin): Here should be used pure tar.gz archive instead of base64-encoded.
base64 --decode f5-lbaas-driver.tar.gz.bs64 > f5-lbaas-driver.tar.gz
# Installing LBaaS API.
sudo pip install f5-lbaas-driver.tar.gz
# Adding a new config section to main config.
cat f5-lbaas-append.conf.sample >> /etc/lbaas/lbaas.conf

View File

@ -0,0 +1,4 @@
[lbaas_f5]
host = host
username = user
password = password

View File

@ -0,0 +1 @@
Nikolay Mahotkin <nmakhotkin@mirantis.com>

View File

@ -0,0 +1,8 @@
CHANGES
=======
* Fixing issues
* Restrict requirements.txt
* Added AUTHORS and ChangeLog
* Initial version of F5 BIG LTM driver for LBaaS API
* Initial commit

View File

@ -0,0 +1,13 @@
Metadata-Version: 1.0
Name: f5_lbaas_driver
Version: 0.0.1.dev4
Summary: LBaaS Project
Home-page: UNKNOWN
Author: Mirantis Inc.
Author-email: nmakhotkin@mirantis.com
License: Apache License, Version 2.0
Description: # f5-lbaas-driver
F5 BIG IP LTM implementation for lbaas-api
Platform: UNKNOWN

View File

@ -0,0 +1,2 @@
# f5-lbaas-driver
F5 BIG IP LTM implementation for lbaas-api

View File

@ -0,0 +1,13 @@
Metadata-Version: 1.0
Name: f5-lbaas-driver
Version: 0.0.1.dev4
Summary: LBaaS Project
Home-page: UNKNOWN
Author: Mirantis Inc.
Author-email: nmakhotkin@mirantis.com
License: Apache License, Version 2.0
Description: # f5-lbaas-driver
F5 BIG IP LTM implementation for lbaas-api
Platform: UNKNOWN

View File

@ -0,0 +1,16 @@
AUTHORS
ChangeLog
README.md
requirements.txt
setup.cfg
setup.py
f5_lbaas_driver/__init__.py
f5_lbaas_driver/f5ltm.py
f5_lbaas_driver.egg-info/PKG-INFO
f5_lbaas_driver.egg-info/SOURCES.txt
f5_lbaas_driver.egg-info/dependency_links.txt
f5_lbaas_driver.egg-info/entry_points.txt
f5_lbaas_driver.egg-info/not-zip-safe
f5_lbaas_driver.egg-info/pbr.json
f5_lbaas_driver.egg-info/requires.txt
f5_lbaas_driver.egg-info/top_level.txt

View File

@ -0,0 +1,3 @@
[lbaas.drivers]
f5ltm = f5_lbaas_driver.f5ltm:F5Driver

View File

@ -0,0 +1 @@
{"is_release": false, "git_version": "5e3cafd"}

View File

@ -0,0 +1,3 @@
f5-sdk>=0.1
requests!=2.9.0,>=2.8.1
oslo.config>=3.7.0

View File

@ -0,0 +1,376 @@
# Copyright 2016 - Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import json
from f5 import bigip
from oslo_config import cfg
from oslo_log import log as logging
import requests
from lbaas import config
from lbaas.drivers import base
bigip_opts = [
cfg.StrOpt('host', help='BIG IP host.'),
cfg.StrOpt('username', help='BIG IP username'),
cfg.StrOpt('password', help='BIG IP password')
]
CONF = cfg.CONF
CONF.register_opts(bigip_opts, group='lbaas_f5')
LOG = logging.getLogger(__name__)
config.read_config()
class F5Driver(base.LoadBalancerDriver):
def __init__(self):
self.bigip = bigip.BigIP(
CONF.lbaas_f5.host,
CONF.lbaas_f5.username,
CONF.lbaas_f5.password
).ltm
@staticmethod
def _install_cert(path, name):
requests.post(
url='https://%s/mgmt/tm/sys/crypto/cert' % CONF.lbaas_f5.host,
data=json.dumps(
{
"fromLocalFile": path,
"name": name,
"command": "install"
}
),
verify=False,
auth=(CONF.lbaas_f5.username, CONF.lbaas_f5.password),
headers={
'Accept': 'application/json',
'Content-Type': 'application/json'
}
)
@staticmethod
def _install_key(path, name):
requests.post(
url='https://%s/mgmt/tm/sys/crypto/key'
% CONF.lbaas_f5.host,
data=json.dumps(
{
"fromLocalFile": path,
"name": name,
"command": "install"
}
),
verify=False,
auth=(CONF.lbaas_f5.username, CONF.lbaas_f5.password),
headers={
'Accept': 'application/json',
'Content-Type': 'application/json'
}
)
def _create_or_update_ssl_profile(self, name, key_name, cert_name,
options, ciphers):
profile_resp = requests.get(
url='https://%s/mgmt/tm/ltm/profile/client-ssl/%s'
% (CONF.lbaas_f5.host, name),
auth=(CONF.lbaas_f5.username, CONF.lbaas_f5.password),
verify=False
)
if profile_resp.status_code == 404:
return self._create_ssl_profile(
name,
key_name,
cert_name,
options,
ciphers
)
else:
return self._update_ssl_profile(
name,
key_name,
cert_name,
options,
ciphers
)
@staticmethod
def _create_ssl_profile(name, key_name, cert_name,
options=None, ciphers=None):
url = (
'https://%s/mgmt/tm/ltm/profile/client-ssl' % CONF.lbaas_f5.host
)
data = {
"name": name,
"cert": cert_name,
"key": key_name
}
if options:
data['options'] = options
if ciphers:
data['ciphers'] = ciphers
resp = requests.post(
url=url,
data=json.dumps(data),
verify=False,
auth=(CONF.lbaas_f5.username, CONF.lbaas_f5.password),
headers={
'Accept': 'application/json',
'Content-Type': 'application/json'
}
)
return resp.json()
@staticmethod
def _update_ssl_profile(name, key_name, cert_name,
options=None, ciphers=None):
url = (
'https://%s/mgmt/tm/ltm/profile/client-ssl/%s'
% (CONF.lbaas_f5.host, name)
)
data = {
"cert": cert_name,
"key": key_name
}
if options:
data['options'] = options
if ciphers:
data['ciphers'] = ciphers
resp = requests.put(
url=url,
data=json.dumps(data),
verify=False,
auth=(CONF.lbaas_f5.username, CONF.lbaas_f5.password),
headers={
'Accept': 'application/json',
'Content-Type': 'application/json'
}
)
return resp.json()
def _assign_ssl_profile(self, ssl_info):
if not ssl_info:
return
# In this case, need to install the cert,
# the key and the new SSL profile.
path = ssl_info['path']
options = ssl_info.get('options', '')
ciphers = ssl_info.get('ciphers', '')
name = path.split('/')[-1].split('.')[0]
# Install the cert and the key.
self._install_cert(path, name)
self._install_key(path, name)
# Create a client SSL profile.
return self._create_or_update_ssl_profile(
name,
"%s.key" % name,
"%s.crt" % name,
options,
ciphers
)
@staticmethod
def _find_member_by_description(pool, mem_description):
all_members = pool.members_s.get_collection()
for mem in all_members:
# Search by name.
if mem.description == mem_description:
return mem
def create_listener(self, listener):
ssl_profile = self._assign_ssl_profile(listener.ssl_info)
if not listener.algorithm:
listener.algorithm = 'round-robin'
if not listener.address:
listener.address = '0.0.0.0'
# Create a new pool associated with current virtual server.
# Assign default ICMP monitor.
self.bigip.pools.pool.create(
name='pool-%s' % listener.name,
loadBalancingMode=listener.algorithm,
monitor='gateway_icmp'
)
kwargs = {
'name': 'virtual-%s' % listener.name,
'pool': 'pool-%s' % listener.name,
'destination': '%s:%s' % (
listener.address,
listener.protocol_port
),
'ipProtocol': listener.protocol
}
if ssl_profile:
kwargs['profiles'] = [{
'context': 'clientside',
'name': ssl_profile['name']
}]
# Create a new virtual server.
self.bigip.virtuals.virtual.create(**kwargs)
return listener
def delete_listener(self, listener):
pool = self.bigip.pools.pool.load(name='pool-%s' % listener.name)
virtual = self.bigip.virtuals.virtual.load(
name='virtual-%s' % listener.name
)
virtual.delete()
pool.delete()
def apply_changes(self):
pass
def delete_member(self, member):
# Delete pool member.
pool = self.bigip.pools.pool.load(
name='pool-%s' % member.listener.name,
)
# Get parent node.
node = self._get_node_by_address(member.address)
# Find given member in current pool.
mem = self._find_member_by_description(
pool,
'%s' % member.name
)
mem.delete()
# Try to delete parent node.
try:
node.delete()
except Exception as e:
# In case if parent node is still used by any other pool member.
LOG.warning(e)
def _get_node_by_address(self, address):
nodes = self.bigip.nodes.get_collection()
filtered = list(filter(lambda x: x.address == address, nodes))
return None if not filtered else filtered[0]
def create_member(self, member):
# Try to get parent node if it already exists.
node = self._get_node_by_address(member.address)
if not node:
# Create a new node.
node = self.bigip.nodes.node.create(
# params
name='%s' % member.address,
address=member.address,
monitor="default",
partition='Common'
)
pool = self.bigip.pools.pool.load(
name='pool-%s' % member.listener.name,
)
# Create a new member in current pool.
pool.members_s.members.create(
name='%s:%s' % (node.name, member.protocol_port),
partition='Common',
description=member.name
)
return member
def update_listener(self, listener):
ssl_profile = self._assign_ssl_profile(listener.ssl_info)
if not listener.algorithm:
listener.algorithm = 'round-robin'
# Get the pool associated with current virtual server.
pool = self.bigip.pools.pool.load(
name='pool-%s' % listener.name,
)
virtual = self.bigip.virtuals.virtual.load(
name='virtual-%s' % listener.name
)
# potential values that could be changed:
# pool: algorithm,
# virtual: address, protocol_port, protocol,
# address, protocol, protocol_port, algorithm, options, ssl_info.
destination = '%s:%s' % (listener.address, listener.protocol_port)
update_virtual = (
destination not in virtual.destination or
virtual.ipProtocol != listener.protocol or
ssl_profile
)
update_pool = pool.loadBalancingMode != listener.algorithm
if update_virtual:
# Update the virtual server.
kwargs = {
'destination': '%s:%s' % (
listener.address,
listener.protocol_port
),
'ipProtocol': listener.protocol
}
if ssl_profile:
kwargs['profiles'] = [{
'context': 'clientside',
'name': ssl_profile['name']
}]
virtual.update(**kwargs)
if update_pool:
# Update the pool.
pool.update(
loadBalancingMode=listener.algorithm
)
return listener
def update_member(self, member):
# Replace member on another one.
self.delete_member(member)
self.create_member(member)
return member

View File

@ -0,0 +1,3 @@
f5-sdk>=0.1
requests!=2.9.0,>=2.8.1 # Apache-2.0
oslo.config>=3.7.0 # Apache-2.0

View File

@ -0,0 +1,31 @@
[metadata]
name = f5_lbaas_driver
summary = LBaaS Project
description-file =
README.md
license = Apache License, Version 2.0
classifiers =
Programming Language :: Python
Programming Language :: Python :: 2
Programming Language :: Python :: 2.7
Environment :: OpenStack
Intended Audience :: Information Technology
Intended Audience :: System Administrators
#License :: OSI Approved :: Apache Software License
Operating System :: POSIX :: Linux
author = Mirantis Inc.
author-email = nmakhotkin@mirantis.com
[files]
packages =
f5_lbaas_driver
[entry_points]
lbaas.drivers =
f5ltm = f5_lbaas_driver.f5ltm:F5Driver
[egg_info]
tag_build =
tag_date = 0
tag_svn_revision = 0

View File

@ -0,0 +1,30 @@
# Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
#
# 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 FILE IS MANAGED BY THE GLOBAL REQUIREMENTS REPO - DO NOT EDIT
import setuptools
# In python < 2.7.4, a lazy loading of package `pbr` will break
# setuptools if some other modules registered functions in `atexit`.
# solution from: http://bugs.python.org/issue15881#msg170215
try:
import multiprocessing # noqa
except ImportError:
pass
setuptools.setup(
setup_requires=['pbr>=1.8'],
pbr=True
)

View File

@ -0,0 +1,104 @@
Version: 2
Application:
?:
type: io.murano.apps.lbaas.F5BigIPLTM
name: $.appConfiguration.name
host: $.bigIPconfiguration.host
username: $.bigIPconfiguration.username
password: $.bigIPconfiguration.password
instance:
?:
type: io.murano.resources.LinuxMuranoInstance
name: generateHostname($.instanceConfiguration.unitNamingPattern, 1)
flavor: $.instanceConfiguration.flavor
image: $.instanceConfiguration.osImage
keyname: $.instanceConfiguration.keyPair
availabilityZone: $.instanceConfiguration.availabilityZone
assignFloatingIp: $.appConfiguration.assignFloatingIP
Forms:
- bigIPconfiguration:
fields:
- name: username
type: string
label: BIG IP username
initial: 'admin'
- name: password
type: string
label: BIG IP password
initial: 'admin'
- name: host
type: string
label: BIG IP host
- appConfiguration:
fields:
- name: name
type: string
label: Application Name
initial: 'F5 BIG IP based LBaaS'
description: >-
Enter a desired name for the application. Just A-Z, a-z, 0-9, dash and
underline are allowed
- name: assignFloatingIP
type: boolean
label: Assign Floating IP
description: >-
Select to true to assign floating IP automatically
initial: true
required: false
widgetMedia:
css: {all: ['muranodashboard/css/checkbox.css']}
- instanceConfiguration:
fields:
- name: title
type: string
required: false
hidden: true
description: Specify some instance parameters on which the application would be created
- name: flavor
type: flavor
label: Instance flavor
description: >-
Select registered in Openstack flavor. Consider that application performance
depends on this parameter.
required: false
- name: osImage
type: image
imageType: linux
label: Instance image
description: >-
Select valid image for the application. Image should already be prepared and
registered in glance.
- name: keyPair
type: keypair
label: Key Pair
description: >-
Select the Key Pair to control access to instances. You can login to
instances using this KeyPair after the deployment of application.
required: false
- name: availabilityZone
type: azone
label: Availability zone
description: Select availability zone where application would be installed.
required: false
- name: network
type: network
label: Network
description: Select a network to join. 'Auto' corresponds to a default environment's network.
required: false
murano_networks: translate
- name: unitNamingPattern
type: string
label: Instance Naming Pattern
required: false
maxLength: 64
regexpValidator: '^[a-zA-z][-_\w]*$'
errorMessages:
invalid: Just letters, numbers, underscores and hyphens are allowed.
helpText: Just letters, numbers, underscores and hyphens are allowed.
description: >-
Specify a string, that will be used in instance hostname.
Just A-Z, a-z, 0-9, dash and underline are allowed.

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

@ -0,0 +1,24 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
Format: 1.0
Type: Application
FullName: io.murano.apps.lbaas.F5BigIPLTM
Name: F5 BIG IP LTM based LBaaS
Description: |
F5 BIG IP Local Traffic manager.
Author: 'Mirantis, Inc'
Tags: [HTTP, TCP, Load Balancing as a Service, F5, BIG IP, Local traffic]
Classes:
io.murano.apps.lbaas.F5BigIPLTM: F5BigIPLTM.yaml
Require:
io.murano.apps.lbaas.LBaaS:

View File

@ -64,7 +64,7 @@ Methods:
- $.environment.reporter.report($this, 'Instance is created.')
- $resources: new(sys:Resources)
- $.installLoadBalancer()
- $lbaas: $.installLBaaS($.implementation)
- $lbaas: $.installLBaaS()
- $.configureLBaaS()
- $.startLBaaS()
- If: $.instance.assignFloatingIp
@ -113,9 +113,6 @@ Methods:
installLBaaS:
# Installs LBaaS itself and its drivers on an instance.
Arguments:
- implementation:
Contract: $.string().notNull()
Body:
- $resources: new(sys:Resources)
- $template: $resources.yaml('DeployLBaaS.template')

View File

@ -21,7 +21,7 @@ sudo pip install mysql-python
sudo mkdir /etc/lbaas
sudo chown -R $USER:$USER /etc/lbaas
sudo chown /var/log/lbaas.log
sudo chown -R $USER:$USER /var/log/lbaas.log
# Moving config to another place.
cp lbaas.conf.sample /etc/lbaas/lbaas.conf

View File

@ -0,0 +1,116 @@
Metadata-Version: 1.0
Name: lbaas
Version: 0.1.0
Summary: LBaaS Project
Home-page: UNKNOWN
Author: Mirantis Inc.
Author-email: nmakhotkin@mirantis.com
License: Apache License, Version 2.0
Description: LBaaS API specification
=======================
Listeners API
-------------
**/v1/listeners** - objects representing a group of machines balancing on LB on specific protocol and port. Each listener contains mapping configuration to members and their listening ports.
Example: listener A listen to HTTP port 80 and maps to 3 machines with their own IPs listening on HTTP port 8080.
---> Member, Machine1_IP (HTTP, 8080)
Listener A (HTTP, 80) ---> Member, Machine2_IP (HTTP, 8080)
---> Member, Machine3_IP (HTTP, 8080)
**POST /v1/listeners**
Creates a new listener object. Returns 201 if succeed.
Parameters:
* **name** - The name of listener. Type string. Required. Should be unique across listener objects.
* **protocol** - The protocol of listener. Type string. Should be one of {“http”, “tcp”}. It is not validated by API! Required.
* **protocol_port** - Protocol TCP port which listener will be listening to. Type integer. Required.
* **algorithm** - Load-balancing algorithm. Type string. If passed, should be compatible with one of possible haproxy algorithm. Optional, default value if not passed - “roundrobin”.
Request body example:
{
“protocol”: “http”,
“protocol_port”: 80,
“name”: “app”,
“algorithm”: “roundrobin”
}
**GET /v1/listeners**
Gets all listeners from LBaaS. Also contains all containing members information. Returns 200 if succeed.
**GET /v1/listeners/<name>**
Gets particular listener from LBaaS. name - the listeners name.
**PUT /v1/listeners/<name>**
Update listener info by its name. Returns 200 code if succeed.
Request body example:
{
“protocol_port”: 8080,
“name”: “app”
}
**DELETE /v1/listeners/<name>**
Deletes the whole listener by its name. Returns 204 if succeed.
Members API
-----------
**/v1/members** - objects representing a machine which is able to receive requests on specific port of specific protocol. Each member belongs to specific listener.
**POST /v1/members**
Creates a new member object. Returns 201 if succeed.
Parameters:
* **name** - The name of member. Type string. Required. Should be unique across member objects.
* **protocol_port** - Protocol TCP port which member is listening to. Type integer. Required.
* **address** - Hostname or IP address of member machine. Type string. Required.
* **listener_name** - The name of listener which adds the current member to. Member will belong to this listener. Each listener may have a number of members. Type string. Required.
Request body example:
{
“address”: “10.0.20.5”,
“protocol_port”: 80,
“name”: “my_server”,
“listener_name”: “app”
}
**GET /v1/members**
Gets all members from LBaaS. Returns 200 if succeed.
**GET /v1/members/<name>**
Gets particular member from LBaaS. name - the members name.
**PUT /v1/members/<name>**
Update listener info by its name. Returns 200 code if succeed.
Request body example:
{
“protocol_port”: 8080,
}
**DELETE /v1/members/<name>**
Deletes the whole member by its name. Returns 204 if succeed.
Platform: UNKNOWN

View File

@ -0,0 +1,78 @@
.testr.conf
AUTHORS
ChangeLog
README.md
requirements.txt
setup.cfg
setup.py
test-requirements.txt
tox.ini
etc/lbaas.conf.sample
etc/logging.conf.sample
lbaas/__init__.py
lbaas/config.py
lbaas/exceptions.py
lbaas/version.py
lbaas.egg-info/PKG-INFO
lbaas.egg-info/SOURCES.txt
lbaas.egg-info/dependency_links.txt
lbaas.egg-info/entry_points.txt
lbaas.egg-info/not-zip-safe
lbaas.egg-info/pbr.json
lbaas.egg-info/requires.txt
lbaas.egg-info/top_level.txt
lbaas/api/__init__.py
lbaas/api/app.py
lbaas/api/controllers/__init__.py
lbaas/api/controllers/resource.py
lbaas/api/controllers/root.py
lbaas/api/controllers/v1/__init__.py
lbaas/api/controllers/v1/listener.py
lbaas/api/controllers/v1/member.py
lbaas/api/controllers/v1/root.py
lbaas/cmd/__init__.py
lbaas/cmd/launch.py
lbaas/db/__init__.py
lbaas/db/sqlalchemy/__init__.py
lbaas/db/sqlalchemy/base.py
lbaas/db/sqlalchemy/model_base.py
lbaas/db/sqlalchemy/types.py
lbaas/db/sqlalchemy/migration/__init__.py
lbaas/db/sqlalchemy/migration/alembic.ini
lbaas/db/sqlalchemy/migration/cli.py
lbaas/db/sqlalchemy/migration/alembic_migrations/README.md
lbaas/db/sqlalchemy/migration/alembic_migrations/__init__.py
lbaas/db/sqlalchemy/migration/alembic_migrations/env.py
lbaas/db/sqlalchemy/migration/alembic_migrations/script.py.mako
lbaas/db/sqlalchemy/migration/alembic_migrations/versions/001_initial_lbaas_scheme.py
lbaas/db/sqlalchemy/migration/alembic_migrations/versions/002_add_options_to_listeners.py
lbaas/db/sqlalchemy/migration/alembic_migrations/versions/003_added_address_field_to_listener.py
lbaas/db/sqlalchemy/migration/alembic_migrations/versions/__init__.py
lbaas/db/v1/__init__.py
lbaas/db/v1/api.py
lbaas/db/v1/sqlalchemy/__init__.py
lbaas/db/v1/sqlalchemy/api.py
lbaas/db/v1/sqlalchemy/models.py
lbaas/drivers/__init__.py
lbaas/drivers/base.py
lbaas/drivers/driver.py
lbaas/drivers/haproxy.py
lbaas/tests/__init__.py
lbaas/tests/unit/__init__.py
lbaas/tests/unit/base.py
lbaas/tests/unit/api/__init__.py
lbaas/tests/unit/api/base.py
lbaas/tests/unit/api/v1/__init__.py
lbaas/tests/unit/api/v1/test_listeners.py
lbaas/tests/unit/api/v1/test_members.py
lbaas/tests/unit/api/v1/test_root.py
lbaas/tests/unit/db/__init__.py
lbaas/tests/unit/db/v1/__init__.py
lbaas/tests/unit/db/v1/test_sqlalchemy_db_api.py
lbaas/tests/unit/drivers/__init__.py
lbaas/tests/unit/drivers/test_haproxy.py
lbaas/utils/__init__.py
lbaas/utils/file_utils.py
lbaas/utils/rest_utils.py
tools/update_env_deps
tools/with_venv.sh

View File

@ -0,0 +1,10 @@
[console_scripts]
lbaas-db-manage = lbaas.db.sqlalchemy.migration.cli:main
lbaas-server = lbaas.cmd.launch:main
[lbaas.drivers]
haproxy = lbaas.drivers.haproxy:HAProxyDriver
[oslo.config.opts]
lbaas.config = lbaas.config:list_opts

View File

@ -0,0 +1 @@
{"is_release": false, "git_version": "64ca7a2"}

View File

@ -0,0 +1,18 @@
alembic>=0.8.0
argparse
eventlet>=0.17.4
jsonschema!=2.5.0,<3.0.0,>=2.0.0
mock>=1.2
oslo.concurrency>=2.3.0
oslo.config>=2.7.0
oslo.db>=3.2.0
oslo.utils>=2.8.0
oslo.log>=1.12.0
oslo.serialization>=1.10.0
pbr>=1.6
pecan>=1.0.0
requests>=2.8.1
six>=1.9.0
SQLAlchemy<1.1.0,>=0.9.9
stevedore>=1.5.0
WSME>=0.8