Devstack plugin fixes

Change-Id: Ie9798fe1bb4c6d511c601306ed1d366d97ff09f7
Signed-off-by: Pino de Candia <giuseppe.decandia@gmail.com>
This commit is contained in:
Pino de Candia 2018-03-02 21:13:47 +00:00
parent fb3766ef9c
commit 5a29ced8b2
17 changed files with 313 additions and 152 deletions

View File

@ -15,6 +15,6 @@ repository. See contrib/vagrant to create a vagrant VM.
> cat local.conf > cat local.conf
[[local|localrc]] [[local|localrc]]
enable_plugin tatu https://github.com/pinodeca/tatu enable_plugin tatu https://github.com/openstack/tatu
3. run ``stack.sh`` 3. run ``stack.sh``

View File

@ -6,7 +6,7 @@ SERVICE_PASSWORD=pinot
SERVICE_TOKEN=pinot SERVICE_TOKEN=pinot
ADMIN_PASSWORD=pinot ADMIN_PASSWORD=pinot
enable_plugin tatu https://github.com/pinodeca/tatu enable_plugin tatu https://git.openstack.org/openstack/tatu
enable_plugin designate https://git.openstack.org/openstack/designate enable_plugin designate https://git.openstack.org/openstack/designate
enable_plugin barbican https://git.openstack.org/openstack/barbican enable_plugin barbican https://git.openstack.org/openstack/barbican
enable_plugin dragonflow https://github.com/pinodeca/dragonflow tatu enable_plugin dragonflow https://github.com/pinodeca/dragonflow tatu
@ -41,6 +41,6 @@ PUBLIC_NETWORK_NAME=public
PUBLIC_NETWORK_GATEWAY=172.24.4.1 PUBLIC_NETWORK_GATEWAY=172.24.4.1
IMAGE_URL_SITE="http://download.fedoraproject.org" IMAGE_URL_SITE="http://download.fedoraproject.org"
IMAGE_URL_PATH="/pub/fedora/linux/releases/25/CloudImages/x86_64/images/" IMAGE_URL_PATH="/pub/fedora/linux/releases/27/CloudImages/x86_64/images/"
IMAGE_URL_FILE="Fedora-Cloud-Base-25-1.3.x86_64.qcow2" IMAGE_URL_FILE="Fedora-Cloud-Base-27-1.6.x86_64.qcow2"
IMAGE_URLS+=","$IMAGE_URL_SITE$IMAGE_URL_PATH$IMAGE_URL_FILE IMAGE_URLS+=","$IMAGE_URL_SITE$IMAGE_URL_PATH$IMAGE_URL_FILE

21
devstack/local.conf Normal file
View File

@ -0,0 +1,21 @@
[[local|localrc]]
DATABASE_PASSWORD=pinot
RABBIT_PASSWORD=pinot
SERVICE_PASSWORD=pinot
SERVICE_TOKEN=pinot
ADMIN_PASSWORD=pinot
enable_plugin tatu https://git.openstack.org/openstack/tatu
enable_plugin designate https://git.openstack.org/openstack/designate
enable_plugin barbican https://git.openstack.org/openstack/barbican
Q_USE_PROVIDERNET_FOR_PUBLIC=True
Q_FLOATING_ALLOCATION_POOL=start=172.24.4.10,end=172.24.4.200
PUBLIC_NETWORK_NAME=public
PUBLIC_NETWORK_GATEWAY=172.24.4.1
IMAGE_URL_SITE="http://download.fedoraproject.org"
IMAGE_URL_PATH="/pub/fedora/linux/releases/27/CloudImages/x86_64/images/"
IMAGE_URL_FILE="Fedora-Cloud-Base-27-1.6.x86_64.qcow2"
IMAGE_URLS+=","$IMAGE_URL_SITE$IMAGE_URL_PATH$IMAGE_URL_FILE

View File

@ -13,10 +13,6 @@ function setup_colorized_logging_tatu {
local user_var=${4:-"user_name"} local user_var=${4:-"user_name"}
setup_colorized_logging $conf_file $conf_section $project_var $user_var setup_colorized_logging $conf_file $conf_section $project_var $user_var
# Override the logging_context_format_string value chosen by
# setup_colorized_logging.
iniset $conf_file $conf_section logging_context_format_string "%(asctime)s.%(msecs)03d %(color)s%(levelname)s %(name)s [%(request_id)s %(user_identity)s%(color)s] %(instance)s%(color)s%(message)s"
} }
# DevStack Plugin # DevStack Plugin
@ -26,7 +22,6 @@ function setup_colorized_logging_tatu {
# runs that a clean run would need to clean up # runs that a clean run would need to clean up
function cleanup_tatu { function cleanup_tatu {
sudo rm -rf $TATU_STATE_PATH $TATU_AUTH_CACHE_DIR sudo rm -rf $TATU_STATE_PATH $TATU_AUTH_CACHE_DIR
cleanup_tatu_backend
} }
# configure_tatu - Set config files, create data dirs, etc # configure_tatu - Set config files, create data dirs, etc
@ -40,34 +35,50 @@ function configure_tatu {
# (Re)create ``tatu.conf`` # (Re)create ``tatu.conf``
rm -f $TATU_CONF rm -f $TATU_CONF
local admin_project
admin_project=$(openstack project show "admin" -f value -c id)
local admin_user
admin_user=$(openstack user show "admin" -f value -c id)
iniset $TATU_CONF tatu auth_url $KEYSTONE_SERVICE_URI/v3
iniset $TATU_CONF tatu user_id $admin_user
iniset $TATU_CONF tatu password $ADMIN_PASSWORD
iniset $TATU_CONF tatu project_id $admin_project
iniset $TATU_CONF tatu use_barbican_key_manager True
iniset $TATU_CONF tatu use_pat_bastions False
iniset $TATU_CONF tatu ssh_port 2222
iniset $TATU_CONF tatu num_total_pats 1
iniset $TATU_CONF tatu num_pat_bastions_per_server 1
iniset $TATU_CONF tatu pat_dns_zone_name tatuDemo.com.
iniset $TATU_CONF tatu pat_dns_zone_email my@tatu.devstack
iniset $TATU_CONF tatu sqlalchemy_engine `database_connection_url tatu`
# Need Keystone and Nova notifications
iniadd $KEYSTONE_CONF oslo_messaging_notifications topics tatu_notifications
iniadd $NOVA_CONF oslo_messaging_notifications topics tatu_notifications
iniset /etc/nova/nova-cpu.conf DEFAULT force_config_drive TRUE
# Set up Tatu static vendor data.
$TATU_DIR/scripts/cloud-config-to-vendor-data $TATU_DIR/files/user-cloud-config > /etc/nova/tatu_static_vd.json
iniset /etc/nova/nova-cpu.conf api vendordata_providers StaticJSON,DynamicJSON
iniset /etc/nova/nova-cpu.conf api vendordata_jsonfile_path /etc/nova/tatu_static_vd.json
# General Configuration # General Configuration
iniset_rpc_backend tatu $TATU_CONF DEFAULT iniset_rpc_backend tatu $TATU_CONF DEFAULT
iniset $TATU_CONF DEFAULT rpc_response_timeout 5 iniset $TATU_CONF DEFAULT rpc_response_timeout 5
iniset $TATU_CONF DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL iniset $TATU_CONF DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL
iniset $TATU_CONF DEFAULT state_path $TATU_STATE_PATH iniset $TATU_CONF DEFAULT state_path $TATU_STATE_PATH
iniset $TATU_CONF DEFAULT root-helper sudo tatu-rootwrap $TATU_ROOTWRAP_CONF
iniset $TATU_CONF storage:sqlalchemy connection `database_connection_url tatu` iniset $TATU_CONF storage:sqlalchemy connection `database_connection_url tatu`
# API Configuration # API Configuration
sudo cp $TATU_DIR/etc/tatu/api-paste.ini $TATU_APIPASTE_CONF sudo cp $TATU_DIR/etc/tatu/api-paste.ini $TATU_APIPASTE_CONF
iniset $TATU_CONF service:api api_base_uri $TATU_SERVICE_PROTOCOL://$TATU_SERVICE_HOST:$TATU_SERVICE_PORT/ iniset $TATU_CONF service:api api_base_uri $TATU_SERVICE_PROTOCOL://$TATU_SERVICE_HOST:$TATU_SERVICE_PORT/
# Root Wrap
sudo cp $TATU_DIR/etc/tatu/rootwrap.conf.sample $TATU_ROOTWRAP_CONF
iniset $TATU_ROOTWRAP_CONF DEFAULT filters_path $TATU_DIR/etc/tatu/rootwrap.d root-helper
# Oslo Concurrency # Oslo Concurrency
iniset $TATU_CONF oslo_concurrency lock_path "$TATU_STATE_PATH" iniset $TATU_CONF oslo_concurrency lock_path "$TATU_STATE_PATH"
# Set up the rootwrap sudoers for tatu
local rootwrap_sudoer_cmd="$TATU_BIN_DIR/tatu-rootwrap $TATU_ROOTWRAP_CONF *"
local tempfile=`mktemp`
echo "$STACK_USER ALL=(root) NOPASSWD: $rootwrap_sudoer_cmd" >$tempfile
chmod 0440 $tempfile
sudo chown root:root $tempfile
sudo mv $tempfile /etc/sudoers.d/tatu-rootwrap
# TLS Proxy Configuration # TLS Proxy Configuration
if is_service_enabled tls-proxy; then if is_service_enabled tls-proxy; then
# Set the service port for a proxy to take the original # Set the service port for a proxy to take the original
@ -125,11 +136,6 @@ function init_tatu {
# (Re)create tatu database # (Re)create tatu database
recreate_database tatu utf8 recreate_database tatu utf8
# Init and migrate tatu database
tatu-manage database sync
init_tatu_backend
} }
# install_tatu - Collect source and prepare # install_tatu - Collect source and prepare
@ -152,34 +158,37 @@ function install_tatudashboard {
for panel in _3980_tatu_panel_group.py \ for panel in _3980_tatu_panel_group.py \
_3981_tatu_ca_panel.py \ _3981_tatu_ca_panel.py \
_3982_tatu_user_panel.py \ _3982_tatu_user_panel.py \
_3983_tatu_host_panel.py; do _3983_tatu_host_panel.py \
_3984_tatu_pat_panel.py \
_3985_tatu_host_cert_panel.py; do
ln -fs $TATUDASHBOARD_DIR/tatudashboard/enabled/$panel $HORIZON_DIR/openstack_dashboard/local/enabled/$panel ln -fs $TATUDASHBOARD_DIR/tatudashboard/enabled/$panel $HORIZON_DIR/openstack_dashboard/local/enabled/$panel
done done
} }
# start_tatu - Start running processes # start_tatu - Start running processes
function start_tatu { function start_tatu {
start_tatu_backend local PSERVE=`which pserve`
run_process tatu-api "$PSERVE $TATU_APIPASTE_CONF"
run_process tatu-central "$TATU_BIN_DIR/tatu-central --config-file $TATU_CONF" local PYTHON=`which python`
run_process tatu-api "$TATU_BIN_DIR/tatu-api --config-file $TATU_CONF" run_process tatu-agent "$PYTHON $TATU_DIR/tatu/notifications.py"
# Start proxies if enabled # Start proxies if enabled
if is_service_enabled tatu-api && is_service_enabled tls-proxy; then if is_service_enabled tatu-api && is_service_enabled tls-proxy; then
start_tls_proxy tatu-api '*' $TATU_SERVICE_PORT $TATU_SERVICE_HOST $TATU_SERVICE_PORT_INT & start_tls_proxy tatu-api '*' $TATU_SERVICE_PORT $TATU_SERVICE_HOST $TATU_SERVICE_PORT_INT &
fi fi
if ! timeout $SERVICE_TIMEOUT sh -c "while ! wget --no-proxy -q -O- $TATU_SERVICE_PROTOCOL://$TATU_SERVICE_HOST:$TATU_SERVICE_PORT; do sleep 1; done"; then local wget_cmd
wget_cmd="wget --no-proxy -q -O- $TATU_SERVICE_PROTOCOL://$TATU_SERVICE_HOST:$TATU_SERVICE_PORT/noauth"
echo waiting on $wget_cmd
if ! timeout $SERVICE_TIMEOUT sh -c "until $wget_cmd; do sleep 1; echo re-trying; done"; then
die $LINENO "Tatu did not start" die $LINENO "Tatu did not start"
fi fi
} }
# stop_tatu - Stop running processes # stop_tatu - Stop running processes
function stop_tatu { function stop_tatu {
stop_process tatu-central
stop_process tatu-api stop_process tatu-api
stop_process tatu-agent
stop_tatu_backend
} }
# This is the main for plugin.sh # This is the main for plugin.sh

View File

@ -1,7 +1,6 @@
define_plugin tatu define_plugin tatu
plugin_requires tatu designate plugin_requires tatu designate
plugin_requires tatu barbican plugin_requires tatu barbican
plugin_requires tatu dragonflow # TODO(pino): remove this dependency
# Default options # Default options
TATU_USE_BARBICAN=${TATU_USE_BARBICAN:-"True"} TATU_USE_BARBICAN=${TATU_USE_BARBICAN:-"True"}
@ -19,8 +18,8 @@ fi
# Default IP/port settings # Default IP/port settings
TATU_SERVICE_PROTOCOL=${TATU_SERVICE_PROTOCOL:-$SERVICE_PROTOCOL} TATU_SERVICE_PROTOCOL=${TATU_SERVICE_PROTOCOL:-$SERVICE_PROTOCOL}
TATU_SERVICE_HOST=${TATU_SERVICE_HOST:-$SERVICE_HOST} TATU_SERVICE_HOST=${TATU_SERVICE_HOST:-$SERVICE_HOST}
TATU_SERVICE_PORT=${TATU_SERVICE_PORT:-8322} TATU_SERVICE_PORT=${TATU_SERVICE_PORT:-18322}
TATU_SERVICE_PORT_INT=${TATU_SERVICE_PORT_INT:-18322} TATU_SERVICE_PORT_INT=${TATU_SERVICE_PORT_INT:-28322}
# Default directories # Default directories
TATU_BIN_DIR=$(get_python_exec_prefix) TATU_BIN_DIR=$(get_python_exec_prefix)
@ -31,22 +30,22 @@ TATU_STATE_PATH=${TATU_STATE_PATH:=$DATA_DIR/tatu}
TATU_CONF=$TATU_CONF_DIR/tatu.conf TATU_CONF=$TATU_CONF_DIR/tatu.conf
TATU_LOG_DIR=/var/log/tatu TATU_LOG_DIR=/var/log/tatu
TATU_AUTH_CACHE_DIR=${TATU_AUTH_CACHE_DIR:-/var/cache/tatu} TATU_AUTH_CACHE_DIR=${TATU_AUTH_CACHE_DIR:-/var/cache/tatu}
TATU_ROOTWRAP_CONF=$TATU_CONF_DIR/rootwrap.conf
TATU_APIPASTE_CONF=$TATU_CONF_DIR/api-paste.ini TATU_APIPASTE_CONF=$TATU_CONF_DIR/api-paste.ini
# Default repositories # Default repositories
TATU_GIT_BASE=https://github.com TATU_GIT_BASE=https://git.openstack.org
TATU_REPO=${TATU_REPO:-${TATU_GIT_BASE}/pinodeca/tatu.git} TATU_REPO=${TATU_REPO:-${TATU_GIT_BASE}/openstack/tatu}
TATU_BRANCH=${TATU_BRANCH:-master} TATU_BRANCH=${TATU_BRANCH:-master}
GITREPO["tatu-dashboard"]=${TATUDASHBOARD_REPO:-${TATU_GIT_BASE}/pinodeca/tatu-dashboard.git} GITREPO["tatu-dashboard"]=${TATUDASHBOARD_REPO:-${TATU_GIT_BASE}/openstack/tatu-dashboard}
GITBRANCH["tatu-dashboard"]=${TATUDASHBOARD_BRANCH:-master} GITBRANCH["tatu-dashboard"]=${TATUDASHBOARD_BRANCH:-master}
GITDIR["tatu-dashboard"]=$DEST/tatu-dashboard GITDIR["tatu-dashboard"]=$DEST/tatu-dashboard
GITREPO["python-tatuclient"]=${TATUCLIENT_REPO:-${TATU_GIT_BASE}/pinodeca/python-tatuclient.git} GITREPO["python-tatuclient"]=${TATUCLIENT_REPO:-${TATU_GIT_BASE}/openstack/python-tatuclient}
GITBRANCH["python-tatuclient"]=${TATUCLIENT_BRANCH:-master} GITBRANCH["python-tatuclient"]=${TATUCLIENT_BRANCH:-master}
GITDIR["python-tatuclient"]=$DEST/python-tatuclient GITDIR["python-tatuclient"]=$DEST/python-tatuclient
# Turn on all Tatu services by default # Turn on all Tatu services by default
enable_service tatu enable_service tatu
enable_service tatu-api enable_service tatu-api
enable_service tatu-agent

188
devstack/tatu_stack.sh Executable file
View File

@ -0,0 +1,188 @@
#!/bin/bash
# **tatu_stack.sh**
# ``tatu_stack.sh`` is meant to run after devstack's stack.sh and stacks only Tatu.
# - it must be run from the openstack-dev/devstack directory as the stack user.
# OpenStack is designed to be run as a non-root user; Horizon will fail to run
# as **root** since Apache will not serve content from **root** user).
# ``stack.sh`` must not be run as **root**. It aborts and suggests one course of
# action to create a suitable user account.
set -o xtrace
unset GREP_OPTIONS
unset LANG
unset LANGUAGE
LC_ALL=en_US.utf8
export LC_ALL
# Make sure umask is sane
umask 022
# Not all distros have sbin in PATH for regular users.
PATH=$PATH:/usr/local/sbin:/usr/sbin:/sbin
# Keep track of the DevStack directory
TOP_DIR=$(cd $(dirname "$0") && pwd)
# Check for uninitialized variables, a big cause of bugs
NOUNSET=${NOUNSET:-}
if [[ -n "$NOUNSET" ]]; then
set -o nounset
fi
# ``stack.sh`` keeps the list of ``deb`` and ``rpm`` dependencies, config
# templates and other useful files in the ``files`` subdirectory
FILES=$TOP_DIR/files
if [ ! -d $FILES ]; then
die $LINENO "missing devstack/files"
fi
# ``stack.sh`` keeps function libraries here
# Make sure ``$TOP_DIR/inc`` directory is present
if [ ! -d $TOP_DIR/inc ]; then
die $LINENO "missing devstack/inc"
fi
# ``stack.sh`` keeps project libraries here
# Make sure ``$TOP_DIR/lib`` directory is present
if [ ! -d $TOP_DIR/lib ]; then
die $LINENO "missing devstack/lib"
fi
if [[ "${POSIXLY_CORRECT}" == "y" ]]; then
set +o xtrace
echo "You are running POSIX compatibility mode, DevStack requires bash 4.2 or newer."
exit 1
fi
if [[ $EUID -eq 0 ]]; then
set +o xtrace
echo "DevStack should be run as a user with sudo permissions, "
echo "not root."
echo "A \"stack\" user configured correctly can be created with:"
echo " $TOP_DIR/tools/create-stack-user.sh"
exit 1
fi
# Initialize variables:
LAST_SPINNER_PID=""
# Import common functions
source $TOP_DIR/functions
# Import config functions
source $TOP_DIR/inc/meta-config
# Import 'public' stack.sh functions
source $TOP_DIR/lib/stack
# Determine what system we are running on. This provides ``os_VENDOR``,
# ``os_RELEASE``, ``os_PACKAGE``, ``os_CODENAME``
# and ``DISTRO``
GetDistro
# Phase: local
rm -f $TOP_DIR/.localrc.auto
extract_localrc_section $TOP_DIR/local.conf $TOP_DIR/localrc $TOP_DIR/.localrc.auto
if [[ ! -r $TOP_DIR/stackrc ]]; then
die $LINENO "missing $TOP_DIR/stackrc - did you grab more than just stack.sh?"
fi
source $TOP_DIR/stackrc
source $TOP_DIR/openrc admin admin
export_proxy_variables
disable_negated_services
# Destination path for installation ``DEST``
DEST=${DEST:-/opt/stack}
# Destination path for service data
DATA_DIR=${DATA_DIR:-${DEST}/data}
LOCAL_HOSTNAME=`hostname -s`
VERBOSE=$(trueorfalse True VERBOSE)
VERBOSE_NO_TIMESTAMP=$(trueorfalse False VERBOSE)
TIMESTAMP_FORMAT=${TIMESTAMP_FORMAT:-"%F-%H%M%S"}
LOGDAYS=${LOGDAYS:-7}
CURRENT_LOG_TIME=$(date "+$TIMESTAMP_FORMAT")
if [[ true ]]; then
# Set up output redirection without log files
# Set fd 3 to a copy of stdout. So we can set fd 1 without losing
# stdout later.
exec 3>&1
if [[ "$VERBOSE" != "True" ]]; then
# Throw away stdout and stderr
exec 1>/dev/null 2>&1
fi
# Always send summary fd to original stdout
exec 6> >( $TOP_DIR/tools/outfilter.py -v >&3 )
fi
# Basic test for ``$DEST`` path permissions (fatal on error unless skipped)
check_path_perm_sanity ${DEST}
# Print the kernel version
uname -a
SSL_BUNDLE_FILE="$DATA_DIR/ca-bundle.pem"
# Import common services (database, message queue) configuration
source $TOP_DIR/lib/database
source $TOP_DIR/lib/rpc_backend
# Configure Projects
# ==================
# Clone all external plugins
fetch_plugins
# Plugin Phase 0: override_defaults - allow plugins to override
# defaults before other services are run
run_phase override_defaults
# Import Apache functions
source $TOP_DIR/lib/apache
# Import TLS functions
source $TOP_DIR/lib/tls
# Source project function libraries
source $TOP_DIR/lib/infra
source $TOP_DIR/lib/libraries
source $TOP_DIR/lib/lvm
source $TOP_DIR/lib/horizon
source $TOP_DIR/lib/keystone
source $TOP_DIR/lib/glance
source $TOP_DIR/lib/nova
source $TOP_DIR/lib/placement
source $TOP_DIR/lib/cinder
source $TOP_DIR/lib/swift
source $TOP_DIR/lib/neutron
source $TOP_DIR/lib/ldap
source $TOP_DIR/lib/dstat
source $TOP_DIR/lib/etcd3
# Extras Source
# --------------
# Phase: source
run_phase source
initialize_database_backends && echo "Using $DATABASE_TYPE database backend" || echo "No database enabled"
source $DEST/tatu/devstack/settings
source $DEST/tatu/devstack/plugin.sh stack pre-install
source $DEST/tatu/devstack/plugin.sh stack install
source $DEST/tatu/devstack/plugin.sh stack post-config
source $DEST/tatu/devstack/plugin.sh stack extra
source $DEST/tatu/devstack/plugin.sh stack test-config

View File

@ -1,21 +0,0 @@
This directory contains the Tatu (SSH-as-a-Service) DevStack plugin.
To configure Tatu with DevStack, you will need to enable this plugin and
the Tatu service by adding one line to the [[local|localrc]] section of
your local.conf file.
To enable the plugin, add a line of the form:
enable_plugin tatu <GITURL> [GITREF]
where
<GITURL> is the URL of a Tatu repository
[GITREF] is an optional git ref (branch/ref/tag). The default is master.
For example
enable_plugin tatu https://github.com/pinodeca/tatu stable/queens
For more information, see the "Externally Hosted Plugins" section of
https://docs.openstack.org/devstack/latest/plugins.html

View File

@ -1,50 +0,0 @@
# plugin.sh - DevStack plugin.sh dispatch script
function install_tatu {
...
}
function init_tatu {
...
}
function configure_tatu {
...
}
# check for service enabled
if is_service_enabled tatu; then
if [[ "$1" == "stack" && "$2" == "pre-install" ]]; then
# Set up system services
echo_summary "Configuring system services tatu"
elif [[ "$1" == "stack" && "$2" == "install" ]]; then
# Perform installation of service source
echo_summary "Installing tatu"
install_tatu
elif [[ "$1" == "stack" && "$2" == "post-config" ]]; then
# Configure after the other layer 1 and 2 services have been configured
echo_summary "Configuring tatu"
configure_tatu
elif [[ "$1" == "stack" && "$2" == "extra" ]]; then
# Initialize and start the tatu service
echo_summary "Initializing tatu"
init_tatu
fi
if [[ "$1" == "unstack" ]]; then
# Shut down tatu services
# no-op
:
fi
if [[ "$1" == "clean" ]]; then
# Remove state and transient data
# Remember clean.sh first calls unstack.sh
# no-op
:
fi
fi

View File

@ -1 +0,0 @@
enable_service tatu

View File

@ -13,13 +13,6 @@ pipeline = authtoken main
[filter:authtoken] [filter:authtoken]
paste.filter_factory = keystonemiddleware.auth_token:filter_factory paste.filter_factory = keystonemiddleware.auth_token:filter_factory
www_authenticate_uri = http://localhost/identity
identity_uri = http://localhost/identity
#auth_version = v2
admin_token = gAAAAABaPEXR3jF2TqsraXh7qkpKOiPcVbnmHdMEsrSYRKUnfQvpCAR9Sq02vDZNcQLoodVLdxu449zc0AwGXeleRMuf7pEPBgjHPfR6ykkYV6_WXNuMt_Cmqvo_fnRdvPh8bJzjsWEqvEM9s_aCM-le8DkaatoacDrUDA3odBAP1AVdJ0PdJdM
#admin_user = nova
#admin_password = pinot
#admin_tenant_name = service
[app:auth_app] [app:auth_app]
paste.app_factory = tatu.api.app:auth_factory paste.app_factory = tatu.api.app:auth_factory

View File

@ -21,7 +21,7 @@ python-memcached
python-designateclient python-designateclient
python-neutronclient python-neutronclient
python-novaclient python-novaclient
dragonflow #dragonflow
eventlet eventlet
vine vine
python-designateclient python-designateclient

View File

@ -6,7 +6,7 @@ license = Apache License, Version 2.0
summary = Management of SSH host/user certificates, plus bastions summary = Management of SSH host/user certificates, plus bastions
author = Pino de Candia author = Pino de Candia
author_email = pino.decandia@huawei.com author_email = pino.decandia@huawei.com
home-page = https://github.com/pinodeca/tatu home-page = https://github.com/openstack/tatu
classifier = classifier =
Environment :: OpenStack Environment :: OpenStack
Intended Audience :: Information Technology Intended Audience :: Information Technology

View File

@ -11,12 +11,18 @@
# under the License. # under the License.
import falcon import falcon
import json
from oslo_log import log as logging from oslo_log import log as logging
from tatu.api import models from tatu.api import models
from tatu.db.persistence import SQLAlchemySessionManager from tatu.db.persistence import SQLAlchemySessionManager
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
class RootPage(object):
def on_get(self, req, resp):
resp.body = json.dumps({})
resp.status = falcon.HTTP_OK
def create_app(sa): def create_app(sa):
LOG.info("Creating falcon API instance for authenticated API calls.") LOG.info("Creating falcon API instance for authenticated API calls.")
api = falcon.API(middleware=[models.Logger(), sa]) api = falcon.API(middleware=[models.Logger(), sa])
@ -39,10 +45,11 @@ def create_noauth_app(sa):
api = falcon.API(middleware=[models.Logger(), sa]) api = falcon.API(middleware=[models.Logger(), sa])
api.add_route('/hostcerts', models.HostCerts()) api.add_route('/hostcerts', models.HostCerts())
api.add_route('/revokeduserkeys/{auth_id}', models.RevokedUserKeys()) api.add_route('/revokeduserkeys/{auth_id}', models.RevokedUserKeys())
api.add_route('/', RootPage())
return api return api
def auth_factory(global_config, **settings): def auth_factory(global_config, **settings):
return create_app(SQLAlchemySessionManager()) return create_app(SQLAlchemySessionManager())
def noauth_factory(global_config, **settings): def noauth_factory(global_config, **settings):
return create_noauth_app(SQLAlchemySessionManager()) return create_noauth_app(SQLAlchemySessionManager())

View File

@ -21,9 +21,11 @@ from tatu.config import CONF
from tatu.db import models as db from tatu.db import models as db
from tatu.dns import add_srv_records from tatu.dns import add_srv_records
from tatu.ks_utils import getProjectRoleNames, getProjectNameForID, getUserNameForID from tatu.ks_utils import getProjectRoleNames, getProjectNameForID, getUserNameForID
from tatu.pat import create_pat_entries, getAllPats, ip_port_tuples_to_string
from tatu.utils import canonical_uuid_string, datetime_to_string from tatu.utils import canonical_uuid_string, datetime_to_string
if CONF.tatu.use_pat_bastions:
from tatu.pat import create_pat_entries, getAllPats, ip_port_tuples_to_string
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
@ -349,12 +351,13 @@ class PATs(object):
@falcon.before(validate) @falcon.before(validate)
def on_get(self, req, resp): def on_get(self, req, resp):
items = [] items = []
for p in getAllPats(): if CONF.tatu.use_pat_bastions:
items.append({ for p in getAllPats():
'ip': str(p.ip_address), items.append({
'chassis': p.chassis.id, 'ip': str(p.ip_address),
'lport': p.lport.id, 'chassis': p.chassis.id,
}) 'lport': p.lport.id,
})
body = {'pats': items} body = {'pats': items}
resp.body = json.dumps(body) resp.body = json.dumps(body)
resp.status = falcon.HTTP_OK resp.status = falcon.HTTP_OK

View File

@ -11,8 +11,6 @@
# under the License. # under the License.
from designateclient.v2 import client as designate_client from designateclient.v2 import client as designate_client
from dragonflow import conf as dragonflow_cfg
from dragonflow.db import api_nb
from keystoneauth1 import session as keystone_session from keystoneauth1 import session as keystone_session
from keystoneauth1.identity import v3 from keystoneauth1.identity import v3
from keystoneclient.v3 import client as keystone_client from keystoneclient.v3 import client as keystone_client
@ -60,7 +58,7 @@ opts = [
help='OpenStack Keystone admin project UUID'), help='OpenStack Keystone admin project UUID'),
] ]
CONF = cfg.CONF CONF = cfg.ConfigOpts()
CONF.register_opts(opts, group='tatu') CONF.register_opts(opts, group='tatu')
logging.register_options(CONF) logging.register_options(CONF)
@ -68,23 +66,27 @@ log_levels = logging.get_default_log_levels() + \
['tatu=DEBUG', '__main__=DEBUG'] ['tatu=DEBUG', '__main__=DEBUG']
logging.set_defaults(default_log_levels=log_levels) logging.set_defaults(default_log_levels=log_levels)
CONF(args=[], default_config_files=['/etc/tatu/tatu.conf'])
try:
CONF(args=[], default_config_files=['/etc/tatu/tatu.conf',
'files/tatu.conf',
'/etc/neutron/dragonflow.ini'])
except Exception as e:
LOG.error("Failed to load configuration file: {}".format(e))
logging.setup(CONF, "tatu") logging.setup(CONF, "tatu")
GCONF = cfg.CONF
if CONF.tatu.use_barbican_key_manager: if CONF.tatu.use_barbican_key_manager:
LOG.debug("Using Barbican as key manager.") LOG.debug("Using Barbican as key manager.")
set_castellan_defaults(CONF) set_castellan_defaults(GCONF)
else: else:
LOG.debug("Using Tatu as key manager.") LOG.debug("Using Tatu as key manager.")
set_castellan_defaults(CONF, set_castellan_defaults(GCONF,
api_class='tatu.castellano.TatuKeyManager') api_class='tatu.castellano.TatuKeyManager')
global_config_files = ['/etc/tatu/tatu.conf']
if CONF.tatu.use_pat_bastions:
from dragonflow import conf as dragonflow_cfg
from dragonflow.db import api_nb
global_files.append('/etc/neutron/dragonflow.ini')
GCONF(args=[], default_config_files=global_config_files)
auth = v3.Password(auth_url=CONF.tatu.auth_url, auth = v3.Password(auth_url=CONF.tatu.auth_url,
user_id=CONF.tatu.user_id, user_id=CONF.tatu.user_id,
password=CONF.tatu.password, password=CONF.tatu.password,
@ -95,8 +97,10 @@ NOVA = nova_client.Client('2', session=session)
NEUTRON = neutron_client.Client(session=session) NEUTRON = neutron_client.Client(session=session)
DESIGNATE = designate_client.Client(session=session) DESIGNATE = designate_client.Client(session=session)
dragonflow_cfg.CONF.set_override('enable_df_pub_sub', False, group='df') DRAGONFLOW = None
DRAGONFLOW = api_nb.NbApi.get_instance(False) if CONF.tatu.use_pat_bastions:
dragonflow_cfg.CONF.set_override('enable_df_pub_sub', False, group='df')
DRAGONFLOW = api_nb.NbApi.get_instance(False)
# Create a context for use by Castellan # Create a context for use by Castellan
CONTEXT = context.RequestContext(auth_token=auth.get_token(session), CONTEXT = context.RequestContext(auth_token=auth.get_token(session),

View File

@ -25,9 +25,11 @@ from tatu.config import KEYSTONE as ks
from tatu.config import NOVA as nova from tatu.config import NOVA as nova
from tatu.db import models as db from tatu.db import models as db
from tatu.dns import delete_srv_records from tatu.dns import delete_srv_records
from tatu.pat import deletePatEntries, string_to_ip_port_tuples
from tatu.utils import canonical_uuid_string from tatu.utils import canonical_uuid_string
if CONF.tatu.use_pat_bastions:
from tatu.pat import deletePatEntries, string_to_ip_port_tuples
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
@ -138,8 +140,9 @@ def _deleteAuthority(session_factory, auth):
def _deleteHost(session_factory, host): def _deleteHost(session_factory, host):
LOG.debug("Clean up DNS and PAT for deleted instance {} with ID {}" LOG.debug("Clean up DNS and PAT for deleted instance {} with ID {}"
.format(host.name, host.id)) .format(host.name, host.id))
delete_srv_records(host.srv_url) if CONF.tatu.use_pat_bastions:
deletePatEntries(string_to_ip_port_tuples(host.pat_bastions)) delete_srv_records(host.srv_url)
deletePatEntries(string_to_ip_port_tuples(host.pat_bastions))
se = session_factory() se = session_factory()
try: try:
LOG.info( LOG.info(

View File

@ -24,14 +24,18 @@ from tatu.utils import dash_uuid
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
#TODO(pino): periodically refresh this list #TODO(pino): periodically refresh this list
PATS = DRAGONFLOW.get_all(PAT) PATS = None
def getAllPats(): def getAllPats():
if not CONF.tatu.use_pat_bastions:
return []
return DRAGONFLOW.get_all(PAT) return DRAGONFLOW.get_all(PAT)
def _sync_pats(): def _sync_pats():
if not CONF.tatu.use_pat_bastions:
return
# TODO(pino): re-bind PATs when hypervisors fail (here and on notification) # TODO(pino): re-bind PATs when hypervisors fail (here and on notification)
all_chassis = DRAGONFLOW.get_all(Chassis) all_chassis = DRAGONFLOW.get_all(Chassis)
# Filter the chassis that already have PATS assigned # Filter the chassis that already have PATS assigned
@ -45,6 +49,8 @@ def _sync_pats():
for c in assigned_chassis: for c in assigned_chassis:
_add_pat(c) _add_pat(c)
dns.sync_bastions(str(p.ip_address) for p in PATS) dns.sync_bastions(str(p.ip_address) for p in PATS)
global PATS
PATS = DRAGONFLOW.get_all(PAT)
def _add_pat(chassis): def _add_pat(chassis):