Updates Octavia to support octavia-lib
This is the base patch that updates octavia to use the new octavia-lib. It is backwards compatible by using debtcollector moves. It adds a new controller process called the "driver-agent". This patch also adds unit test coverage for a few additional modules. Depends-On: https://review.openstack.org/#/c/641180/ Change-Id: I438e1548ec0fb6111d1ab85b05015007d9d0a006
This commit is contained in:
parent
c00faa7edd
commit
8997def2b5
@ -23,7 +23,7 @@ For example
|
||||
|
||||
For example
|
||||
|
||||
ENABLED_SERVICES+=octavia,o-api,o-cw,o-hk,o-hm
|
||||
ENABLED_SERVICES+=octavia,o-api,o-cw,o-hk,o-hm,o-da
|
||||
|
||||
For more information, see the "Externally Hosted Plugins" section of
|
||||
https://docs.openstack.org/devstack/latest/plugins.html
|
||||
|
@ -45,7 +45,7 @@ ENABLED_SERVICES+=,neutron-metadata-agent,neutron-qos
|
||||
# Tempest (optional)
|
||||
#ENABLED_SERVICES+=,tempest
|
||||
# Octavia
|
||||
ENABLED_SERVICES+=,octavia,o-api,o-cw,o-hm,o-hk
|
||||
ENABLED_SERVICES+=,octavia,o-api,o-cw,o-hm,o-hk,o-da
|
||||
EOF
|
||||
|
||||
# Create the stack user
|
||||
|
@ -29,6 +29,15 @@ function octaviaclient_install {
|
||||
fi
|
||||
}
|
||||
|
||||
function octavia_lib_install {
|
||||
if use_library_from_git "octavia-lib"; then
|
||||
git_clone_by_name "octavia-lib"
|
||||
setup_dev_lib "octavia-lib"
|
||||
else
|
||||
pip_install_gr octavia-lib
|
||||
fi
|
||||
}
|
||||
|
||||
function install_diskimage_builder {
|
||||
if use_library_from_git "diskimage-builder"; then
|
||||
GITREPO["diskimage-builder"]=$DISKIMAGE_BUILDER_REPO_URL
|
||||
@ -209,6 +218,9 @@ function octavia_configure {
|
||||
sudo mkdir -m 755 -p $OCTAVIA_CONF_DIR
|
||||
safe_chown $STACK_USER $OCTAVIA_CONF_DIR
|
||||
|
||||
sudo mkdir -m 700 -p $OCTAVIA_RUN_DIR
|
||||
safe_chown $STACK_USER $OCTAVIA_RUN_DIR
|
||||
|
||||
if ! [ -e $OCTAVIA_CONF ] ; then
|
||||
cp $OCTAVIA_DIR/etc/octavia.conf $OCTAVIA_CONF
|
||||
fi
|
||||
@ -477,6 +489,7 @@ function octavia_start {
|
||||
run_process $OCTAVIA_API "$OCTAVIA_API_BINARY $OCTAVIA_API_ARGS"
|
||||
fi
|
||||
|
||||
run_process $OCTAVIA_DRIVER_AGENT "$OCTAVIA_DRIVER_AGENT_BINARY $OCTAVIA_DRIVER_AGENT_ARGS"
|
||||
run_process $OCTAVIA_CONSUMER "$OCTAVIA_CONSUMER_BINARY $OCTAVIA_CONSUMER_ARGS"
|
||||
run_process $OCTAVIA_HOUSEKEEPER "$OCTAVIA_HOUSEKEEPER_BINARY $OCTAVIA_HOUSEKEEPER_ARGS"
|
||||
run_process $OCTAVIA_HEALTHMANAGER "$OCTAVIA_HEALTHMANAGER_BINARY $OCTAVIA_HEALTHMANAGER_ARGS"
|
||||
@ -489,6 +502,7 @@ function octavia_stop {
|
||||
else
|
||||
stop_process $OCTAVIA_API
|
||||
fi
|
||||
stop_process $OCTAVIA_DRIVER_AGENT
|
||||
stop_process $OCTAVIA_CONSUMER
|
||||
stop_process $OCTAVIA_HOUSEKEEPER
|
||||
stop_process $OCTAVIA_HEALTHMANAGER
|
||||
@ -523,6 +537,9 @@ function octavia_cleanup {
|
||||
if [ ${OCTAVIA_CONF_DIR}x != x ] ; then
|
||||
sudo rm -rf ${OCTAVIA_CONF_DIR}
|
||||
fi
|
||||
if [ ${OCTAVIA_RUN_DIR}x != x ] ; then
|
||||
sudo rm -rf ${OCTAVIA_RUN_DIR}
|
||||
fi
|
||||
if [ ${OCTAVIA_AMP_SSH_KEY_PATH}x != x ] ; then
|
||||
rm -f ${OCTAVIA_AMP_SSH_KEY_PATH} ${OCTAVIA_AMP_SSH_KEY_PATH}.pub
|
||||
fi
|
||||
@ -635,6 +652,7 @@ if is_service_enabled $OCTAVIA; then
|
||||
if [[ "$1" == "stack" && "$2" == "install" ]]; then
|
||||
# Perform installation of service source
|
||||
echo_summary "Installing octavia"
|
||||
octavia_lib_install
|
||||
octavia_install
|
||||
octaviaclient_install
|
||||
|
||||
|
@ -61,6 +61,7 @@ enable_service o-hm
|
||||
enable_service o-hk
|
||||
enable_service o-api
|
||||
enable_service o-api-ha
|
||||
enable_service o-da
|
||||
|
||||
OCTAVIA_USE_PREGENERATED_CERTS=True
|
||||
OCTAVIA_USE_PREGENERATED_SSH_KEY=True
|
||||
|
@ -73,6 +73,7 @@ enable_service o-cw
|
||||
enable_service o-hm
|
||||
enable_service o-hk
|
||||
enable_service o-api
|
||||
enable_service o-da
|
||||
|
||||
|
||||
# enable DVR
|
||||
|
@ -16,6 +16,7 @@ OCTAVIA_DHCLIENT_CONF=${OCTAVIA_DHCLIENT_CONF:-${OCTAVIA_DHCLIENT_DIR}/dhclient.
|
||||
OCTAVIA_CONF=${OCTAVIA_CONF:-${OCTAVIA_CONF_DIR}/octavia.conf}
|
||||
OCTAVIA_AUDIT_MAP=${OCTAVIA_AUDIT_MAP:-${OCTAVIA_CONF_DIR}/octavia_api_audit_map.conf}
|
||||
OCTAVIA_TEMPEST_DIR=${OCTAVIA_TEMPEST_DIR:-${OCTAVIA_DIR}/octavia/tests/tempest}
|
||||
OCTAVIA_RUN_DIR=${OCTAVIA_RUN_DIR:-"/var/run/octavia"}
|
||||
|
||||
OCTAVIA_AMPHORA_DRIVER=${OCTAVIA_AMPHORA_DRIVER:-"amphora_haproxy_rest_driver"}
|
||||
OCTAVIA_NETWORK_DRIVER=${OCTAVIA_NETWORK_DRIVER:-"allowed_address_pairs_driver"}
|
||||
@ -61,11 +62,13 @@ OCTAVIA_API_BINARY=${OCTAVIA_API_BINARY:-${OCTAVIA_BIN_DIR}/octavia-api}
|
||||
OCTAVIA_CONSUMER_BINARY=${OCTAVIA_CONSUMER_BINARY:-${OCTAVIA_BIN_DIR}/octavia-worker}
|
||||
OCTAVIA_HOUSEKEEPER_BINARY=${OCTAVIA_HOUSEKEEPER_BINARY:-${OCTAVIA_BIN_DIR}/octavia-housekeeping}
|
||||
OCTAVIA_HEALTHMANAGER_BINARY=${OCTAVIA_HEALTHMANAGER_BINARY:-${OCTAVIA_BIN_DIR}/octavia-health-manager}
|
||||
OCTAVIA_DRIVER_AGENT_BINARY=${OCTAVIA_DRIVER_AGENT_BINARY:-${OCTAVIA_BIN_DIR}/octavia-driver-agent}
|
||||
|
||||
OCTAVIA_API_ARGS=${OCTAVIA_API_ARGS:-" --config-file $OCTAVIA_CONF"}
|
||||
OCTAVIA_CONSUMER_ARGS=${OCTAVIA_CONSUMER_ARGS:-" --config-file $OCTAVIA_CONF"}
|
||||
OCTAVIA_HOUSEKEEPER_ARGS=${OCTAVIA_HOUSEKEEPER_ARGS:-" --config-file $OCTAVIA_CONF"}
|
||||
OCTAVIA_HEALTHMANAGER_ARGS=${OCTAVIA_HEALTHMANAGER_ARGS:-" --config-file $OCTAVIA_CONF"}
|
||||
OCTAVIA_DRIVER_AGENT_ARGS=${OCTAVIA_DRIVER_AGENT_ARGS:-" --config-file $OCTAVIA_CONF"}
|
||||
|
||||
OCTAVIA_TEMPEST=${OCTAVIA_TEMPEST:-"disabled"}
|
||||
|
||||
@ -75,12 +78,18 @@ OCTAVIA_HOUSEKEEPER="o-hk"
|
||||
OCTAVIA_HEALTHMANAGER="o-hm"
|
||||
OCTAVIA_SERVICE="octavia"
|
||||
OCTAVIA_API_HAPROXY="o-api-ha"
|
||||
OCTAVIA_DRIVER_AGENT="o-da"
|
||||
|
||||
# Client settings
|
||||
GITREPO["python-octaviaclient"]=${OCTAVIACLIENT_REPO:-${GIT_BASE}/openstack/python-octaviaclient.git}
|
||||
GITBRANCH["python-octaviaclient"]=${OCTAVIACLIENT_BRANCH:-master}
|
||||
GITDIR["python-octaviaclient"]=$DEST/python-octaviaclient
|
||||
|
||||
# Library settings
|
||||
GITREPO["octavia-lib"]=${OCTAVIA_LIB_REPO:-${GIT_BASE}/openstack/octavia-lib.git}
|
||||
GITBRANCH["octavia-lib"]=${OCTAVIA_LIB_BRANCH:-master}
|
||||
GITDIR["octavia-lib"]=$DEST/octavia-lib
|
||||
|
||||
NEUTRON_LBAAS_DIR=$DEST/neutron-lbaas
|
||||
NEUTRON_LBAAS_CONF=$NEUTRON_CONF_DIR/neutron_lbaas.conf
|
||||
OCTAVIA_SERVICE_PROVIDER=${OCTAVIA_SERVICE_PROVIDER:-"LOADBALANCERV2:Octavia:neutron_lbaas.drivers.octavia.driver.OctaviaDriver:default"}
|
||||
|
@ -55,10 +55,11 @@ Provider drivers should only access the following Octavia APIs. All other
|
||||
Octavia APIs are not considered stable or safe for provider driver use and
|
||||
may change at any time.
|
||||
|
||||
* octavia.api.drivers.data_models
|
||||
* octavia.api.drivers.driver_lib
|
||||
* octavia.api.drivers.exceptions
|
||||
* octavia.api.drivers.provider_base
|
||||
* octavia_lib.api.drivers.data_models
|
||||
* octavia_lib.api.drivers.driver_lib
|
||||
* octavia_lib.api.drivers.exceptions
|
||||
* octavia_lib.api.drivers.provider_base
|
||||
* octavia_lib.common.constants
|
||||
|
||||
Octavia Provider Driver API
|
||||
===========================
|
||||
@ -1695,7 +1696,7 @@ Driver Support Library
|
||||
|
||||
Provider drivers need support for updating provisioning status, operating
|
||||
status, and statistics. Drivers will not directly use database operations,
|
||||
and instead will callback to Octavia using a new API.
|
||||
and instead will callback to octavia-lib using a new API.
|
||||
|
||||
.. warning::
|
||||
|
||||
@ -1708,7 +1709,7 @@ and instead will callback to Octavia using a new API.
|
||||
|
||||
This library is interim and will be removed when the driver support endpoint
|
||||
is made available. At which point drivers will not import any code from
|
||||
Octavia.
|
||||
octavia-lib.
|
||||
|
||||
Update Provisioning and Operating Status API
|
||||
--------------------------------------------
|
||||
@ -1723,6 +1724,13 @@ and operating status parameters are as defined by Octavia status codes. If an
|
||||
existing object is not included in the input parameter, the status remains
|
||||
unchanged.
|
||||
|
||||
.. note::
|
||||
|
||||
If the driver-agent exceeds its configured `status_max_processes` this call
|
||||
may block while it waits for a status process slot to become available.
|
||||
The operator will be notified if the driver-agent approaches or reaches
|
||||
the configured limit.
|
||||
|
||||
provisioning_status: status associated with lifecycle of the
|
||||
resource. See `Octavia Provisioning Status Codes <https://developer.openstack.org/api-ref/load-balancer/v2/index.html#provisioning-status-codes>`_.
|
||||
|
||||
@ -1765,6 +1773,13 @@ with multiple listener statistics is used to update statistics in a single
|
||||
call. If an existing listener is not included, the statistics that object
|
||||
remain unchanged.
|
||||
|
||||
.. note::
|
||||
|
||||
If the driver-agent exceeds its configured `stats_max_processes` this call
|
||||
may block while it waits for a stats process slot to become available.
|
||||
The operator will be notified if the driver-agent approaches or reaches
|
||||
the configured limit.
|
||||
|
||||
The general form of the input dictionary is a list of listener statistics:
|
||||
|
||||
.. code-block:: python
|
||||
|
@ -83,10 +83,9 @@ It is also possible to use Octavia as a Neutron LBaaS plugin, in the same way
|
||||
as any other vendor. You can think of Octavia as an "open source vendor" for
|
||||
Neutron LBaaS.
|
||||
|
||||
Soon, Octavia will support third-party vendor drivers just like Neutron LBaaS,
|
||||
and will then fully replace Neutron LBaaS as the load balancing solution for
|
||||
OpenStack. At that time, third-party vendor drivers that presently "plug in" to
|
||||
Neutron LBaaS will plug in to Octavia instead.
|
||||
Octavia supports third-party vendor drivers just like Neutron LBaaS,
|
||||
and fully replaces Neutron LBaaS as the load balancing solution for
|
||||
OpenStack.
|
||||
|
||||
For further information on OpenStack Neutron LBaaS deprecation, please refer to
|
||||
https://wiki.openstack.org/wiki/Neutron/LBaaS/Deprecation.
|
||||
@ -119,7 +118,7 @@ A 10,000-foot overview of Octavia components
|
||||
:width: 660px
|
||||
:alt: Octavia Component Overview
|
||||
|
||||
Octavia version 0.9 consists of the following major components:
|
||||
Octavia version 4.0 consists of the following major components:
|
||||
|
||||
* **amphorae** - Amphorae are the individual virtual machines, containers, or
|
||||
bare metal servers that accomplish the delivery of load balancing services to
|
||||
@ -128,7 +127,7 @@ Octavia version 0.9 consists of the following major components:
|
||||
HAProxy.
|
||||
|
||||
* **controller** - The Controller is the "brains" of Octavia. It consists of
|
||||
four sub-components, which are individual daemons. They can be run on
|
||||
five sub-components, which are individual daemons. They can be run on
|
||||
separate back-end infrastructure if desired:
|
||||
|
||||
* **API Controller** - As the name implies, this subcomponent runs Octavia's
|
||||
@ -147,6 +146,9 @@ Octavia version 0.9 consists of the following major components:
|
||||
database records, manages the spares pool, and manages amphora certificate
|
||||
rotation.
|
||||
|
||||
* **Driver Agent** - The driver agent receives status and statistics updates
|
||||
from provider drivers.
|
||||
|
||||
* **network** - Octavia cannot accomplish what it does without manipulating
|
||||
the network environment. Amphorae are spun up with a network interface on the
|
||||
"load balancer network," and they may also plug directly into tenant networks
|
||||
|
@ -1,16 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by Microsoft Visio, SVG Export OctaviaComp.svg Page-1 -->
|
||||
<!-- Generated by Microsoft Visio, SVG Export Octaviav2APIDriverAgent.svg Page-1 -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events"
|
||||
xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="11.6929in" height="8.26772in"
|
||||
viewBox="0 0 841.89 595.276" xml:space="preserve" color-interpolation-filters="sRGB" class="st15">
|
||||
<v:documentProperties v:langID="1033" v:metric="true" v:viewMarkup="false">
|
||||
<v:userDefs>
|
||||
<v:ud v:nameU="msvSubprocessMaster" v:prompt="" v:val="VT4(Rectangle)"/>
|
||||
<v:ud v:nameU="msvNoAutoConnect" v:val="VT0(1):26"/>
|
||||
</v:userDefs>
|
||||
</v:documentProperties>
|
||||
|
||||
width="11.6929in" height="8.26772in" viewBox="0 0 841.89 595.276" xml:space="preserve" color-interpolation-filters="sRGB"
|
||||
class="st17">
|
||||
<style type="text/css">
|
||||
<![CDATA[
|
||||
.st1 {fill:#339933;fill-opacity:0.64;stroke:#ffffff;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.5}
|
||||
@ -18,16 +11,18 @@
|
||||
.st3 {fill:#ffffff;font-family:Segoe UI;font-size:1.16666em}
|
||||
.st4 {font-size:1em}
|
||||
.st5 {fill:#d80073;stroke:#ffffff;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.5}
|
||||
.st6 {marker-end:url(#mrkr4-43);marker-start:url(#mrkr4-41);stroke:#1897d5;stroke-linecap:round;stroke-linejoin:round;stroke-width:2}
|
||||
.st6 {marker-end:url(#mrkr4-44);marker-start:url(#mrkr4-42);stroke:#1897d5;stroke-linecap:round;stroke-linejoin:round;stroke-width:2}
|
||||
.st7 {fill:#1897d5;fill-opacity:1;stroke:#1897d5;stroke-opacity:1;stroke-width:0.44247787610619}
|
||||
.st8 {marker-end:url(#mrkr4-43);stroke:#1897d5;stroke-linecap:round;stroke-linejoin:round;stroke-width:2}
|
||||
.st8 {marker-end:url(#mrkr4-44);stroke:#1897d5;stroke-linecap:round;stroke-linejoin:round;stroke-width:2}
|
||||
.st9 {fill:#f09609;stroke:#ffffff;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.5}
|
||||
.st10 {fill:none;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.5}
|
||||
.st11 {fill:#339933;fill-opacity:0.79;stroke:#ffffff;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.5}
|
||||
.st12 {fill:#339933;stroke:#ffffff;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.5}
|
||||
.st13 {marker-start:url(#mrkr4-41);stroke:#1897d5;stroke-linecap:round;stroke-linejoin:round;stroke-width:2}
|
||||
.st13 {marker-start:url(#mrkr4-42);stroke:#1897d5;stroke-linecap:round;stroke-linejoin:round;stroke-width:2}
|
||||
.st14 {fill:#a200ff;stroke:#ffffff;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.5}
|
||||
.st15 {fill:none;fill-rule:evenodd;font-size:12px;overflow:visible;stroke-linecap:square;stroke-miterlimit:3}
|
||||
.st15 {marker-end:url(#mrkr4-161);stroke:#1897d5;stroke-linecap:round;stroke-linejoin:round;stroke-width:2.25}
|
||||
.st16 {fill:#1897d5;fill-opacity:1;stroke:#1897d5;stroke-opacity:1;stroke-width:0.47169811320755}
|
||||
.st17 {fill:none;fill-rule:evenodd;font-size:12px;overflow:visible;stroke-linecap:square;stroke-miterlimit:3}
|
||||
]]>
|
||||
</style>
|
||||
|
||||
@ -35,162 +30,97 @@
|
||||
<g id="lend4">
|
||||
<path d="M 2 1 L 0 0 L 2 -1 L 2 1 " style="stroke:none"/>
|
||||
</g>
|
||||
<marker id="mrkr4-41" class="st7" v:arrowType="4" v:arrowSize="2" v:setback="4.34" refX="4.34" orient="auto"
|
||||
markerUnits="strokeWidth" overflow="visible">
|
||||
<marker id="mrkr4-42" class="st7" refX="4.34" orient="auto" markerUnits="strokeWidth" overflow="visible">
|
||||
<use xlink:href="#lend4" transform="scale(2.26) "/>
|
||||
</marker>
|
||||
<marker id="mrkr4-43" class="st7" v:arrowType="4" v:arrowSize="2" v:setback="4.52" refX="-4.52" orient="auto"
|
||||
markerUnits="strokeWidth" overflow="visible">
|
||||
<marker id="mrkr4-44" class="st7" refX="-4.52" orient="auto" markerUnits="strokeWidth" overflow="visible">
|
||||
<use xlink:href="#lend4" transform="scale(-2.26,-2.26) "/>
|
||||
</marker>
|
||||
<marker id="mrkr4-161" class="st16" refX="-4.24" orient="auto" markerUnits="strokeWidth" overflow="visible">
|
||||
<use xlink:href="#lend4" transform="scale(-2.12,-2.12) "/>
|
||||
</marker>
|
||||
</defs>
|
||||
<g v:mID="0" v:index="1" v:groupContext="foregroundPage">
|
||||
<v:userDefs>
|
||||
<v:ud v:nameU="msvThemeOrder" v:val="VT0(0):26"/>
|
||||
</v:userDefs>
|
||||
<g>
|
||||
<title>Page-1</title>
|
||||
<v:pageProperties v:drawingScale="0.0393701" v:pageScale="0.0393701" v:drawingUnits="24" v:shadowOffsetX="8.50394"
|
||||
v:shadowOffsetY="-8.50394"/>
|
||||
<v:layer v:name="Connector" v:index="0"/>
|
||||
<v:layer v:name="Flowchart" v:index="1"/>
|
||||
<g id="shape1023-1" v:mID="1023" v:groupContext="shape" transform="translate(307.343,-28.3465)">
|
||||
<g id="shape1023-1" transform="translate(305.179,-99.2126)">
|
||||
<title>Parallelogram.1023</title>
|
||||
<v:userDefs>
|
||||
<v:ud v:nameU="visVersion" v:prompt="" v:val="VT0(15):26"/>
|
||||
</v:userDefs>
|
||||
<path d="M0 595.28 L102.05 595.28 L113.39 510.24 L11.34 510.24 L0 595.28 Z" class="st1"/>
|
||||
</g>
|
||||
<g id="shape1-3" v:mID="1" v:groupContext="shape" transform="translate(331.214,-253.382)">
|
||||
<g id="shape1-3" transform="translate(329.049,-324.248)">
|
||||
<title>Rectangle</title>
|
||||
<desc>Controller Worker Driver</desc>
|
||||
<v:userDefs>
|
||||
<v:ud v:nameU="visVersion" v:val="VT0(15):26"/>
|
||||
</v:userDefs>
|
||||
<v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/>
|
||||
<v:textRect cx="223.228" cy="569.54" width="446.46" height="51.4712"/>
|
||||
<rect x="0" y="543.804" width="446.457" height="51.4712" class="st2"/>
|
||||
<text x="147.47" y="573.74" class="st3" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Controller Worker Driver</text> </g>
|
||||
<g id="shape2-6" v:mID="2" v:groupContext="shape" transform="translate(451.214,-166.925)">
|
||||
<text x="147.47" y="573.74" class="st3">Controller Worker Driver</text> </g>
|
||||
<g id="shape2-6" transform="translate(449.049,-237.791)">
|
||||
<title>Square</title>
|
||||
<desc>Certificate Driver</desc>
|
||||
<v:userDefs>
|
||||
<v:ud v:nameU="visVersion" v:val="VT0(15):26"/>
|
||||
</v:userDefs>
|
||||
<v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/>
|
||||
<v:textRect cx="43.2283" cy="552.047" width="86.46" height="86.4567"/>
|
||||
<rect x="0" y="508.819" width="86.4567" height="86.4567" class="st2"/>
|
||||
<text x="12.02" y="547.85" class="st3" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Certificate<v:newlineChar/><tspan
|
||||
x="24.74" dy="1.2em" class="st4">Driver</tspan></text> </g>
|
||||
<g id="shape3-10" v:mID="3" v:groupContext="shape" transform="translate(571.214,-166.925)">
|
||||
<text x="12.02" y="547.85" class="st3">Certificate <tspan x="24.74" dy="1.2em" class="st4">Driver</tspan></text> </g>
|
||||
<g id="shape3-10" transform="translate(569.049,-237.791)">
|
||||
<title>Square.3</title>
|
||||
<desc>Compute Driver</desc>
|
||||
<v:userDefs>
|
||||
<v:ud v:nameU="visVersion" v:val="VT0(15):26"/>
|
||||
</v:userDefs>
|
||||
<v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/>
|
||||
<v:textRect cx="43.2283" cy="552.047" width="86.46" height="86.4567"/>
|
||||
<rect x="0" y="508.819" width="86.4567" height="86.4567" class="st2"/>
|
||||
<text x="14.65" y="547.85" class="st3" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Compute<v:newlineChar/><tspan
|
||||
x="24.74" dy="1.2em" class="st4">Driver</tspan></text> </g>
|
||||
<g id="shape4-14" v:mID="4" v:groupContext="shape" transform="translate(691.214,-166.925)">
|
||||
<text x="14.65" y="547.85" class="st3">Compute <tspan x="24.74" dy="1.2em" class="st4">Driver</tspan></text> </g>
|
||||
<g id="shape4-14" transform="translate(689.049,-237.791)">
|
||||
<title>Square.4</title>
|
||||
<desc>Network Driver</desc>
|
||||
<v:userDefs>
|
||||
<v:ud v:nameU="visVersion" v:val="VT0(15):26"/>
|
||||
</v:userDefs>
|
||||
<v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/>
|
||||
<v:textRect cx="43.2283" cy="552.047" width="86.46" height="86.4567"/>
|
||||
<rect x="0" y="508.819" width="86.4567" height="86.4567" class="st2"/>
|
||||
<text x="16.89" y="547.85" class="st3" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Network<v:newlineChar/><tspan
|
||||
x="24.74" dy="1.2em" class="st4">Driver</tspan></text> </g>
|
||||
<g id="shape5-18" v:mID="5" v:groupContext="shape" transform="translate(331.214,-166.925)">
|
||||
<text x="16.89" y="547.85" class="st3">Network <tspan x="24.74" dy="1.2em" class="st4">Driver</tspan></text> </g>
|
||||
<g id="shape5-18" transform="translate(329.049,-237.791)">
|
||||
<title>Square.5</title>
|
||||
<desc>Amphora Driver</desc>
|
||||
<v:userDefs>
|
||||
<v:ud v:nameU="visVersion" v:val="VT0(15):26"/>
|
||||
</v:userDefs>
|
||||
<v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/>
|
||||
<v:textRect cx="43.2283" cy="552.047" width="86.46" height="86.4567"/>
|
||||
<rect x="0" y="508.819" width="86.4567" height="86.4567" class="st2"/>
|
||||
<text x="14.51" y="547.85" class="st3" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Amphora<v:newlineChar/><tspan
|
||||
x="24.74" dy="1.2em" class="st4">Driver</tspan></text> </g>
|
||||
<g id="shape1001-22" v:mID="1001" v:groupContext="shape" transform="translate(687.192,-53.5394)">
|
||||
<text x="14.51" y="547.85" class="st3">Amphora <tspan x="24.74" dy="1.2em" class="st4">Driver</tspan></text> </g>
|
||||
<g id="shape1001-22" transform="translate(685.028,-124.406)">
|
||||
<title>Ellipse.6</title>
|
||||
<desc>Neutron</desc>
|
||||
<v:userDefs>
|
||||
<v:ud v:nameU="visVersion" v:val="VT0(15):26"/>
|
||||
</v:userDefs>
|
||||
<v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/>
|
||||
<v:textRect cx="47.25" cy="563.776" width="82.69" height="55.125"/>
|
||||
<path d="M0 563.78 A47.25 31.5 0 0 1 94.5 563.78 A47.25 31.5 0 1 1 0 563.78 Z" class="st5"/>
|
||||
<text x="21.52" y="567.98" class="st3" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Neutron</text> </g>
|
||||
<g id="shape1002-25" v:mID="1002" v:groupContext="shape" transform="translate(567.192,-53.5394)">
|
||||
<text x="21.52" y="567.98" class="st3">Neutron</text> </g>
|
||||
<g id="shape1002-25" transform="translate(565.028,-124.406)">
|
||||
<title>Ellipse.5</title>
|
||||
<desc>Nova</desc>
|
||||
<v:userDefs>
|
||||
<v:ud v:nameU="visVersion" v:val="VT0(15):26"/>
|
||||
</v:userDefs>
|
||||
<v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/>
|
||||
<v:textRect cx="47.25" cy="563.776" width="82.69" height="55.125"/>
|
||||
<path d="M0 563.78 A47.25 31.5 0 0 1 94.5 563.78 A47.25 31.5 0 1 1 0 563.78 Z" class="st5"/>
|
||||
<text x="31" y="567.98" class="st3" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Nova</text> </g>
|
||||
<g id="shape1003-28" v:mID="1003" v:groupContext="shape" transform="translate(447.192,-53.5394)">
|
||||
<text x="31" y="567.98" class="st3">Nova</text> </g>
|
||||
<g id="shape1003-28" transform="translate(445.028,-124.406)">
|
||||
<title>Ellipse.69</title>
|
||||
<desc>Barbican</desc>
|
||||
<v:userDefs>
|
||||
<v:ud v:nameU="visVersion" v:val="VT0(15):26"/>
|
||||
</v:userDefs>
|
||||
<v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/>
|
||||
<v:textRect cx="47.25" cy="563.776" width="82.69" height="55.125"/>
|
||||
<desc>Barbican / Castellan</desc>
|
||||
<path d="M0 563.78 A47.25 31.5 0 0 1 94.5 563.78 A47.25 31.5 0 1 1 0 563.78 Z" class="st5"/>
|
||||
<text x="20.68" y="567.98" class="st3" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Barbican</text> </g>
|
||||
<g id="shape1004-31" v:mID="1004" v:groupContext="shape" transform="translate(210.906,-330.27)">
|
||||
<text x="16.03" y="559.58" class="st3">Barbican / <tspan x="19.44" dy="1.2em" class="st4">Castellan</tspan></text> </g>
|
||||
<g id="shape1004-32" transform="translate(208.742,-401.136)">
|
||||
<title>Ellipse.3</title>
|
||||
<desc>Oslo Messaging</desc>
|
||||
<v:userDefs>
|
||||
<v:ud v:nameU="visVersion" v:val="VT0(15):26"/>
|
||||
</v:userDefs>
|
||||
<v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/>
|
||||
<v:textRect cx="47.25" cy="563.776" width="82.69" height="55.125"/>
|
||||
<path d="M0 563.78 A47.25 31.5 0 0 1 94.5 563.78 A47.25 31.5 0 1 1 0 563.78 Z" class="st5"/>
|
||||
<text x="33.21" y="559.58" class="st3" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Oslo<v:newlineChar/><tspan
|
||||
x="13.9" dy="1.2em" class="st4">Messaging</tspan></text> </g>
|
||||
<g id="shape1006-35" v:mID="1006" v:groupContext="shape" v:layerMember="0" transform="translate(331.214,-272.031)">
|
||||
<text x="33.21" y="559.58" class="st3">Oslo <tspan x="13.9" dy="1.2em" class="st4">Messaging</tspan></text> </g>
|
||||
<g id="shape1006-36" transform="translate(329.049,-342.897)">
|
||||
<title>Dynamic connector.1006</title>
|
||||
<path d="M-8.68 588.19 L-9.04 588.19 L-29.47 588.19" class="st6"/>
|
||||
</g>
|
||||
<g id="shape1007-44" v:mID="1007" v:groupContext="shape" v:layerMember="0" transform="translate(727.356,-166.925)">
|
||||
<g id="shape1007-45" transform="translate(739.364,-237.791)">
|
||||
<title>Dynamic connector.1007</title>
|
||||
<path d="M7.09 595.28 L7.09 636.62" class="st8"/>
|
||||
<path d="M-7.09 595.28 L-7.09 636.62" class="st8"/>
|
||||
</g>
|
||||
<g id="shape1008-49" v:mID="1008" v:groupContext="shape" v:layerMember="0" transform="translate(607.356,-166.925)">
|
||||
<g id="shape1008-50" transform="translate(605.191,-237.791)">
|
||||
<title>Dynamic connector.1008</title>
|
||||
<path d="M7.09 595.28 L7.09 636.62" class="st8"/>
|
||||
</g>
|
||||
<g id="shape1009-54" v:mID="1009" v:groupContext="shape" v:layerMember="0" transform="translate(487.356,-166.925)">
|
||||
<g id="shape1009-55" transform="translate(485.191,-237.791)">
|
||||
<title>Dynamic connector.1009</title>
|
||||
<path d="M7.09 595.28 L7.09 636.62" class="st8"/>
|
||||
</g>
|
||||
<g id="shape1010-59" v:mID="1010" v:groupContext="shape" v:layerMember="0" transform="translate(417.671,-203.067)">
|
||||
<g id="shape1010-60" transform="translate(415.506,-288.106)">
|
||||
<title>Dynamic connector.1010</title>
|
||||
<path d="M0 588.19 L24.5 588.19" class="st8"/>
|
||||
<path d="M0 602.36 L24.5 602.36" class="st8"/>
|
||||
</g>
|
||||
<g id="group1011-64" transform="translate(71.7133,-304.853)" v:mID="1011" v:groupContext="group">
|
||||
<g id="group1011-65" transform="translate(69.5486,-375.719)">
|
||||
<title>Sheet.1011</title>
|
||||
<g id="shape9-65" v:mID="9" v:groupContext="shape" transform="translate(0,-0.447576)">
|
||||
<g id="shape9-66" transform="translate(0,-0.447576)">
|
||||
<title>Square.9</title>
|
||||
<desc>Octavia API</desc>
|
||||
<v:userDefs>
|
||||
<v:ud v:nameU="visVersion" v:val="VT0(15):26"/>
|
||||
</v:userDefs>
|
||||
<v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/>
|
||||
<v:textRect cx="56.6929" cy="538.583" width="113.39" height="113.386"/>
|
||||
<rect x="0" y="481.89" width="113.386" height="113.386" class="st9"/>
|
||||
<text x="33.64" y="534.38" class="st3" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Octavia<v:newlineChar/><tspan
|
||||
x="46.39" dy="1.2em" class="st4">API</tspan></text> </g>
|
||||
<g id="shape15-69" v:mID="15" v:groupContext="shape" transform="translate(80.3899,0)">
|
||||
<text x="21.42" y="504.09" class="st3">Octavia API</text> </g>
|
||||
<g id="shape15-69" transform="translate(80.3899,-5.68434E-13)">
|
||||
<title>Sheet.15</title>
|
||||
<rect v:rectContext="foreign" x="0" y="564.279" width="32.9959" height="30.9961" class="st10"/>
|
||||
<rect x="0" y="564.279" width="32.9959" height="30.9961" class="st10"/>
|
||||
<image x="0" y="564.279" width="32.9959" height="30.9961" preserveAspectRatio="none" xlink:href="data:image/png;base64,
|
||||
iVBORw0KGgoAAAANSUhEUgAAACEAAAAfCAYAAABplKSyAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMA
|
||||
AA7DAcdvqGQAAAI9SURBVFhHxZYhUxxBEIVXICIQCEQEAolERiAQCEREBAKBQCAQEQj+AzIyMiIiAhGBQCAQCATixAkEAqoQCERE
|
||||
@ -202,25 +132,19 @@
|
||||
5tq5s24jF7wTFwesCDKSkw8U7j/fC+RAlyoasOk1sSp+iIm6krGio3aYg7Sx6/w4rOiQ8TS5eg5Tu+wz75vz47BiiWxORM3gWCIY
|
||||
tYSbxLGFxvcnSXjrfDms6JCxkS0RmxgU41ELuFUk9WIen4YV25CRbJ8Kjf+N9ax1xYp9Y8W+sWK/jKoXFAS4xJXVHUYAAAAASUVO
|
||||
RK5CYII="/>
|
||||
<rect v:rectContext="foreign" x="0" y="564.279" width="32.9959" height="30.9961" class="st10"/>
|
||||
<rect x="0" y="564.279" width="32.9959" height="30.9961" class="st10"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="group1012-73" transform="translate(331.214,-304.853)" v:mID="1012" v:groupContext="group">
|
||||
<g id="group1012-73" transform="translate(329.049,-375.719)">
|
||||
<title>Sheet.1012</title>
|
||||
<g id="shape6-74" v:mID="6" v:groupContext="shape" transform="translate(-1.59872E-14,-0.447576)">
|
||||
<g id="shape6-74" transform="translate(0,-0.447576)">
|
||||
<title>Square.6</title>
|
||||
<desc>Octavia Worker</desc>
|
||||
<v:userDefs>
|
||||
<v:ud v:nameU="visVersion" v:val="VT0(15):26"/>
|
||||
</v:userDefs>
|
||||
<v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/>
|
||||
<v:textRect cx="56.6929" cy="538.583" width="113.39" height="113.386"/>
|
||||
<rect x="0" y="481.89" width="113.386" height="113.386" class="st9"/>
|
||||
<text x="33.64" y="534.38" class="st3" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Octavia<v:newlineChar/><tspan
|
||||
x="34.05" dy="1.2em" class="st4">Worker</tspan></text> </g>
|
||||
<g id="shape16-78" v:mID="16" v:groupContext="shape" transform="translate(80.3899,0)">
|
||||
<text x="33.64" y="534.38" class="st3">Octavia <tspan x="34.05" dy="1.2em" class="st4">Worker</tspan></text> </g>
|
||||
<g id="shape16-78" transform="translate(80.3899,0)">
|
||||
<title>Sheet.16</title>
|
||||
<rect v:rectContext="foreign" x="0" y="564.279" width="32.9959" height="30.9961" class="st10"/>
|
||||
<rect x="0" y="564.279" width="32.9959" height="30.9961" class="st10"/>
|
||||
<image x="0" y="564.279" width="32.9959" height="30.9961" preserveAspectRatio="none" xlink:href="data:image/png;base64,
|
||||
iVBORw0KGgoAAAANSUhEUgAAACEAAAAfCAYAAABplKSyAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMA
|
||||
AA7DAcdvqGQAAAI9SURBVFhHxZYhUxxBEIVXICIQCEQEAolERiAQCEREBAKBQCAQEQj+AzIyMiIiAhGBQCAQCATixAkEAqoQCERE
|
||||
@ -232,25 +156,19 @@
|
||||
5tq5s24jF7wTFwesCDKSkw8U7j/fC+RAlyoasOk1sSp+iIm6krGio3aYg7Sx6/w4rOiQ8TS5eg5Tu+wz75vz47BiiWxORM3gWCIY
|
||||
tYSbxLGFxvcnSXjrfDms6JCxkS0RmxgU41ELuFUk9WIen4YV25CRbJ8Kjf+N9ax1xYp9Y8W+sWK/jKoXFAS4xJXVHUYAAAAASUVO
|
||||
RK5CYII="/>
|
||||
<rect v:rectContext="foreign" x="0" y="564.279" width="32.9959" height="30.9961" class="st10"/>
|
||||
<rect x="0" y="564.279" width="32.9959" height="30.9961" class="st10"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="group1013-82" transform="translate(497.749,-305.301)" v:mID="1013" v:groupContext="group">
|
||||
<g id="group1013-82" transform="translate(495.585,-376.167)">
|
||||
<title>Sheet.1013</title>
|
||||
<g id="shape7-83" v:mID="7" v:groupContext="shape">
|
||||
<g id="shape7-83">
|
||||
<title>Square.7</title>
|
||||
<desc>Health Manager</desc>
|
||||
<v:userDefs>
|
||||
<v:ud v:nameU="visVersion" v:val="VT0(15):26"/>
|
||||
</v:userDefs>
|
||||
<v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/>
|
||||
<v:textRect cx="56.6929" cy="538.583" width="113.39" height="113.386"/>
|
||||
<rect x="0" y="481.89" width="113.386" height="113.386" class="st9"/>
|
||||
<text x="36.47" y="534.38" class="st3" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Health<v:newlineChar/><tspan
|
||||
x="29.11" dy="1.2em" class="st4">Manager</tspan></text> </g>
|
||||
<g id="shape17-87" v:mID="17" v:groupContext="shape" transform="translate(80.3899,0)">
|
||||
<text x="36.47" y="534.38" class="st3">Health <tspan x="29.11" dy="1.2em" class="st4">Manager</tspan></text> </g>
|
||||
<g id="shape17-87" transform="translate(80.3899,0)">
|
||||
<title>Sheet.17</title>
|
||||
<rect v:rectContext="foreign" x="0" y="564.279" width="32.9959" height="30.9961" class="st10"/>
|
||||
<rect x="0" y="564.279" width="32.9959" height="30.9961" class="st10"/>
|
||||
<image x="0" y="564.279" width="32.9959" height="30.9961" preserveAspectRatio="none" xlink:href="data:image/png;base64,
|
||||
iVBORw0KGgoAAAANSUhEUgAAACEAAAAfCAYAAABplKSyAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMA
|
||||
AA7DAcdvqGQAAAI9SURBVFhHxZYhUxxBEIVXICIQCEQEAolERiAQCEREBAKBQCAQEQj+AzIyMiIiAhGBQCAQCATixAkEAqoQCERE
|
||||
@ -262,25 +180,19 @@
|
||||
5tq5s24jF7wTFwesCDKSkw8U7j/fC+RAlyoasOk1sSp+iIm6krGio3aYg7Sx6/w4rOiQ8TS5eg5Tu+wz75vz47BiiWxORM3gWCIY
|
||||
tYSbxLGFxvcnSXjrfDms6JCxkS0RmxgU41ELuFUk9WIen4YV25CRbJ8Kjf+N9ax1xYp9Y8W+sWK/jKoXFAS4xJXVHUYAAAAASUVO
|
||||
RK5CYII="/>
|
||||
<rect v:rectContext="foreign" x="0" y="564.279" width="32.9959" height="30.9961" class="st10"/>
|
||||
<rect x="0" y="564.279" width="32.9959" height="30.9961" class="st10"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="group1014-91" transform="translate(664.285,-304.853)" v:mID="1014" v:groupContext="group">
|
||||
<g id="group1014-91" transform="translate(662.12,-375.719)">
|
||||
<title>Sheet.1014</title>
|
||||
<g id="shape8-92" v:mID="8" v:groupContext="shape" transform="translate(3.19744E-14,-0.447576)">
|
||||
<g id="shape8-92" transform="translate(3.19744E-14,-0.447576)">
|
||||
<title>Square.8</title>
|
||||
<desc>Housekeeping Manager</desc>
|
||||
<v:userDefs>
|
||||
<v:ud v:nameU="visVersion" v:val="VT0(15):26"/>
|
||||
</v:userDefs>
|
||||
<v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/>
|
||||
<v:textRect cx="56.6929" cy="538.583" width="113.39" height="113.386"/>
|
||||
<rect x="0" y="481.89" width="113.386" height="113.386" class="st9"/>
|
||||
<text x="12.33" y="534.38" class="st3" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Housekeeping<v:newlineChar/><tspan
|
||||
x="29.11" dy="1.2em" class="st4">Manager</tspan></text> </g>
|
||||
<g id="shape18-96" v:mID="18" v:groupContext="shape" transform="translate(80.3899,0)">
|
||||
<text x="12.33" y="534.38" class="st3">Housekeeping <tspan x="29.11" dy="1.2em" class="st4">Manager</tspan></text> </g>
|
||||
<g id="shape18-96" transform="translate(80.3899,0)">
|
||||
<title>Sheet.18</title>
|
||||
<rect v:rectContext="foreign" x="0" y="564.279" width="32.9959" height="30.9961" class="st10"/>
|
||||
<rect x="0" y="564.279" width="32.9959" height="30.9961" class="st10"/>
|
||||
<image x="0" y="564.279" width="32.9959" height="30.9961" preserveAspectRatio="none" xlink:href="data:image/png;base64,
|
||||
iVBORw0KGgoAAAANSUhEUgAAACEAAAAfCAYAAABplKSyAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMA
|
||||
AA7DAcdvqGQAAAI9SURBVFhHxZYhUxxBEIVXICIQCEQEAolERiAQCEREBAKBQCAQEQj+AzIyMiIiAhGBQCAQCATixAkEAqoQCERE
|
||||
@ -292,109 +204,88 @@
|
||||
5tq5s24jF7wTFwesCDKSkw8U7j/fC+RAlyoasOk1sSp+iIm6krGio3aYg7Sx6/w4rOiQ8TS5eg5Tu+wz75vz47BiiWxORM3gWCIY
|
||||
tYSbxLGFxvcnSXjrfDms6JCxkS0RmxgU41ELuFUk9WIen4YV25CRbJ8Kjf+N9ax1xYp9Y8W+sWK/jKoXFAS4xJXVHUYAAAAASUVO
|
||||
RK5CYII="/>
|
||||
<rect v:rectContext="foreign" x="0" y="564.279" width="32.9959" height="30.9961" class="st10"/>
|
||||
<rect x="0" y="564.279" width="32.9959" height="30.9961" class="st10"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="shape1016-100" v:mID="1016" v:groupContext="shape" v:layerMember="0" transform="translate(185.099,-368.968)">
|
||||
<g id="shape1016-100" transform="translate(168.761,-425.464)">
|
||||
<title>Dynamic connector.1016</title>
|
||||
<path d="M0 602.25 L16.77 602.4" class="st8"/>
|
||||
<path d="M0 588.27 L30.94 588.14" class="st8"/>
|
||||
</g>
|
||||
<g id="shape1017-105" v:mID="1017" v:groupContext="shape" v:layerMember="0" transform="translate(305.406,-354.795)">
|
||||
<g id="shape1017-105" transform="translate(303.242,-425.661)">
|
||||
<title>Dynamic connector.1017</title>
|
||||
<path d="M0 588.3 L16.77 588.16" class="st8"/>
|
||||
</g>
|
||||
<g id="shape1018-110" v:mID="1018" v:groupContext="shape" v:layerMember="0" transform="translate(128.406,-305.301)">
|
||||
<g id="shape1018-110" transform="translate(126.242,-376.167)">
|
||||
<title>Dynamic connector.1018</title>
|
||||
<path d="M0 603.96 L0 604.32 L0 621.46 L86.16 621.46" class="st6"/>
|
||||
</g>
|
||||
<g id="group1019-117" transform="translate(223.609,-244.57)" v:mID="1019" v:groupContext="group">
|
||||
<v:userDefs>
|
||||
<v:ud v:nameU="visVersion" v:prompt="" v:val="VT0(15):26"/>
|
||||
</v:userDefs>
|
||||
<g id="group1019-117" transform="translate(221.445,-315.436)">
|
||||
<title>Can.1019</title>
|
||||
<desc>Database</desc>
|
||||
<g id="shape1020-118" v:mID="1020" v:groupContext="shape">
|
||||
<g id="shape1020-118">
|
||||
<title>Sheet.1020</title>
|
||||
<v:userDefs>
|
||||
<v:ud v:nameU="ControlHalfHeight" v:prompt="" v:val="VT0(0.11811023622047):24"/>
|
||||
<v:ud v:nameU="FillForegnd" v:prompt="" v:val="VT0(1):26"/>
|
||||
<v:ud v:nameU="ControlHalfHeight" v:prompt="" v:val="VT0(0.095964566929134):1"/>
|
||||
<v:ud v:nameU="FillForegnd" v:prompt="" v:val="VT5(#d80073)"/>
|
||||
</v:userDefs>
|
||||
<path d="M0 588.37 A34.5472 6.90945 -180 0 0 69.09 588.37 L69.09 533.09 L0 533.09 L0 588.37 Z" class="st5"/>
|
||||
</g>
|
||||
<g id="shape1019-120" v:mID="1019" v:groupContext="groupContent">
|
||||
<v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/>
|
||||
<v:textRect cx="34.5472" cy="560.728" width="69.1" height="69.0945"/>
|
||||
<g id="shape1019-120">
|
||||
<ellipse cx="34.5472" cy="533.091" rx="34.5472" ry="6.90945" class="st5"/>
|
||||
<text x="5.84" y="564.93" class="st3" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Database</text> </g>
|
||||
<text x="5.84" y="564.93" class="st3">Database</text> </g>
|
||||
</g>
|
||||
<g id="shape1021-123" v:mID="1021" v:groupContext="shape" transform="translate(293.17,-39.3661)">
|
||||
<g id="shape1021-123" transform="translate(291.005,-110.232)">
|
||||
<title>Parallelogram.1021</title>
|
||||
<v:userDefs>
|
||||
<v:ud v:nameU="visVersion" v:prompt="" v:val="VT0(15):26"/>
|
||||
</v:userDefs>
|
||||
<path d="M0 595.28 L102.05 595.28 L113.39 510.24 L11.34 510.24 L0 595.28 Z" class="st11"/>
|
||||
</g>
|
||||
<g id="shape1022-125" v:mID="1022" v:groupContext="shape" transform="translate(278.531,-50.3858)">
|
||||
<g id="shape1022-125" transform="translate(276.366,-121.252)">
|
||||
<title>Parallelogram.1022</title>
|
||||
<desc>Amphora</desc>
|
||||
<v:userDefs>
|
||||
<v:ud v:nameU="visVersion" v:prompt="" v:val="VT0(15):26"/>
|
||||
</v:userDefs>
|
||||
<v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/>
|
||||
<v:textRect cx="56.6929" cy="552.756" width="113.39" height="85.0394"/>
|
||||
<path d="M0 595.28 L102.05 595.28 L113.39 510.24 L11.34 510.24 L0 595.28 Z" class="st12"/>
|
||||
<text x="27.98" y="556.96" class="st3" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Amphora</text> </g>
|
||||
<g id="group1054-128" transform="translate(359.038,-138.579)" v:mID="1054" v:groupContext="group">
|
||||
<text x="27.98" y="556.96" class="st3">Amphora</text> </g>
|
||||
<g id="group1054-128" transform="translate(356.874,-209.445)">
|
||||
<title>Sheet.1054</title>
|
||||
<g id="shape1050-129" v:mID="1050" v:groupContext="shape" v:layerMember="0" transform="translate(30.8081,-28.3465)">
|
||||
<g id="shape1050-129" transform="translate(30.8081,-28.3465)">
|
||||
<title>Dynamic connector.1050</title>
|
||||
<path d="M-6.99 603.95 L-7 604.31 L-7.33 623.62" class="st13"/>
|
||||
</g>
|
||||
<g id="shape1051-134" v:mID="1051" v:groupContext="shape" v:layerMember="0" transform="translate(14.1732,-28.3465)">
|
||||
<g id="shape1051-134" transform="translate(14.1732,-28.3465)">
|
||||
<title>Dynamic connector.1051</title>
|
||||
<path d="M-6.84 595.28 L-7.17 614.58" class="st8"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="group1064-139" transform="translate(60.1975,-453.543)" v:mID="1064" v:groupContext="group">
|
||||
<title>Sheet.1064</title>
|
||||
<g id="shape1056-140" v:mID="1056" v:groupContext="shape">
|
||||
<title>Rectangle.1056</title>
|
||||
<desc>Neutron</desc>
|
||||
<v:userDefs>
|
||||
<v:ud v:nameU="visVersion" v:val="VT0(15):26"/>
|
||||
</v:userDefs>
|
||||
<v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/>
|
||||
<v:textRect cx="68.2087" cy="491.339" width="136.42" height="18.8976"/>
|
||||
<rect x="0" y="481.89" width="136.417" height="113.386" class="st5"/>
|
||||
<text x="42.48" y="495.54" class="st3" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Neutron</text> </g>
|
||||
<g id="shape1057-143" v:mID="1057" v:groupContext="shape" transform="translate(11.5157,-11.3386)">
|
||||
<title>Rectangle.1057</title>
|
||||
<desc>LBaaS v2 User API Handler</desc>
|
||||
<v:userDefs>
|
||||
<v:ud v:nameU="visVersion" v:val="VT0(15):26"/>
|
||||
</v:userDefs>
|
||||
<v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/>
|
||||
<v:textRect cx="56.6929" cy="537.101" width="113.39" height="42.3913"/>
|
||||
<rect x="0" y="515.906" width="113.386" height="79.3701" class="st14"/>
|
||||
<text x="29.5" y="532.9" class="st3" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>LBaaS v2<v:newlineChar/><tspan
|
||||
x="4.28" dy="1.2em" class="st4">User API Handler</tspan></text> </g>
|
||||
<g id="shape1058-147" v:mID="1058" v:groupContext="shape" transform="translate(20.9587,-17.0079)">
|
||||
<title>Rectangle.1058</title>
|
||||
<desc>Octavia Driver</desc>
|
||||
<v:userDefs>
|
||||
<v:ud v:nameU="visVersion" v:val="VT0(15):26"/>
|
||||
</v:userDefs>
|
||||
<v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/>
|
||||
<v:textRect cx="47.25" cy="577.01" width="94.5" height="36.5315"/>
|
||||
<rect x="0" y="558.744" width="94.5" height="36.5315" class="st9"/>
|
||||
<text x="24.2" y="572.81" class="st3" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Octavia <tspan
|
||||
x="28.77" dy="1.2em" class="st4">Driver</tspan></text> </g>
|
||||
<g id="shape1056-139" transform="translate(83.7218,-411.024)">
|
||||
<title>Sheet.1056</title>
|
||||
<desc>Amphora Driver</desc>
|
||||
<rect x="0" y="552.756" width="85.0394" height="42.5197" class="st14"/>
|
||||
<text x="13.8" y="569.82" class="st3">Amphora <tspan x="24.04" dy="1.2em" class="st4">Driver</tspan></text> </g>
|
||||
<g id="group1057-143" transform="translate(69.5486,-212.598)">
|
||||
<title>Sheet.1057</title>
|
||||
<g id="shape1058-144">
|
||||
<title>Square.7</title>
|
||||
<desc>Driver Agent</desc>
|
||||
<rect x="0" y="481.89" width="113.386" height="113.386" class="st9"/>
|
||||
<text x="17.66" y="542.78" class="st3">Driver Agent</text> </g>
|
||||
<g id="shape19-147" transform="translate(80.3899,0)">
|
||||
<title>Sheet.19</title>
|
||||
<rect x="0" y="564.279" width="32.9959" height="30.9961" class="st10"/>
|
||||
<image x="0" y="564.279" width="32.9959" height="30.9961" preserveAspectRatio="none" xlink:href="data:image/png;base64,
|
||||
iVBORw0KGgoAAAANSUhEUgAAACEAAAAfCAYAAABplKSyAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMA
|
||||
AA7DAcdvqGQAAAI9SURBVFhHxZYhUxxBEIVXICIQCEQEAolERiAQCEREBAKBQCAQEQj+AzIyMiIiAhGBQCAQCATixAkEAqoQCERE
|
||||
BAJxvC9sX/UNb2/3iqpNV311M29mumd3evq2Go1G/x0r9o0V+8aKfWPFLsjmiv587s+CFach+yxOxHmhfxfX4qtYyGNtWNEhOxQ0
|
||||
4Lb+XanH5sVfETptNtXp7VjRIfstngUd+CMeBYEfRB5Du3Z+HFZ0yDbqAF1gQwfOj8OKgexjam+LCNIGm7gQ/45DtgDhq8SKIFsX
|
||||
T+KnIB/y6+7KpTgW+DlyccCKIPsl7gXnnR3PAsHJjyuBn4lrPY5lxapaFDjIDh1lMuYxx5aNZ8XJ69gEt+NAcGw7gqeddmSMndp4
|
||||
VqyqTYFTOlzDcJTZKNZ8ECTjQJRzgbG9vGa81omBjCfNjoJhw/wvaU5mas2wYiDbTY4yEyU7zW+qJbNvQkZi7osbkZ0FlOVxDUnr
|
||||
juqxcj5Ju1bOD7z4ej1pnNa/JSQlZ7yU1lDMmhIzbo5/g1Z8zfhw0AQJS1AKUlstuRPMtQXrjRDI+Fs+E9nZe2ATyzaWE0EWtYIz
|
||||
5tq5s24jF7wTFwesCDKSkw8U7j/fC+RAlyoasOk1sSp+iIm6krGio3aYg7Sx6/w4rOiQ8TS5eg5Tu+wz75vz47BiiWxORM3gWCIY
|
||||
tYSbxLGFxvcnSXjrfDms6JCxkS0RmxgU41ELuFUk9WIen4YV25CRbJ8Kjf+N9ax1xYp9Y8W+sWK/jKoXFAS4xJXVHUYAAAAASUVO
|
||||
RK5CYII="/>
|
||||
<rect x="0" y="564.279" width="32.9959" height="30.9961" class="st10"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="shape1065-151" v:mID="1065" v:groupContext="shape" v:layerMember="0" transform="translate(121.32,-470.551)">
|
||||
<title>Dynamic connector.1065</title>
|
||||
<path d="M7.09 595.28 L7.09 638.1" class="st8"/>
|
||||
<g id="shape1059-151" transform="translate(90.2835,-411.024)">
|
||||
<title>Dynamic connector.1059</title>
|
||||
<path d="M7.09 595.28 L7.09 671.27" class="st8"/>
|
||||
</g>
|
||||
<g id="shape1061-156" transform="translate(182.934,-269.291)">
|
||||
<title>Dynamic connector</title>
|
||||
<path d="M0 595.28 L73.06 595.28 L73.06 558.67" class="st15"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 18 KiB |
@ -460,3 +460,23 @@
|
||||
# A URL representing messaging driver to use for notification. If not
|
||||
# specified, we fall back to the same configuration used for RPC.
|
||||
# transport_url =
|
||||
|
||||
[driver_agent]
|
||||
# status_socket_path = /var/run/octavia/status.sock
|
||||
# stats_socket_path = /var/run/octavia/stats.sock
|
||||
|
||||
# Maximum time to wait for a status message before checking for shutdown
|
||||
# status_request_timeout = 5
|
||||
|
||||
# Maximum number of status processes per driver-agent
|
||||
# status_max_processes = 50
|
||||
|
||||
# Maximum time to wait for a stats message before checking for shutdown
|
||||
# stats_request_timeout = 5
|
||||
|
||||
# Maximum number of stats processes per driver-agent
|
||||
# stats_max_processes = 50
|
||||
|
||||
# Percentage of max_processes (both status and stats) in use to start
|
||||
# logging warning messages about an overloaded driver-agent.
|
||||
# max_process_warning_percent = .75
|
||||
|
@ -72,6 +72,7 @@ munch==2.2.0
|
||||
netaddr==0.7.19
|
||||
netifaces==0.10.4
|
||||
networkx==1.11
|
||||
octavia-lib==1.1.1
|
||||
openstacksdk==0.12.0
|
||||
os-client-config==1.29.0
|
||||
os-service-types==1.2.0
|
||||
|
@ -14,15 +14,17 @@
|
||||
|
||||
from jsonschema import exceptions as js_exceptions
|
||||
from jsonschema import validate
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
import oslo_messaging as messaging
|
||||
from stevedore import driver as stevedore_driver
|
||||
|
||||
from octavia_lib.api.drivers import data_models as driver_dm
|
||||
from octavia_lib.api.drivers import exceptions
|
||||
from octavia_lib.api.drivers import provider_base as driver_base
|
||||
|
||||
from octavia.api.drivers.amphora_driver import flavor_schema
|
||||
from octavia.api.drivers import data_models as driver_dm
|
||||
from octavia.api.drivers import exceptions
|
||||
from octavia.api.drivers import provider_base as driver_base
|
||||
from octavia.api.drivers import utils as driver_utils
|
||||
from octavia.common import constants as consts
|
||||
from octavia.common import data_models
|
||||
@ -93,7 +95,7 @@ class AmphoraProviderDriver(driver_base.ProviderDriver):
|
||||
# expects
|
||||
vip_qos_policy_id = lb_dict.pop('vip_qos_policy_id', None)
|
||||
if vip_qos_policy_id:
|
||||
vip_dict = {"qos_policy_id": vip_qos_policy_id}
|
||||
vip_dict = {"vip_qos_policy_id": vip_qos_policy_id}
|
||||
lb_dict["vip"] = vip_dict
|
||||
|
||||
payload = {consts.LOAD_BALANCER_ID: lb_id,
|
||||
|
@ -15,270 +15,44 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import six
|
||||
import warnings
|
||||
|
||||
from oslo_log import log as logging
|
||||
from debtcollector import moves
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
from octavia_lib.api.drivers import data_models as lib_data_models
|
||||
|
||||
|
||||
class BaseDataModel(object):
|
||||
def to_dict(self, calling_classes=None, recurse=False,
|
||||
render_unsets=False, **kwargs):
|
||||
"""Converts a data model to a dictionary."""
|
||||
calling_classes = calling_classes or []
|
||||
ret = {}
|
||||
for attr in self.__dict__:
|
||||
if attr.startswith('_') or not kwargs.get(attr, True):
|
||||
continue
|
||||
value = self.__dict__[attr]
|
||||
warnings.simplefilter('default', DeprecationWarning)
|
||||
|
||||
if recurse:
|
||||
if isinstance(getattr(self, attr), list):
|
||||
ret[attr] = []
|
||||
for item in value:
|
||||
if isinstance(item, BaseDataModel):
|
||||
if type(self) not in calling_classes:
|
||||
ret[attr].append(
|
||||
item.to_dict(calling_classes=(
|
||||
calling_classes + [type(self)]),
|
||||
recurse=True,
|
||||
render_unsets=render_unsets))
|
||||
else:
|
||||
ret[attr].append(None)
|
||||
else:
|
||||
ret[attr].append(item)
|
||||
elif isinstance(getattr(self, attr), BaseDataModel):
|
||||
if type(self) not in calling_classes:
|
||||
ret[attr] = value.to_dict(
|
||||
render_unsets=render_unsets,
|
||||
calling_classes=calling_classes + [type(self)])
|
||||
else:
|
||||
ret[attr] = None
|
||||
elif six.PY2 and isinstance(value, six.text_type):
|
||||
ret[attr.encode('utf8')] = value.encode('utf8')
|
||||
elif isinstance(value, UnsetType):
|
||||
if render_unsets:
|
||||
ret[attr] = None
|
||||
else:
|
||||
continue
|
||||
else:
|
||||
ret[attr] = value
|
||||
else:
|
||||
if (isinstance(getattr(self, attr), (BaseDataModel, list)) or
|
||||
isinstance(value, UnsetType)):
|
||||
if render_unsets:
|
||||
ret[attr] = None
|
||||
else:
|
||||
continue
|
||||
else:
|
||||
ret[attr] = value
|
||||
BaseDataModel = moves.moved_class(lib_data_models.BaseDataModel,
|
||||
'BaseDataModel', __name__,
|
||||
version='Stein', removal_version='U')
|
||||
|
||||
return ret
|
||||
UnsetType = moves.moved_class(lib_data_models.UnsetType, 'UnsetType', __name__,
|
||||
version='Stein', removal_version='U')
|
||||
|
||||
def __eq__(self, other):
|
||||
if isinstance(other, self.__class__):
|
||||
return self.to_dict() == other.to_dict()
|
||||
return False
|
||||
LoadBalancer = moves.moved_class(lib_data_models.LoadBalancer, 'LoadBalancer',
|
||||
__name__, version='Stein',
|
||||
removal_version='U')
|
||||
|
||||
def __ne__(self, other):
|
||||
return not self.__eq__(other)
|
||||
Listener = moves.moved_class(lib_data_models.Listener, 'Listener', __name__,
|
||||
version='Stein', removal_version='U')
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, dict):
|
||||
return cls(**dict)
|
||||
Pool = moves.moved_class(lib_data_models.Pool, 'Pool', __name__,
|
||||
version='Stein', removal_version='U')
|
||||
|
||||
Member = moves.moved_class(lib_data_models.Member, 'Member', __name__,
|
||||
version='Stein', removal_version='U')
|
||||
|
||||
class UnsetType(object):
|
||||
def __bool__(self):
|
||||
return False
|
||||
__nonzero__ = __bool__
|
||||
HealthMonitor = moves.moved_class(lib_data_models.HealthMonitor,
|
||||
'HealthMonitor', __name__,
|
||||
version='Stein', removal_version='U')
|
||||
|
||||
def __repr__(self):
|
||||
return 'Unset'
|
||||
L7Policy = moves.moved_class(lib_data_models.L7Policy, 'L7Policy', __name__,
|
||||
version='Stein', removal_version='U')
|
||||
|
||||
L7Rule = moves.moved_class(lib_data_models.L7Rule, 'L7Rule', __name__,
|
||||
version='Stein', removal_version='U')
|
||||
|
||||
Unset = UnsetType()
|
||||
|
||||
|
||||
class LoadBalancer(BaseDataModel):
|
||||
def __init__(self, admin_state_up=Unset, description=Unset, flavor=Unset,
|
||||
listeners=Unset, loadbalancer_id=Unset, name=Unset,
|
||||
pools=Unset, project_id=Unset, vip_address=Unset,
|
||||
vip_network_id=Unset, vip_port_id=Unset, vip_subnet_id=Unset,
|
||||
vip_qos_policy_id=Unset):
|
||||
|
||||
self.admin_state_up = admin_state_up
|
||||
self.description = description
|
||||
self.flavor = flavor
|
||||
self.listeners = listeners
|
||||
self.loadbalancer_id = loadbalancer_id
|
||||
self.name = name
|
||||
self.pools = pools
|
||||
self.project_id = project_id
|
||||
self.vip_address = vip_address
|
||||
self.vip_network_id = vip_network_id
|
||||
self.vip_port_id = vip_port_id
|
||||
self.vip_subnet_id = vip_subnet_id
|
||||
self.vip_qos_policy_id = vip_qos_policy_id
|
||||
|
||||
|
||||
class Listener(BaseDataModel):
|
||||
def __init__(self, admin_state_up=Unset, connection_limit=Unset,
|
||||
default_pool=Unset, default_pool_id=Unset,
|
||||
default_tls_container_ref=Unset,
|
||||
default_tls_container_data=Unset, description=Unset,
|
||||
insert_headers=Unset, l7policies=Unset, listener_id=Unset,
|
||||
loadbalancer_id=Unset, name=Unset, protocol=Unset,
|
||||
protocol_port=Unset, sni_container_refs=Unset,
|
||||
sni_container_data=Unset, timeout_client_data=Unset,
|
||||
timeout_member_connect=Unset, timeout_member_data=Unset,
|
||||
timeout_tcp_inspect=Unset, client_ca_tls_container_ref=Unset,
|
||||
client_ca_tls_container_data=Unset,
|
||||
client_authentication=Unset, client_crl_container_ref=Unset,
|
||||
client_crl_container_data=Unset):
|
||||
|
||||
self.admin_state_up = admin_state_up
|
||||
self.connection_limit = connection_limit
|
||||
self.default_pool = default_pool
|
||||
self.default_pool_id = default_pool_id
|
||||
self.default_tls_container_data = default_tls_container_data
|
||||
self.default_tls_container_ref = default_tls_container_ref
|
||||
self.description = description
|
||||
self.insert_headers = insert_headers
|
||||
self.l7policies = l7policies
|
||||
self.listener_id = listener_id
|
||||
self.loadbalancer_id = loadbalancer_id
|
||||
self.name = name
|
||||
self.protocol = protocol
|
||||
self.protocol_port = protocol_port
|
||||
self.sni_container_data = sni_container_data
|
||||
self.sni_container_refs = sni_container_refs
|
||||
self.timeout_client_data = timeout_client_data
|
||||
self.timeout_member_connect = timeout_member_connect
|
||||
self.timeout_member_data = timeout_member_data
|
||||
self.timeout_tcp_inspect = timeout_tcp_inspect
|
||||
self.client_ca_tls_container_ref = client_ca_tls_container_ref
|
||||
self.client_ca_tls_container_data = client_ca_tls_container_data
|
||||
self.client_authentication = client_authentication
|
||||
self.client_crl_container_ref = client_crl_container_ref
|
||||
self.client_crl_container_data = client_crl_container_data
|
||||
|
||||
|
||||
class Pool(BaseDataModel):
|
||||
def __init__(self, admin_state_up=Unset, description=Unset,
|
||||
healthmonitor=Unset, lb_algorithm=Unset,
|
||||
loadbalancer_id=Unset, members=Unset, name=Unset,
|
||||
pool_id=Unset, listener_id=Unset, protocol=Unset,
|
||||
session_persistence=Unset, tls_container_ref=Unset,
|
||||
tls_container_data=Unset, ca_tls_container_ref=Unset,
|
||||
ca_tls_container_data=Unset, crl_container_ref=Unset,
|
||||
crl_container_data=Unset, tls_enabled=Unset):
|
||||
|
||||
self.admin_state_up = admin_state_up
|
||||
self.description = description
|
||||
self.healthmonitor = healthmonitor
|
||||
self.lb_algorithm = lb_algorithm
|
||||
self.loadbalancer_id = loadbalancer_id
|
||||
self.members = members
|
||||
self.name = name
|
||||
self.pool_id = pool_id
|
||||
self.listener_id = listener_id
|
||||
self.protocol = protocol
|
||||
self.session_persistence = session_persistence
|
||||
self.tls_container_ref = tls_container_ref
|
||||
self.tls_container_data = tls_container_data
|
||||
self.ca_tls_container_ref = ca_tls_container_ref
|
||||
self.ca_tls_container_data = ca_tls_container_data
|
||||
self.crl_container_ref = crl_container_ref
|
||||
self.crl_container_data = crl_container_data
|
||||
self.tls_enabled = tls_enabled
|
||||
|
||||
|
||||
class Member(BaseDataModel):
|
||||
def __init__(self, address=Unset, admin_state_up=Unset, member_id=Unset,
|
||||
monitor_address=Unset, monitor_port=Unset, name=Unset,
|
||||
pool_id=Unset, protocol_port=Unset, subnet_id=Unset,
|
||||
weight=Unset, backup=Unset):
|
||||
|
||||
self.address = address
|
||||
self.admin_state_up = admin_state_up
|
||||
self.member_id = member_id
|
||||
self.monitor_address = monitor_address
|
||||
self.monitor_port = monitor_port
|
||||
self.name = name
|
||||
self.pool_id = pool_id
|
||||
self.protocol_port = protocol_port
|
||||
self.subnet_id = subnet_id
|
||||
self.weight = weight
|
||||
self.backup = backup
|
||||
|
||||
|
||||
class HealthMonitor(BaseDataModel):
|
||||
def __init__(self, admin_state_up=Unset, delay=Unset, expected_codes=Unset,
|
||||
healthmonitor_id=Unset, http_method=Unset, max_retries=Unset,
|
||||
max_retries_down=Unset, name=Unset, pool_id=Unset,
|
||||
timeout=Unset, type=Unset, url_path=Unset, http_version=Unset,
|
||||
domain_name=Unset):
|
||||
|
||||
self.admin_state_up = admin_state_up
|
||||
self.delay = delay
|
||||
self.expected_codes = expected_codes
|
||||
self.healthmonitor_id = healthmonitor_id
|
||||
self.http_method = http_method
|
||||
self.max_retries = max_retries
|
||||
self.max_retries_down = max_retries_down
|
||||
self.name = name
|
||||
self.pool_id = pool_id
|
||||
self.timeout = timeout
|
||||
self.type = type
|
||||
self.url_path = url_path
|
||||
self.http_version = http_version
|
||||
self.domain_name = domain_name
|
||||
|
||||
|
||||
class L7Policy(BaseDataModel):
|
||||
def __init__(self, action=Unset, admin_state_up=Unset, description=Unset,
|
||||
l7policy_id=Unset, listener_id=Unset, name=Unset,
|
||||
position=Unset, redirect_pool_id=Unset, redirect_url=Unset,
|
||||
rules=Unset, redirect_prefix=Unset, redirect_http_code=Unset):
|
||||
|
||||
self.action = action
|
||||
self.admin_state_up = admin_state_up
|
||||
self.description = description
|
||||
self.l7policy_id = l7policy_id
|
||||
self.listener_id = listener_id
|
||||
self.name = name
|
||||
self.position = position
|
||||
self.redirect_pool_id = redirect_pool_id
|
||||
self.redirect_url = redirect_url
|
||||
self.rules = rules
|
||||
self.redirect_prefix = redirect_prefix
|
||||
self.redirect_http_code = redirect_http_code
|
||||
|
||||
|
||||
class L7Rule(BaseDataModel):
|
||||
def __init__(self, admin_state_up=Unset, compare_type=Unset, invert=Unset,
|
||||
key=Unset, l7policy_id=Unset, l7rule_id=Unset, type=Unset,
|
||||
value=Unset):
|
||||
|
||||
self.admin_state_up = admin_state_up
|
||||
self.compare_type = compare_type
|
||||
self.invert = invert
|
||||
self.key = key
|
||||
self.l7policy_id = l7policy_id
|
||||
self.l7rule_id = l7rule_id
|
||||
self.type = type
|
||||
self.value = value
|
||||
|
||||
|
||||
class VIP(BaseDataModel):
|
||||
def __init__(self, vip_address=Unset, vip_network_id=Unset,
|
||||
vip_port_id=Unset, vip_subnet_id=Unset,
|
||||
vip_qos_policy_id=Unset):
|
||||
|
||||
self.vip_address = vip_address
|
||||
self.vip_network_id = vip_network_id
|
||||
self.vip_port_id = vip_port_id
|
||||
self.vip_subnet_id = vip_subnet_id
|
||||
self.vip_qos_policy_id = vip_qos_policy_id
|
||||
VIP = moves.moved_class(lib_data_models.VIP, 'VIP', __name__,
|
||||
version='Stein', removal_version='U')
|
||||
|
11
octavia/api/drivers/driver_agent/__init__.py
Normal file
11
octavia/api/drivers/driver_agent/__init__.py
Normal file
@ -0,0 +1,11 @@
|
||||
# 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.
|
144
octavia/api/drivers/driver_agent/driver_listener.py
Normal file
144
octavia/api/drivers/driver_agent/driver_listener.py
Normal file
@ -0,0 +1,144 @@
|
||||
# Copyright 2018 Rackspace, US 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 errno
|
||||
import os
|
||||
import signal
|
||||
import threading
|
||||
|
||||
import six.moves.socketserver as socketserver
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
from oslo_serialization import jsonutils
|
||||
|
||||
from octavia.api.drivers.driver_agent import driver_updater
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _recv(recv_socket):
|
||||
size_str = b''
|
||||
char = recv_socket.recv(1)
|
||||
while char != b'\n':
|
||||
size_str += char
|
||||
char = recv_socket.recv(1)
|
||||
payload_size = int(size_str)
|
||||
mv_buffer = memoryview(bytearray(payload_size))
|
||||
next_offset = 0
|
||||
while payload_size - next_offset > 0:
|
||||
recv_size = recv_socket.recv_into(mv_buffer[next_offset:],
|
||||
payload_size - next_offset)
|
||||
next_offset += recv_size
|
||||
return jsonutils.loads(mv_buffer.tobytes())
|
||||
|
||||
|
||||
class StatusRequestHandler(socketserver.BaseRequestHandler):
|
||||
|
||||
def handle(self):
|
||||
# Get the update data
|
||||
status = _recv(self.request)
|
||||
|
||||
# Process the update
|
||||
updater = driver_updater.DriverUpdater()
|
||||
response = updater.update_loadbalancer_status(status)
|
||||
|
||||
# Send the response
|
||||
json_data = jsonutils.dump_as_bytes(response)
|
||||
len_str = '{}\n'.format(len(json_data)).encode('utf-8')
|
||||
self.request.send(len_str)
|
||||
self.request.sendall(json_data)
|
||||
|
||||
|
||||
class StatsRequestHandler(socketserver.BaseRequestHandler):
|
||||
|
||||
def handle(self):
|
||||
# Get the update data
|
||||
stats = _recv(self.request)
|
||||
|
||||
# Process the update
|
||||
updater = driver_updater.DriverUpdater()
|
||||
response = updater.update_listener_statistics(stats)
|
||||
|
||||
# Send the response
|
||||
json_data = jsonutils.dump_as_bytes(response)
|
||||
len_str = '{}\n'.format(len(json_data)).encode('utf-8')
|
||||
self.request.send(len_str)
|
||||
self.request.sendall(json_data)
|
||||
|
||||
|
||||
class ForkingUDSServer(socketserver.ForkingMixIn,
|
||||
socketserver.UnixStreamServer):
|
||||
pass
|
||||
|
||||
|
||||
def _mutate_config(*args, **kwargs):
|
||||
CONF.mutate_config_files()
|
||||
|
||||
|
||||
def _cleanup_socket_file(filename):
|
||||
# Remove the socket file if it already exists
|
||||
try:
|
||||
os.remove(filename)
|
||||
except OSError as e:
|
||||
if e.errno != errno.ENOENT:
|
||||
raise
|
||||
|
||||
|
||||
def status_listener(exit_event):
|
||||
signal.signal(signal.SIGINT, signal.SIG_IGN)
|
||||
signal.signal(signal.SIGHUP, _mutate_config)
|
||||
|
||||
_cleanup_socket_file(CONF.driver_agent.status_socket_path)
|
||||
|
||||
server = ForkingUDSServer(CONF.driver_agent.status_socket_path,
|
||||
StatusRequestHandler)
|
||||
|
||||
server.timeout = CONF.driver_agent.status_request_timeout
|
||||
server.max_children = CONF.driver_agent.status_max_processes
|
||||
|
||||
while not exit_event.is_set():
|
||||
server.handle_request()
|
||||
|
||||
LOG.info('Waiting for driver status listener to shutdown...')
|
||||
# Can't shut ourselves down as we would deadlock, spawn a thread
|
||||
threading.Thread(target=server.shutdown).start()
|
||||
LOG.info('Driver status listener shutdown finished.')
|
||||
server.server_close()
|
||||
_cleanup_socket_file(CONF.driver_agent.status_socket_path)
|
||||
|
||||
|
||||
def stats_listener(exit_event):
|
||||
signal.signal(signal.SIGINT, signal.SIG_IGN)
|
||||
signal.signal(signal.SIGHUP, _mutate_config)
|
||||
|
||||
_cleanup_socket_file(CONF.driver_agent.stats_socket_path)
|
||||
|
||||
server = ForkingUDSServer(CONF.driver_agent.stats_socket_path,
|
||||
StatsRequestHandler)
|
||||
|
||||
server.timeout = CONF.driver_agent.stats_request_timeout
|
||||
server.max_children = CONF.driver_agent.stats_max_processes
|
||||
|
||||
while not exit_event.is_set():
|
||||
server.handle_request()
|
||||
|
||||
LOG.info('Waiting for driver statistics listener to shutdown...')
|
||||
# Can't shut ourselves down as we would deadlock, spawn a thread
|
||||
threading.Thread(target=server.shutdown).start()
|
||||
LOG.info('Driver statistics listener shutdown finished.')
|
||||
server.server_close()
|
||||
_cleanup_socket_file(CONF.driver_agent.stats_socket_path)
|
174
octavia/api/drivers/driver_agent/driver_updater.py
Normal file
174
octavia/api/drivers/driver_agent/driver_updater.py
Normal file
@ -0,0 +1,174 @@
|
||||
# Copyright 2018 Rackspace, US Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from octavia_lib.api.drivers import exceptions as driver_exceptions
|
||||
from octavia_lib.common import constants as lib_consts
|
||||
|
||||
from octavia.common import constants as consts
|
||||
from octavia.common import utils
|
||||
from octavia.db import api as db_apis
|
||||
from octavia.db import repositories as repo
|
||||
|
||||
|
||||
class DriverUpdater(object):
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
self.loadbalancer_repo = repo.LoadBalancerRepository()
|
||||
self.listener_repo = repo.ListenerRepository()
|
||||
self.pool_repo = repo.PoolRepository()
|
||||
self.health_mon_repo = repo.HealthMonitorRepository()
|
||||
self.member_repo = repo.MemberRepository()
|
||||
self.l7policy_repo = repo.L7PolicyRepository()
|
||||
self.l7rule_repo = repo.L7RuleRepository()
|
||||
self.listener_stats_repo = repo.ListenerStatisticsRepository()
|
||||
|
||||
self.db_session = db_apis.get_session()
|
||||
super(DriverUpdater, self).__init__(**kwargs)
|
||||
|
||||
def _check_for_lb_vip_deallocate(self, repo, lb_id):
|
||||
lb = repo.get(self.db_session, id=lb_id)
|
||||
if lb.vip.octavia_owned:
|
||||
vip = lb.vip
|
||||
# We need a backreference
|
||||
vip.load_balancer = lb
|
||||
# Only lookup the network driver if we have a VIP to deallocate
|
||||