#!/usr/bin/env bash # Install and start **Barbican** service # To enable a minimal set of Barbican features, add the following to localrc: # enable_service barbican-svc barbican-retry barbican-keystone-listener # # Dependencies: # - functions # - OS_AUTH_URL for auth in api # - DEST set to the destination directory # - SERVICE_PASSWORD, SERVICE_PROJECT_NAME for auth in api # - STACK_USER service user # stack.sh # --------- # install_barbican # configure_barbican # init_barbican # start_barbican # stop_barbican # cleanup_barbican # Save trace setting XTRACE=$(set +o | grep xtrace) set +o xtrace # PyKMIP configuration PYKMIP_SERVER_KEY=${PYKMIP_SERVER_KEY:-$INT_CA_DIR/private/pykmip-server.key} PYKMIP_SERVER_CERT=${PYKMIP_SERVER_CERT:-$INT_CA_DIR/pykmip-server.crt} PYKMIP_CLIENT_KEY=${PYKMIP_CLIENT_KEY:-$INT_CA_DIR/private/pykmip-client.key} PYKMIP_CLIENT_CERT=${PYKMIP_CLIENT_CERT:-$INT_CA_DIR/pykmip-client.crt} PYKMIP_CA_PATH=${PYKMIP_CA_PATH:-$INT_CA_DIR/ca-chain.pem} # Functions # --------- # TODO(john-wood-w) These 'magic' functions are called by devstack to enable # a given service (so the name between 'is_' and '_enabled'). Currently the # Zuul infra gate configuration (at https://github.com/openstack-infra/project-config/blob/master/jenkins/jobs/barbican.yaml) # only enables the 'barbican' service. So the two functions below, for the two # services we wish to run, have to key off of that lone 'barbican' selection. # Once the Zuul config is updated to add these two services properly, then # these functions should be replaced by the single method below. # !!!! Special thanks to rm_work for figuring this out !!!! function is_barbican-retry_enabled { [[ ,${ENABLED_SERVICES} =~ ,"barbican" ]] && return 0 } function is_barbican-svc_enabled { [[ ,${ENABLED_SERVICES} =~ ,"barbican" ]] && return 0 } function is_barbican-keystone-listener_enabled { [[ ,${ENABLED_SERVICES} =~ ,"barbican" ]] && return 0 } # TODO(john-wood-w) Replace the above two functions with the one below once # Zuul is update per above. ## Test if any Barbican services are enabled ## is_barbican_enabled #function is_barbican_enabled { # [[ ,${ENABLED_SERVICES} =~ ,"barbican-" ]] && return 0 # return 1 #} # cleanup_barbican - Remove residual data files, anything left over from previous # runs that a clean run would need to clean up function cleanup_barbican { : } # configure_barbicanclient - Set config files, create data dirs, etc function configure_barbicanclient { setup_develop $BARBICANCLIENT_DIR } # configure_dogtag_plugin - Change config to use dogtag plugin function configure_dogtag_plugin { sudo openssl pkcs12 -in /root/.dogtag/pki-tomcat/ca_admin_cert.p12 -passin pass:PASSWORD -out $BARBICAN_CONF_DIR/kra_admin_cert.pem -nodes sudo chown $USER $BARBICAN_CONF_DIR/kra_admin_cert.pem iniset $BARBICAN_CONF dogtag_plugin dogtag_port 8373 iniset $BARBICAN_CONF dogtag_plugin pem_path "$BARBICAN_CONF_DIR/kra_admin_cert.pem" iniset $BARBICAN_CONF dogtag_plugin dogtag_host localhost iniset $BARBICAN_CONF dogtag_plugin nss_db_path '/etc/barbican/alias' iniset $BARBICAN_CONF dogtag_plugin nss_db_path_ca '/etc/barbican/alias-ca' iniset $BARBICAN_CONF dogtag_plugin nss_password 'password123' iniset $BARBICAN_CONF dogtag_plugin simple_cmc_profile 'caOtherCert' iniset $BARBICAN_CONF dogtag_plugin ca_expiration_time 1 iniset $BARBICAN_CONF dogtag_plugin plugin_working_dir '/etc/barbican/dogtag' iniset $BARBICAN_CONF secretstore enabled_secretstore_plugins dogtag_crypto iniset $BARBICAN_CONF certificate enabled_certificate_plugins dogtag } # configure_barbican - Set config files, create data dirs, etc function configure_barbican { setup_develop $BARBICAN_DIR [ ! -d $BARBICAN_CONF_DIR ] && sudo mkdir -m 755 -p $BARBICAN_CONF_DIR sudo chown $USER $BARBICAN_CONF_DIR [ ! -d $BARBICAN_API_LOG_DIR ] && sudo mkdir -m 755 -p $BARBICAN_API_LOG_DIR sudo chown $USER $BARBICAN_API_LOG_DIR [ ! -d $BARBICAN_CONF_DIR ] && sudo mkdir -m 755 -p $BARBICAN_CONF_DIR sudo chown $USER $BARBICAN_CONF_DIR # Copy the barbican config files to the config dir cp $BARBICAN_DIR/etc/barbican/barbican-api-paste.ini $BARBICAN_CONF_DIR cp -R $BARBICAN_DIR/etc/barbican/vassals $BARBICAN_CONF_DIR # Copy functional test config cp $BARBICAN_DIR/etc/barbican/barbican-functional.conf $BARBICAN_CONF_DIR # Enable DEBUG iniset $BARBICAN_CONF DEFAULT debug True # Set the host_href iniset $BARBICAN_CONF DEFAULT host_href "$BARBICAN_HOST_HREF" # Set the log file location iniset $BARBICAN_CONF DEFAULT log_file "$BARBICAN_API_LOG_DIR/barbican.log" # Enable logging to stderr to have log also in the screen window iniset $BARBICAN_CONF DEFAULT use_stderr True # Format logging if [ "$LOG_COLOR" == "True" ] && [ "$SYSLOG" == "False" ]; then setup_colorized_logging $BARBICAN_CONF DEFAULT project user fi # Set the database connection url iniset $BARBICAN_CONF DEFAULT sql_connection `database_connection_url barbican` # Disable auto-migration when deploying Barbican iniset $BARBICAN_CONF DEFAULT db_auto_create False # Increase default request buffer size, keystone auth PKI tokens can be very long iniset $BARBICAN_CONF_DIR/vassals/barbican-api.ini uwsgi buffer-size 65535 # Rabbit settings if is_service_enabled rabbit; then iniset $BARBICAN_CONF DEFAULT transport_url rabbit://$RABBIT_USERID:$RABBIT_PASSWORD@$RABBIT_HOST:5672 else echo_summary "Barbican requires that the RabbitMQ service is enabled" fi write_uwsgi_config "$BARBICAN_UWSGI_CONF" "$BARBICAN_WSGI" "/key-manager" ## Set up keystone # Turn on the middleware iniset $BARBICAN_PASTE_CONF 'pipeline:barbican_api' pipeline 'barbican-api-keystone' # Set the keystone parameters configure_auth_token_middleware $BARBICAN_CONF barbican $BARBICAN_AUTH_CACHE_DIR # Enable the keystone listener iniset $BARBICAN_CONF keystone_notifications enable True iniset $BARBICAN_CONF keystone_notifications control_exchange 'keystone' } # init_barbican - Initialize etc. function init_barbican { # Create cache dir sudo mkdir -p $BARBICAN_AUTH_CACHE_DIR sudo chown $STACK_USER $BARBICAN_AUTH_CACHE_DIR rm -f $BARBICAN_AUTH_CACHE_DIR/* recreate_database barbican utf8 $BARBICAN_BIN_DIR/barbican-manage db upgrade -v head } # install_barbican - Collect source and prepare function install_barbican { # Install package requirements if is_fedora; then install_package sqlite-devel openldap-devel fi # TODO(ravips): We need this until barbican gets into devstack setup_develop $BARBICAN_DIR pip_install 'uwsgi' } # install_barbicanclient - Collect source and prepare function install_barbicanclient { git_clone $BARBICANCLIENT_REPO $BARBICANCLIENT_DIR $BARBICANCLIENT_BRANCH setup_develop $BARBICANCLIENT_DIR } # start_barbican - Start running processes, including screen function start_barbican { # Start the Barbican service up. run_process barbican-svc "$BARBICAN_BIN_DIR/uwsgi --ini $BARBICAN_UWSGI_CONF" # Pause while the barbican-svc populates the database, otherwise the retry # service below might try to do this at the same time, leading to race # conditions. sleep 10 # Start the retry scheduler server up. run_process barbican-retry "$BARBICAN_BIN_DIR/barbican-retry --config-file=$BARBICAN_CONF_DIR/barbican.conf" # Start the barbican-keystone-listener run_process barbican-keystone-listener "$BARBICAN_BIN_DIR/barbican-keystone-listener --config-file=$BARBICAN_CONF_DIR/barbican.conf" } # stop_barbican - Stop running processes function stop_barbican { # This will eventually be refactored to work like # Solum and Manila (script to kick off a wsgiref server) # For now, this will stop uWSGI rather than have it hang killall -9 uwsgi # This cleans up the PID file, but uses pkill so Barbican # uWSGI emperor process doesn't actually stop stop_process barbican-svc stop_process barbican-retry stop_process barbican-keystone-listener } function get_id { echo `"$@" | awk '/ id / { print $4 }'` } function create_barbican_accounts { # # Setup Default Admin User # SERVICE_PROJECT=$(openstack project list | awk "/ $SERVICE_PROJECT_NAME / { print \$2 }") ADMIN_ROLE=$(openstack role list | awk "/ admin / { print \$2 }") BARBICAN_USER=$(openstack user create \ --password "$SERVICE_PASSWORD" \ --project $SERVICE_PROJECT \ --email "barbican@example.com" \ barbican \ | grep " id " | get_field 2) openstack role add --project $SERVICE_PROJECT \ --user $BARBICAN_USER \ $ADMIN_ROLE # # Setup Default service-admin User # SERVICE_ADMIN=$(get_id openstack user create \ --password "$SERVICE_PASSWORD" \ --email "service-admin@example.com" \ "service-admin") SERVICE_ADMIN_ROLE=$(get_id openstack role create \ "key-manager:service-admin") openstack role add \ --user "$SERVICE_ADMIN" \ --project "$SERVICE_PROJECT" \ "$SERVICE_ADMIN_ROLE" # # Setup RBAC User Projects and Roles # PASSWORD="barbican" PROJECT_A_ID=$(get_id openstack project create "project_a") PROJECT_B_ID=$(get_id openstack project create "project_b") ROLE_ADMIN_ID=$(get_id openstack role show admin) ROLE_CREATOR_ID=$(get_id openstack role create "creator") ROLE_OBSERVER_ID=$(get_id openstack role create "observer") ROLE_AUDIT_ID=$(get_id openstack role create "audit") # # Setup RBAC Admin of Project A # USER_ID=$(get_id openstack user create \ --password "$PASSWORD" \ --email "admin_a@example.net" \ "project_a_admin") openstack role add \ --user "$USER_ID" \ --project "$PROJECT_A_ID" \ "$ROLE_ADMIN_ID" # # Setup RBAC Creator of Project A # USER_ID=$(get_id openstack user create \ --password "$PASSWORD" \ --email "creator_a@example.net" \ "project_a_creator") openstack role add \ --user "$USER_ID" \ --project "$PROJECT_A_ID" \ "$ROLE_CREATOR_ID" # Adding second creator user in project_a USER_ID=$(openstack user create \ --password "$PASSWORD" \ --email "creator2_a@example.net" \ "project_a_creator_2" -f value -c id) openstack role add \ --user "$USER_ID" \ --project "$PROJECT_A_ID" \ "$ROLE_CREATOR_ID" # # Setup RBAC Observer of Project A # USER_ID=$(get_id openstack user create \ --password "$PASSWORD" \ --email "observer_a@example.net" \ "project_a_observer") openstack role add \ --user "$USER_ID" \ --project "$PROJECT_A_ID" \ "$ROLE_OBSERVER_ID" # # Setup RBAC Auditor of Project A # USER_ID=$(get_id openstack user create \ --password "$PASSWORD" \ --email "auditor_a@example.net" \ "project_a_auditor") openstack role add \ --user "$USER_ID" \ --project "$PROJECT_A_ID" \ "$ROLE_AUDIT_ID" # # Setup RBAC Admin of Project B # USER_ID=$(get_id openstack user create \ --password "$PASSWORD" \ --email "admin_b@example.net" \ "project_b_admin") openstack role add \ --user "$USER_ID" \ --project "$PROJECT_B_ID" \ "$ROLE_ADMIN_ID" # # Setup RBAC Creator of Project B # USER_ID=$(get_id openstack user create \ --password "$PASSWORD" \ --email "creator_b@example.net" \ "project_b_creator") openstack role add \ --user "$USER_ID" \ --project "$PROJECT_B_ID" \ "$ROLE_CREATOR_ID" # # Setup RBAC Observer of Project B # USER_ID=$(get_id openstack user create \ --password "$PASSWORD" \ --email "observer_b@example.net" \ "project_b_observer") openstack role add \ --user "$USER_ID" \ --project "$PROJECT_B_ID" \ "$ROLE_OBSERVER_ID" # # Setup RBAC auditor of Project B # USER_ID=$(get_id openstack user create \ --password "$PASSWORD" \ --email "auditor_b@example.net" \ "project_b_auditor") openstack role add \ --user "$USER_ID" \ --project "$PROJECT_B_ID" \ "$ROLE_AUDIT_ID" # # Setup Barbican Endpoint # BARBICAN_SERVICE=$(openstack service create \ --name barbican \ --description "Barbican Service" \ 'key-manager' \ | grep " id " | get_field 2) openstack endpoint create \ --os-identity-api-version 3 \ --region RegionOne \ $BARBICAN_SERVICE \ public "http://$SERVICE_HOST/key-manager" openstack endpoint create \ --os-identity-api-version 3 \ --region RegionOne \ $BARBICAN_SERVICE \ internal "http://$SERVICE_HOST/key-manager" } # PyKMIP functions # ---------------- # install_pykmip - install the PyKMIP python module # create keys and certificate for server function install_pykmip { pip_install 'pykmip' if is_service_enabled pykmip-server; then [ ! -d ${PYKMIP_CONF_DIR} ] && sudo mkdir -p ${PYKMIP_CONF_DIR} sudo chown ${USER} ${PYKMIP_CONF_DIR} [ ! -d ${PYKMIP_LOG_DIR} ] && sudo mkdir -p ${PYKMIP_LOG_DIR} sudo chown ${USER} ${PYKMIP_LOG_DIR} init_CA if [ ! -e ${PYKMIP_SERVER_KEY} ]; then make_cert ${INT_CA_DIR} 'pykmip-server' 'pykmip-server' chmod 400 ${PYKMIP_SERVER_KEY} fi if [ ! -e ${PYKMIP_CLIENT_KEY} ]; then make_cert ${INT_CA_DIR} 'pykmip-client' 'pykmip-client' chmod 400 ${PYKMIP_CLIENT_KEY} fi if [ ! -e ${PYKMIP_CONF} ]; then cat > ${PYKMIP_CONF} < .tmp.setup.inf < .tmp.ca.cfg < .tmp.kra.cfg <