Adding credsmgr support in devstack
Change-Id: Ied7da6e314d81426e60063f7347dbeb1dc05216b
This commit is contained in:
parent
bc94150974
commit
d05c20bb60
4
.gitignore
vendored
4
.gitignore
vendored
@ -9,3 +9,7 @@ build/*
|
||||
creds_manager/build/*
|
||||
.testrepository
|
||||
openstack
|
||||
.DS_Store
|
||||
devstack/.DS_Store
|
||||
.gitreview
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
[gerrit]
|
||||
host=review.openstack.org
|
||||
port=29418
|
||||
project=openstack/omni.git
|
||||
project=x/omni.git
|
||||
|
@ -26,15 +26,15 @@ Following lines need to be added in local.conf to enable Omni plugin:
|
||||
|
||||
*3. Parameters required for Omni drivers:*
|
||||
|
||||
================== =====
|
||||
---------------------------
|
||||
AWS GCE
|
||||
================== =====
|
||||
SECRET_KEY ZONE
|
||||
ACCESS_KEY PROJECT_ID
|
||||
REGION_NAME REGION
|
||||
AVAILABILITY_ZONE
|
||||
================== =====
|
||||
================== =====
|
||||
-------------------------------------
|
||||
AWS GCE
|
||||
================== =====
|
||||
AWS_SECRET_KEY ZONE
|
||||
AWS_ACCESS_KEY PROJECT_ID
|
||||
AWS_REGION_NAME REGION
|
||||
AWS_AVAILABILITY_ZONE
|
||||
================== =====
|
||||
|
||||
Run stack.sh in your devstack tree to get started.
|
||||
|
||||
|
179
devstack/lib/creds_mgr
Normal file
179
devstack/lib/creds_mgr
Normal file
@ -0,0 +1,179 @@
|
||||
#!/bin/bash -xe
|
||||
|
||||
# Save trace setting
|
||||
XTRACE=$(set +o | grep xtrace)
|
||||
set +o xtrace
|
||||
|
||||
|
||||
PROJECT_NAME="credsmgr"
|
||||
OMNI_DATA_DIR="/opt/stack/omni"
|
||||
CINDER_DIR="/opt/stack/cinder"
|
||||
NOVA_DIR="/opt/stack/nova"
|
||||
CREDSMGR_DIR="/opt/stack/credsmgr"
|
||||
CREDSMGR_SERVICE_NAME=devstack@credsmgr.service
|
||||
STACK_USER="stack"
|
||||
CREDSMGR_CONF="/etc/credsmgr/credsmgr.conf"
|
||||
CREDSMGR_URL="http://${SERVICE_HOST}:8091/"
|
||||
FERNET_SALT=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1)
|
||||
FERNET_PASSWORD=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1)
|
||||
|
||||
function install_credsmgr {
|
||||
install_dependencies
|
||||
|
||||
sudo cp -R $OMNI_DATA_DIR/creds_manager/credsmgr $CREDSMGR_DIR/lib/python2.?/site-packages/
|
||||
sudo cp -R $OMNI_DATA_DIR/creds_manager/etc/* /etc/
|
||||
|
||||
# Remove the default credsmgr.conf and write the file afresh.
|
||||
sudo rm -f /etc/credsmgr/credsmgr.conf
|
||||
|
||||
# Grant permissions on /etc folders
|
||||
sudo chown -R $STACK_USER:$STACK_USER /etc/credsmgr
|
||||
sudo chown -R $STACK_USER:$STACK_USER /etc/logrotate.d
|
||||
sudo chown -R $STACK_USER:$STACK_USER /etc/rsyslog.d
|
||||
|
||||
create_service_file
|
||||
|
||||
init_credsmgr
|
||||
update_credsmgr_config
|
||||
create_credsmgr_accounts
|
||||
|
||||
configure_creds_decryption_for_ostack_components $NOVA_CONF
|
||||
configure_creds_decryption_for_ostack_components $NEUTRON_CONF
|
||||
configure_creds_decryption_for_ostack_components $GLANCE_API_CONF
|
||||
configure_creds_decryption_for_ostack_components $CINDER_CONF
|
||||
|
||||
# Change the code in specific services' file to fetch credsmgr endpoints in the service_catalog object created in their contexts
|
||||
fetch_credsmgr_in_service_catalog
|
||||
|
||||
restart_services
|
||||
start_credsmgr_service
|
||||
sleep 20
|
||||
|
||||
# Create and associate credentials with tenant id
|
||||
create_and_associate_credentials
|
||||
}
|
||||
|
||||
function install_dependencies {
|
||||
# Create virtualenv and install credsmgr dependencies
|
||||
virtualenv $CREDSMGR_DIR
|
||||
|
||||
export PBR_VERSION=1.8.1
|
||||
$CREDSMGR_DIR/bin/python $CREDSMGR_DIR/bin/pip install \
|
||||
-chttps://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt?h=stable/newton \
|
||||
-r $OMNI_DATA_DIR/creds_manager/requirements.txt
|
||||
|
||||
cp -r $OMNI_DATA_DIR/credsmgrclient $CREDSMGR_DIR/lib/python2.?/site-packages/
|
||||
|
||||
cd $OMNI_DATA_DIR/creds_manager
|
||||
$CREDSMGR_DIR/bin/python setup.py install
|
||||
}
|
||||
|
||||
function create_service_file {
|
||||
cat <<EOF | sudo tee /etc/systemd/system/$CREDSMGR_SERVICE_NAME
|
||||
[Unit]
|
||||
Description=Devstack $CREDSMGR_SERVICE_NAME
|
||||
After=network.target
|
||||
ConditionPathExists=/opt/stack/credsmgr/bin/python
|
||||
ConditionPathExists=/opt/stack/credsmgr/bin/credsmgr-api
|
||||
[Service]
|
||||
Type=simple
|
||||
User=stack
|
||||
WorkingDirectory=/opt/stack/credsmgr
|
||||
ExecStart=/opt/stack/credsmgr/bin/python /opt/stack/credsmgr/bin/credsmgr-api --config-file /etc/credsmgr/credsmgr.conf
|
||||
StandardOutput=syslog
|
||||
StandardError=syslog
|
||||
SyslogIdentifier=credsmgr_api
|
||||
PIDFile=/var/run/credsmgr/credsmgr.pid
|
||||
PermissionsStartOnly=True
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
}
|
||||
|
||||
function init_credsmgr {
|
||||
recreate_database credsmgr
|
||||
time_start "dbsync"
|
||||
local dburl
|
||||
dburl=$(database_connection_url credsmgr)
|
||||
iniset $CREDSMGR_CONF database connection $dburl
|
||||
$CREDSMGR_DIR/bin/python $CREDSMGR_DIR/bin/credsmgr-manage
|
||||
time_stop "dbsync"
|
||||
}
|
||||
|
||||
function update_credsmgr_config {
|
||||
iniset $CREDSMGR_CONF DEFAULT credsmgr_api_listen_port 8091
|
||||
iniset $CREDSMGR_CONF DEFAULT credsmgr_api_use_ssl False
|
||||
iniset $CREDSMGR_CONF DEFAULT credsmgr_api_workers 1
|
||||
|
||||
iniset $CREDSMGR_CONF keystone_authtoken auth_type password
|
||||
iniset $CREDSMGR_CONF keystone_authtoken auth_url "http://${SERVICE_HOST}/identity"
|
||||
iniset $CREDSMGR_CONF keystone_authtoken username "credsmgr"
|
||||
iniset $CREDSMGR_CONF keystone_authtoken password $SERVICE_PASSWORD
|
||||
iniset $CREDSMGR_CONF keystone_authtoken user_domain_name "$SERVICE_DOMAIN_NAME"
|
||||
iniset $CREDSMGR_CONF keystone_authtoken project_name "service"
|
||||
iniset $CREDSMGR_CONF keystone_authtoken project_domain_name "$SERVICE_DOMAIN_NAME"
|
||||
iniset $CREDSMGR_CONF keystone_authtoken identity_uri $KEYSTONE_AUTH_URI
|
||||
|
||||
iniset $CREDSMGR_CONF credsmgr encryptor "credsmgrclient.encryption.noop.NoEncryption"
|
||||
# uncomment following code when encryptor class is "credsmgrclient.encryption.fernet.FernetKeyEncryption"
|
||||
# iniset $CREDSMGR_CONF credsmgr fernet_salt $FERNET_SALT
|
||||
# iniset $CREDSMGR_CONF credsmgr fernet_password $FERNET_PASSWORD
|
||||
}
|
||||
|
||||
function restart_credsmgr_service {
|
||||
sudo systemctl restart $CREDSMGR_SERVICE_NAME
|
||||
}
|
||||
|
||||
function start_credsmgr_service {
|
||||
sudo systemctl start $CREDSMGR_SERVICE_NAME
|
||||
}
|
||||
|
||||
function stop_credsmgr_service {
|
||||
sudo systemctl stop $CREDSMGR_SERVICE_NAME
|
||||
}
|
||||
|
||||
function create_credsmgr_accounts {
|
||||
create_service_user "credsmgr"
|
||||
|
||||
get_or_create_service $PROJECT_NAME $PROJECT_NAME "Credentials manager"
|
||||
get_or_create_endpoint $PROJECT_NAME $OS_REGION_NAME $CREDSMGR_URL \
|
||||
$CREDSMGR_URL $CREDSMGR_URL
|
||||
}
|
||||
|
||||
function configure_creds_decryption_for_ostack_components {
|
||||
local conf_file=$1
|
||||
iniset $conf_file credsmgr encryptor "credsmgrclient.encryption.noop.NoEncryption"
|
||||
# uncomment following code when encryptor class is "credsmgrclient.encryption.fernet.FernetKeyEncryption"
|
||||
# iniset $conf_file credsmgr fernet_salt $FERNET_SALT
|
||||
# iniset $conf_file credsmgr fernet_password $FERNET_PASSWORD
|
||||
}
|
||||
|
||||
# Few services have service_catalog object prepopulated with selected services' endpoints.
|
||||
# We need to edit this code to make it fetch credsmgr endpoints as well.
|
||||
function fetch_credsmgr_in_service_catalog {
|
||||
# Change cinder's context.py file to fetch the credsmgr endpoints along with other endpoints.
|
||||
sudo sed -i "s/'image'/'image', 'credsmgr'/g" ${CINDER_DIR}/cinder/context.py
|
||||
sudo sed -i -e "s/, 'placement'/, 'placement', 'credsmgr'/g" ${NOVA_DIR}/nova/context.py
|
||||
# Use this space to add similar code as above to edit the code in the specific services if required
|
||||
# .
|
||||
# .
|
||||
# .
|
||||
}
|
||||
|
||||
function create_and_associate_credentials {
|
||||
source $TOP_DIR/openrc "" "" "" ""
|
||||
|
||||
local token
|
||||
local tenant_id
|
||||
token=$(openstack token issue -c id -f value)
|
||||
tenant_id=$(openstack project show "admin" -f value -c id)
|
||||
cred_id=$(curl $CREDSMGR_URL/v1/credentials/aws -H "X-Auth-Token: $token" -H "Content-Type: application/json" -X POST -d "{\"aws_access_key_id\": \"${AWS_ACCESS_KEY}\", \"aws_secret_access_key\": \"${AWS_SECRET_KEY}\"}")
|
||||
cred_id=$(echo $cred_id | awk {'print$2'} | cut -d"}" -f1 | tr -d '"')
|
||||
curl -i $CREDSMGR_URL/v1/credentials/aws/$cred_id/association -H "X-Auth-Token: $token" -H "Content-Type: application/json" -X POST -d "{\"tenant_id\": \"${tenant_id}\"}"
|
||||
}
|
||||
|
||||
# Restore xtrace
|
||||
$XTRACE
|
||||
|
||||
## mode: shell-script
|
||||
## End:
|
@ -8,19 +8,19 @@ DIST_PACKAGES="/usr/local/lib/python2.7/dist-packages"
|
||||
ENTRY_POINT="$DIST_PACKAGES/glance_store-*.dist-info/entry_points.txt"
|
||||
NEUTRON_ENTRY_POINT="/opt/stack/neutron/neutron.egg-info/entry_points.txt"
|
||||
ML2_CONF="/etc/neutron/plugins/ml2/ml2_conf.ini"
|
||||
NOVA_CPU_CONF="/etc/nova/nova-cpu.conf"
|
||||
|
||||
# Functions
|
||||
# ------------
|
||||
|
||||
function set_aws_keys_and_region {
|
||||
function set_aws_region_and_az {
|
||||
local conf_file=$1
|
||||
iniset $conf_file AWS secret_key ${AWS_SECRET_KEY}
|
||||
iniset $conf_file AWS access_key ${AWS_ACCESS_KEY}
|
||||
iniset $conf_file AWS region_name ${AWS_REGION_NAME}
|
||||
iniset $conf_file AWS az ${AWS_AVAILABILITY_ZONE}
|
||||
}
|
||||
|
||||
function configure_glance {
|
||||
set_aws_keys_and_region $GLANCE_API_CONF
|
||||
set_aws_region_and_az $GLANCE_API_CONF
|
||||
iniset $GLANCE_API_CONF DEFAULT show_multiple_locations True
|
||||
iniset $GLANCE_API_CONF glance_store default_store aws
|
||||
iniset $GLANCE_API_CONF glance_store stores aws
|
||||
@ -34,33 +34,52 @@ function configure_glance {
|
||||
}
|
||||
|
||||
function configure_cinder {
|
||||
set_aws_keys_and_region $CINDER_CONF
|
||||
iniset $CINDER_CONF AWS az ${AWS_AVAILABILITY_ZONE}
|
||||
set_aws_region_and_az $CINDER_CONF
|
||||
iniset $CINDER_CONF AWS volume_driver ${AWS_CINDER_DRIVER}
|
||||
iniset $CINDER_CONF DEFAULT enable_force_upload ${ENABLE_FORCE_UPLOAD}
|
||||
iniset $CINDER_CONF DEFAULT enabled_backends AWS
|
||||
iniset $CINDER_CONF DEFAULT volumes_dir ${VOLUME_DIR}
|
||||
iniset $CINDER_CONF DEFAULT os_privileged_user_name ${CINDER_USER}
|
||||
iniset $CINDER_CONF DEFAULT default_volume_type AWS
|
||||
iniset $CINDER_CONF DEFAULT os_region_name AWS
|
||||
iniset $CINDER_CONF DEFAULT os_region_name ${OS_REGION_NAME}
|
||||
}
|
||||
|
||||
function configure_nova {
|
||||
set_aws_keys_and_region $NOVA_CONF
|
||||
set_aws_region_and_az $NOVA_CONF
|
||||
iniset $NOVA_CONF DEFAULT compute_driver ${AWS_COMPUTE_DRIVER}
|
||||
iniset $NOVA_CONF DEFAULT glance_api_insecure True
|
||||
iniset $NOVA_CONF DEFAULT cinder_api_insecure True
|
||||
iniset $NOVA_CONF DEFAULT vnc_enabled True
|
||||
iniset $NOVA_CONF DEFAULT osapi_compute_extension ${COMPUTE_EXTENSION}
|
||||
iniset $NOVA_CONF DEFAULT force_dhcp_release True
|
||||
|
||||
iniset $NOVA_CONF keystone_authtoken identity_uri "http://${SERVICE_HOST}/identity"
|
||||
iniset $NOVA_CONF keystone_authtoken username nova
|
||||
iniset $NOVA_CONF keystone_authtoken admin_user nova
|
||||
iniset $NOVA_CONF keystone_authtoken password $SERVICE_PASSWORD
|
||||
iniset $NOVA_CONF keystone_authtoken project_name $SERVICE_PROJECT_NAME
|
||||
iniset $NOVA_CONF keystone_authtoken admin_password $SERVICE_PASSWORD
|
||||
iniset $NOVA_CONF keystone_authtoken admin_tenant_name $SERVICE_PROJECT_NAME
|
||||
iniset $NOVA_CONF keystone_authtoken region_name ${OS_REGION_NAME}
|
||||
|
||||
set_aws_region_and_az $NOVA_CPU_CONF
|
||||
iniset $NOVA_CPU_CONF keystone_authtoken identity_uri "http://${SERVICE_HOST}/identity"
|
||||
iniset $NOVA_CPU_CONF keystone_authtoken username nova
|
||||
iniset $NOVA_CPU_CONF keystone_authtoken admin_user nova
|
||||
iniset $NOVA_CPU_CONF keystone_authtoken password $SERVICE_PASSWORD
|
||||
iniset $NOVA_CPU_CONF keystone_authtoken project_name $SERVICE_PROJECT_NAME
|
||||
iniset $NOVA_CPU_CONF keystone_authtoken admin_password $SERVICE_PASSWORD
|
||||
iniset $NOVA_CPU_CONF keystone_authtoken admin_tenant_name $SERVICE_PROJECT_NAME
|
||||
iniset $NOVA_CPU_CONF keystone_authtoken region_name ${OS_REGION_NAME}
|
||||
|
||||
}
|
||||
|
||||
function configure_neutron {
|
||||
set_aws_keys_and_region $NEUTRON_CONF
|
||||
iniset $NEUTRON_CONF AWS az ${AWS_AVAILABILITY_ZONE}
|
||||
set_aws_region_and_az $NEUTRON_CONF
|
||||
iniset $NEUTRON_CONF DEFAULT core_plugin ${CORE_PLUGIN}
|
||||
iniset $NEUTRON_CONF DEFAULT service_plugins ${AWS_SERVICE_PLUGIN}
|
||||
iniset $NEUTRON_CONF nova region_name AWS
|
||||
iniset $NEUTRON_CONF nova region_name ${OS_REGION_NAME}
|
||||
iniset $NEUTRON_CONF keystone_authtoken auth_uri "http://${SERVICE_HOST}/identity"
|
||||
|
||||
iniset $ML2_CONF ml2 type_drivers ${ML2_DRIVERS}
|
||||
iniset $ML2_CONF ml2 tenant_network_types ${ML2_TENANT}
|
||||
|
@ -5,16 +5,29 @@ cp /opt/stack/omni/devstack/lib/* $TOP_DIR/lib/
|
||||
sudo apt-get install crudini -y
|
||||
sudo pip install -r /opt/stack/omni/requirements.txt
|
||||
|
||||
|
||||
if [[ "$1" == "stack" && "$2" == "pre-install" ]]; then
|
||||
if [ "$OMNI_PROVIDER" != "gce" ] && [ "$OMNI_PROVIDER" != "aws" ]; then
|
||||
echo "$OMNI_PROVIDER is not supported"
|
||||
exit 1
|
||||
fi
|
||||
if [ "$OMNI_PROVIDER" == "aws" ]; then
|
||||
if [ -z "$AWS_ACCESS_KEY" ] || [ -z "$AWS_SECRET_KEY" ]; then
|
||||
echo "AWS_ACCESS_KEY and AWS_SECRET_KEY are not provided"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "$1" == "stack" && "$2" == "extra" ]]; then
|
||||
source $TOP_DIR/lib/omni_$OMNI_PROVIDER
|
||||
source $TOP_DIR/lib/common_functions
|
||||
|
||||
if [ "$OMNI_PROVIDER" == "aws" ]; then
|
||||
source $TOP_DIR/lib/creds_mgr
|
||||
install_credsmgr
|
||||
fi
|
||||
|
||||
configure_glance
|
||||
configure_cinder
|
||||
configure_nova
|
||||
@ -22,3 +35,10 @@ if [[ "$1" == "stack" && "$2" == "extra" ]]; then
|
||||
copy_omni_files
|
||||
restart_services
|
||||
fi
|
||||
|
||||
if [[ "$1" == "unstack" ]]; then
|
||||
if [ "$OMNI_PROVIDER" == "aws" ]; then
|
||||
source $TOP_DIR/lib/creds_mgr
|
||||
stop_credsmgr_service
|
||||
fi
|
||||
fi
|
||||
|
@ -186,6 +186,10 @@ class AwsMechanismDriver(api.MechanismDriver):
|
||||
raise NetworkWithMultipleAZs()
|
||||
aws_az = network_az_hints[0]
|
||||
else:
|
||||
aws_az = cfg.CONF.AWS.az
|
||||
LOG.info("AZ details missing in context, so fetching from the"
|
||||
" conf file. aws_az: %s", aws_az)
|
||||
if aws_az is None:
|
||||
raise AzNotProvided()
|
||||
self._validate_az(aws_az)
|
||||
ec2_subnet_id = self.aws_utils.create_subnet_and_tags(
|
||||
@ -209,8 +213,20 @@ class AwsMechanismDriver(api.MechanismDriver):
|
||||
if ',' in aws_az:
|
||||
raise NetworkWithMultipleAZs()
|
||||
session = self.aws_utils.get_keystone_session()
|
||||
azmgr_url = session.get_endpoint(service_type='azmanager',
|
||||
region_name=cfg.CONF.nova_region_name)
|
||||
azmgr_url = ''
|
||||
try:
|
||||
azmgr_url = session.get_endpoint(service_type='azmanager',
|
||||
region_name=cfg.CONF.nova_region_name)
|
||||
if not (azmgr_url and azmgr_url.strip()):
|
||||
LOG.warning("AZ manager endpoint not found. Proceeding without"
|
||||
" validating the AZ information. Error: "
|
||||
"None or empty endpoint found.")
|
||||
return
|
||||
except Exception as e:
|
||||
LOG.error("Error in finding AZ manager endpoint. "
|
||||
"Proceeding without validating the AZ information. "
|
||||
"Error: %s" % e)
|
||||
return
|
||||
zones = self._send_request(session, azmgr_url)
|
||||
if aws_az not in zones:
|
||||
LOG.error("Provided az %s not found in zones %s", aws_az, zones)
|
||||
|
@ -46,10 +46,27 @@ aws_opts = [
|
||||
help='Listen to keypair delete notifications and act on them')
|
||||
]
|
||||
|
||||
keystone_authtoken_group = cfg.OptGroup(name='keystone_authtoken',
|
||||
title='Options to connect to Keystone')
|
||||
|
||||
keystone_authtoken_opts = [
|
||||
cfg.StrOpt('identity_uri', help='Keystone url'),
|
||||
cfg.StrOpt('username', help='Keystone Username'),
|
||||
cfg.StrOpt('password', help='Keystone Password'),
|
||||
cfg.StrOpt('project_name', help='Project name'),
|
||||
cfg.StrOpt('region_name', help='AWS region name'),
|
||||
cfg.StrOpt('admin_user', help='Keystone admin username'),
|
||||
cfg.StrOpt('admin_password', help='Keystone admin password'),
|
||||
cfg.StrOpt('admin_tenant_name', help='Keystone admin tenant name')
|
||||
]
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
CONF.register_group(aws_group)
|
||||
CONF.register_opts(aws_opts, group=aws_group)
|
||||
CONF.register_group(keystone_authtoken_group)
|
||||
CONF.register_opts(keystone_authtoken_opts, group=keystone_authtoken_group)
|
||||
|
||||
|
||||
EC2_STATE_MAP = {
|
||||
"pending": power_state.NOSTATE,
|
||||
|
@ -137,9 +137,9 @@ class RestClient(object):
|
||||
|
||||
os_username = os.getenv('OS_USERNAME')
|
||||
os_password = os.getenv('OS_PASSWORD')
|
||||
os_tenant_name = os.getenv('OS_TENANT_NAME')
|
||||
os_tenant_name = os.getenv('OS_PROJECT_NAME')
|
||||
|
||||
self.glance_endpoint = os_auth_url.replace('keystone/v3', 'glance')
|
||||
self.glance_endpoint = os_auth_url.replace('identity/v3', 'image')
|
||||
sys.stdout.write('Using glance endpoint: ' + self.glance_endpoint)
|
||||
|
||||
v3_auth = v3.Password(auth_url=os_auth_url, username=os_username,
|
||||
|
Loading…
Reference in New Issue
Block a user