From 06d616d1c4964a5057d3fcc8759461e5e2155849 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Wed, 18 Feb 2015 16:40:04 +0000 Subject: Keystone configuration to ansible --- openstack-keystone.configure | 98 +- openstack/etc/keystone/keystone-paste.ini | 112 -- openstack/etc/keystone/keystone.conf | 1384 -------------------- openstack/etc/keystone/logging.conf | 39 - openstack/etc/keystone/policy.json | 144 -- .../system/openstack-keystone-setup.service | 7 +- openstack/manifest | 30 +- openstack/usr/share/openstack/hosts | 1 + openstack/usr/share/openstack/keystone.yml | 73 ++ .../share/openstack/keystone/keystone-paste.ini | 112 ++ .../usr/share/openstack/keystone/keystone.conf | 1384 ++++++++++++++++++++ .../usr/share/openstack/keystone/logging.conf | 39 + openstack/usr/share/openstack/keystone/policy.json | 144 ++ openstack/usr/share/openstack/modules/README | 3 + .../usr/share/openstack/modules/cinder_manage | 105 ++ openstack/usr/share/openstack/modules/glance | 176 +++ .../usr/share/openstack/modules/glance_manage | 158 +++ openstack/usr/share/openstack/modules/heat_manage | 105 ++ .../usr/share/openstack/modules/keystone_manage | 123 ++ .../usr/share/openstack/modules/keystone_service | 309 +++++ .../share/openstack/modules/neutron_floating_ip | 274 ++++ .../usr/share/openstack/modules/neutron_network | 282 ++++ .../usr/share/openstack/modules/neutron_router | 210 +++ .../share/openstack/modules/neutron_router_gateway | 215 +++ .../openstack/modules/neutron_router_interface | 249 ++++ .../usr/share/openstack/modules/neutron_sec_group | 382 ++++++ .../usr/share/openstack/modules/neutron_subnet | 294 +++++ openstack/usr/share/openstack/modules/nova_flavor | 188 +++ openstack/usr/share/openstack/modules/nova_manage | 93 ++ .../usr/share/openstack/openstack-keystone-setup | 92 -- 30 files changed, 5017 insertions(+), 1808 deletions(-) delete mode 100644 openstack/etc/keystone/keystone-paste.ini delete mode 100644 openstack/etc/keystone/keystone.conf delete mode 100644 openstack/etc/keystone/logging.conf delete mode 100644 openstack/etc/keystone/policy.json create mode 100644 openstack/usr/share/openstack/hosts create mode 100644 openstack/usr/share/openstack/keystone.yml create mode 100644 openstack/usr/share/openstack/keystone/keystone-paste.ini create mode 100644 openstack/usr/share/openstack/keystone/keystone.conf create mode 100644 openstack/usr/share/openstack/keystone/logging.conf create mode 100644 openstack/usr/share/openstack/keystone/policy.json create mode 100644 openstack/usr/share/openstack/modules/README create mode 100644 openstack/usr/share/openstack/modules/cinder_manage create mode 100644 openstack/usr/share/openstack/modules/glance create mode 100644 openstack/usr/share/openstack/modules/glance_manage create mode 100644 openstack/usr/share/openstack/modules/heat_manage create mode 100644 openstack/usr/share/openstack/modules/keystone_manage create mode 100644 openstack/usr/share/openstack/modules/keystone_service create mode 100644 openstack/usr/share/openstack/modules/neutron_floating_ip create mode 100644 openstack/usr/share/openstack/modules/neutron_network create mode 100644 openstack/usr/share/openstack/modules/neutron_router create mode 100644 openstack/usr/share/openstack/modules/neutron_router_gateway create mode 100644 openstack/usr/share/openstack/modules/neutron_router_interface create mode 100644 openstack/usr/share/openstack/modules/neutron_sec_group create mode 100644 openstack/usr/share/openstack/modules/neutron_subnet create mode 100644 openstack/usr/share/openstack/modules/nova_flavor create mode 100644 openstack/usr/share/openstack/modules/nova_manage delete mode 100644 openstack/usr/share/openstack/openstack-keystone-setup diff --git a/openstack-keystone.configure b/openstack-keystone.configure index d2d1171e..8cdc8e64 100644 --- a/openstack-keystone.configure +++ b/openstack-keystone.configure @@ -20,37 +20,79 @@ set -e ROOT="$1" ########################################################################## -# Substitutions in configuration files + +ln -s "/etc/systemd/system/openstack-keystone-setup.service" \ + "$ROOT/etc/systemd/system/multi-user.target.wants/openstack-keystone-setup.service" + +########################################################################## +# Check variables ########################################################################## -cat < "$ROOT"/etc/openstack-keystone-setup.sed -s/##KEYSTONE_TEMPORARY_ADMIN_TOKEN##/$KEYSTONE_TEMPORARY_ADMIN_TOKEN/g -s/##KEYSTONE_TEMPORARY_ADMIN_PASSWORD##/$KEYSTONE_TEMPORARY_ADMIN_PASSWORD/g -s/##KEYSTONE_PUBLIC_URL##/$KEYSTONE_PUBLIC_URL/g -s/##KEYSTONE_INTERNAL_URL##/$KEYSTONE_INTERNAL_URL/g -s/##KEYSTONE_ADMIN_URL##/$KEYSTONE_ADMIN_URL/g -s/##OPENSTACK_AUTH_HOST##/$OPENSTACK_AUTH_HOST/g -s/##OPENSTACK_AUTH_PORT##/$OPENSTACK_AUTH_PORT/g -s/##IDENTITY_URI##/$IDENTITY_URI/g -s/##KEYSTONE_DB_USER##/$KEYSTONE_DB_USER/g -s/##KEYSTONE_DB_PASSWORD##/$KEYSTONE_DB_PASSWORD/g -EOF +if [ -z "$KEYSTONE_TEMPORARY_ADMIN_TOKEN" -a \ + -z "$KEYSTONE_ADMIN_PASSWORD" -a \ + -z "$KEYSTONE_PUBLIC_URL" -a \ + -z "$KEYSTONE_INTERNAL_URL" -a \ + -z "$KEYSTONE_ADMIN_URL" -a \ + -z "$OPENSTACK_AUTH_HOST" -a \ + -z "$OPENSTACK_AUTH_PORT" -a \ + -z "$IDENTITY_URI" -a \ + -z "$KEYSTONE_DB_USER" -a \ + -z "$KEYSTONE_DB_PASSWORD" -a \ + -z "$RABBITMQ_HOST" -a \ + -z "$RABBITMQ_PORT" -a \ + -z "$RABBITMQ_USER" -a \ + -z "$RABBITMQ_PASSWORD" -a \ + -z "$CONTROLLER_HOST" ]; then + # No Keystone options defined, do nothing. + exit 0 +fi -sed -f "$ROOT"/etc/openstack-keystone-setup.sed -i \ - "$ROOT"/etc/keystone/keystone.conf \ - "$ROOT"/etc/glance/glance-api.conf \ - "$ROOT"/etc/glance/glance-registry.conf \ - "$ROOT"/etc/nova/nova.conf \ - "$ROOT"/etc/cinder/cinder.conf \ - "$ROOT"/etc/neutron/neutron.conf \ - "$ROOT"/etc/neutron/metadata_agent.ini \ - "$ROOT"/usr/share/openstack/openstack-keystone-setup \ - "$ROOT"/usr/share/openstack/openstack-glance-setup \ - "$ROOT"/usr/share/openstack/openstack-nova-setup \ - "$ROOT"/usr/share/openstack/openstack-neutron-setup \ - "$ROOT"/usr/share/openstack/openstack-cinder-setup +if [ -z "$KEYSTONE_TEMPORARY_ADMIN_TOKEN" -o \ + -z "$KEYSTONE_ADMIN_PASSWORD" -o \ + -z "$KEYSTONE_PUBLIC_URL" -o \ + -z "$KEYSTONE_INTERNAL_URL" -o \ + -z "$KEYSTONE_ADMIN_URL" -o \ + -z "$OPENSTACK_AUTH_HOST" -o \ + -z "$OPENSTACK_AUTH_PORT" -o \ + -z "$IDENTITY_URI" -a \ + -z "$KEYSTONE_DB_USER" -o \ + -z "$KEYSTONE_DB_PASSWORD" -o \ + -z "$RABBITMQ_HOST" -o \ + -z "$RABBITMQ_PORT" -o \ + -z "$RABBITMQ_USER" -o \ + -z "$RABBITMQ_PASSWORD" -o \ + -z "$CONTROLLER_HOST" ]; then + echo Some options required for Keystone were defined, but not all. + exit 1 +fi +########################################################################## +# Generate config variable shell snippet ########################################################################## -ln -s "/etc/systemd/system/openstack-keystone-setup.service" \ - "$ROOT/etc/systemd/system/multi-user.target.wants/openstack-keystone-setup.service" +OPENSTACK_DATA="$ROOT/etc/openstack" +mkdir -p "$OPENSTACK_DATA" + +python <<'EOF' >"$OPENSTACK_DATA/keystone.conf" +import os, sys, yaml + +keystone_configuration={ + 'KEYSTONE_TEMPORARY_ADMIN_TOKEN': os.environ['KEYSTONE_TEMPORARY_ADMIN_TOKEN'], + 'KEYSTONE_ADMIN_PASSWORD': os.environ['KEYSTONE_ADMIN_PASSWORD'], + 'KEYSTONE_PUBLIC_URL': os.environ['KEYSTONE_PUBLIC_URL'], + 'KEYSTONE_INTERNAL_URL': os.environ['KEYSTONE_INTERNAL_URL'], + 'KEYSTONE_ADMIN_URL': os.environ['KEYSTONE_ADMIN_URL'], + 'OPENSTACK_AUTH_HOST': os.environ['OPENSTACK_AUTH_HOST'], + 'OPENSTACK_AUTH_PORT': os.environ['OPENSTACK_AUTH_PORT'], + 'IDENTITY_URI': os.environ['IDENTITY_URI'], + 'KEYSTONE_DB_USER': os.environ['KEYSTONE_DB_USER'], + 'KEYSTONE_DB_PASSWORD': os.environ['KEYSTONE_DB_PASSWORD'], + 'CONTROLLER_HOST': os.environ['CONTROLLER_HOST'], + 'RABBITMQ_HOST': os.environ['RABBITMQ_HOST'], + 'RABBITMQ_PORT': os.environ['RABBITMQ_PORT'], + 'RABBITMQ_USER': os.environ['RABBITMQ_USER'], + 'RABBITMQ_PASSWORD': os.environ['RABBITMQ_PASSWORD'], +} + +yaml.dump(keystone_configuration, sys.stdout, default_flow_style=False) +EOF diff --git a/openstack/etc/keystone/keystone-paste.ini b/openstack/etc/keystone/keystone-paste.ini deleted file mode 100644 index cd132971..00000000 --- a/openstack/etc/keystone/keystone-paste.ini +++ /dev/null @@ -1,112 +0,0 @@ -# Keystone PasteDeploy configuration file. - -[filter:debug] -paste.filter_factory = keystone.common.wsgi:Debug.factory - -[filter:build_auth_context] -paste.filter_factory = keystone.middleware:AuthContextMiddleware.factory - -[filter:token_auth] -paste.filter_factory = keystone.middleware:TokenAuthMiddleware.factory - -[filter:admin_token_auth] -paste.filter_factory = keystone.middleware:AdminTokenAuthMiddleware.factory - -[filter:xml_body] -paste.filter_factory = keystone.middleware:XmlBodyMiddleware.factory - -[filter:xml_body_v2] -paste.filter_factory = keystone.middleware:XmlBodyMiddlewareV2.factory - -[filter:xml_body_v3] -paste.filter_factory = keystone.middleware:XmlBodyMiddlewareV3.factory - -[filter:json_body] -paste.filter_factory = keystone.middleware:JsonBodyMiddleware.factory - -[filter:user_crud_extension] -paste.filter_factory = keystone.contrib.user_crud:CrudExtension.factory - -[filter:crud_extension] -paste.filter_factory = keystone.contrib.admin_crud:CrudExtension.factory - -[filter:ec2_extension] -paste.filter_factory = keystone.contrib.ec2:Ec2Extension.factory - -[filter:ec2_extension_v3] -paste.filter_factory = keystone.contrib.ec2:Ec2ExtensionV3.factory - -[filter:federation_extension] -paste.filter_factory = keystone.contrib.federation.routers:FederationExtension.factory - -[filter:oauth1_extension] -paste.filter_factory = keystone.contrib.oauth1.routers:OAuth1Extension.factory - -[filter:s3_extension] -paste.filter_factory = keystone.contrib.s3:S3Extension.factory - -[filter:endpoint_filter_extension] -paste.filter_factory = keystone.contrib.endpoint_filter.routers:EndpointFilterExtension.factory - -[filter:simple_cert_extension] -paste.filter_factory = keystone.contrib.simple_cert:SimpleCertExtension.factory - -[filter:revoke_extension] -paste.filter_factory = keystone.contrib.revoke.routers:RevokeExtension.factory - -[filter:url_normalize] -paste.filter_factory = keystone.middleware:NormalizingFilter.factory - -[filter:sizelimit] -paste.filter_factory = keystone.middleware:RequestBodySizeLimiter.factory - -[filter:stats_monitoring] -paste.filter_factory = keystone.contrib.stats:StatsMiddleware.factory - -[filter:stats_reporting] -paste.filter_factory = keystone.contrib.stats:StatsExtension.factory - -[filter:access_log] -paste.filter_factory = keystone.contrib.access:AccessLogMiddleware.factory - -[app:public_service] -paste.app_factory = keystone.service:public_app_factory - -[app:service_v3] -paste.app_factory = keystone.service:v3_app_factory - -[app:admin_service] -paste.app_factory = keystone.service:admin_app_factory - -[pipeline:public_api] -pipeline = sizelimit url_normalize build_auth_context token_auth admin_token_auth xml_body_v2 json_body ec2_extension user_crud_extension public_service - -[pipeline:admin_api] -pipeline = sizelimit url_normalize build_auth_context token_auth admin_token_auth xml_body_v2 json_body ec2_extension s3_extension crud_extension admin_service - -[pipeline:api_v3] -pipeline = sizelimit url_normalize build_auth_context token_auth admin_token_auth xml_body_v3 json_body ec2_extension_v3 s3_extension simple_cert_extension service_v3 - -[app:public_version_service] -paste.app_factory = keystone.service:public_version_app_factory - -[app:admin_version_service] -paste.app_factory = keystone.service:admin_version_app_factory - -[pipeline:public_version_api] -pipeline = sizelimit url_normalize xml_body public_version_service - -[pipeline:admin_version_api] -pipeline = sizelimit url_normalize xml_body admin_version_service - -[composite:main] -use = egg:Paste#urlmap -/v2.0 = public_api -/v3 = api_v3 -/ = public_version_api - -[composite:admin] -use = egg:Paste#urlmap -/v2.0 = admin_api -/v3 = api_v3 -/ = admin_version_api diff --git a/openstack/etc/keystone/keystone.conf b/openstack/etc/keystone/keystone.conf deleted file mode 100644 index a46cc5fc..00000000 --- a/openstack/etc/keystone/keystone.conf +++ /dev/null @@ -1,1384 +0,0 @@ -[DEFAULT] - -# -# Options defined in keystone -# - -# A "shared secret" that can be used to bootstrap Keystone. -# This "token" does not represent a user, and carries no -# explicit authorization. To disable in production (highly -# recommended), remove AdminTokenAuthMiddleware from your -# paste application pipelines (for example, in keystone- -# paste.ini). (string value) -admin_token=##KEYSTONE_TEMPORARY_ADMIN_TOKEN## - -# The IP address of the network interface for the public -# service to listen on. (string value) -# Deprecated group/name - [DEFAULT]/bind_host -#public_bind_host=0.0.0.0 - -# The IP address of the network interface for the admin -# service to listen on. (string value) -# Deprecated group/name - [DEFAULT]/bind_host -#admin_bind_host=0.0.0.0 - -# The port which the OpenStack Compute service listens on. -# (integer value) -compute_port=8774 - -# The port number which the admin service listens on. (integer -# value) -admin_port=35357 - -# The port number which the public service listens on. -# (integer value) -public_port=5000 - -# The base public endpoint URL for Keystone that is advertised -# to clients (NOTE: this does NOT affect how Keystone listens -# for connections). Defaults to the base host URL of the -# request. E.g. a request to http://server:5000/v2.0/users -# will default to http://server:5000. You should only need to -# set this value if the base URL contains a path (e.g. -# /prefix/v2.0) or the endpoint should be found on a different -# server. (string value) -#public_endpoint= - -# The base admin endpoint URL for Keystone that is advertised -# to clients (NOTE: this does NOT affect how Keystone listens -# for connections). Defaults to the base host URL of the -# request. E.g. a request to http://server:35357/v2.0/users -# will default to http://server:35357. You should only need to -# set this value if the base URL contains a path (e.g. -# /prefix/v2.0) or the endpoint should be found on a different -# server. (string value) -#admin_endpoint= - -# The number of worker processes to serve the public WSGI -# application (integer value) -#public_workers=1 - -# The number of worker processes to serve the admin WSGI -# application (integer value) -#admin_workers=1 - -# Enforced by optional sizelimit middleware -# (keystone.middleware:RequestBodySizeLimiter). (integer -# value) -#max_request_body_size=114688 - -# Limit the sizes of user & project ID/names. (integer value) -#max_param_size=64 - -# Similar to max_param_size, but provides an exception for -# token values. (integer value) -#max_token_size=8192 - -# During a SQL upgrade member_role_id will be used to create a -# new role that will replace records in the assignment table -# with explicit role grants. After migration, the -# member_role_id will be used in the API add_user_to_project. -# (string value) -#member_role_id=9fe2ff9ee4384b1894a90878d3e92bab - -# During a SQL upgrade member_role_name will be used to create -# a new role that will replace records in the assignment table -# with explicit role grants. After migration, member_role_name -# will be ignored. (string value) -#member_role_name=_member_ - -# The value passed as the keyword "rounds" to passlib's -# encrypt method. (integer value) -#crypt_strength=40000 - -# Set this to true if you want to enable TCP_KEEPALIVE on -# server sockets, i.e. sockets used by the Keystone wsgi -# server for client connections. (boolean value) -#tcp_keepalive=false - -# Sets the value of TCP_KEEPIDLE in seconds for each server -# socket. Only applies if tcp_keepalive is true. Not supported -# on OS X. (integer value) -#tcp_keepidle=600 - -# The maximum number of entities that will be returned in a -# collection, with no limit set by default. This global limit -# may be then overridden for a specific driver, by specifying -# a list_limit in the appropriate section (e.g. [assignment]). -# (integer value) -#list_limit= - -# Set this to false if you want to enable the ability for -# user, group and project entities to be moved between domains -# by updating their domain_id. Allowing such movement is not -# recommended if the scope of a domain admin is being -# restricted by use of an appropriate policy file (see -# policy.v3cloudsample as an example). (boolean value) -#domain_id_immutable=true - -# If set to true, strict password length checking is performed -# for password manipulation. If a password exceeds the maximum -# length, the operation will fail with an HTTP 403 Forbidden -# error. If set to false, passwords are automatically -# truncated to the maximum length. (boolean value) -#strict_password_check=false - - -# -# Options defined in oslo.messaging -# - -# Use durable queues in amqp. (boolean value) -# Deprecated group/name - [DEFAULT]/rabbit_durable_queues -#amqp_durable_queues=false - -# Auto-delete queues in amqp. (boolean value) -#amqp_auto_delete=false - -# Size of RPC connection pool. (integer value) -#rpc_conn_pool_size=30 - -# Modules of exceptions that are permitted to be recreated -# upon receiving exception data from an rpc call. (list value) -#allowed_rpc_exception_modules=oslo.messaging.exceptions,nova.exception,cinder.exception,exceptions - -# Qpid broker hostname. (string value) -#qpid_hostname=keystone - -# Qpid broker port. (integer value) -#qpid_port=5672 - -# Qpid HA cluster host:port pairs. (list value) -#qpid_hosts=$qpid_hostname:$qpid_port - -# Username for Qpid connection. (string value) -#qpid_username= - -# Password for Qpid connection. (string value) -#qpid_password= - -# Space separated list of SASL mechanisms to use for auth. -# (string value) -#qpid_sasl_mechanisms= - -# Seconds between connection keepalive heartbeats. (integer -# value) -#qpid_heartbeat=60 - -# Transport to use, either 'tcp' or 'ssl'. (string value) -#qpid_protocol=tcp - -# Whether to disable the Nagle algorithm. (boolean value) -#qpid_tcp_nodelay=true - -# The qpid topology version to use. Version 1 is what was -# originally used by impl_qpid. Version 2 includes some -# backwards-incompatible changes that allow broker federation -# to work. Users should update to version 2 when they are -# able to take everything down, as it requires a clean break. -# (integer value) -#qpid_topology_version=1 - -# SSL version to use (valid only if SSL enabled). valid values -# are TLSv1, SSLv23 and SSLv3. SSLv2 may be available on some -# distributions. (string value) -#kombu_ssl_version= - -# SSL key file (valid only if SSL enabled). (string value) -#kombu_ssl_keyfile= - -# SSL cert file (valid only if SSL enabled). (string value) -#kombu_ssl_certfile= - -# SSL certification authority file (valid only if SSL -# enabled). (string value) -#kombu_ssl_ca_certs= - -# How long to wait before reconnecting in response to an AMQP -# consumer cancel notification. (floating point value) -#kombu_reconnect_delay=1.0 - -# The RabbitMQ broker address where a single node is used. -# (string value) -rabbit_host=##RABBITMQ_HOST## - -# The RabbitMQ broker port where a single node is used. -# (integer value) -rabbit_port=##RABBITMQ_PORT## - -# RabbitMQ HA cluster host:port pairs. (list value) -rabbit_hosts=$rabbit_host:$rabbit_port - -# Connect over SSL for RabbitMQ. (boolean value) -rabbit_use_ssl=false - -# The RabbitMQ userid. (string value) -rabbit_userid=##RABBITMQ_USER## - -# The RabbitMQ password. (string value) -rabbit_password=##RABBITMQ_PASSWORD## - -# the RabbitMQ login method (string value) -#rabbit_login_method=AMQPLAIN - -# The RabbitMQ virtual host. (string value) -#rabbit_virtual_host=/ - -# How frequently to retry connecting with RabbitMQ. (integer -# value) -#rabbit_retry_interval=1 - -# How long to backoff for between retries when connecting to -# RabbitMQ. (integer value) -#rabbit_retry_backoff=2 - -# Maximum number of RabbitMQ connection retries. Default is 0 -# (infinite retry count). (integer value) -#rabbit_max_retries=0 - -# Use HA queues in RabbitMQ (x-ha-policy: all). If you change -# this option, you must wipe the RabbitMQ database. (boolean -# value) -#rabbit_ha_queues=false - -# If passed, use a fake RabbitMQ provider. (boolean value) -#fake_rabbit=false - -# ZeroMQ bind address. Should be a wildcard (*), an ethernet -# interface, or IP. The "host" option should point or resolve -# to this address. (string value) -#rpc_zmq_bind_address=* - -# MatchMaker driver. (string value) -#rpc_zmq_matchmaker=oslo.messaging._drivers.matchmaker.MatchMakerLocalhost - -# ZeroMQ receiver listening port. (integer value) -#rpc_zmq_port=9501 - -# Number of ZeroMQ contexts, defaults to 1. (integer value) -#rpc_zmq_contexts=1 - -# Maximum number of ingress messages to locally buffer per -# topic. Default is unlimited. (integer value) -#rpc_zmq_topic_backlog= - -# Directory for holding IPC sockets. (string value) -#rpc_zmq_ipc_dir=/var/run/openstack - -# Name of this node. Must be a valid hostname, FQDN, or IP -# address. Must match "host" option, if running Nova. (string -# value) -#rpc_zmq_host=keystone - -# Seconds to wait before a cast expires (TTL). Only supported -# by impl_zmq. (integer value) -#rpc_cast_timeout=30 - -# Heartbeat frequency. (integer value) -#matchmaker_heartbeat_freq=300 - -# Heartbeat time-to-live. (integer value) -#matchmaker_heartbeat_ttl=600 - -# Host to locate redis. (string value) -#host=localhost - -# Use this port to connect to redis host. (integer value) -#port=6379 - -# Password for Redis server (optional). (string value) -#password= - -# Size of RPC greenthread pool. (integer value) -#rpc_thread_pool_size=64 - -# Driver or drivers to handle sending notifications. (multi -# valued) -#notification_driver= - -# AMQP topic used for OpenStack notifications. (list value) -# Deprecated group/name - [rpc_notifier2]/topics -#notification_topics=notifications - -# Seconds to wait for a response from a call. (integer value) -#rpc_response_timeout=60 - -# A URL representing the messaging driver to use and its full -# configuration. If not set, we fall back to the rpc_backend -# option and driver specific configuration. (string value) -#transport_url= - -# The messaging driver to use, defaults to rabbit. Other -# drivers include qpid and zmq. (string value) -rpc_backend=rabbit - -# The default exchange under which topics are scoped. May be -# overridden by an exchange name specified in the -# transport_url option. (string value) -#control_exchange=openstack - - -# -# Options defined in keystone.notifications -# - -# Default publisher_id for outgoing notifications (string -# value) -#default_publisher_id= - - -# -# Options defined in keystone.middleware.ec2_token -# - -# URL to get token from ec2 request. (string value) -#keystone_ec2_url=http://localhost:5000/v2.0/ec2tokens - -# Required if EC2 server requires client certificate. (string -# value) -#keystone_ec2_keyfile= - -# Client certificate key filename. Required if EC2 server -# requires client certificate. (string value) -#keystone_ec2_certfile= - -# A PEM encoded certificate authority to use when verifying -# HTTPS connections. Defaults to the system CAs. (string -# value) -#keystone_ec2_cafile= - -# Disable SSL certificate verification. (boolean value) -#keystone_ec2_insecure=false - - -# -# Options defined in keystone.openstack.common.eventlet_backdoor -# - -# Enable eventlet backdoor. Acceptable values are 0, , -# and :, where 0 results in listening on a random -# tcp port number; results in listening on the -# specified port number (and not enabling backdoor if that -# port is in use); and : results in listening on -# the smallest unused port number within the specified range -# of port numbers. The chosen port is displayed in the -# service's log file. (string value) -#backdoor_port= - - -# -# Options defined in keystone.openstack.common.lockutils -# - -# Enables or disables inter-process locks. (boolean value) -#disable_process_locking=false - -# Directory to use for lock files. (string value) -#lock_path= - - -# -# Options defined in keystone.openstack.common.log -# - -# Print debugging output (set logging level to DEBUG instead -# of default WARNING level). (boolean value) -#debug=false - -# Print more verbose output (set logging level to INFO instead -# of default WARNING level). (boolean value) -#verbose=false - -# Log output to standard error. (boolean value) -#use_stderr=true - -# Format string to use for log messages with context. (string -# value) -#logging_context_format_string=%(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s [%(request_id)s %(user_identity)s] %(instance)s%(message)s - -# Format string to use for log messages without context. -# (string value) -#logging_default_format_string=%(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s [-] %(instance)s%(message)s - -# Data to append to log format when level is DEBUG. (string -# value) -#logging_debug_format_suffix=%(funcName)s %(pathname)s:%(lineno)d - -# Prefix each line of exception output with this format. -# (string value) -#logging_exception_prefix=%(asctime)s.%(msecs)03d %(process)d TRACE %(name)s %(instance)s - -# List of logger=LEVEL pairs. (list value) -#default_log_levels=amqp=WARN,amqplib=WARN,boto=WARN,qpid=WARN,sqlalchemy=WARN,suds=INFO,oslo.messaging=INFO,iso8601=WARN,requests.packages.urllib3.connectionpool=WARN - -# Enables or disables publication of error events. (boolean -# value) -#publish_errors=false - -# Enables or disables fatal status of deprecations. (boolean -# value) -#fatal_deprecations=false - -# The format for an instance that is passed with the log -# message. (string value) -#instance_format="[instance: %(uuid)s] " - -# The format for an instance UUID that is passed with the log -# message. (string value) -#instance_uuid_format="[instance: %(uuid)s] " - -# The name of a logging configuration file. This file is -# appended to any existing logging configuration files. For -# details about logging configuration files, see the Python -# logging module documentation. (string value) -# Deprecated group/name - [DEFAULT]/log_config -#log_config_append= - -# DEPRECATED. A logging.Formatter log message format string -# which may use any of the available logging.LogRecord -# attributes. This option is deprecated. Please use -# logging_context_format_string and -# logging_default_format_string instead. (string value) -#log_format= - -# Format string for %%(asctime)s in log records. Default: -# %(default)s . (string value) -#log_date_format=%Y-%m-%d %H:%M:%S - -# (Optional) Name of log file to output to. If no default is -# set, logging will go to stdout. (string value) -# Deprecated group/name - [DEFAULT]/logfile -#log_file= - -# (Optional) The base directory used for relative --log-file -# paths. (string value) -# Deprecated group/name - [DEFAULT]/logdir -#log_dir= - -# Use syslog for logging. Existing syslog format is DEPRECATED -# during I, and will chang in J to honor RFC5424. (boolean -# value) -#use_syslog=false - -# (Optional) Enables or disables syslog rfc5424 format for -# logging. If enabled, prefixes the MSG part of the syslog -# message with APP-NAME (RFC5424). The format without the APP- -# NAME is deprecated in I, and will be removed in J. (boolean -# value) -#use_syslog_rfc_format=false - -# Syslog facility to receive log lines. (string value) -#syslog_log_facility=LOG_USER - - -# -# Options defined in keystone.openstack.common.policy -# - -# The JSON file that defines policies. (string value) -#policy_file=policy.json - -# Default rule. Enforced when a requested rule is not found. -# (string value) -#policy_default_rule=default - - -[assignment] - -# -# Options defined in keystone -# - -# Assignment backend driver. (string value) -#driver= - -# Toggle for assignment caching. This has no effect unless -# global caching is enabled. (boolean value) -#caching=true - -# TTL (in seconds) to cache assignment data. This has no -# effect unless global caching is enabled. (integer value) -#cache_time= - -# Maximum number of entities that will be returned in an -# assignment collection. (integer value) -#list_limit= - - -[auth] - -# -# Options defined in keystone -# - -# Default auth methods. (list value) -#methods=external,password,token - -# The password auth plugin module. (string value) -#password=keystone.auth.plugins.password.Password - -# The token auth plugin module. (string value) -#token=keystone.auth.plugins.token.Token - -# The external (REMOTE_USER) auth plugin module. (string -# value) -#external=keystone.auth.plugins.external.DefaultDomain - - -[cache] - -# -# Options defined in keystone -# - -# Prefix for building the configuration dictionary for the -# cache region. This should not need to be changed unless -# there is another dogpile.cache region with the same -# configuration name. (string value) -#config_prefix=cache.keystone - -# Default TTL, in seconds, for any cached item in the -# dogpile.cache region. This applies to any cached method that -# doesn't have an explicit cache expiration time defined for -# it. (integer value) -#expiration_time=600 - -# Dogpile.cache backend module. It is recommended that -# Memcache (dogpile.cache.memcached) or Redis -# (dogpile.cache.redis) be used in production deployments. -# Small workloads (single process) like devstack can use the -# dogpile.cache.memory backend. (string value) -#backend=keystone.common.cache.noop - -# Use a key-mangling function (sha1) to ensure fixed length -# cache-keys. This is toggle-able for debugging purposes, it -# is highly recommended to always leave this set to true. -# (boolean value) -#use_key_mangler=true - -# Arguments supplied to the backend module. Specify this -# option once per argument to be passed to the dogpile.cache -# backend. Example format: ":". (multi valued) -#backend_argument= - -# Proxy classes to import that will affect the way the -# dogpile.cache backend functions. See the dogpile.cache -# documentation on changing-backend-behavior. (list value) -#proxies= - -# Global toggle for all caching using the should_cache_fn -# mechanism. (boolean value) -#enabled=false - -# Extra debugging from the cache backend (cache keys, -# get/set/delete/etc calls). This is only really useful if you -# need to see the specific cache-backend get/set/delete calls -# with the keys/values. Typically this should be left set to -# false. (boolean value) -#debug_cache_backend=false - - -[catalog] - -# -# Options defined in keystone -# - -# Catalog template file name for use with the template catalog -# backend. (string value) -#template_file=default_catalog.templates - -# Catalog backend driver. (string value) -#driver=keystone.catalog.backends.sql.Catalog - -# Maximum number of entities that will be returned in a -# catalog collection. (integer value) -#list_limit= - - -[credential] - -# -# Options defined in keystone -# - -# Credential backend driver. (string value) -#driver=keystone.credential.backends.sql.Credential - - -[database] - -# -# Options defined in oslo.db -# - -# The file name to use with SQLite. (string value) -#sqlite_db=oslo.sqlite - -# If True, SQLite uses synchronous mode. (boolean value) -#sqlite_synchronous=true - -# The back end to use for the database. (string value) -# Deprecated group/name - [DEFAULT]/db_backend -#backend=sqlalchemy - -# The SQLAlchemy connection string to use to connect to the -# database. (string value) -# Deprecated group/name - [DEFAULT]/sql_connection -# Deprecated group/name - [DATABASE]/sql_connection -# Deprecated group/name - [sql]/connection -#connection= -connection=postgresql://##KEYSTONE_DB_USER##:##KEYSTONE_DB_PASSWORD##@onenode/keystone - -# The SQLAlchemy connection string to use to connect to the -# slave database. (string value) -#slave_connection= - -# The SQL mode to be used for MySQL sessions. This option, -# including the default, overrides any server-set SQL mode. To -# use whatever SQL mode is set by the server configuration, -# set this to no value. Example: mysql_sql_mode= (string -# value) -#mysql_sql_mode=TRADITIONAL - -# Timeout before idle SQL connections are reaped. (integer -# value) -# Deprecated group/name - [DEFAULT]/sql_idle_timeout -# Deprecated group/name - [DATABASE]/sql_idle_timeout -# Deprecated group/name - [sql]/idle_timeout -#idle_timeout=3600 - -# Minimum number of SQL connections to keep open in a pool. -# (integer value) -# Deprecated group/name - [DEFAULT]/sql_min_pool_size -# Deprecated group/name - [DATABASE]/sql_min_pool_size -#min_pool_size=1 - -# Maximum number of SQL connections to keep open in a pool. -# (integer value) -# Deprecated group/name - [DEFAULT]/sql_max_pool_size -# Deprecated group/name - [DATABASE]/sql_max_pool_size -#max_pool_size= - -# Maximum db connection retries during startup. Set to -1 to -# specify an infinite retry count. (integer value) -# Deprecated group/name - [DEFAULT]/sql_max_retries -# Deprecated group/name - [DATABASE]/sql_max_retries -#max_retries=10 - -# Interval between retries of opening a SQL connection. -# (integer value) -# Deprecated group/name - [DEFAULT]/sql_retry_interval -# Deprecated group/name - [DATABASE]/reconnect_interval -#retry_interval=10 - -# If set, use this value for max_overflow with SQLAlchemy. -# (integer value) -# Deprecated group/name - [DEFAULT]/sql_max_overflow -# Deprecated group/name - [DATABASE]/sqlalchemy_max_overflow -#max_overflow= - -# Verbosity of SQL debugging information: 0=None, -# 100=Everything. (integer value) -# Deprecated group/name - [DEFAULT]/sql_connection_debug -#connection_debug=0 - -# Add Python stack traces to SQL as comment strings. (boolean -# value) -# Deprecated group/name - [DEFAULT]/sql_connection_trace -#connection_trace=false - -# If set, use this value for pool_timeout with SQLAlchemy. -# (integer value) -# Deprecated group/name - [DATABASE]/sqlalchemy_pool_timeout -#pool_timeout= - -# Enable the experimental use of database reconnect on -# connection lost. (boolean value) -#use_db_reconnect=false - -# Seconds between database connection retries. (integer value) -#db_retry_interval=1 - -# If True, increases the interval between database connection -# retries up to db_max_retry_interval. (boolean value) -#db_inc_retry_interval=true - -# If db_inc_retry_interval is set, the maximum seconds between -# database connection retries. (integer value) -#db_max_retry_interval=10 - -# Maximum database connection retries before error is raised. -# Set to -1 to specify an infinite retry count. (integer -# value) -#db_max_retries=20 - - -[ec2] - -# -# Options defined in keystone -# - -# EC2Credential backend driver. (string value) -#driver=keystone.contrib.ec2.backends.kvs.Ec2 - - -[endpoint_filter] - -# -# Options defined in keystone -# - -# Endpoint Filter backend driver (string value) -#driver=keystone.contrib.endpoint_filter.backends.sql.EndpointFilter - -# Toggle to return all active endpoints if no filter exists. -# (boolean value) -#return_all_endpoints_if_no_filter=true - - -[federation] - -# -# Options defined in keystone -# - -# Federation backend driver. (string value) -#driver=keystone.contrib.federation.backends.sql.Federation - -# Value to be used when filtering assertion parameters from -# the environment. (string value) -#assertion_prefix= - - -[identity] - -# -# Options defined in keystone -# - -# This references the domain to use for all Identity API v2 -# requests (which are not aware of domains). A domain with -# this ID will be created for you by keystone-manage db_sync -# in migration 008. The domain referenced by this ID cannot be -# deleted on the v3 API, to prevent accidentally breaking the -# v2 API. There is nothing special about this domain, other -# than the fact that it must exist to order to maintain -# support for your v2 clients. (string value) -#default_domain_id=default - -# A subset (or all) of domains can have their own identity -# driver, each with their own partial configuration file in a -# domain configuration directory. Only values specific to the -# domain need to be placed in the domain specific -# configuration file. This feature is disabled by default; set -# to true to enable. (boolean value) -#domain_specific_drivers_enabled=false - -# Path for Keystone to locate the domain specific identity -# configuration files if domain_specific_drivers_enabled is -# set to true. (string value) -#domain_config_dir=/etc/keystone/domains - -# Identity backend driver. (string value) -#driver=keystone.identity.backends.sql.Identity - -# Maximum supported length for user passwords; decrease to -# improve performance. (integer value) -#max_password_length=4096 - -# Maximum number of entities that will be returned in an -# identity collection. (integer value) -#list_limit= - - -[kvs] - -# -# Options defined in keystone -# - -# Extra dogpile.cache backend modules to register with the -# dogpile.cache library. (list value) -#backends= - -# Prefix for building the configuration dictionary for the KVS -# region. This should not need to be changed unless there is -# another dogpile.cache region with the same configuration -# name. (string value) -#config_prefix=keystone.kvs - -# Toggle to disable using a key-mangling function to ensure -# fixed length keys. This is toggle-able for debugging -# purposes, it is highly recommended to always leave this set -# to true. (boolean value) -#enable_key_mangler=true - -# Default lock timeout for distributed locking. (integer -# value) -#default_lock_timeout=5 - - -[ldap] - -# -# Options defined in keystone -# - -# URL for connecting to the LDAP server. (string value) -#url=ldap://keystone - -# User BindDN to query the LDAP server. (string value) -#user= - -# Password for the BindDN to query the LDAP server. (string -# value) -#password= - -# LDAP server suffix (string value) -#suffix=cn=example,cn=com - -# If true, will add a dummy member to groups. This is required -# if the objectclass for groups requires the "member" -# attribute. (boolean value) -#use_dumb_member=false - -# DN of the "dummy member" to use when "use_dumb_member" is -# enabled. (string value) -#dumb_member=cn=dumb,dc=nonexistent - -# Delete subtrees using the subtree delete control. Only -# enable this option if your LDAP server supports subtree -# deletion. (boolean value) -#allow_subtree_delete=false - -# The LDAP scope for queries, this can be either "one" -# (onelevel/singleLevel) or "sub" (subtree/wholeSubtree). -# (string value) -#query_scope=one - -# Maximum results per page; a value of zero ("0") disables -# paging. (integer value) -#page_size=0 - -# The LDAP dereferencing option for queries. This can be -# either "never", "searching", "always", "finding" or -# "default". The "default" option falls back to using default -# dereferencing configured by your ldap.conf. (string value) -#alias_dereferencing=default - -# Sets the LDAP debugging level for LDAP calls. A value of 0 -# means that debugging is not enabled. This value is a -# bitmask, consult your LDAP documentation for possible -# values. (integer value) -#debug_level= - -# Override the system's default referral chasing behavior for -# queries. (boolean value) -#chase_referrals= - -# Search base for users. (string value) -#user_tree_dn= - -# LDAP search filter for users. (string value) -#user_filter= - -# LDAP objectclass for users. (string value) -#user_objectclass=inetOrgPerson - -# LDAP attribute mapped to user id. (string value) -#user_id_attribute=cn - -# LDAP attribute mapped to user name. (string value) -#user_name_attribute=sn - -# LDAP attribute mapped to user email. (string value) -#user_mail_attribute=email - -# LDAP attribute mapped to password. (string value) -#user_pass_attribute=userPassword - -# LDAP attribute mapped to user enabled flag. (string value) -#user_enabled_attribute=enabled - -# Bitmask integer to indicate the bit that the enabled value -# is stored in if the LDAP server represents "enabled" as a -# bit on an integer rather than a boolean. A value of "0" -# indicates the mask is not used. If this is not set to "0" -# the typical value is "2". This is typically used when -# "user_enabled_attribute = userAccountControl". (integer -# value) -#user_enabled_mask=0 - -# Default value to enable users. This should match an -# appropriate int value if the LDAP server uses non-boolean -# (bitmask) values to indicate if a user is enabled or -# disabled. If this is not set to "True" the typical value is -# "512". This is typically used when "user_enabled_attribute = -# userAccountControl". (string value) -#user_enabled_default=True - -# List of attributes stripped off the user on update. (list -# value) -#user_attribute_ignore=default_project_id,tenants - -# LDAP attribute mapped to default_project_id for users. -# (string value) -#user_default_project_id_attribute= - -# Allow user creation in LDAP backend. (boolean value) -#user_allow_create=true - -# Allow user updates in LDAP backend. (boolean value) -#user_allow_update=true - -# Allow user deletion in LDAP backend. (boolean value) -#user_allow_delete=true - -# If true, Keystone uses an alternative method to determine if -# a user is enabled or not by checking if they are a member of -# the "user_enabled_emulation_dn" group. (boolean value) -#user_enabled_emulation=false - -# DN of the group entry to hold enabled users when using -# enabled emulation. (string value) -#user_enabled_emulation_dn= - -# List of additional LDAP attributes used for mapping -# additional attribute mappings for users. Attribute mapping -# format is :, where ldap_attr is the -# attribute in the LDAP entry and user_attr is the Identity -# API attribute. (list value) -#user_additional_attribute_mapping= - -# Search base for projects (string value) -# Deprecated group/name - [ldap]/tenant_tree_dn -#project_tree_dn= - -# LDAP search filter for projects. (string value) -# Deprecated group/name - [ldap]/tenant_filter -#project_filter= - -# LDAP objectclass for projects. (string value) -# Deprecated group/name - [ldap]/tenant_objectclass -#project_objectclass=groupOfNames - -# LDAP attribute mapped to project id. (string value) -# Deprecated group/name - [ldap]/tenant_id_attribute -#project_id_attribute=cn - -# LDAP attribute mapped to project membership for user. -# (string value) -# Deprecated group/name - [ldap]/tenant_member_attribute -#project_member_attribute=member - -# LDAP attribute mapped to project name. (string value) -# Deprecated group/name - [ldap]/tenant_name_attribute -#project_name_attribute=ou - -# LDAP attribute mapped to project description. (string value) -# Deprecated group/name - [ldap]/tenant_desc_attribute -#project_desc_attribute=description - -# LDAP attribute mapped to project enabled. (string value) -# Deprecated group/name - [ldap]/tenant_enabled_attribute -#project_enabled_attribute=enabled - -# LDAP attribute mapped to project domain_id. (string value) -# Deprecated group/name - [ldap]/tenant_domain_id_attribute -#project_domain_id_attribute=businessCategory - -# List of attributes stripped off the project on update. (list -# value) -# Deprecated group/name - [ldap]/tenant_attribute_ignore -#project_attribute_ignore= - -# Allow project creation in LDAP backend. (boolean value) -# Deprecated group/name - [ldap]/tenant_allow_create -#project_allow_create=true - -# Allow project update in LDAP backend. (boolean value) -# Deprecated group/name - [ldap]/tenant_allow_update -#project_allow_update=true - -# Allow project deletion in LDAP backend. (boolean value) -# Deprecated group/name - [ldap]/tenant_allow_delete -#project_allow_delete=true - -# If true, Keystone uses an alternative method to determine if -# a project is enabled or not by checking if they are a member -# of the "project_enabled_emulation_dn" group. (boolean value) -# Deprecated group/name - [ldap]/tenant_enabled_emulation -#project_enabled_emulation=false - -# DN of the group entry to hold enabled projects when using -# enabled emulation. (string value) -# Deprecated group/name - [ldap]/tenant_enabled_emulation_dn -#project_enabled_emulation_dn= - -# Additional attribute mappings for projects. Attribute -# mapping format is :, where ldap_attr -# is the attribute in the LDAP entry and user_attr is the -# Identity API attribute. (list value) -# Deprecated group/name - [ldap]/tenant_additional_attribute_mapping -#project_additional_attribute_mapping= - -# Search base for roles. (string value) -#role_tree_dn= - -# LDAP search filter for roles. (string value) -#role_filter= - -# LDAP objectclass for roles. (string value) -#role_objectclass=organizationalRole - -# LDAP attribute mapped to role id. (string value) -#role_id_attribute=cn - -# LDAP attribute mapped to role name. (string value) -#role_name_attribute=ou - -# LDAP attribute mapped to role membership. (string value) -#role_member_attribute=roleOccupant - -# List of attributes stripped off the role on update. (list -# value) -#role_attribute_ignore= - -# Allow role creation in LDAP backend. (boolean value) -#role_allow_create=true - -# Allow role update in LDAP backend. (boolean value) -#role_allow_update=true - -# Allow role deletion in LDAP backend. (boolean value) -#role_allow_delete=true - -# Additional attribute mappings for roles. Attribute mapping -# format is :, where ldap_attr is the -# attribute in the LDAP entry and user_attr is the Identity -# API attribute. (list value) -#role_additional_attribute_mapping= - -# Search base for groups. (string value) -#group_tree_dn= - -# LDAP search filter for groups. (string value) -#group_filter= - -# LDAP objectclass for groups. (string value) -#group_objectclass=groupOfNames - -# LDAP attribute mapped to group id. (string value) -#group_id_attribute=cn - -# LDAP attribute mapped to group name. (string value) -#group_name_attribute=ou - -# LDAP attribute mapped to show group membership. (string -# value) -#group_member_attribute=member - -# LDAP attribute mapped to group description. (string value) -#group_desc_attribute=description - -# List of attributes stripped off the group on update. (list -# value) -#group_attribute_ignore= - -# Allow group creation in LDAP backend. (boolean value) -#group_allow_create=true - -# Allow group update in LDAP backend. (boolean value) -#group_allow_update=true - -# Allow group deletion in LDAP backend. (boolean value) -#group_allow_delete=true - -# Additional attribute mappings for groups. Attribute mapping -# format is :, where ldap_attr is the -# attribute in the LDAP entry and user_attr is the Identity -# API attribute. (list value) -#group_additional_attribute_mapping= - -# CA certificate file path for communicating with LDAP -# servers. (string value) -#tls_cacertfile= - -# CA certificate directory path for communicating with LDAP -# servers. (string value) -#tls_cacertdir= - -# Enable TLS for communicating with LDAP servers. (boolean -# value) -#use_tls=false - -# Valid options for tls_req_cert are demand, never, and allow. -# (string value) -#tls_req_cert=demand - - -[matchmaker_ring] - -# -# Options defined in oslo.messaging -# - -# Matchmaker ring file (JSON). (string value) -# Deprecated group/name - [DEFAULT]/matchmaker_ringfile -#ringfile=/etc/oslo/matchmaker_ring.json - - -[memcache] - -# -# Options defined in keystone -# - -# Memcache servers in the format of "host:port". (list value) -#servers=localhost:11211 - -# Number of compare-and-set attempts to make when using -# compare-and-set in the token memcache back end. (integer -# value) -#max_compare_and_set_retry=16 - - -[oauth1] - -# -# Options defined in keystone -# - -# Credential backend driver. (string value) -#driver=keystone.contrib.oauth1.backends.sql.OAuth1 - -# Duration (in seconds) for the OAuth Request Token. (integer -# value) -#request_token_duration=28800 - -# Duration (in seconds) for the OAuth Access Token. (integer -# value) -#access_token_duration=86400 - - -[os_inherit] - -# -# Options defined in keystone -# - -# role-assignment inheritance to projects from owning domain -# can be optionally enabled. (boolean value) -#enabled=false - - -[paste_deploy] - -# -# Options defined in keystone -# - -# Name of the paste configuration file that defines the -# available pipelines. (string value) -#config_file=keystone-paste.ini - - -[policy] - -# -# Options defined in keystone -# - -# Policy backend driver. (string value) -#driver=keystone.policy.backends.sql.Policy - -# Maximum number of entities that will be returned in a policy -# collection. (integer value) -#list_limit= - - -[revoke] - -# -# Options defined in keystone -# - -# An implementation of the backend for persisting revocation -# events. (string value) -#driver=keystone.contrib.revoke.backends.kvs.Revoke - -# This value (calculated in seconds) is added to token -# expiration before a revocation event may be removed from the -# backend. (integer value) -#expiration_buffer=1800 - -# Toggle for revocation event cacheing. This has no effect -# unless global caching is enabled. (boolean value) -#caching=true - - -[signing] - -# -# Options defined in keystone -# - -# Deprecated in favor of provider in the [token] section. -# (string value) -#token_format= - -# Path of the certfile for token signing. For non-production -# environments, you may be interested in using `keystone- -# manage pki_setup` to generate self-signed certificates. -# (string value) -#certfile=/etc/keystone/ssl/certs/signing_cert.pem - -# Path of the keyfile for token signing. (string value) -#keyfile=/etc/keystone/ssl/private/signing_key.pem - -# Path of the CA for token signing. (string value) -#ca_certs=/etc/keystone/ssl/certs/ca.pem - -# Path of the CA key for token signing. (string value) -#ca_key=/etc/keystone/ssl/private/cakey.pem - -# Key size (in bits) for token signing cert (auto generated -# certificate). (integer value) -#key_size=2048 - -# Days the token signing cert is valid for (auto generated -# certificate). (integer value) -#valid_days=3650 - -# Certificate subject (auto generated certificate) for token -# signing. (string value) -#cert_subject=/C=US/ST=Unset/L=Unset/O=Unset/CN=www.example.com - - -[ssl] - -# -# Options defined in keystone -# - -# Toggle for SSL support on the Keystone eventlet servers. -# (boolean value) -#enable=false - -# Path of the certfile for SSL. For non-production -# environments, you may be interested in using `keystone- -# manage ssl_setup` to generate self-signed certificates. -# (string value) -#certfile=/etc/keystone/ssl/certs/keystone.pem - -# Path of the keyfile for SSL. (string value) -#keyfile=/etc/keystone/ssl/private/keystonekey.pem - -# Path of the ca cert file for SSL. (string value) -#ca_certs=/etc/keystone/ssl/certs/ca.pem - -# Path of the CA key file for SSL. (string value) -#ca_key=/etc/keystone/ssl/private/cakey.pem - -# Require client certificate. (boolean value) -#cert_required=false - -# SSL key length (in bits) (auto generated certificate). -# (integer value) -#key_size=1024 - -# Days the certificate is valid for once signed (auto -# generated certificate). (integer value) -#valid_days=3650 - -# SSL certificate subject (auto generated certificate). -# (string value) -#cert_subject=/C=US/ST=Unset/L=Unset/O=Unset/CN=keystone - - -[stats] - -# -# Options defined in keystone -# - -# Stats backend driver. (string value) -#driver=keystone.contrib.stats.backends.kvs.Stats - - -[token] - -# -# Options defined in keystone -# - -# External auth mechanisms that should add bind information to -# token, e.g., kerberos,x509. (list value) -#bind= - -# Enforcement policy on tokens presented to Keystone with bind -# information. One of disabled, permissive, strict, required -# or a specifically required bind mode, e.g., kerberos or x509 -# to require binding to that authentication. (string value) -#enforce_token_bind=permissive - -# Amount of time a token should remain valid (in seconds). -# (integer value) -#expiration=3600 - -# Controls the token construction, validation, and revocation -# operations. Core providers are -# "keystone.token.providers.[pkiz|pki|uuid].Provider". The -# default provider is pkiz. (string value) -#provider= - -# Token persistence backend driver. (string value) -#driver=keystone.token.backends.sql.Token - -# Toggle for token system cacheing. This has no effect unless -# global caching is enabled. (boolean value) -#caching=true - -# Time to cache the revocation list and the revocation events -# if revoke extension is enabled (in seconds). This has no -# effect unless global and token caching are enabled. (integer -# value) -#revocation_cache_time=3600 - -# Time to cache tokens (in seconds). This has no effect unless -# global and token caching are enabled. (integer value) -#cache_time= - -# Revoke token by token identifier. Setting revoke_by_id to -# true enables various forms of enumerating tokens, e.g. `list -# tokens for user`. These enumerations are processed to -# determine the list of tokens to revoke. Only disable if you -# are switching to using the Revoke extension with a backend -# other than KVS, which stores events in memory. (boolean -# value) -#revoke_by_id=true - -# The hash algorithm to use for PKI tokens. This can be set to -# any algorithm that hashlib supports. WARNING: Before -# changing this value, the auth_token middleware must be -# configured with the hash_algorithms, otherwise token -# revocation will not be processed correctly. (string value) -#hash_algorithm=md5 - - -[trust] - -# -# Options defined in keystone -# - -# Delegation and impersonation features can be optionally -# disabled. (boolean value) -#enabled=true - -# Trust backend driver. (string value) -#driver=keystone.trust.backends.sql.Trust - - diff --git a/openstack/etc/keystone/logging.conf b/openstack/etc/keystone/logging.conf deleted file mode 100644 index 21d43c8d..00000000 --- a/openstack/etc/keystone/logging.conf +++ /dev/null @@ -1,39 +0,0 @@ -[loggers] -keys=root - -[formatters] -keys=normal,normal_with_name,debug - -[handlers] -keys=production,file,devel - -[logger_root] -level=WARNING -handlers=file - -[handler_production] -class=handlers.SysLogHandler -level=ERROR -formatter=normal_with_name -args=(('127.0.0.1', handlers.SYSLOG_UDP_PORT), handlers.SysLogHandler.LOG_USER) - -[handler_file] -class=FileHandler -level=DEBUG -formatter=normal_with_name -args=('/var/log/keystone/keystone.log', 'a') - -[handler_devel] -class=StreamHandler -level=NOTSET -formatter=debug -args=(sys.stdout,) - -[formatter_normal] -format=%(asctime)s %(levelname)s %(message)s - -[formatter_normal_with_name] -format=(%(name)s): %(asctime)s %(levelname)s %(message)s - -[formatter_debug] -format=(%(name)s): %(asctime)s %(levelname)s %(module)s %(funcName)s %(message)s diff --git a/openstack/etc/keystone/policy.json b/openstack/etc/keystone/policy.json deleted file mode 100644 index 9c7e646e..00000000 --- a/openstack/etc/keystone/policy.json +++ /dev/null @@ -1,144 +0,0 @@ -{ - "admin_required": "role:admin or is_admin:1", - "service_role": "role:service", - "service_or_admin": "rule:admin_required or rule:service_role", - "owner" : "user_id:%(user_id)s", - "admin_or_owner": "rule:admin_required or rule:owner", - - "default": "rule:admin_required", - - "identity:get_region": "", - "identity:list_regions": "", - "identity:create_region": "rule:admin_required", - "identity:update_region": "rule:admin_required", - "identity:delete_region": "rule:admin_required", - - "identity:get_service": "rule:admin_required", - "identity:list_services": "rule:admin_required", - "identity:create_service": "rule:admin_required", - "identity:update_service": "rule:admin_required", - "identity:delete_service": "rule:admin_required", - - "identity:get_endpoint": "rule:admin_required", - "identity:list_endpoints": "rule:admin_required", - "identity:create_endpoint": "rule:admin_required", - "identity:update_endpoint": "rule:admin_required", - "identity:delete_endpoint": "rule:admin_required", - - "identity:get_domain": "rule:admin_required", - "identity:list_domains": "rule:admin_required", - "identity:create_domain": "rule:admin_required", - "identity:update_domain": "rule:admin_required", - "identity:delete_domain": "rule:admin_required", - - "identity:get_project": "rule:admin_required", - "identity:list_projects": "rule:admin_required", - "identity:list_user_projects": "rule:admin_or_owner", - "identity:create_project": "rule:admin_required", - "identity:update_project": "rule:admin_required", - "identity:delete_project": "rule:admin_required", - - "identity:get_user": "rule:admin_required", - "identity:list_users": "rule:admin_required", - "identity:create_user": "rule:admin_required", - "identity:update_user": "rule:admin_required", - "identity:delete_user": "rule:admin_required", - "identity:change_password": "rule:admin_or_owner", - - "identity:get_group": "rule:admin_required", - "identity:list_groups": "rule:admin_required", - "identity:list_groups_for_user": "rule:admin_or_owner", - "identity:create_group": "rule:admin_required", - "identity:update_group": "rule:admin_required", - "identity:delete_group": "rule:admin_required", - "identity:list_users_in_group": "rule:admin_required", - "identity:remove_user_from_group": "rule:admin_required", - "identity:check_user_in_group": "rule:admin_required", - "identity:add_user_to_group": "rule:admin_required", - - "identity:get_credential": "rule:admin_required", - "identity:list_credentials": "rule:admin_required", - "identity:create_credential": "rule:admin_required", - "identity:update_credential": "rule:admin_required", - "identity:delete_credential": "rule:admin_required", - - "identity:ec2_get_credential": "rule:admin_or_owner", - "identity:ec2_list_credentials": "rule:admin_or_owner", - "identity:ec2_create_credential": "rule:admin_or_owner", - "identity:ec2_delete_credential": "rule:admin_required or (rule:owner and user_id:%(target.credential.user_id)s)", - - "identity:get_role": "rule:admin_required", - "identity:list_roles": "rule:admin_required", - "identity:create_role": "rule:admin_required", - "identity:update_role": "rule:admin_required", - "identity:delete_role": "rule:admin_required", - - "identity:check_grant": "rule:admin_required", - "identity:list_grants": "rule:admin_required", - "identity:create_grant": "rule:admin_required", - "identity:revoke_grant": "rule:admin_required", - - "identity:list_role_assignments": "rule:admin_required", - - "identity:get_policy": "rule:admin_required", - "identity:list_policies": "rule:admin_required", - "identity:create_policy": "rule:admin_required", - "identity:update_policy": "rule:admin_required", - "identity:delete_policy": "rule:admin_required", - - "identity:check_token": "rule:admin_required", - "identity:validate_token": "rule:service_or_admin", - "identity:validate_token_head": "rule:service_or_admin", - "identity:revocation_list": "rule:service_or_admin", - "identity:revoke_token": "rule:admin_or_owner", - - "identity:create_trust": "user_id:%(trust.trustor_user_id)s", - "identity:get_trust": "rule:admin_or_owner", - "identity:list_trusts": "", - "identity:list_roles_for_trust": "", - "identity:check_role_for_trust": "", - "identity:get_role_for_trust": "", - "identity:delete_trust": "", - - "identity:create_consumer": "rule:admin_required", - "identity:get_consumer": "rule:admin_required", - "identity:list_consumers": "rule:admin_required", - "identity:delete_consumer": "rule:admin_required", - "identity:update_consumer": "rule:admin_required", - - "identity:authorize_request_token": "rule:admin_required", - "identity:list_access_token_roles": "rule:admin_required", - "identity:get_access_token_role": "rule:admin_required", - "identity:list_access_tokens": "rule:admin_required", - "identity:get_access_token": "rule:admin_required", - "identity:delete_access_token": "rule:admin_required", - - "identity:list_projects_for_endpoint": "rule:admin_required", - "identity:add_endpoint_to_project": "rule:admin_required", - "identity:check_endpoint_in_project": "rule:admin_required", - "identity:list_endpoints_for_project": "rule:admin_required", - "identity:remove_endpoint_from_project": "rule:admin_required", - - "identity:create_identity_provider": "rule:admin_required", - "identity:list_identity_providers": "rule:admin_required", - "identity:get_identity_providers": "rule:admin_required", - "identity:update_identity_provider": "rule:admin_required", - "identity:delete_identity_provider": "rule:admin_required", - - "identity:create_protocol": "rule:admin_required", - "identity:update_protocol": "rule:admin_required", - "identity:get_protocol": "rule:admin_required", - "identity:list_protocols": "rule:admin_required", - "identity:delete_protocol": "rule:admin_required", - - "identity:create_mapping": "rule:admin_required", - "identity:get_mapping": "rule:admin_required", - "identity:list_mappings": "rule:admin_required", - "identity:delete_mapping": "rule:admin_required", - "identity:update_mapping": "rule:admin_required", - - "identity:list_projects_for_groups": "", - "identity:list_domains_for_groups": "", - - "identity:list_revoke_events": "" -} diff --git a/openstack/etc/systemd/system/openstack-keystone-setup.service b/openstack/etc/systemd/system/openstack-keystone-setup.service index fb2793bb..9ea04c1d 100644 --- a/openstack/etc/systemd/system/openstack-keystone-setup.service +++ b/openstack/etc/systemd/system/openstack-keystone-setup.service @@ -1,11 +1,12 @@ [Unit] -Description=Run openstack-keystone-setup (once) +Description=Run keystone-setup Ansible scripts After=local-fs.target postgres-server.service +ConditionPathExists=/etc/openstack/keystone.conf [Service] +# Oneshot, since others setup have to wait until this service finishes Type=oneshot -ExecStart=/usr/share/openstack/openstack-keystone-setup -Restart=no +ExecStart=/usr/bin/ansible-playbook -v -M /usr/share/ansible/ansible-openstack-modules -i /usr/share/openstack/hosts /usr/share/openstack/keystone.yml [Install] WantedBy=multi-user.target diff --git a/openstack/manifest b/openstack/manifest index 8c7b9915..aca952e0 100644 --- a/openstack/manifest +++ b/openstack/manifest @@ -1,11 +1,29 @@ -0040755 0 0 /etc/keystone -0040755 0 0 /var/lib/keystone 0040755 0 0 /usr/share/openstack +0100644 0 0 /usr/share/openstack/hosts +0100644 0 0 /usr/share/openstack/keystone.yml +0040755 0 0 /usr/share/openstack/keystone 0100755 0 0 /usr/share/openstack/openstack-keystone-setup -0100644 0 0 /etc/keystone/logging.conf -0100644 0 0 /etc/keystone/keystone.conf -0100644 0 0 /etc/keystone/policy.json -0100644 0 0 /etc/keystone/keystone-paste.ini +0100644 0 0 /usr/share/openstack/keystone/logging.conf +0100644 0 0 /usr/share/openstack/keystone/keystone.conf +0100644 0 0 /usr/share/openstack/keystone/policy.json +0100644 0 0 /usr/share/openstack/keystone/keystone-paste.ini +0040755 0 0 /usr/share/openstack/modules +0100644 0 0 /usr/share/openstack/modules/README +0100644 0 0 /usr/share/openstack/modules/cinder_manage +0100644 0 0 /usr/share/openstack/modules/glance +0100644 0 0 /usr/share/openstack/modules/glance_manage +0100644 0 0 /usr/share/openstack/modules/heat_manage +0100644 0 0 /usr/share/openstack/modules/keystone_manage +0100644 0 0 /usr/share/openstack/modules/keystone_service +0100644 0 0 /usr/share/openstack/modules/neutron_floating_ip +0100644 0 0 /usr/share/openstack/modules/neutron_network +0100644 0 0 /usr/share/openstack/modules/neutron_router +0100644 0 0 /usr/share/openstack/modules/neutron_router_gateway +0100644 0 0 /usr/share/openstack/modules/neutron_router_interface +0100644 0 0 /usr/share/openstack/modules/neutron_sec_group +0100644 0 0 /usr/share/openstack/modules/neutron_subnet +0100644 0 0 /usr/share/openstack/modules/nova_flavor +0100644 0 0 /usr/share/openstack/modules/nova_manage 0100644 0 0 /etc/logrotate.d/openstack-keystone 0100644 0 0 /etc/systemd/system/openstack-keystone.service 0100644 0 0 /etc/systemd/system/openstack-keystone-setup.service diff --git a/openstack/usr/share/openstack/hosts b/openstack/usr/share/openstack/hosts new file mode 100644 index 00000000..5b97818d --- /dev/null +++ b/openstack/usr/share/openstack/hosts @@ -0,0 +1 @@ +localhost ansible_connection=local diff --git a/openstack/usr/share/openstack/keystone.yml b/openstack/usr/share/openstack/keystone.yml new file mode 100644 index 00000000..dcd96857 --- /dev/null +++ b/openstack/usr/share/openstack/keystone.yml @@ -0,0 +1,73 @@ +--- +- hosts: localhost + vars_files: + - "/etc/openstack/keystone.conf" + tasks: + - name: Create the keystone user. + user: name=keystone comment="Openstack Keystone Daemons" shell=/sbin/nologin home=/var/lib/keystone + + - name: Create the /var folders for keystone + file: path={{ item }} state=directory owner=keystone group=keystone + with_items: + - /var/run/keystone + - /var/lock/keystone + - /var/log/keystone + - /var/lib/keystone + + - file: path=/etc/keystone state=directory + - name: Add the configuration needed for lorry in /etc using templates + template: src=/usr/share/openstack/keystone/{{ item }} dest=/etc/keystone/{{ item }} + with_lines: + - (cd /usr/share/openstack/keystone && find -type f) + + - postgresql_user: name={{ KEYSTONE_DB_USER }} password={{ KEYSTONE_DB_PASSWORD }} + sudo: yes + sudo_user: keystone + - postgresql_db: name=keystone owner={{ KEYSTONE_DB_USER }} + sudo: yes + sudo_user: keystone + + - keystone_manage: action=dbsync + sudo: yes + sudo_user: keystone + + - name: Enable and start openstack-keystone service + service: name=openstack-keystone.service enabled=yes state=started + + - keystone_user: > + tenant=admin + tenant_description="Admin Tenant" + token={{ KEYSTONE_TEMPORARY_ADMIN_TOKEN }} + endpoint={{ KEYSTONE_ADMIN_URL }} + + - keystone_user: > + user=admin + tenant=admin + password={{ KEYSTONE_ADMIN_PASSWORD }} + token={{ KEYSTONE_TEMPORARY_ADMIN_TOKEN }} + endpoint={{ KEYSTONE_ADMIN_URL }} + + - keystone_user: > + role=admin + user=admin + tenant=admin + token={{ KEYSTONE_TEMPORARY_ADMIN_TOKEN }} + endpoint={{ KEYSTONE_ADMIN_URL }} + + - keystone_user: > + tenant=service + tenant_description="Service Tenant" + token={{ KEYSTONE_TEMPORARY_ADMIN_TOKEN }} + endpoint={{ KEYSTONE_ADMIN_URL }} + + - keystone_service: > + name=keystone + type=identity + description="Keystone Identity Service" + publicurl={{ KEYSTONE_PUBLIC_URL }} + internalurl={{ KEYSTONE_INTERNAL_URL }} + adminurl={{ KEYSTONE_ADMIN_URL }} + region='RegionOne' + token={{ KEYSTONE_TEMPORARY_ADMIN_TOKEN }} + endpoint={{ KEYSTONE_ADMIN_URL }} + diff --git a/openstack/usr/share/openstack/keystone/keystone-paste.ini b/openstack/usr/share/openstack/keystone/keystone-paste.ini new file mode 100644 index 00000000..cd132971 --- /dev/null +++ b/openstack/usr/share/openstack/keystone/keystone-paste.ini @@ -0,0 +1,112 @@ +# Keystone PasteDeploy configuration file. + +[filter:debug] +paste.filter_factory = keystone.common.wsgi:Debug.factory + +[filter:build_auth_context] +paste.filter_factory = keystone.middleware:AuthContextMiddleware.factory + +[filter:token_auth] +paste.filter_factory = keystone.middleware:TokenAuthMiddleware.factory + +[filter:admin_token_auth] +paste.filter_factory = keystone.middleware:AdminTokenAuthMiddleware.factory + +[filter:xml_body] +paste.filter_factory = keystone.middleware:XmlBodyMiddleware.factory + +[filter:xml_body_v2] +paste.filter_factory = keystone.middleware:XmlBodyMiddlewareV2.factory + +[filter:xml_body_v3] +paste.filter_factory = keystone.middleware:XmlBodyMiddlewareV3.factory + +[filter:json_body] +paste.filter_factory = keystone.middleware:JsonBodyMiddleware.factory + +[filter:user_crud_extension] +paste.filter_factory = keystone.contrib.user_crud:CrudExtension.factory + +[filter:crud_extension] +paste.filter_factory = keystone.contrib.admin_crud:CrudExtension.factory + +[filter:ec2_extension] +paste.filter_factory = keystone.contrib.ec2:Ec2Extension.factory + +[filter:ec2_extension_v3] +paste.filter_factory = keystone.contrib.ec2:Ec2ExtensionV3.factory + +[filter:federation_extension] +paste.filter_factory = keystone.contrib.federation.routers:FederationExtension.factory + +[filter:oauth1_extension] +paste.filter_factory = keystone.contrib.oauth1.routers:OAuth1Extension.factory + +[filter:s3_extension] +paste.filter_factory = keystone.contrib.s3:S3Extension.factory + +[filter:endpoint_filter_extension] +paste.filter_factory = keystone.contrib.endpoint_filter.routers:EndpointFilterExtension.factory + +[filter:simple_cert_extension] +paste.filter_factory = keystone.contrib.simple_cert:SimpleCertExtension.factory + +[filter:revoke_extension] +paste.filter_factory = keystone.contrib.revoke.routers:RevokeExtension.factory + +[filter:url_normalize] +paste.filter_factory = keystone.middleware:NormalizingFilter.factory + +[filter:sizelimit] +paste.filter_factory = keystone.middleware:RequestBodySizeLimiter.factory + +[filter:stats_monitoring] +paste.filter_factory = keystone.contrib.stats:StatsMiddleware.factory + +[filter:stats_reporting] +paste.filter_factory = keystone.contrib.stats:StatsExtension.factory + +[filter:access_log] +paste.filter_factory = keystone.contrib.access:AccessLogMiddleware.factory + +[app:public_service] +paste.app_factory = keystone.service:public_app_factory + +[app:service_v3] +paste.app_factory = keystone.service:v3_app_factory + +[app:admin_service] +paste.app_factory = keystone.service:admin_app_factory + +[pipeline:public_api] +pipeline = sizelimit url_normalize build_auth_context token_auth admin_token_auth xml_body_v2 json_body ec2_extension user_crud_extension public_service + +[pipeline:admin_api] +pipeline = sizelimit url_normalize build_auth_context token_auth admin_token_auth xml_body_v2 json_body ec2_extension s3_extension crud_extension admin_service + +[pipeline:api_v3] +pipeline = sizelimit url_normalize build_auth_context token_auth admin_token_auth xml_body_v3 json_body ec2_extension_v3 s3_extension simple_cert_extension service_v3 + +[app:public_version_service] +paste.app_factory = keystone.service:public_version_app_factory + +[app:admin_version_service] +paste.app_factory = keystone.service:admin_version_app_factory + +[pipeline:public_version_api] +pipeline = sizelimit url_normalize xml_body public_version_service + +[pipeline:admin_version_api] +pipeline = sizelimit url_normalize xml_body admin_version_service + +[composite:main] +use = egg:Paste#urlmap +/v2.0 = public_api +/v3 = api_v3 +/ = public_version_api + +[composite:admin] +use = egg:Paste#urlmap +/v2.0 = admin_api +/v3 = api_v3 +/ = admin_version_api diff --git a/openstack/usr/share/openstack/keystone/keystone.conf b/openstack/usr/share/openstack/keystone/keystone.conf new file mode 100644 index 00000000..c35ecc15 --- /dev/null +++ b/openstack/usr/share/openstack/keystone/keystone.conf @@ -0,0 +1,1384 @@ +[DEFAULT] + +# +# Options defined in keystone +# + +# A "shared secret" that can be used to bootstrap Keystone. +# This "token" does not represent a user, and carries no +# explicit authorization. To disable in production (highly +# recommended), remove AdminTokenAuthMiddleware from your +# paste application pipelines (for example, in keystone- +# paste.ini). (string value) +admin_token={{ KEYSTONE_TEMPORARY_ADMIN_TOKEN }} + +# The IP address of the network interface for the public +# service to listen on. (string value) +# Deprecated group/name - [DEFAULT]/bind_host +#public_bind_host=0.0.0.0 + +# The IP address of the network interface for the admin +# service to listen on. (string value) +# Deprecated group/name - [DEFAULT]/bind_host +#admin_bind_host=0.0.0.0 + +# The port which the OpenStack Compute service listens on. +# (integer value) +compute_port=8774 + +# The port number which the admin service listens on. (integer +# value) +admin_port=35357 + +# The port number which the public service listens on. +# (integer value) +public_port=5000 + +# The base public endpoint URL for Keystone that is advertised +# to clients (NOTE: this does NOT affect how Keystone listens +# for connections). Defaults to the base host URL of the +# request. E.g. a request to http://server:5000/v2.0/users +# will default to http://server:5000. You should only need to +# set this value if the base URL contains a path (e.g. +# /prefix/v2.0) or the endpoint should be found on a different +# server. (string value) +#public_endpoint= + +# The base admin endpoint URL for Keystone that is advertised +# to clients (NOTE: this does NOT affect how Keystone listens +# for connections). Defaults to the base host URL of the +# request. E.g. a request to http://server:35357/v2.0/users +# will default to http://server:35357. You should only need to +# set this value if the base URL contains a path (e.g. +# /prefix/v2.0) or the endpoint should be found on a different +# server. (string value) +#admin_endpoint= + +# The number of worker processes to serve the public WSGI +# application (integer value) +#public_workers=1 + +# The number of worker processes to serve the admin WSGI +# application (integer value) +#admin_workers=1 + +# Enforced by optional sizelimit middleware +# (keystone.middleware:RequestBodySizeLimiter). (integer +# value) +#max_request_body_size=114688 + +# Limit the sizes of user & project ID/names. (integer value) +#max_param_size=64 + +# Similar to max_param_size, but provides an exception for +# token values. (integer value) +#max_token_size=8192 + +# During a SQL upgrade member_role_id will be used to create a +# new role that will replace records in the assignment table +# with explicit role grants. After migration, the +# member_role_id will be used in the API add_user_to_project. +# (string value) +#member_role_id=9fe2ff9ee4384b1894a90878d3e92bab + +# During a SQL upgrade member_role_name will be used to create +# a new role that will replace records in the assignment table +# with explicit role grants. After migration, member_role_name +# will be ignored. (string value) +#member_role_name=_member_ + +# The value passed as the keyword "rounds" to passlib's +# encrypt method. (integer value) +#crypt_strength=40000 + +# Set this to true if you want to enable TCP_KEEPALIVE on +# server sockets, i.e. sockets used by the Keystone wsgi +# server for client connections. (boolean value) +#tcp_keepalive=false + +# Sets the value of TCP_KEEPIDLE in seconds for each server +# socket. Only applies if tcp_keepalive is true. Not supported +# on OS X. (integer value) +#tcp_keepidle=600 + +# The maximum number of entities that will be returned in a +# collection, with no limit set by default. This global limit +# may be then overridden for a specific driver, by specifying +# a list_limit in the appropriate section (e.g. [assignment]). +# (integer value) +#list_limit= + +# Set this to false if you want to enable the ability for +# user, group and project entities to be moved between domains +# by updating their domain_id. Allowing such movement is not +# recommended if the scope of a domain admin is being +# restricted by use of an appropriate policy file (see +# policy.v3cloudsample as an example). (boolean value) +#domain_id_immutable=true + +# If set to true, strict password length checking is performed +# for password manipulation. If a password exceeds the maximum +# length, the operation will fail with an HTTP 403 Forbidden +# error. If set to false, passwords are automatically +# truncated to the maximum length. (boolean value) +#strict_password_check=false + + +# +# Options defined in oslo.messaging +# + +# Use durable queues in amqp. (boolean value) +# Deprecated group/name - [DEFAULT]/rabbit_durable_queues +#amqp_durable_queues=false + +# Auto-delete queues in amqp. (boolean value) +#amqp_auto_delete=false + +# Size of RPC connection pool. (integer value) +#rpc_conn_pool_size=30 + +# Modules of exceptions that are permitted to be recreated +# upon receiving exception data from an rpc call. (list value) +#allowed_rpc_exception_modules=oslo.messaging.exceptions,nova.exception,cinder.exception,exceptions + +# Qpid broker hostname. (string value) +#qpid_hostname=keystone + +# Qpid broker port. (integer value) +#qpid_port=5672 + +# Qpid HA cluster host:port pairs. (list value) +#qpid_hosts=$qpid_hostname:$qpid_port + +# Username for Qpid connection. (string value) +#qpid_username= + +# Password for Qpid connection. (string value) +#qpid_password= + +# Space separated list of SASL mechanisms to use for auth. +# (string value) +#qpid_sasl_mechanisms= + +# Seconds between connection keepalive heartbeats. (integer +# value) +#qpid_heartbeat=60 + +# Transport to use, either 'tcp' or 'ssl'. (string value) +#qpid_protocol=tcp + +# Whether to disable the Nagle algorithm. (boolean value) +#qpid_tcp_nodelay=true + +# The qpid topology version to use. Version 1 is what was +# originally used by impl_qpid. Version 2 includes some +# backwards-incompatible changes that allow broker federation +# to work. Users should update to version 2 when they are +# able to take everything down, as it requires a clean break. +# (integer value) +#qpid_topology_version=1 + +# SSL version to use (valid only if SSL enabled). valid values +# are TLSv1, SSLv23 and SSLv3. SSLv2 may be available on some +# distributions. (string value) +#kombu_ssl_version= + +# SSL key file (valid only if SSL enabled). (string value) +#kombu_ssl_keyfile= + +# SSL cert file (valid only if SSL enabled). (string value) +#kombu_ssl_certfile= + +# SSL certification authority file (valid only if SSL +# enabled). (string value) +#kombu_ssl_ca_certs= + +# How long to wait before reconnecting in response to an AMQP +# consumer cancel notification. (floating point value) +#kombu_reconnect_delay=1.0 + +# The RabbitMQ broker address where a single node is used. +# (string value) +rabbit_host={{ RABBITMQ_HOST }} + +# The RabbitMQ broker port where a single node is used. +# (integer value) +rabbit_port={{ RABBITMQ_PORT }} + +# RabbitMQ HA cluster host:port pairs. (list value) +rabbit_hosts=$rabbit_host:$rabbit_port + +# Connect over SSL for RabbitMQ. (boolean value) +rabbit_use_ssl=false + +# The RabbitMQ userid. (string value) +rabbit_userid={{ RABBITMQ_USER }} + +# The RabbitMQ password. (string value) +rabbit_password={{ RABBITMQ_PASSWORD }} + +# the RabbitMQ login method (string value) +#rabbit_login_method=AMQPLAIN + +# The RabbitMQ virtual host. (string value) +#rabbit_virtual_host=/ + +# How frequently to retry connecting with RabbitMQ. (integer +# value) +#rabbit_retry_interval=1 + +# How long to backoff for between retries when connecting to +# RabbitMQ. (integer value) +#rabbit_retry_backoff=2 + +# Maximum number of RabbitMQ connection retries. Default is 0 +# (infinite retry count). (integer value) +#rabbit_max_retries=0 + +# Use HA queues in RabbitMQ (x-ha-policy: all). If you change +# this option, you must wipe the RabbitMQ database. (boolean +# value) +#rabbit_ha_queues=false + +# If passed, use a fake RabbitMQ provider. (boolean value) +#fake_rabbit=false + +# ZeroMQ bind address. Should be a wildcard (*), an ethernet +# interface, or IP. The "host" option should point or resolve +# to this address. (string value) +#rpc_zmq_bind_address=* + +# MatchMaker driver. (string value) +#rpc_zmq_matchmaker=oslo.messaging._drivers.matchmaker.MatchMakerLocalhost + +# ZeroMQ receiver listening port. (integer value) +#rpc_zmq_port=9501 + +# Number of ZeroMQ contexts, defaults to 1. (integer value) +#rpc_zmq_contexts=1 + +# Maximum number of ingress messages to locally buffer per +# topic. Default is unlimited. (integer value) +#rpc_zmq_topic_backlog= + +# Directory for holding IPC sockets. (string value) +#rpc_zmq_ipc_dir=/var/run/openstack + +# Name of this node. Must be a valid hostname, FQDN, or IP +# address. Must match "host" option, if running Nova. (string +# value) +#rpc_zmq_host=keystone + +# Seconds to wait before a cast expires (TTL). Only supported +# by impl_zmq. (integer value) +#rpc_cast_timeout=30 + +# Heartbeat frequency. (integer value) +#matchmaker_heartbeat_freq=300 + +# Heartbeat time-to-live. (integer value) +#matchmaker_heartbeat_ttl=600 + +# Host to locate redis. (string value) +#host=localhost + +# Use this port to connect to redis host. (integer value) +#port=6379 + +# Password for Redis server (optional). (string value) +#password= + +# Size of RPC greenthread pool. (integer value) +#rpc_thread_pool_size=64 + +# Driver or drivers to handle sending notifications. (multi +# valued) +#notification_driver= + +# AMQP topic used for OpenStack notifications. (list value) +# Deprecated group/name - [rpc_notifier2]/topics +#notification_topics=notifications + +# Seconds to wait for a response from a call. (integer value) +#rpc_response_timeout=60 + +# A URL representing the messaging driver to use and its full +# configuration. If not set, we fall back to the rpc_backend +# option and driver specific configuration. (string value) +#transport_url= + +# The messaging driver to use, defaults to rabbit. Other +# drivers include qpid and zmq. (string value) +rpc_backend=rabbit + +# The default exchange under which topics are scoped. May be +# overridden by an exchange name specified in the +# transport_url option. (string value) +#control_exchange=openstack + + +# +# Options defined in keystone.notifications +# + +# Default publisher_id for outgoing notifications (string +# value) +#default_publisher_id= + + +# +# Options defined in keystone.middleware.ec2_token +# + +# URL to get token from ec2 request. (string value) +#keystone_ec2_url=http://localhost:5000/v2.0/ec2tokens + +# Required if EC2 server requires client certificate. (string +# value) +#keystone_ec2_keyfile= + +# Client certificate key filename. Required if EC2 server +# requires client certificate. (string value) +#keystone_ec2_certfile= + +# A PEM encoded certificate authority to use when verifying +# HTTPS connections. Defaults to the system CAs. (string +# value) +#keystone_ec2_cafile= + +# Disable SSL certificate verification. (boolean value) +#keystone_ec2_insecure=false + + +# +# Options defined in keystone.openstack.common.eventlet_backdoor +# + +# Enable eventlet backdoor. Acceptable values are 0, , +# and :, where 0 results in listening on a random +# tcp port number; results in listening on the +# specified port number (and not enabling backdoor if that +# port is in use); and : results in listening on +# the smallest unused port number within the specified range +# of port numbers. The chosen port is displayed in the +# service's log file. (string value) +#backdoor_port= + + +# +# Options defined in keystone.openstack.common.lockutils +# + +# Enables or disables inter-process locks. (boolean value) +#disable_process_locking=false + +# Directory to use for lock files. (string value) +#lock_path= + + +# +# Options defined in keystone.openstack.common.log +# + +# Print debugging output (set logging level to DEBUG instead +# of default WARNING level). (boolean value) +#debug=false + +# Print more verbose output (set logging level to INFO instead +# of default WARNING level). (boolean value) +#verbose=false + +# Log output to standard error. (boolean value) +#use_stderr=true + +# Format string to use for log messages with context. (string +# value) +#logging_context_format_string=%(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s [%(request_id)s %(user_identity)s] %(instance)s%(message)s + +# Format string to use for log messages without context. +# (string value) +#logging_default_format_string=%(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s [-] %(instance)s%(message)s + +# Data to append to log format when level is DEBUG. (string +# value) +#logging_debug_format_suffix=%(funcName)s %(pathname)s:%(lineno)d + +# Prefix each line of exception output with this format. +# (string value) +#logging_exception_prefix=%(asctime)s.%(msecs)03d %(process)d TRACE %(name)s %(instance)s + +# List of logger=LEVEL pairs. (list value) +#default_log_levels=amqp=WARN,amqplib=WARN,boto=WARN,qpid=WARN,sqlalchemy=WARN,suds=INFO,oslo.messaging=INFO,iso8601=WARN,requests.packages.urllib3.connectionpool=WARN + +# Enables or disables publication of error events. (boolean +# value) +#publish_errors=false + +# Enables or disables fatal status of deprecations. (boolean +# value) +#fatal_deprecations=false + +# The format for an instance that is passed with the log +# message. (string value) +#instance_format="[instance: %(uuid)s] " + +# The format for an instance UUID that is passed with the log +# message. (string value) +#instance_uuid_format="[instance: %(uuid)s] " + +# The name of a logging configuration file. This file is +# appended to any existing logging configuration files. For +# details about logging configuration files, see the Python +# logging module documentation. (string value) +# Deprecated group/name - [DEFAULT]/log_config +#log_config_append= + +# DEPRECATED. A logging.Formatter log message format string +# which may use any of the available logging.LogRecord +# attributes. This option is deprecated. Please use +# logging_context_format_string and +# logging_default_format_string instead. (string value) +#log_format= + +# Format string for %%(asctime)s in log records. Default: +# %(default)s . (string value) +#log_date_format=%Y-%m-%d %H:%M:%S + +# (Optional) Name of log file to output to. If no default is +# set, logging will go to stdout. (string value) +# Deprecated group/name - [DEFAULT]/logfile +#log_file= + +# (Optional) The base directory used for relative --log-file +# paths. (string value) +# Deprecated group/name - [DEFAULT]/logdir +#log_dir= + +# Use syslog for logging. Existing syslog format is DEPRECATED +# during I, and will chang in J to honor RFC5424. (boolean +# value) +#use_syslog=false + +# (Optional) Enables or disables syslog rfc5424 format for +# logging. If enabled, prefixes the MSG part of the syslog +# message with APP-NAME (RFC5424). The format without the APP- +# NAME is deprecated in I, and will be removed in J. (boolean +# value) +#use_syslog_rfc_format=false + +# Syslog facility to receive log lines. (string value) +#syslog_log_facility=LOG_USER + + +# +# Options defined in keystone.openstack.common.policy +# + +# The JSON file that defines policies. (string value) +#policy_file=policy.json + +# Default rule. Enforced when a requested rule is not found. +# (string value) +#policy_default_rule=default + + +[assignment] + +# +# Options defined in keystone +# + +# Assignment backend driver. (string value) +#driver= + +# Toggle for assignment caching. This has no effect unless +# global caching is enabled. (boolean value) +#caching=true + +# TTL (in seconds) to cache assignment data. This has no +# effect unless global caching is enabled. (integer value) +#cache_time= + +# Maximum number of entities that will be returned in an +# assignment collection. (integer value) +#list_limit= + + +[auth] + +# +# Options defined in keystone +# + +# Default auth methods. (list value) +#methods=external,password,token + +# The password auth plugin module. (string value) +#password=keystone.auth.plugins.password.Password + +# The token auth plugin module. (string value) +#token=keystone.auth.plugins.token.Token + +# The external (REMOTE_USER) auth plugin module. (string +# value) +#external=keystone.auth.plugins.external.DefaultDomain + + +[cache] + +# +# Options defined in keystone +# + +# Prefix for building the configuration dictionary for the +# cache region. This should not need to be changed unless +# there is another dogpile.cache region with the same +# configuration name. (string value) +#config_prefix=cache.keystone + +# Default TTL, in seconds, for any cached item in the +# dogpile.cache region. This applies to any cached method that +# doesn't have an explicit cache expiration time defined for +# it. (integer value) +#expiration_time=600 + +# Dogpile.cache backend module. It is recommended that +# Memcache (dogpile.cache.memcached) or Redis +# (dogpile.cache.redis) be used in production deployments. +# Small workloads (single process) like devstack can use the +# dogpile.cache.memory backend. (string value) +#backend=keystone.common.cache.noop + +# Use a key-mangling function (sha1) to ensure fixed length +# cache-keys. This is toggle-able for debugging purposes, it +# is highly recommended to always leave this set to true. +# (boolean value) +#use_key_mangler=true + +# Arguments supplied to the backend module. Specify this +# option once per argument to be passed to the dogpile.cache +# backend. Example format: ":". (multi valued) +#backend_argument= + +# Proxy classes to import that will affect the way the +# dogpile.cache backend functions. See the dogpile.cache +# documentation on changing-backend-behavior. (list value) +#proxies= + +# Global toggle for all caching using the should_cache_fn +# mechanism. (boolean value) +#enabled=false + +# Extra debugging from the cache backend (cache keys, +# get/set/delete/etc calls). This is only really useful if you +# need to see the specific cache-backend get/set/delete calls +# with the keys/values. Typically this should be left set to +# false. (boolean value) +#debug_cache_backend=false + + +[catalog] + +# +# Options defined in keystone +# + +# Catalog template file name for use with the template catalog +# backend. (string value) +#template_file=default_catalog.templates + +# Catalog backend driver. (string value) +#driver=keystone.catalog.backends.sql.Catalog + +# Maximum number of entities that will be returned in a +# catalog collection. (integer value) +#list_limit= + + +[credential] + +# +# Options defined in keystone +# + +# Credential backend driver. (string value) +#driver=keystone.credential.backends.sql.Credential + + +[database] + +# +# Options defined in oslo.db +# + +# The file name to use with SQLite. (string value) +#sqlite_db=oslo.sqlite + +# If True, SQLite uses synchronous mode. (boolean value) +#sqlite_synchronous=true + +# The back end to use for the database. (string value) +# Deprecated group/name - [DEFAULT]/db_backend +#backend=sqlalchemy + +# The SQLAlchemy connection string to use to connect to the +# database. (string value) +# Deprecated group/name - [DEFAULT]/sql_connection +# Deprecated group/name - [DATABASE]/sql_connection +# Deprecated group/name - [sql]/connection +#connection= +connection=postgresql://{{ KEYSTONE_DB_USER }}:{{ KEYSTONE_DB_PASSWORD }}@{{ CONTROLLER_HOST }}/keystone + +# The SQLAlchemy connection string to use to connect to the +# slave database. (string value) +#slave_connection= + +# The SQL mode to be used for MySQL sessions. This option, +# including the default, overrides any server-set SQL mode. To +# use whatever SQL mode is set by the server configuration, +# set this to no value. Example: mysql_sql_mode= (string +# value) +#mysql_sql_mode=TRADITIONAL + +# Timeout before idle SQL connections are reaped. (integer +# value) +# Deprecated group/name - [DEFAULT]/sql_idle_timeout +# Deprecated group/name - [DATABASE]/sql_idle_timeout +# Deprecated group/name - [sql]/idle_timeout +#idle_timeout=3600 + +# Minimum number of SQL connections to keep open in a pool. +# (integer value) +# Deprecated group/name - [DEFAULT]/sql_min_pool_size +# Deprecated group/name - [DATABASE]/sql_min_pool_size +#min_pool_size=1 + +# Maximum number of SQL connections to keep open in a pool. +# (integer value) +# Deprecated group/name - [DEFAULT]/sql_max_pool_size +# Deprecated group/name - [DATABASE]/sql_max_pool_size +#max_pool_size= + +# Maximum db connection retries during startup. Set to -1 to +# specify an infinite retry count. (integer value) +# Deprecated group/name - [DEFAULT]/sql_max_retries +# Deprecated group/name - [DATABASE]/sql_max_retries +#max_retries=10 + +# Interval between retries of opening a SQL connection. +# (integer value) +# Deprecated group/name - [DEFAULT]/sql_retry_interval +# Deprecated group/name - [DATABASE]/reconnect_interval +#retry_interval=10 + +# If set, use this value for max_overflow with SQLAlchemy. +# (integer value) +# Deprecated group/name - [DEFAULT]/sql_max_overflow +# Deprecated group/name - [DATABASE]/sqlalchemy_max_overflow +#max_overflow= + +# Verbosity of SQL debugging information: 0=None, +# 100=Everything. (integer value) +# Deprecated group/name - [DEFAULT]/sql_connection_debug +#connection_debug=0 + +# Add Python stack traces to SQL as comment strings. (boolean +# value) +# Deprecated group/name - [DEFAULT]/sql_connection_trace +#connection_trace=false + +# If set, use this value for pool_timeout with SQLAlchemy. +# (integer value) +# Deprecated group/name - [DATABASE]/sqlalchemy_pool_timeout +#pool_timeout= + +# Enable the experimental use of database reconnect on +# connection lost. (boolean value) +#use_db_reconnect=false + +# Seconds between database connection retries. (integer value) +#db_retry_interval=1 + +# If True, increases the interval between database connection +# retries up to db_max_retry_interval. (boolean value) +#db_inc_retry_interval=true + +# If db_inc_retry_interval is set, the maximum seconds between +# database connection retries. (integer value) +#db_max_retry_interval=10 + +# Maximum database connection retries before error is raised. +# Set to -1 to specify an infinite retry count. (integer +# value) +#db_max_retries=20 + + +[ec2] + +# +# Options defined in keystone +# + +# EC2Credential backend driver. (string value) +#driver=keystone.contrib.ec2.backends.kvs.Ec2 + + +[endpoint_filter] + +# +# Options defined in keystone +# + +# Endpoint Filter backend driver (string value) +#driver=keystone.contrib.endpoint_filter.backends.sql.EndpointFilter + +# Toggle to return all active endpoints if no filter exists. +# (boolean value) +#return_all_endpoints_if_no_filter=true + + +[federation] + +# +# Options defined in keystone +# + +# Federation backend driver. (string value) +#driver=keystone.contrib.federation.backends.sql.Federation + +# Value to be used when filtering assertion parameters from +# the environment. (string value) +#assertion_prefix= + + +[identity] + +# +# Options defined in keystone +# + +# This references the domain to use for all Identity API v2 +# requests (which are not aware of domains). A domain with +# this ID will be created for you by keystone-manage db_sync +# in migration 008. The domain referenced by this ID cannot be +# deleted on the v3 API, to prevent accidentally breaking the +# v2 API. There is nothing special about this domain, other +# than the fact that it must exist to order to maintain +# support for your v2 clients. (string value) +#default_domain_id=default + +# A subset (or all) of domains can have their own identity +# driver, each with their own partial configuration file in a +# domain configuration directory. Only values specific to the +# domain need to be placed in the domain specific +# configuration file. This feature is disabled by default; set +# to true to enable. (boolean value) +#domain_specific_drivers_enabled=false + +# Path for Keystone to locate the domain specific identity +# configuration files if domain_specific_drivers_enabled is +# set to true. (string value) +#domain_config_dir=/etc/keystone/domains + +# Identity backend driver. (string value) +#driver=keystone.identity.backends.sql.Identity + +# Maximum supported length for user passwords; decrease to +# improve performance. (integer value) +#max_password_length=4096 + +# Maximum number of entities that will be returned in an +# identity collection. (integer value) +#list_limit= + + +[kvs] + +# +# Options defined in keystone +# + +# Extra dogpile.cache backend modules to register with the +# dogpile.cache library. (list value) +#backends= + +# Prefix for building the configuration dictionary for the KVS +# region. This should not need to be changed unless there is +# another dogpile.cache region with the same configuration +# name. (string value) +#config_prefix=keystone.kvs + +# Toggle to disable using a key-mangling function to ensure +# fixed length keys. This is toggle-able for debugging +# purposes, it is highly recommended to always leave this set +# to true. (boolean value) +#enable_key_mangler=true + +# Default lock timeout for distributed locking. (integer +# value) +#default_lock_timeout=5 + + +[ldap] + +# +# Options defined in keystone +# + +# URL for connecting to the LDAP server. (string value) +#url=ldap://keystone + +# User BindDN to query the LDAP server. (string value) +#user= + +# Password for the BindDN to query the LDAP server. (string +# value) +#password= + +# LDAP server suffix (string value) +#suffix=cn=example,cn=com + +# If true, will add a dummy member to groups. This is required +# if the objectclass for groups requires the "member" +# attribute. (boolean value) +#use_dumb_member=false + +# DN of the "dummy member" to use when "use_dumb_member" is +# enabled. (string value) +#dumb_member=cn=dumb,dc=nonexistent + +# Delete subtrees using the subtree delete control. Only +# enable this option if your LDAP server supports subtree +# deletion. (boolean value) +#allow_subtree_delete=false + +# The LDAP scope for queries, this can be either "one" +# (onelevel/singleLevel) or "sub" (subtree/wholeSubtree). +# (string value) +#query_scope=one + +# Maximum results per page; a value of zero ("0") disables +# paging. (integer value) +#page_size=0 + +# The LDAP dereferencing option for queries. This can be +# either "never", "searching", "always", "finding" or +# "default". The "default" option falls back to using default +# dereferencing configured by your ldap.conf. (string value) +#alias_dereferencing=default + +# Sets the LDAP debugging level for LDAP calls. A value of 0 +# means that debugging is not enabled. This value is a +# bitmask, consult your LDAP documentation for possible +# values. (integer value) +#debug_level= + +# Override the system's default referral chasing behavior for +# queries. (boolean value) +#chase_referrals= + +# Search base for users. (string value) +#user_tree_dn= + +# LDAP search filter for users. (string value) +#user_filter= + +# LDAP objectclass for users. (string value) +#user_objectclass=inetOrgPerson + +# LDAP attribute mapped to user id. (string value) +#user_id_attribute=cn + +# LDAP attribute mapped to user name. (string value) +#user_name_attribute=sn + +# LDAP attribute mapped to user email. (string value) +#user_mail_attribute=email + +# LDAP attribute mapped to password. (string value) +#user_pass_attribute=userPassword + +# LDAP attribute mapped to user enabled flag. (string value) +#user_enabled_attribute=enabled + +# Bitmask integer to indicate the bit that the enabled value +# is stored in if the LDAP server represents "enabled" as a +# bit on an integer rather than a boolean. A value of "0" +# indicates the mask is not used. If this is not set to "0" +# the typical value is "2". This is typically used when +# "user_enabled_attribute = userAccountControl". (integer +# value) +#user_enabled_mask=0 + +# Default value to enable users. This should match an +# appropriate int value if the LDAP server uses non-boolean +# (bitmask) values to indicate if a user is enabled or +# disabled. If this is not set to "True" the typical value is +# "512". This is typically used when "user_enabled_attribute = +# userAccountControl". (string value) +#user_enabled_default=True + +# List of attributes stripped off the user on update. (list +# value) +#user_attribute_ignore=default_project_id,tenants + +# LDAP attribute mapped to default_project_id for users. +# (string value) +#user_default_project_id_attribute= + +# Allow user creation in LDAP backend. (boolean value) +#user_allow_create=true + +# Allow user updates in LDAP backend. (boolean value) +#user_allow_update=true + +# Allow user deletion in LDAP backend. (boolean value) +#user_allow_delete=true + +# If true, Keystone uses an alternative method to determine if +# a user is enabled or not by checking if they are a member of +# the "user_enabled_emulation_dn" group. (boolean value) +#user_enabled_emulation=false + +# DN of the group entry to hold enabled users when using +# enabled emulation. (string value) +#user_enabled_emulation_dn= + +# List of additional LDAP attributes used for mapping +# additional attribute mappings for users. Attribute mapping +# format is :, where ldap_attr is the +# attribute in the LDAP entry and user_attr is the Identity +# API attribute. (list value) +#user_additional_attribute_mapping= + +# Search base for projects (string value) +# Deprecated group/name - [ldap]/tenant_tree_dn +#project_tree_dn= + +# LDAP search filter for projects. (string value) +# Deprecated group/name - [ldap]/tenant_filter +#project_filter= + +# LDAP objectclass for projects. (string value) +# Deprecated group/name - [ldap]/tenant_objectclass +#project_objectclass=groupOfNames + +# LDAP attribute mapped to project id. (string value) +# Deprecated group/name - [ldap]/tenant_id_attribute +#project_id_attribute=cn + +# LDAP attribute mapped to project membership for user. +# (string value) +# Deprecated group/name - [ldap]/tenant_member_attribute +#project_member_attribute=member + +# LDAP attribute mapped to project name. (string value) +# Deprecated group/name - [ldap]/tenant_name_attribute +#project_name_attribute=ou + +# LDAP attribute mapped to project description. (string value) +# Deprecated group/name - [ldap]/tenant_desc_attribute +#project_desc_attribute=description + +# LDAP attribute mapped to project enabled. (string value) +# Deprecated group/name - [ldap]/tenant_enabled_attribute +#project_enabled_attribute=enabled + +# LDAP attribute mapped to project domain_id. (string value) +# Deprecated group/name - [ldap]/tenant_domain_id_attribute +#project_domain_id_attribute=businessCategory + +# List of attributes stripped off the project on update. (list +# value) +# Deprecated group/name - [ldap]/tenant_attribute_ignore +#project_attribute_ignore= + +# Allow project creation in LDAP backend. (boolean value) +# Deprecated group/name - [ldap]/tenant_allow_create +#project_allow_create=true + +# Allow project update in LDAP backend. (boolean value) +# Deprecated group/name - [ldap]/tenant_allow_update +#project_allow_update=true + +# Allow project deletion in LDAP backend. (boolean value) +# Deprecated group/name - [ldap]/tenant_allow_delete +#project_allow_delete=true + +# If true, Keystone uses an alternative method to determine if +# a project is enabled or not by checking if they are a member +# of the "project_enabled_emulation_dn" group. (boolean value) +# Deprecated group/name - [ldap]/tenant_enabled_emulation +#project_enabled_emulation=false + +# DN of the group entry to hold enabled projects when using +# enabled emulation. (string value) +# Deprecated group/name - [ldap]/tenant_enabled_emulation_dn +#project_enabled_emulation_dn= + +# Additional attribute mappings for projects. Attribute +# mapping format is :, where ldap_attr +# is the attribute in the LDAP entry and user_attr is the +# Identity API attribute. (list value) +# Deprecated group/name - [ldap]/tenant_additional_attribute_mapping +#project_additional_attribute_mapping= + +# Search base for roles. (string value) +#role_tree_dn= + +# LDAP search filter for roles. (string value) +#role_filter= + +# LDAP objectclass for roles. (string value) +#role_objectclass=organizationalRole + +# LDAP attribute mapped to role id. (string value) +#role_id_attribute=cn + +# LDAP attribute mapped to role name. (string value) +#role_name_attribute=ou + +# LDAP attribute mapped to role membership. (string value) +#role_member_attribute=roleOccupant + +# List of attributes stripped off the role on update. (list +# value) +#role_attribute_ignore= + +# Allow role creation in LDAP backend. (boolean value) +#role_allow_create=true + +# Allow role update in LDAP backend. (boolean value) +#role_allow_update=true + +# Allow role deletion in LDAP backend. (boolean value) +#role_allow_delete=true + +# Additional attribute mappings for roles. Attribute mapping +# format is :, where ldap_attr is the +# attribute in the LDAP entry and user_attr is the Identity +# API attribute. (list value) +#role_additional_attribute_mapping= + +# Search base for groups. (string value) +#group_tree_dn= + +# LDAP search filter for groups. (string value) +#group_filter= + +# LDAP objectclass for groups. (string value) +#group_objectclass=groupOfNames + +# LDAP attribute mapped to group id. (string value) +#group_id_attribute=cn + +# LDAP attribute mapped to group name. (string value) +#group_name_attribute=ou + +# LDAP attribute mapped to show group membership. (string +# value) +#group_member_attribute=member + +# LDAP attribute mapped to group description. (string value) +#group_desc_attribute=description + +# List of attributes stripped off the group on update. (list +# value) +#group_attribute_ignore= + +# Allow group creation in LDAP backend. (boolean value) +#group_allow_create=true + +# Allow group update in LDAP backend. (boolean value) +#group_allow_update=true + +# Allow group deletion in LDAP backend. (boolean value) +#group_allow_delete=true + +# Additional attribute mappings for groups. Attribute mapping +# format is :, where ldap_attr is the +# attribute in the LDAP entry and user_attr is the Identity +# API attribute. (list value) +#group_additional_attribute_mapping= + +# CA certificate file path for communicating with LDAP +# servers. (string value) +#tls_cacertfile= + +# CA certificate directory path for communicating with LDAP +# servers. (string value) +#tls_cacertdir= + +# Enable TLS for communicating with LDAP servers. (boolean +# value) +#use_tls=false + +# Valid options for tls_req_cert are demand, never, and allow. +# (string value) +#tls_req_cert=demand + + +[matchmaker_ring] + +# +# Options defined in oslo.messaging +# + +# Matchmaker ring file (JSON). (string value) +# Deprecated group/name - [DEFAULT]/matchmaker_ringfile +#ringfile=/etc/oslo/matchmaker_ring.json + + +[memcache] + +# +# Options defined in keystone +# + +# Memcache servers in the format of "host:port". (list value) +#servers=localhost:11211 + +# Number of compare-and-set attempts to make when using +# compare-and-set in the token memcache back end. (integer +# value) +#max_compare_and_set_retry=16 + + +[oauth1] + +# +# Options defined in keystone +# + +# Credential backend driver. (string value) +#driver=keystone.contrib.oauth1.backends.sql.OAuth1 + +# Duration (in seconds) for the OAuth Request Token. (integer +# value) +#request_token_duration=28800 + +# Duration (in seconds) for the OAuth Access Token. (integer +# value) +#access_token_duration=86400 + + +[os_inherit] + +# +# Options defined in keystone +# + +# role-assignment inheritance to projects from owning domain +# can be optionally enabled. (boolean value) +#enabled=false + + +[paste_deploy] + +# +# Options defined in keystone +# + +# Name of the paste configuration file that defines the +# available pipelines. (string value) +#config_file=keystone-paste.ini + + +[policy] + +# +# Options defined in keystone +# + +# Policy backend driver. (string value) +#driver=keystone.policy.backends.sql.Policy + +# Maximum number of entities that will be returned in a policy +# collection. (integer value) +#list_limit= + + +[revoke] + +# +# Options defined in keystone +# + +# An implementation of the backend for persisting revocation +# events. (string value) +driver=keystone.contrib.revoke.backends.sql.Revoke + +# This value (calculated in seconds) is added to token +# expiration before a revocation event may be removed from the +# backend. (integer value) +#expiration_buffer=1800 + +# Toggle for revocation event cacheing. This has no effect +# unless global caching is enabled. (boolean value) +#caching=true + + +[signing] + +# +# Options defined in keystone +# + +# Deprecated in favor of provider in the [token] section. +# (string value) +#token_format= + +# Path of the certfile for token signing. For non-production +# environments, you may be interested in using `keystone- +# manage pki_setup` to generate self-signed certificates. +# (string value) +#certfile=/etc/keystone/ssl/certs/signing_cert.pem + +# Path of the keyfile for token signing. (string value) +#keyfile=/etc/keystone/ssl/private/signing_key.pem + +# Path of the CA for token signing. (string value) +#ca_certs=/etc/keystone/ssl/certs/ca.pem + +# Path of the CA key for token signing. (string value) +#ca_key=/etc/keystone/ssl/private/cakey.pem + +# Key size (in bits) for token signing cert (auto generated +# certificate). (integer value) +#key_size=2048 + +# Days the token signing cert is valid for (auto generated +# certificate). (integer value) +#valid_days=3650 + +# Certificate subject (auto generated certificate) for token +# signing. (string value) +#cert_subject=/C=US/ST=Unset/L=Unset/O=Unset/CN=www.example.com + + +[ssl] + +# +# Options defined in keystone +# + +# Toggle for SSL support on the Keystone eventlet servers. +# (boolean value) +#enable=false + +# Path of the certfile for SSL. For non-production +# environments, you may be interested in using `keystone- +# manage ssl_setup` to generate self-signed certificates. +# (string value) +#certfile=/etc/keystone/ssl/certs/keystone.pem + +# Path of the keyfile for SSL. (string value) +#keyfile=/etc/keystone/ssl/private/keystonekey.pem + +# Path of the ca cert file for SSL. (string value) +#ca_certs=/etc/keystone/ssl/certs/ca.pem + +# Path of the CA key file for SSL. (string value) +#ca_key=/etc/keystone/ssl/private/cakey.pem + +# Require client certificate. (boolean value) +#cert_required=false + +# SSL key length (in bits) (auto generated certificate). +# (integer value) +#key_size=1024 + +# Days the certificate is valid for once signed (auto +# generated certificate). (integer value) +#valid_days=3650 + +# SSL certificate subject (auto generated certificate). +# (string value) +#cert_subject=/C=US/ST=Unset/L=Unset/O=Unset/CN=keystone + + +[stats] + +# +# Options defined in keystone +# + +# Stats backend driver. (string value) +#driver=keystone.contrib.stats.backends.kvs.Stats + + +[token] + +# +# Options defined in keystone +# + +# External auth mechanisms that should add bind information to +# token, e.g., kerberos,x509. (list value) +#bind= + +# Enforcement policy on tokens presented to Keystone with bind +# information. One of disabled, permissive, strict, required +# or a specifically required bind mode, e.g., kerberos or x509 +# to require binding to that authentication. (string value) +#enforce_token_bind=permissive + +# Amount of time a token should remain valid (in seconds). +# (integer value) +#expiration=3600 + +# Controls the token construction, validation, and revocation +# operations. Core providers are +# "keystone.token.providers.[pkiz|pki|uuid].Provider". The +# default provider is pkiz. (string value) +provider=keystone.token.providers.uuid.Provider + +# Token persistence backend driver. (string value) +driver=keystone.token.backends.sql.Token + +# Toggle for token system cacheing. This has no effect unless +# global caching is enabled. (boolean value) +#caching=true + +# Time to cache the revocation list and the revocation events +# if revoke extension is enabled (in seconds). This has no +# effect unless global and token caching are enabled. (integer +# value) +#revocation_cache_time=3600 + +# Time to cache tokens (in seconds). This has no effect unless +# global and token caching are enabled. (integer value) +#cache_time= + +# Revoke token by token identifier. Setting revoke_by_id to +# true enables various forms of enumerating tokens, e.g. `list +# tokens for user`. These enumerations are processed to +# determine the list of tokens to revoke. Only disable if you +# are switching to using the Revoke extension with a backend +# other than KVS, which stores events in memory. (boolean +# value) +#revoke_by_id=true + +# The hash algorithm to use for PKI tokens. This can be set to +# any algorithm that hashlib supports. WARNING: Before +# changing this value, the auth_token middleware must be +# configured with the hash_algorithms, otherwise token +# revocation will not be processed correctly. (string value) +#hash_algorithm=md5 + + +[trust] + +# +# Options defined in keystone +# + +# Delegation and impersonation features can be optionally +# disabled. (boolean value) +#enabled=true + +# Trust backend driver. (string value) +#driver=keystone.trust.backends.sql.Trust + + diff --git a/openstack/usr/share/openstack/keystone/logging.conf b/openstack/usr/share/openstack/keystone/logging.conf new file mode 100644 index 00000000..21d43c8d --- /dev/null +++ b/openstack/usr/share/openstack/keystone/logging.conf @@ -0,0 +1,39 @@ +[loggers] +keys=root + +[formatters] +keys=normal,normal_with_name,debug + +[handlers] +keys=production,file,devel + +[logger_root] +level=WARNING +handlers=file + +[handler_production] +class=handlers.SysLogHandler +level=ERROR +formatter=normal_with_name +args=(('127.0.0.1', handlers.SYSLOG_UDP_PORT), handlers.SysLogHandler.LOG_USER) + +[handler_file] +class=FileHandler +level=DEBUG +formatter=normal_with_name +args=('/var/log/keystone/keystone.log', 'a') + +[handler_devel] +class=StreamHandler +level=NOTSET +formatter=debug +args=(sys.stdout,) + +[formatter_normal] +format=%(asctime)s %(levelname)s %(message)s + +[formatter_normal_with_name] +format=(%(name)s): %(asctime)s %(levelname)s %(message)s + +[formatter_debug] +format=(%(name)s): %(asctime)s %(levelname)s %(module)s %(funcName)s %(message)s diff --git a/openstack/usr/share/openstack/keystone/policy.json b/openstack/usr/share/openstack/keystone/policy.json new file mode 100644 index 00000000..9c7e646e --- /dev/null +++ b/openstack/usr/share/openstack/keystone/policy.json @@ -0,0 +1,144 @@ +{ + "admin_required": "role:admin or is_admin:1", + "service_role": "role:service", + "service_or_admin": "rule:admin_required or rule:service_role", + "owner" : "user_id:%(user_id)s", + "admin_or_owner": "rule:admin_required or rule:owner", + + "default": "rule:admin_required", + + "identity:get_region": "", + "identity:list_regions": "", + "identity:create_region": "rule:admin_required", + "identity:update_region": "rule:admin_required", + "identity:delete_region": "rule:admin_required", + + "identity:get_service": "rule:admin_required", + "identity:list_services": "rule:admin_required", + "identity:create_service": "rule:admin_required", + "identity:update_service": "rule:admin_required", + "identity:delete_service": "rule:admin_required", + + "identity:get_endpoint": "rule:admin_required", + "identity:list_endpoints": "rule:admin_required", + "identity:create_endpoint": "rule:admin_required", + "identity:update_endpoint": "rule:admin_required", + "identity:delete_endpoint": "rule:admin_required", + + "identity:get_domain": "rule:admin_required", + "identity:list_domains": "rule:admin_required", + "identity:create_domain": "rule:admin_required", + "identity:update_domain": "rule:admin_required", + "identity:delete_domain": "rule:admin_required", + + "identity:get_project": "rule:admin_required", + "identity:list_projects": "rule:admin_required", + "identity:list_user_projects": "rule:admin_or_owner", + "identity:create_project": "rule:admin_required", + "identity:update_project": "rule:admin_required", + "identity:delete_project": "rule:admin_required", + + "identity:get_user": "rule:admin_required", + "identity:list_users": "rule:admin_required", + "identity:create_user": "rule:admin_required", + "identity:update_user": "rule:admin_required", + "identity:delete_user": "rule:admin_required", + "identity:change_password": "rule:admin_or_owner", + + "identity:get_group": "rule:admin_required", + "identity:list_groups": "rule:admin_required", + "identity:list_groups_for_user": "rule:admin_or_owner", + "identity:create_group": "rule:admin_required", + "identity:update_group": "rule:admin_required", + "identity:delete_group": "rule:admin_required", + "identity:list_users_in_group": "rule:admin_required", + "identity:remove_user_from_group": "rule:admin_required", + "identity:check_user_in_group": "rule:admin_required", + "identity:add_user_to_group": "rule:admin_required", + + "identity:get_credential": "rule:admin_required", + "identity:list_credentials": "rule:admin_required", + "identity:create_credential": "rule:admin_required", + "identity:update_credential": "rule:admin_required", + "identity:delete_credential": "rule:admin_required", + + "identity:ec2_get_credential": "rule:admin_or_owner", + "identity:ec2_list_credentials": "rule:admin_or_owner", + "identity:ec2_create_credential": "rule:admin_or_owner", + "identity:ec2_delete_credential": "rule:admin_required or (rule:owner and user_id:%(target.credential.user_id)s)", + + "identity:get_role": "rule:admin_required", + "identity:list_roles": "rule:admin_required", + "identity:create_role": "rule:admin_required", + "identity:update_role": "rule:admin_required", + "identity:delete_role": "rule:admin_required", + + "identity:check_grant": "rule:admin_required", + "identity:list_grants": "rule:admin_required", + "identity:create_grant": "rule:admin_required", + "identity:revoke_grant": "rule:admin_required", + + "identity:list_role_assignments": "rule:admin_required", + + "identity:get_policy": "rule:admin_required", + "identity:list_policies": "rule:admin_required", + "identity:create_policy": "rule:admin_required", + "identity:update_policy": "rule:admin_required", + "identity:delete_policy": "rule:admin_required", + + "identity:check_token": "rule:admin_required", + "identity:validate_token": "rule:service_or_admin", + "identity:validate_token_head": "rule:service_or_admin", + "identity:revocation_list": "rule:service_or_admin", + "identity:revoke_token": "rule:admin_or_owner", + + "identity:create_trust": "user_id:%(trust.trustor_user_id)s", + "identity:get_trust": "rule:admin_or_owner", + "identity:list_trusts": "", + "identity:list_roles_for_trust": "", + "identity:check_role_for_trust": "", + "identity:get_role_for_trust": "", + "identity:delete_trust": "", + + "identity:create_consumer": "rule:admin_required", + "identity:get_consumer": "rule:admin_required", + "identity:list_consumers": "rule:admin_required", + "identity:delete_consumer": "rule:admin_required", + "identity:update_consumer": "rule:admin_required", + + "identity:authorize_request_token": "rule:admin_required", + "identity:list_access_token_roles": "rule:admin_required", + "identity:get_access_token_role": "rule:admin_required", + "identity:list_access_tokens": "rule:admin_required", + "identity:get_access_token": "rule:admin_required", + "identity:delete_access_token": "rule:admin_required", + + "identity:list_projects_for_endpoint": "rule:admin_required", + "identity:add_endpoint_to_project": "rule:admin_required", + "identity:check_endpoint_in_project": "rule:admin_required", + "identity:list_endpoints_for_project": "rule:admin_required", + "identity:remove_endpoint_from_project": "rule:admin_required", + + "identity:create_identity_provider": "rule:admin_required", + "identity:list_identity_providers": "rule:admin_required", + "identity:get_identity_providers": "rule:admin_required", + "identity:update_identity_provider": "rule:admin_required", + "identity:delete_identity_provider": "rule:admin_required", + + "identity:create_protocol": "rule:admin_required", + "identity:update_protocol": "rule:admin_required", + "identity:get_protocol": "rule:admin_required", + "identity:list_protocols": "rule:admin_required", + "identity:delete_protocol": "rule:admin_required", + + "identity:create_mapping": "rule:admin_required", + "identity:get_mapping": "rule:admin_required", + "identity:list_mappings": "rule:admin_required", + "identity:delete_mapping": "rule:admin_required", + "identity:update_mapping": "rule:admin_required", + + "identity:list_projects_for_groups": "", + "identity:list_domains_for_groups": "", + + "identity:list_revoke_events": "" +} diff --git a/openstack/usr/share/openstack/modules/README b/openstack/usr/share/openstack/modules/README new file mode 100644 index 00000000..5cabf204 --- /dev/null +++ b/openstack/usr/share/openstack/modules/README @@ -0,0 +1,3 @@ +Ansible modules borrowed from: + +https://github.com/openstack-ansible/openstack-ansible-modules diff --git a/openstack/usr/share/openstack/modules/cinder_manage b/openstack/usr/share/openstack/modules/cinder_manage new file mode 100644 index 00000000..75a0b453 --- /dev/null +++ b/openstack/usr/share/openstack/modules/cinder_manage @@ -0,0 +1,105 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +DOCUMENTATION = ''' +--- +module: cinder_manage +short_description: Initialize OpenStack Block Storage (cinder) database +description: Create the tables for the database backend used by cinder +options: + action: + description: + - action to perform. Currently only dbysnc is supported + required: true + conf: + description: + - path to cinder config file. + required: false + default: /etc/cinder/cinder.conf +requirements: [ cinder ] +author: Lorin Hochstein +''' + +EXAMPLES = ''' +cinder_manage: action=dbsync +''' + +import subprocess + +cinder_found = True +try: + from cinder.db.sqlalchemy import migration + try: + from cinder import flags + FLAGS = flags.FLAGS + except ImportError: + # Starting with icehouse + import cinder.common.config + FLAGS = cinder.common.config.CONF +except ImportError: + cinder_found = False + + +def load_config_file(conf): + FLAGS(args=[], project='cinder', default_config_files=[conf]) + +def will_db_change(): + """ Check if the database version will change after the sync. + + """ + # Load the config file options + current_version = migration.db_version() + repository = migration._find_migrate_repo() + repo_version = repository.latest + return current_version != repo_version + + +def do_dbsync(): + """Do the dbsync. Returns (returncode, stdout, stderr)""" + # We call cinder-manage db_sync on the shell rather than trying to + # do this in Python since we have no guarantees about changes to the + # internals. + args = ['cinder-manage', 'db', 'sync'] + + call = subprocess.Popen(args, shell=False, + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + out, err = call.communicate() + return (call.returncode, out, err) + + +def main(): + + module = AnsibleModule( + argument_spec=dict( + action=dict(required=True), + conf=dict(required=False, default="/etc/cinder/cinder.conf") + ), + supports_check_mode=True + ) + + if not cinder_found: + module.fail_json(msg="cinder package could not be found") + + action = module.params['action'] + conf = module.params['conf'] + + if action not in ['dbsync', 'db_sync']: + module.fail_json(msg="Only supported action is 'dbsync'") + + load_config_file(conf) + + changed = will_db_change() + if module.check_mode: + module.exit_json(changed=changed) + + (res, stdout, stderr) = do_dbsync() + + if res == 0: + module.exit_json(changed=changed, stdout=stdout, stderr=stderr) + else: + module.fail_json(msg="cinder-manage returned non-zero value: %d" % res, + stdout=stdout, stderr=stderr) + +# this is magic, see lib/ansible/module_common.py +#<> +main() diff --git a/openstack/usr/share/openstack/modules/glance b/openstack/usr/share/openstack/modules/glance new file mode 100644 index 00000000..f62942f9 --- /dev/null +++ b/openstack/usr/share/openstack/modules/glance @@ -0,0 +1,176 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +DOCUMENTATION = ''' +--- +module: glance +short_description: Manage OpenStack virtual machine images +description: + - Upload virtual machine images to OpenStack Image Service (glance) +requirements: [ python-glanceclient ] +options: + name: + description: + - name of the image + required: true + format: + description: + - disk format + choices: [ami, ari, aki, vhd, vmdk, raw, qcow2, vdi, iso] + required: true + is_public: + description: + - if true, image is public + choices: [true, false] + aliases: [public] + required: false + default: false + file: + description: + - path to the file that contains the image + required: true + aliases: [path] + auth_url: + description: + - URL to Identity service (keystone) catalog endpoint + required: true + region: + description: + - OpenStack region name + required: false + aliases: [region_name] + username: + description: + - user name to authenticate against Identity service + aliases: [user, user_name, login_user] + password: + description: + - password to authenticate against Identity service + aliases: [pass, login_password] + tenant_name: + description: + - name of the tenant + endpoint_type: + description: + - endpoint URL type + choices: [publicURL, internalURL] + required: false + default: publicURL + +examples: + - code: 'glance: name=cirros file=/tmp/cirros.img format=qcow2 is_public=true auth_url=http://192.168.206.130:5000/v2.0/ username=admin tenant_name=demo password=secrete region=RegionOne endpoint_type=publicURL ' +''' + + +try: + from glanceclient import Client + from keystoneclient.v2_0 import client as ksclient +except ImportError: + glanceclient_found = False +else: + glanceclient_found = True + + +def get_token_and_endpoint(auth_url, username, password, tenant_name, + region_name, endpoint_type): + + keystone = ksclient.Client(username=username, + password=password, + tenant_name=tenant_name, + auth_url=auth_url, + region_name=region_name) + glance_endpoint = keystone.service_catalog.url_for( + service_type="image", + endpoint_type=endpoint_type) + return (keystone.auth_token, glance_endpoint) + + +def authenticate(auth_url, username, password, tenant_name, region, + endpoint_type, version='1'): + """Return a keystone client object""" + + (token, endpoint) = get_token_and_endpoint(auth_url, username, password, + tenant_name, region, + endpoint_type) + + return Client(version, endpoint=endpoint, token=token) + + +def get_images(glance, name): + """ Retrieve all images with a certain name """ + images = [x for x in glance.images.list() if x.name == name] + return images + + +def create_image(glance, name, path, disk_format, is_public, check_mode): + """ Create a new image from a file on the path. + + Return a pair. First element indicates whether a change occurred, + second one is the ID of the iamge """ + + # If the image(s) already exists, we're done + images = get_images(glance, name) + if len(images) > 0: + return (False, images[0].id) + + if check_mode: + return (True, None) + + image = glance.images.create(name=name, disk_format=disk_format, + container_format='bare', + is_public=is_public) + image.update(data=open(path, 'rb')) + return (True, image.id) + + +def main(): + + module = AnsibleModule( + argument_spec=dict( + name=dict(required=True), + file=dict(required=True, aliases=['path']), + auth_url=dict(required=True), + region=dict(required=False, aliases=['region_name']), + username=dict(required=True, aliases=['user', + 'user_name', + 'login_user']), + password=dict(required=True, aliases=['pass', 'login_password']), + tenant_name=dict(required=True, aliases=['tenant']), + disk_format=dict(required=True, + choices=['ami', 'ari', 'aki', 'vhd', 'vmdk', 'raw', + 'qcow2', 'vdi', 'iso'], + aliases=['disk-format', 'format']), + is_public=dict(required=False, + default=False, + aliases=['public']), + endpoint_type=dict(required=False, + choices=['publicURL', 'internalURL'], + default='publicURL') + ), + supports_check_mode=True + ) + + name = module.params['name'] + path = module.params['file'] + auth_url = module.params['auth_url'] + region = module.params['region'] + username = module.params['username'] + password = module.params['password'] + tenant_name = module.params['tenant_name'] + disk_format = module.params['disk_format'] + is_public = module.params['is_public'] + endpoint_type = module.params['endpoint_type'] + check_mode = module.check_mode + + glance = authenticate(auth_url, username, password, tenant_name, region, + endpoint_type) + + (changed, id) = create_image(glance, name, path, disk_format, is_public, + check_mode) + + module.exit_json(changed=changed, name=name, id=id) + +# this is magic, see lib/ansible/module_common.py +#<> +if __name__ == '__main__': + main() diff --git a/openstack/usr/share/openstack/modules/glance_manage b/openstack/usr/share/openstack/modules/glance_manage new file mode 100644 index 00000000..b89e7bb0 --- /dev/null +++ b/openstack/usr/share/openstack/modules/glance_manage @@ -0,0 +1,158 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +DOCUMENTATION = ''' +--- +module: glance_manage +short_description: Initialize OpenStack Image (glance) database +description: Create the tables for the database backend used by glance +options: + action: + description: + - action to perform. Currently only dbsync is supported. + required: true + conf: + description: + - path to glance-registry config file. + required: false + default: /etc/glance/glance-registry.conf +requirements: [ glance ] +author: Lorin Hochstein +''' + +EXAMPLES = ''' +glance_manage: action=dbsync +''' + +import os +import subprocess +import sys + +try: + import glance + import sqlalchemy +except ImportError: + print("failed=True msg='glance is not installed'") + sys.exit(1) + +from glance.version import version_info +# this is necessary starting from havana release due to bug 885529 +# https://bugs.launchpad.net/glance/+bug/885529 +from glance.openstack.common import gettextutils +gettextutils.install('glance') +import glance.db.sqlalchemy.api + +try: + glance_version = version_info.version_string() +except AttributeError: + glance_version = version_info.version + +if glance_version.startswith('2014.2'): + from oslo.config.cfg import CONF + from oslo.db.sqlalchemy import migration + from migrate.versioning import api as versioning_api + from glance.db import migration as db_migration + from glance.db.sqlalchemy import api as db_api +elif glance_version.startswith('2014.1'): + from oslo.config.cfg import CONF + from glance.openstack.common.db.sqlalchemy import migration + from migrate.versioning import api as versioning_api +else: + from glance.db.sqlalchemy import migration + from glance.common.exception import DatabaseMigrationError + from migrate.versioning import api as versioning_api + CONF = migration.CONF + +def is_under_version_control(conf): + """ Return true if the database is under version control""" + CONF(project='glance', default_config_files=[conf]) + try: + migration.db_version() + except DatabaseMigrationError: + return False + # db_version() will fail with TypeError on icehouse. Icehouse uses db + # migration so we're good. + finally: + return True + + +def will_db_change(conf): + """ Check if the database version will change after the sync """ + # Load the config file options + if not is_under_version_control(conf): + return True + if glance_version.startswith('2014.2'): + engine = db_api.get_engine() + repo_path = db_migration.MIGRATE_REPO_PATH + current_version = migration.db_version(db_api.get_engine(), + repo_path, + db_migration.INIT_VERSION) + elif glance_version.startswith('2014.1'): + repo_path = os.path.join(os.path.dirname(glance.__file__), + 'db', 'sqlalchemy', 'migrate_repo') + engine = sqlalchemy.create_engine(CONF.database.connection) + current_version = migration.db_version(engine, repo_path, 0) + else: + repo_path = migration.get_migrate_repo_path() + current_version = migration.db_version() + + repo_version = versioning_api.repository.Repository(repo_path).latest + return current_version != repo_version + + +def put_under_version_control(): + """ Create the initial sqlalchemy migrate database tables. """ + args = ['glance-manage', 'version_control', '0'] + + call = subprocess.Popen(args, shell=False, + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + out, err = call.communicate() + return (call.returncode, out, err) + + +def do_dbsync(): + """ Do a database migration """ + args = ['glance-manage', 'db_sync'] + + call = subprocess.Popen(args, shell=False, + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + out, err = call.communicate() + return (call.returncode, out, err) + + +def main(): + + module = AnsibleModule( + argument_spec=dict( + action=dict(required=True), + conf=dict(required=False, + default="/etc/glance/glance-registry.conf") + ), + supports_check_mode=True + ) + + action = module.params['action'] + if action not in ['dbsync', 'db_sync']: + module.fail_json(msg="Only supported action is 'dbsync'") + + conf = module.params['conf'] + + changed = will_db_change(conf) + if module.check_mode: + module.exit_json(changed=changed) + + if not is_under_version_control(conf): + (res, stdout, stderr) = put_under_version_control() + if res != 0: + msg = "failed to put glance db under version control" + module.fail_json(msg=msg, stdout=stdout, stderr=stderr) + + (res, stdout, stderr) = do_dbsync() + if res != 0: + msg = "failed to synchronize glance db with repository" + module.fail_json(msg=msg, stdout=stdout, stderr=stderr) + + module.exit_json(changed=changed) + +#<> +main() diff --git a/openstack/usr/share/openstack/modules/heat_manage b/openstack/usr/share/openstack/modules/heat_manage new file mode 100644 index 00000000..e24abbda --- /dev/null +++ b/openstack/usr/share/openstack/modules/heat_manage @@ -0,0 +1,105 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +DOCUMENTATION = ''' +--- +module: heat_manage +short_description: Initialize Orchestration (heat) database +description: Create the tables for the database backend used by heat +options: + action: + description: + - action to perform. Currently only dbysnc is supported + required: true + conf: + description: + - path to keystone config file. + required: false + default: /etc/heat/heat.conf +requirements: [ python-heatclient ] +author: Gauvain Pocentek +''' + +EXAMPLES = ''' +heat_manage: action=dbsync +''' + +import subprocess + +try: + import heat + from heat.db.sqlalchemy import migration + from migrate.versioning import api as versioning_api + from heat.db import api + from oslo.config import cfg +except ImportError: + heat_found = False +else: + heat_found = True + + +def will_db_change(conf): + """ Check if the database version will change after the sync. + + conf is the path to the heat config file + + """ + # Load the config file options + cfg.CONF(project='heat', default_config_files=[conf]) + try: + current_version = migration.db_version() + except TypeError: # juno + current_version = api.db_version(api.get_engine()) + + repo_path = os.path.join(os.path.dirname(heat.__file__), + 'db', 'sqlalchemy', 'migrate_repo') + repo_version = versioning_api.repository.Repository(repo_path).latest + return current_version != repo_version + + +def do_dbsync(): + """Do the dbsync. Returns (returncode, stdout, stderr)""" + # We call heat-manage db_sync on the shell rather than trying to + # do this in Python since we have no guarantees about changes to the + # internals. + args = ['heat-manage', 'db_sync'] + + call = subprocess.Popen(args, shell=False, + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + out, err = call.communicate() + return (call.returncode, out, err) + + +def main(): + + module = AnsibleModule( + argument_spec=dict( + action=dict(required=True), + conf=dict(required=False, default="/etc/heat/heat.conf") + ), + supports_check_mode=True + ) + + if not heat_found: + module.fail_json(msg="python-heatclient could not be found") + + action = module.params['action'] + conf = module.params['conf'] + if action not in ['dbsync', 'db_sync']: + module.fail_json(msg="Only supported action is 'dbsync'") + + changed = will_db_change(conf) + if module.check_mode: + module.exit_json(changed=changed) + + (res, stdout, stderr) = do_dbsync() + + if res == 0: + module.exit_json(changed=changed, stdout=stdout, stderr=stderr) + else: + module.fail_json(msg="heat-manage returned non-zero value: %d" % res, + stdout=stdout, stderr=stderr) + + +from ansible.module_utils.basic import * +main() diff --git a/openstack/usr/share/openstack/modules/keystone_manage b/openstack/usr/share/openstack/modules/keystone_manage new file mode 100644 index 00000000..780f7c9a --- /dev/null +++ b/openstack/usr/share/openstack/modules/keystone_manage @@ -0,0 +1,123 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +DOCUMENTATION = ''' +--- +module: keystone_manage +short_description: Initialize OpenStack Identity (keystone) database +description: Create the tables for the database backend used by keystone +options: + action: + description: + - action to perform. Currently only dbysnc is supported + required: true + conf: + description: + - path to keystone config file. + required: false + default: /etc/keystone/keystone.conf +requirements: [ keystone ] +author: Lorin Hochstein +''' + +EXAMPLES = ''' +keystone_manage: action=dbsync +''' + +import subprocess + +try: + # this is necessary starting from havana release due to bug 885529 + # https://bugs.launchpad.net/glance/+bug/885529 + from keystone.openstack.common import gettextutils + gettextutils.install('keystone') +except AttributeError: + # this is not havana + pass + +try: + from keystone.common import sql + from migrate.versioning import api as versioning_api +except ImportError: + keystone_found = False +else: + keystone_found = True + +try: + # for icehouse + from keystone.common.sql import migration_helpers as migration +except ImportError: + pass + + +def will_db_change(conf): + """ Check if the database version will change after the sync. + + conf is the path to the keystone config file + + """ + # Load the config file options + try: + # before icehouse + sql.migration.CONF(project='keystone', default_config_files=[conf]) + current_version = sql.migration.db_version() + except AttributeError: + # starting with icehouse + sql.core.CONF(project='keystone', default_config_files=[conf]) + current_version = migration.get_db_version() + + # in havana the method _find_migrate_repo has been renamed to find_migrate_repo + try: + repo_path = migration.find_migrate_repo() + except AttributeError: + repo_path = migration._find_migrate_repo() + repo_version = versioning_api.repository.Repository(repo_path).latest + return current_version != repo_version + + +def do_dbsync(): + """Do the dbsync. Returns (returncode, stdout, stderr)""" + # We call keystone-manage db_sync on the shell rather than trying to + # do this in Python since we have no guarantees about changes to the + # internals. + args = ['keystone-manage', 'db_sync'] + + call = subprocess.Popen(args, shell=False, + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + out, err = call.communicate() + return (call.returncode, out, err) + + +def main(): + + module = AnsibleModule( + argument_spec=dict( + action=dict(required=True), + conf=dict(required=False, default="/etc/keystone/keystone.conf") + ), + supports_check_mode=True + ) + + if not keystone_found: + module.fail_json(msg="keystone package could not be found") + + action = module.params['action'] + conf = module.params['conf'] + if action not in ['dbsync', 'db_sync']: + module.fail_json(msg="Only supported action is 'dbsync'") + + changed = will_db_change(conf) + if module.check_mode: + module.exit_json(changed=changed) + + (res, stdout, stderr) = do_dbsync() + + if res == 0: + module.exit_json(changed=changed, stdout=stdout, stderr=stderr) + else: + module.fail_json(msg="keystone-manage returned non-zero value: %d" % res, + stdout=stdout, stderr=stderr) + +# this is magic, see lib/ansible/module_common.py +#<> +main() diff --git a/openstack/usr/share/openstack/modules/keystone_service b/openstack/usr/share/openstack/modules/keystone_service new file mode 100644 index 00000000..aa4302d1 --- /dev/null +++ b/openstack/usr/share/openstack/modules/keystone_service @@ -0,0 +1,309 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +DOCUMENTATION = ''' +--- +module: keystone_service +short_description: Manage OpenStack Identity (keystone) service endpoints +options: + name: + description: + - name of service (e.g., keystone) + required: yes + type: + description: + - type of service (e.g., identity) + required: yes + description: + description: + - description of service (e.g., Identity Service) + required: yes + public_url: + description: + - public url of service. + - 'Alias: I(url)' + - 'Alias: I(publicurl)' + required: yes + internal_url: + description: + - internal url of service. + - 'Alias: I(internalurl)' + required: no + default: value of public_url + admin_url: + description: + - admin url of service. + - 'Alias: I(adminurl)' + required: no + default: value of public_url + insecure: + description: + - allow use of self-signed SSL certificates + required: no + choices: [ "yes", "no" ] + region: + description: + - region of service + required: yes + state: + description: + - Indicate desired state of the resource + choices: ['present', 'absent'] + default: present + + + +requirements: [ python-keystoneclient ] +author: Lorin Hochstein +''' + +EXAMPLES = ''' +examples: +keystone_service: > + name=keystone + type=identity + description="Keystone Identity Service" + publicurl=http://192.168.206.130:5000/v2.0 + internalurl=http://192.168.206.130:5000/v2.0 + adminurl=http://192.168.206.130:35357/v2.0 + +keystone_service: > + name=glance + type=image + description="Glance Identity Service" + url=http://192.168.206.130:9292 + +''' + +try: + from keystoneclient.v2_0 import client +except ImportError: + keystoneclient_found = False +else: + keystoneclient_found = True + +import traceback + + +def authenticate(endpoint, token, login_user, login_password, tenant_name, + insecure): + """Return a keystone client object""" + + if token: + return client.Client(endpoint=endpoint, token=token, insecure=insecure) + else: + return client.Client(auth_url=endpoint, username=login_user, + password=login_password, tenant_name=tenant_name, + insecure=insecure) + +def get_service(keystone, name): + """ Retrieve a service by name """ + services = [x for x in keystone.services.list() if x.name == name] + count = len(services) + if count == 0: + raise KeyError("No keystone services with name %s" % name) + elif count > 1: + raise ValueError("%d services with name %s" % (count, name)) + else: + return services[0] + + +def get_endpoint(keystone, name): + """ Retrieve a service endpoint by name """ + service = get_service(keystone, name) + endpoints = [x for x in keystone.endpoints.list() + if x.service_id == service.id] + count = len(endpoints) + if count == 0: + raise KeyError("No keystone endpoints with service name %s" % name) + elif count > 1: + raise ValueError("%d endpoints with service name %s" % (count, name)) + else: + return endpoints[0] + + +def ensure_service_present(keystone, name, service_type, description, + check_mode): + """ Ensure the service is present and has the right values + + Returns a pair, where the first element is a boolean that indicates + a state change, and the second element is the service uuid, or None + if running in check mode""" + service = None + try: + service = get_service(keystone, name) + except: + # Service doesn't exist yet, we'll need to create one + pass + else: + # See if it matches exactly + if service.name == name and \ + service.type == service_type and \ + service.description == description: + + # Same, no changes needed + return (False, service.id) + + # At this point, we know we will need to make a change + if check_mode: + return (True, None) + + if service is None: + service = keystone.services.create(name=name, + service_type=service_type, + description=description) + return (True, service.id) + else: + msg = "keystone v2 API doesn't support updating services" + raise ValueError(msg) + + +def ensure_endpoint_present(keystone, name, public_url, internal_url, + admin_url, region, check_mode): + """ Ensure the service endpoint is present and have the right values + + Assumes the service object has already been created at this point""" + + service = get_service(keystone, name) + endpoint = None + try: + endpoint = get_endpoint(keystone, name) + except: + # Endpoint doesn't exist yet, we'll need to create one + pass + else: + # See if it matches + if endpoint.publicurl == public_url and \ + endpoint.adminurl == admin_url and \ + endpoint.internalurl == internal_url and \ + endpoint.region == region: + + # Same, no changes needed + return (False, endpoint.id) + + # At this point, we know we will need to make a change + if check_mode: + return (True, None) + + if endpoint is None: + endpoint = keystone.endpoints.create(region=region, + service_id=service.id, + publicurl=public_url, + adminurl=admin_url, + internalurl=internal_url) + return (True, endpoint.id) + else: + msg = "keystone v2 API doesn't support updating endpoints" + raise ValueError(msg) + + +def ensure_service_absent(keystone, name, check_mode): + """ Ensure the service is absent""" + + raise NotImplementedError() + +def ensure_endpoint_absent(keystone, name, check_mode): + """ Ensure the service endpoint """ + raise NotImplementedError() + + +def dispatch(keystone, name, service_type, description, public_url, + internal_url, admin_url, region, state, check_mode): + + if state == 'present': + (service_changed, service_id) = ensure_service_present(keystone, + name, + service_type, + description, + check_mode) + + (endpoint_changed, endpoint_id) = ensure_endpoint_present( + keystone, + name, + public_url, + internal_url, + admin_url, + region, + check_mode) + return dict(changed=service_changed or endpoint_changed, + service_id=service_id, + endpoint_id=endpoint_id) + elif state == 'absent': + endpoint_changed = ensure_endpoint_absent(keystone, name, check_mode) + service_changed = ensure_service_absent(keystone, name, check_mode) + return dict(changed=service_changed or endpoint_changed) + else: + raise ValueError("Code should never reach here") + + + +def main(): + + module = AnsibleModule( + argument_spec=dict( + name=dict(required=True), + type=dict(required=True), + description=dict(required=False), + public_url=dict(required=True, aliases=['url', 'publicurl']), + internal_url=dict(required=False, aliases=['internalurl']), + admin_url=dict(required=False, aliases=['adminurl']), + region=dict(required=True), + state=dict(default='present', choices=['present', 'absent']), + endpoint=dict(required=False, + default="http://127.0.0.1:35357/v2.0", + aliases=['auth_url']), + token=dict(required=False), + insecure=dict(required=False, default=False, choices=BOOLEANS), + + login_user=dict(required=False), + login_password=dict(required=False), + tenant_name=dict(required=False, aliases=['tenant']) + ), + supports_check_mode=True, + mutually_exclusive=[['token', 'login_user'], + ['token', 'login_password'], + ['token', 'tenant_name']] + ) + + endpoint = module.params['endpoint'] + token = module.params['token'] + login_user = module.params['login_user'] + login_password = module.params['login_password'] + tenant_name = module.params['tenant_name'] + insecure = module.boolean(module.params['insecure']) + name = module.params['name'] + service_type = module.params['type'] + description = module.params['description'] + public_url = module.params['public_url'] + internal_url = module.params['internal_url'] + if internal_url is None: + internal_url = public_url + admin_url = module.params['admin_url'] + if admin_url is None: + admin_url = public_url + region = module.params['region'] + state = module.params['state'] + + keystone = authenticate(endpoint, token, login_user, login_password, + tenant_name, insecure) + check_mode = module.check_mode + + try: + d = dispatch(keystone, name, service_type, description, + public_url, internal_url, admin_url, region, state, + check_mode) + except Exception: + if check_mode: + # If we have a failure in check mode + module.exit_json(changed=True, + msg="exception: %s" % traceback.format_exc()) + else: + module.fail_json(msg=traceback.format_exc()) + else: + module.exit_json(**d) + + +# this is magic, see lib/ansible/module_common.py +#<> +if __name__ == '__main__': + main() diff --git a/openstack/usr/share/openstack/modules/neutron_floating_ip b/openstack/usr/share/openstack/modules/neutron_floating_ip new file mode 100644 index 00000000..4c141025 --- /dev/null +++ b/openstack/usr/share/openstack/modules/neutron_floating_ip @@ -0,0 +1,274 @@ +#!/usr/bin/python +#coding: utf-8 -*- + +# (c) 2013, Benno Joy +# +# This module is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This software is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this software. If not, see . + +try: + from novaclient.v1_1 import client as nova_client + from neutronclient.neutron import client + from keystoneclient.v2_0 import client as ksclient + import time +except ImportError: + print("failed=True msg='glanceclient,keystoneclient and neutronclient client are required'") + +DOCUMENTATION = ''' +--- +module: neutron_floating_ip +version_added: "1.2" +short_description: Add/Remove floating IP from an instance +description: + - Add or Remove a floating IP to an instance +options: + login_username: + description: + - login username to authenticate to keystone + required: true + default: admin + login_password: + description: + - Password of login user + required: true + default: 'yes' + login_tenant_name: + description: + - The tenant name of the login user + required: true + default: 'yes' + auth_url: + description: + - The keystone url for authentication + required: false + default: 'http://127.0.0.1:35357/v2.0/' + region_name: + description: + - Name of the region + required: false + default: None + state: + description: + - Indicate desired state of the resource + choices: ['present', 'absent'] + default: present + network_name: + description: + - Name of the network from which IP has to be assigned to VM. Please make sure the network is an external network + required: true + default: None + port_network_name: + description: + - Name of the network where the VM port lives. Useful when the VM has more than one port + required: false + default: None + instance_name: + description: + - The name of the instance to which the IP address should be assigned + required: true + default: None +requirements: ["novaclient", "neutronclient", "keystoneclient"] +''' + +EXAMPLES = ''' +# Assign a floating ip to the instance from an external network +- neutron_floating_ip: state=present login_username=admin login_password=admin + login_tenant_name=admin network_name=external_network + instance_name=vm1 +''' + +def _get_ksclient(module, kwargs): + try: + kclient = ksclient.Client(username=kwargs.get('login_username'), + password=kwargs.get('login_password'), + tenant_name=kwargs.get('login_tenant_name'), + auth_url=kwargs.get('auth_url')) + except Exception as e: + module.fail_json(msg = "Error authenticating to the keystone: %s " % e.message) + global _os_keystone + _os_keystone = kclient + return kclient + + +def _get_endpoint(module, ksclient): + try: + endpoint = ksclient.service_catalog.url_for(service_type='network', endpoint_type='publicURL') + except Exception as e: + module.fail_json(msg = "Error getting endpoint for glance: %s" % e.message) + return endpoint + +def _get_neutron_client(module, kwargs): + _ksclient = _get_ksclient(module, kwargs) + token = _ksclient.auth_token + endpoint = _get_endpoint(module, _ksclient) + kwargs = { + 'token': token, + 'endpoint_url': endpoint + } + try: + neutron = client.Client('2.0', **kwargs) + except Exception as e: + module.fail_json(msg = "Error in connecting to neutron: %s " % e.message) + return neutron + +def _get_server_state(module, nova): + server_info = None + server = None + try: + for server in nova.servers.list(): + if server: + info = server._info + if info['name'] == module.params['instance_name']: + if info['status'] != 'ACTIVE' and module.params['state'] == 'present': + module.fail_json( msg="The VM is available but not Active. state:" + info['status']) + server_info = info + break + except Exception as e: + module.fail_json(msg = "Error in getting the server list: %s" % e.message) + return server_info, server + +def _get_port_info(neutron, module, instance_id): + if module.params['port_network_name'] is None: + kwargs = { + 'device_id': instance_id + } + else: + network_id = _get_net_id(neutron, module.params['port_network_name']) + if not network_id: + module.fail_json(msg = "cannot find the network specified, please check") + + kwargs = { + 'device_id': instance_id, + 'network_id': network_id + } + try: + ports = neutron.list_ports(**kwargs) + except Exception as e: + module.fail_json( msg = "Error in listing ports: %s" % e.message) + if not ports['ports']: + return None, None + return ports['ports'][0]['fixed_ips'][0]['ip_address'], ports['ports'][0]['id'] + +def _get_floating_ip(module, neutron, fixed_ip_address): + kwargs = { + 'fixed_ip_address': fixed_ip_address + } + try: + ips = neutron.list_floatingips(**kwargs) + except Exception as e: + module.fail_json(msg = "error in fetching the floatingips's %s" % e.message) + if not ips['floatingips']: + return None, None + return ips['floatingips'][0]['id'], ips['floatingips'][0]['floating_ip_address'] + +def _assign_floating_ip(neutron, module, port_id, net_id): + kwargs = { + 'floating_network_id': net_id + } + try: + ips = neutron.list_floatingips(**kwargs) + except Exception as e: + module.fail_json(msg = "error in fetching the floatingips's %s" % e.message) + + fip = next((fip for fip in ips['floatingips'] if fip['port_id'] is None), None) + + if fip is None: + _create_floating_ip(neutron, module, port_id, net_id) + else: + _update_floating_ip(neutron, module, port_id, fip['id']) + +def _create_floating_ip(neutron, module, port_id, net_id): + kwargs = { + 'port_id': port_id, + 'floating_network_id': net_id + } + try: + result = neutron.create_floatingip({'floatingip': kwargs}) + except Exception as e: + module.fail_json(msg="There was an error in updating the floating ip address: %s" % e.message) + module.exit_json(changed=True, result=result, public_ip=result['floatingip']['floating_ip_address']) + +def _get_net_id(neutron, network_name): + kwargs = { + 'name': network_name, + } + try: + networks = neutron.list_networks(**kwargs) + except Exception as e: + module.fail_json("Error in listing neutron networks: %s" % e.message) + if not networks['networks']: + return None + return networks['networks'][0]['id'] + +def _update_floating_ip(neutron, module, port_id, floating_ip_id): + kwargs = { + 'port_id': port_id + } + try: + result = neutron.update_floatingip(floating_ip_id, {'floatingip': kwargs}) + except Exception as e: + module.fail_json(msg="There was an error in updating the floating ip address: %s" % e.message) + module.exit_json(changed=True, result=result, public_ip=result['floatingip']['floating_ip_address']) + + +def main(): + + module = AnsibleModule( + argument_spec = dict( + login_username = dict(default='admin'), + login_password = dict(required=True), + login_tenant_name = dict(required='True'), + auth_url = dict(default='http://127.0.0.1:35357/v2.0/'), + region_name = dict(default=None), + network_name = dict(required=True), + instance_name = dict(required=True), + port_network_name = dict(default=None), + state = dict(default='present', choices=['absent', 'present']) + ), + ) + + try: + nova = nova_client.Client(module.params['login_username'], module.params['login_password'], + module.params['login_tenant_name'], module.params['auth_url'], service_type='compute') + neutron = _get_neutron_client(module, module.params) + except Exception as e: + module.fail_json(msg="Error in authenticating to nova: %s" % e.message) + + server_info, server_obj = _get_server_state(module, nova) + if not server_info: + module.fail_json(msg="The instance name provided cannot be found") + + fixed_ip, port_id = _get_port_info(neutron, module, server_info['id']) + if not port_id: + module.fail_json(msg="Cannot find a port for this instance, maybe fixed ip is not assigned") + + floating_id, floating_ip = _get_floating_ip(module, neutron, fixed_ip) + + if module.params['state'] == 'present': + if floating_ip: + module.exit_json(changed = False, public_ip=floating_ip) + net_id = _get_net_id(neutron, module.params['network_name']) + if not net_id: + module.fail_json(msg = "cannot find the network specified, please check") + _assign_floating_ip(neutron, module, port_id, net_id) + + if module.params['state'] == 'absent': + if floating_ip: + _update_floating_ip(neutron, module, None, floating_id) + module.exit_json(changed=False) + +# this is magic, see lib/ansible/module.params['common.py +from ansible.module_utils.basic import * +main() + + diff --git a/openstack/usr/share/openstack/modules/neutron_network b/openstack/usr/share/openstack/modules/neutron_network new file mode 100644 index 00000000..6dee0450 --- /dev/null +++ b/openstack/usr/share/openstack/modules/neutron_network @@ -0,0 +1,282 @@ +#!/usr/bin/python +#coding: utf-8 -*- + +# (c) 2013, Benno Joy +# +# This module is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This software is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this software. If not, see . + +try: + from neutronclient.neutron import client + from keystoneclient.v2_0 import client as ksclient +except ImportError: + print("failed=True msg='neutronclient and keystone client are required'") + +DOCUMENTATION = ''' +--- +module: neutron_network +version_added: "1.4" +short_description: Creates/Removes networks from OpenStack +description: + - Add or Remove network from OpenStack. +options: + login_username: + description: + - login username to authenticate to keystone + required: true + default: admin + login_password: + description: + - Password of login user + required: true + default: 'yes' + login_tenant_name: + description: + - The tenant name of the login user + required: true + default: 'yes' + tenant_name: + description: + - The name of the tenant for whom the network is created + required: false + default: None + auth_url: + description: + - The keystone url for authentication + required: false + default: 'http://127.0.0.1:35357/v2.0/' + region_name: + description: + - Name of the region + required: false + default: None + state: + description: + - Indicate desired state of the resource + choices: ['present', 'absent'] + default: present + name: + description: + - Name to be assigned to the nework + required: true + default: None + provider_network_type: + description: + - The type of the network to be created, gre, vxlan, vlan, local. Available types depend on the plugin. The Neutron service decides if not specified. + required: false + default: None + provider_physical_network: + description: + - The physical network which would realize the virtual network for flat and vlan networks. + required: false + default: None + provider_segmentation_id: + description: + - The id that has to be assigned to the network, in case of vlan networks that would be vlan id, for gre the tunnel id and for vxlan the VNI. + required: false + default: None + router_external: + description: + - If 'yes', specifies that the virtual network is a external network (public). + required: false + default: false + shared: + description: + - Whether this network is shared or not + required: false + default: false + admin_state_up: + description: + - Whether the state should be marked as up or down + required: false + default: true +requirements: ["neutronclient", "keystoneclient"] + +''' + +EXAMPLES = ''' +# Create a GRE backed Neutron network with tunnel id 1 for tenant1 +- neutron_network: name=t1network tenant_name=tenant1 state=present + provider_network_type=gre provider_segmentation_id=1 + login_username=admin login_password=admin login_tenant_name=admin + +# Create an external network +- neutron_network: name=external_network state=present + provider_network_type=local router_external=yes + login_username=admin login_password=admin login_tenant_name=admin +''' + +_os_keystone = None +_os_tenant_id = None + +def _get_ksclient(module, kwargs): + try: + kclient = ksclient.Client(username=kwargs.get('login_username'), + password=kwargs.get('login_password'), + tenant_name=kwargs.get('login_tenant_name'), + auth_url=kwargs.get('auth_url')) + except Exception as e: + module.fail_json(msg = "Error authenticating to the keystone: %s" %e.message) + global _os_keystone + _os_keystone = kclient + return kclient + + +def _get_endpoint(module, ksclient): + try: + endpoint = ksclient.service_catalog.url_for(service_type='network', endpoint_type='publicURL') + except Exception as e: + module.fail_json(msg = "Error getting endpoint for Neutron: %s " %e.message) + return endpoint + +def _get_neutron_client(module, kwargs): + _ksclient = _get_ksclient(module, kwargs) + token = _ksclient.auth_token + endpoint = _get_endpoint(module, _ksclient) + kwargs = { + 'token': token, + 'endpoint_url': endpoint + } + try: + neutron = client.Client('2.0', **kwargs) + except Exception as e: + module.fail_json(msg = " Error in connecting to Neutron: %s " %e.message) + return neutron + +def _set_tenant_id(module): + global _os_tenant_id + if not module.params['tenant_name']: + tenant_name = module.params['login_tenant_name'] + else: + tenant_name = module.params['tenant_name'] + + for tenant in _os_keystone.tenants.list(): + if tenant.name == tenant_name: + _os_tenant_id = tenant.id + break + if not _os_tenant_id: + module.fail_json(msg = "The tenant id cannot be found, please check the paramters") + + +def _get_net_id(neutron, module): + kwargs = { + 'tenant_id': _os_tenant_id, + 'name': module.params['name'], + } + try: + networks = neutron.list_networks(**kwargs) + except Exception as e: + module.fail_json(msg = "Error in listing Neutron networks: %s" % e.message) + if not networks['networks']: + return None + return networks['networks'][0]['id'] + +def _create_network(module, neutron): + + neutron.format = 'json' + + network = { + 'name': module.params.get('name'), + 'tenant_id': _os_tenant_id, + 'provider:network_type': module.params.get('provider_network_type'), + 'provider:physical_network': module.params.get('provider_physical_network'), + 'provider:segmentation_id': module.params.get('provider_segmentation_id'), + 'router:external': module.params.get('router_external'), + 'shared': module.params.get('shared'), + 'admin_state_up': module.params.get('admin_state_up'), + } + + if module.params['provider_network_type'] == 'local': + network.pop('provider:physical_network', None) + network.pop('provider:segmentation_id', None) + + if module.params['provider_network_type'] == 'flat': + network.pop('provider:segmentation_id', None) + + if module.params['provider_network_type'] == 'gre': + network.pop('provider:physical_network', None) + + if module.params['provider_network_type'] == 'vxlan': + network.pop('provider:physical_network', None) + + if module.params['provider_network_type'] is None: + network.pop('provider:network_type', None) + network.pop('provider:physical_network', None) + network.pop('provider:segmentation_id', None) + + try: + net = neutron.create_network({'network':network}) + except Exception as e: + module.fail_json(msg = "Error in creating network: %s" % e.message) + return net['network']['id'] + +def _delete_network(module, net_id, neutron): + + try: + id = neutron.delete_network(net_id) + except Exception as e: + module.fail_json(msg = "Error in deleting the network: %s" % e.message) + return True + +def main(): + + module = AnsibleModule( + argument_spec = dict( + login_username = dict(default='admin'), + login_password = dict(required=True), + login_tenant_name = dict(required='True'), + auth_url = dict(default='http://127.0.0.1:35357/v2.0/'), + region_name = dict(default=None), + name = dict(required=True), + tenant_name = dict(default=None), + provider_network_type = dict(default=None, choices=['local', 'vlan', 'flat', 'gre', 'vxlan']), + provider_physical_network = dict(default=None), + provider_segmentation_id = dict(default=None), + router_external = dict(default=False, type='bool'), + shared = dict(default=False, type='bool'), + admin_state_up = dict(default=True, type='bool'), + state = dict(default='present', choices=['absent', 'present']) + ), + ) + + if module.params['provider_network_type'] in ['vlan' , 'flat']: + if not module.params['provider_physical_network']: + module.fail_json(msg = " for vlan and flat networks, variable provider_physical_network should be set.") + + if module.params['provider_network_type'] in ['vlan', 'gre', 'vxlan']: + if not module.params['provider_segmentation_id']: + module.fail_json(msg = " for vlan, gre & vxlan networks, variable provider_segmentation_id should be set.") + + neutron = _get_neutron_client(module, module.params) + + _set_tenant_id(module) + + if module.params['state'] == 'present': + network_id = _get_net_id(neutron, module) + if not network_id: + network_id = _create_network(module, neutron) + module.exit_json(changed = True, result = "Created", id = network_id) + else: + module.exit_json(changed = False, result = "Success", id = network_id) + + if module.params['state'] == 'absent': + network_id = _get_net_id(neutron, module) + if not network_id: + module.exit_json(changed = False, result = "Success") + else: + _delete_network(module, network_id, neutron) + module.exit_json(changed = True, result = "Deleted") + +# this is magic, see lib/ansible/module.params['common.py +from ansible.module_utils.basic import * +main() diff --git a/openstack/usr/share/openstack/modules/neutron_router b/openstack/usr/share/openstack/modules/neutron_router new file mode 100644 index 00000000..56d384d0 --- /dev/null +++ b/openstack/usr/share/openstack/modules/neutron_router @@ -0,0 +1,210 @@ +#!/usr/bin/python +#coding: utf-8 -*- + +# (c) 2013, Benno Joy +# +# This module is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This software is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this software. If not, see . + +try: + from neutronclient.neutron import client + from keystoneclient.v2_0 import client as ksclient +except ImportError: + print("failed=True msg='neutronclient and keystone client are required'") + +DOCUMENTATION = ''' +--- +module: neutron_router +version_added: "1.2" +short_description: Create or Remove router from openstack +description: + - Create or Delete routers from OpenStack +options: + login_username: + description: + - login username to authenticate to keystone + required: true + default: admin + login_password: + description: + - Password of login user + required: true + default: 'yes' + login_tenant_name: + description: + - The tenant name of the login user + required: true + default: 'yes' + auth_url: + description: + - The keystone url for authentication + required: false + default: 'http://127.0.0.1:35357/v2.0/' + region_name: + description: + - Name of the region + required: false + default: None + state: + description: + - Indicate desired state of the resource + choices: ['present', 'absent'] + default: present + name: + description: + - Name to be give to the router + required: true + default: None + tenant_name: + description: + - Name of the tenant for which the router has to be created, if none router would be created for the login tenant. + required: false + default: None + admin_state_up: + description: + - desired admin state of the created router . + required: false + default: true +requirements: ["neutronclient", "keystoneclient"] +''' + +EXAMPLES = ''' +# Creates a router for tenant admin +- neutron_router: state=present + login_username=admin + login_password=admin + login_tenant_name=admin + name=router1" +''' + +_os_keystone = None +_os_tenant_id = None + +def _get_ksclient(module, kwargs): + try: + kclient = ksclient.Client(username=kwargs.get('login_username'), + password=kwargs.get('login_password'), + tenant_name=kwargs.get('login_tenant_name'), + auth_url=kwargs.get('auth_url')) + except Exception as e: + module.fail_json(msg = "Error authenticating to the keystone: %s " % e.message) + global _os_keystone + _os_keystone = kclient + return kclient + + +def _get_endpoint(module, ksclient): + try: + endpoint = ksclient.service_catalog.url_for(service_type='network', endpoint_type='publicURL') + except Exception as e: + module.fail_json(msg = "Error getting endpoint for glance: %s" % e.message) + return endpoint + +def _get_neutron_client(module, kwargs): + _ksclient = _get_ksclient(module, kwargs) + token = _ksclient.auth_token + endpoint = _get_endpoint(module, _ksclient) + kwargs = { + 'token': token, + 'endpoint_url': endpoint + } + try: + neutron = client.Client('2.0', **kwargs) + except Exception as e: + module.fail_json(msg = "Error in connecting to Neutron: %s " % e.message) + return neutron + +def _set_tenant_id(module): + global _os_tenant_id + if not module.params['tenant_name']: + login_tenant_name = module.params['login_tenant_name'] + else: + login_tenant_name = module.params['tenant_name'] + + for tenant in _os_keystone.tenants.list(): + if tenant.name == login_tenant_name: + _os_tenant_id = tenant.id + break + if not _os_tenant_id: + module.fail_json(msg = "The tenant id cannot be found, please check the paramters") + + +def _get_router_id(module, neutron): + kwargs = { + 'name': module.params['name'], + 'tenant_id': _os_tenant_id, + } + try: + routers = neutron.list_routers(**kwargs) + except Exception as e: + module.fail_json(msg = "Error in getting the router list: %s " % e.message) + if not routers['routers']: + return None + return routers['routers'][0]['id'] + +def _create_router(module, neutron): + router = { + 'name': module.params['name'], + 'tenant_id': _os_tenant_id, + 'admin_state_up': module.params['admin_state_up'], + } + try: + new_router = neutron.create_router(dict(router=router)) + except Exception as e: + module.fail_json( msg = "Error in creating router: %s" % e.message) + return new_router['router']['id'] + +def _delete_router(module, neutron, router_id): + try: + neutron.delete_router(router_id) + except: + module.fail_json("Error in deleting the router") + return True + +def main(): + module = AnsibleModule( + argument_spec = dict( + login_username = dict(default='admin'), + login_password = dict(required=True), + login_tenant_name = dict(required='True'), + auth_url = dict(default='http://127.0.0.1:35357/v2.0/'), + region_name = dict(default=None), + name = dict(required=True), + tenant_name = dict(default=None), + state = dict(default='present', choices=['absent', 'present']), + admin_state_up = dict(type='bool', default=True), + ), + ) + + neutron = _get_neutron_client(module, module.params) + _set_tenant_id(module) + + if module.params['state'] == 'present': + router_id = _get_router_id(module, neutron) + if not router_id: + router_id = _create_router(module, neutron) + module.exit_json(changed=True, result="Created", id=router_id) + else: + module.exit_json(changed=False, result="success" , id=router_id) + + else: + router_id = _get_router_id(module, neutron) + if not router_id: + module.exit_json(changed=False, result="success") + else: + _delete_router(module, neutron, router_id) + module.exit_json(changed=True, result="deleted") + +# this is magic, see lib/ansible/module.params['common.py +from ansible.module_utils.basic import * +main() diff --git a/openstack/usr/share/openstack/modules/neutron_router_gateway b/openstack/usr/share/openstack/modules/neutron_router_gateway new file mode 100644 index 00000000..93235b85 --- /dev/null +++ b/openstack/usr/share/openstack/modules/neutron_router_gateway @@ -0,0 +1,215 @@ +#!/usr/bin/python +#coding: utf-8 -*- + +# (c) 2013, Benno Joy +# +# This module is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This software is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this software. If not, see . + +try: + from neutronclient.neutron import client + from keystoneclient.v2_0 import client as ksclient +except ImportError: + print("failed=True msg='neutronclient and keystone client are required'") +DOCUMENTATION = ''' +--- +module: neutron_router_gateway +version_added: "1.2" +short_description: set/unset a gateway interface for the router with the specified external network +description: + - Creates/Removes a gateway interface from the router, used to associate a external network with a router to route external traffic. +options: + login_username: + description: + - login username to authenticate to keystone + required: true + default: admin + login_password: + description: + - Password of login user + required: true + default: 'yes' + login_tenant_name: + description: + - The tenant name of the login user + required: true + default: 'yes' + auth_url: + description: + - The keystone URL for authentication + required: false + default: 'http://127.0.0.1:35357/v2.0/' + region_name: + description: + - Name of the region + required: false + default: None + state: + description: + - Indicate desired state of the resource + choices: ['present', 'absent'] + default: present + router_name: + description: + - Name of the router to which the gateway should be attached. + required: true + default: None + network_name: + description: + - Name of the external network which should be attached to the router. + required: true + default: None +requirements: ["neutronclient", "keystoneclient"] +''' + +EXAMPLES = ''' +# Attach an external network with a router to allow flow of external traffic +- neutron_router_gateway: state=present login_username=admin login_password=admin + login_tenant_name=admin router_name=external_router + network_name=external_network +''' + +_os_keystone = None +def _get_ksclient(module, kwargs): + try: + kclient = ksclient.Client(username=kwargs.get('login_username'), + password=kwargs.get('login_password'), + tenant_name=kwargs.get('login_tenant_name'), + auth_url=kwargs.get('auth_url')) + except Exception as e: + module.fail_json(msg = "Error authenticating to the keystone: %s " % e.message) + global _os_keystone + _os_keystone = kclient + return kclient + + +def _get_endpoint(module, ksclient): + try: + endpoint = ksclient.service_catalog.url_for(service_type='network', endpoint_type='publicURL') + except Exception as e: + module.fail_json(msg = "Error getting endpoint for glance: %s" % e.message) + return endpoint + +def _get_neutron_client(module, kwargs): + _ksclient = _get_ksclient(module, kwargs) + token = _ksclient.auth_token + endpoint = _get_endpoint(module, _ksclient) + kwargs = { + 'token': token, + 'endpoint_url': endpoint + } + try: + neutron = client.Client('2.0', **kwargs) + except Exception as e: + module.fail_json(msg = "Error in connecting to neutron: %s " % e.message) + return neutron + +def _get_router_id(module, neutron): + kwargs = { + 'name': module.params['router_name'], + } + try: + routers = neutron.list_routers(**kwargs) + except Exception as e: + module.fail_json(msg = "Error in getting the router list: %s " % e.message) + if not routers['routers']: + return None + return routers['routers'][0]['id'] + +def _get_net_id(neutron, module): + kwargs = { + 'name': module.params['network_name'], + 'router:external': True + } + try: + networks = neutron.list_networks(**kwargs) + except Exception as e: + module.fail_json("Error in listing neutron networks: %s" % e.message) + if not networks['networks']: + return None + return networks['networks'][0]['id'] + +def _get_port_id(neutron, module, router_id, network_id): + kwargs = { + 'device_id': router_id, + 'network_id': network_id, + } + try: + ports = neutron.list_ports(**kwargs) + except Exception as e: + module.fail_json( msg = "Error in listing ports: %s" % e.message) + if not ports['ports']: + return None + return ports['ports'][0]['id'] + +def _add_gateway_router(neutron, module, router_id, network_id): + kwargs = { + 'network_id': network_id + } + try: + neutron.add_gateway_router(router_id, kwargs) + except Exception as e: + module.fail_json(msg = "Error in adding gateway to router: %s" % e.message) + return True + +def _remove_gateway_router(neutron, module, router_id): + try: + neutron.remove_gateway_router(router_id) + except Exception as e: + module.fail_json(msg = "Error in removing gateway to router: %s" % e.message) + return True + +def main(): + + module = AnsibleModule( + argument_spec = dict( + login_username = dict(default='admin'), + login_password = dict(required=True), + login_tenant_name = dict(required='True'), + auth_url = dict(default='http://127.0.0.1:35357/v2.0/'), + region_name = dict(default=None), + router_name = dict(required=True), + network_name = dict(required=True), + state = dict(default='present', choices=['absent', 'present']), + ), + ) + + neutron = _get_neutron_client(module, module.params) + router_id = _get_router_id(module, neutron) + + if not router_id: + module.fail_json(msg="failed to get the router id, please check the router name") + + network_id = _get_net_id(neutron, module) + if not network_id: + module.fail_json(msg="failed to get the network id, please check the network name and make sure it is external") + + if module.params['state'] == 'present': + port_id = _get_port_id(neutron, module, router_id, network_id) + if not port_id: + _add_gateway_router(neutron, module, router_id, network_id) + module.exit_json(changed=True, result="created") + module.exit_json(changed=False, result="success") + + if module.params['state'] == 'absent': + port_id = _get_port_id(neutron, module, router_id, network_id) + if not port_id: + module.exit_json(changed=False, result="Success") + _remove_gateway_router(neutron, module, router_id) + module.exit_json(changed=True, result="Deleted") + +# this is magic, see lib/ansible/module.params['common.py +from ansible.module_utils.basic import * +main() + + diff --git a/openstack/usr/share/openstack/modules/neutron_router_interface b/openstack/usr/share/openstack/modules/neutron_router_interface new file mode 100644 index 00000000..8d57725c --- /dev/null +++ b/openstack/usr/share/openstack/modules/neutron_router_interface @@ -0,0 +1,249 @@ +#!/usr/bin/python +#coding: utf-8 -*- + +# (c) 2013, Benno Joy +# +# This module is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This software is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this software. If not, see . + +try: + from neutronclient.neutron import client + from keystoneclient.v2_0 import client as ksclient +except ImportError: + print("failed=True msg='neutronclient and keystone client are required'") +DOCUMENTATION = ''' +--- +module: neutron_router_interface +version_added: "1.2" +short_description: Attach/Dettach a subnet's interface to a router +description: + - Attach/Dettach a subnet interface to a router, to provide a gateway for the subnet. +options: + login_username: + description: + - login username to authenticate to keystone + required: true + default: admin + login_password: + description: + - Password of login user + required: true + default: 'yes' + login_tenant_name: + description: + - The tenant name of the login user + required: true + default: 'yes' + auth_url: + description: + - The keystone URL for authentication + required: false + default: 'http://127.0.0.1:35357/v2.0/' + region_name: + description: + - Name of the region + required: false + default: None + state: + description: + - Indicate desired state of the resource + choices: ['present', 'absent'] + default: present + router_name: + description: + - Name of the router to which the subnet's interface should be attached. + required: true + default: None + subnet_name: + description: + - Name of the subnet to whose interface should be attached to the router. + required: true + default: None + tenant_name: + description: + - Name of the tenant whose subnet has to be attached. + required: false + default: None +requirements: ["neutronclient", "keystoneclient"] +''' + +EXAMPLES = ''' +# Attach tenant1's subnet to the external router +- neutron_router_interface: state=present login_username=admin + login_password=admin + login_tenant_name=admin + tenant_name=tenant1 + router_name=external_route + subnet_name=t1subnet +''' + + +_os_keystone = None +_os_tenant_id = None + +def _get_ksclient(module, kwargs): + try: + kclient = ksclient.Client(username=kwargs.get('login_username'), + password=kwargs.get('login_password'), + tenant_name=kwargs.get('login_tenant_name'), + auth_url=kwargs.get('auth_url')) + except Exception as e: + module.fail_json(msg = "Error authenticating to the keystone: %s " % e.message) + global _os_keystone + _os_keystone = kclient + return kclient + + +def _get_endpoint(module, ksclient): + try: + endpoint = ksclient.service_catalog.url_for(service_type='network', endpoint_type='publicURL') + except Exception as e: + module.fail_json(msg = "Error getting endpoint for glance: %s" % e.message) + return endpoint + +def _get_neutron_client(module, kwargs): + _ksclient = _get_ksclient(module, kwargs) + token = _ksclient.auth_token + endpoint = _get_endpoint(module, _ksclient) + kwargs = { + 'token': token, + 'endpoint_url': endpoint + } + try: + neutron = client.Client('2.0', **kwargs) + except Exception as e: + module.fail_json(msg = "Error in connecting to neutron: %s " % e.message) + return neutron + +def _set_tenant_id(module): + global _os_tenant_id + if not module.params['tenant_name']: + login_tenant_name = module.params['login_tenant_name'] + else: + login_tenant_name = module.params['tenant_name'] + + for tenant in _os_keystone.tenants.list(): + if tenant.name == login_tenant_name: + _os_tenant_id = tenant.id + break + if not _os_tenant_id: + module.fail_json(msg = "The tenant id cannot be found, please check the paramters") + + +def _get_router_id(module, neutron): + kwargs = { + 'name': module.params['router_name'], + } + try: + routers = neutron.list_routers(**kwargs) + except Exception as e: + module.fail_json(msg = "Error in getting the router list: %s " % e.message) + if not routers['routers']: + return None + return routers['routers'][0]['id'] + + +def _get_subnet_id(module, neutron): + subnet_id = None + kwargs = { + 'tenant_id': _os_tenant_id, + 'name': module.params['subnet_name'], + } + try: + subnets = neutron.list_subnets(**kwargs) + except Exception as e: + module.fail_json( msg = " Error in getting the subnet list:%s " % e.message) + if not subnets['subnets']: + return None + return subnets['subnets'][0]['id'] + +def _get_port_id(neutron, module, router_id, subnet_id): + kwargs = { + 'tenant_id': _os_tenant_id, + 'device_id': router_id, + } + try: + ports = neutron.list_ports(**kwargs) + except Exception as e: + module.fail_json( msg = "Error in listing ports: %s" % e.message) + if not ports['ports']: + return None + for port in ports['ports']: + for subnet in port['fixed_ips']: + if subnet['subnet_id'] == subnet_id: + return port['id'] + return None + +def _add_interface_router(neutron, module, router_id, subnet_id): + kwargs = { + 'subnet_id': subnet_id + } + try: + neutron.add_interface_router(router_id, kwargs) + except Exception as e: + module.fail_json(msg = "Error in adding interface to router: %s" % e.message) + return True + +def _remove_interface_router(neutron, module, router_id, subnet_id): + kwargs = { + 'subnet_id': subnet_id + } + try: + neutron.remove_interface_router(router_id, kwargs) + except Exception as e: + module.fail_json(msg="Error in removing interface from router: %s" % e.message) + return True + +def main(): + module = AnsibleModule( + argument_spec = dict( + login_username = dict(default='admin'), + login_password = dict(required=True), + login_tenant_name = dict(required='True'), + auth_url = dict(default='http://127.0.0.1:35357/v2.0/'), + region_name = dict(default=None), + router_name = dict(required=True), + subnet_name = dict(required=True), + tenant_name = dict(default=None), + state = dict(default='present', choices=['absent', 'present']), + ), + ) + + neutron = _get_neutron_client(module, module.params) + _set_tenant_id(module) + + router_id = _get_router_id(module, neutron) + if not router_id: + module.fail_json(msg="failed to get the router id, please check the router name") + + subnet_id = _get_subnet_id(module, neutron) + if not subnet_id: + module.fail_json(msg="failed to get the subnet id, please check the subnet name") + + if module.params['state'] == 'present': + port_id = _get_port_id(neutron, module, router_id, subnet_id) + if not port_id: + _add_interface_router(neutron, module, router_id, subnet_id) + module.exit_json(changed=True, result="created", id=port_id) + module.exit_json(changed=False, result="success", id=port_id) + + if module.params['state'] == 'absent': + port_id = _get_port_id(neutron, module, router_id, subnet_id) + if not port_id: + module.exit_json(changed = False, result = "Success") + _remove_interface_router(neutron, module, router_id, subnet_id) + module.exit_json(changed=True, result="Deleted") + +# this is magic, see lib/ansible/module.params['common.py +from ansible.module_utils.basic import * +main() diff --git a/openstack/usr/share/openstack/modules/neutron_sec_group b/openstack/usr/share/openstack/modules/neutron_sec_group new file mode 100644 index 00000000..518c50e7 --- /dev/null +++ b/openstack/usr/share/openstack/modules/neutron_sec_group @@ -0,0 +1,382 @@ +#!/usr/bin/python +# +# (c) Cisco Systems, 2014 +# +# This module is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This software is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this software. If not, see . + +DOCUMENTATION = ''' +--- +module: neutron_sec_group +short_description: Create, Remove or Update Openstack security groups +description: + - Create, Remove or Update Openstack security groups +options: + login_username: + description: + - login username to authenticate to keystone + required: true + login_password: + description: + - Password of login user + required: true + login_tenant_name: + description: + - The tenant name of the login user + required: true + auth_url: + description: + - The keystone url for authentication + required: false + default: 'http://127.0.0.1:5000/v2.0/' + region_name: + description: + - Name of the region + required: false + default: None + state: + description: + - Indicate desired state of the security group + choices: ['present', 'absent'] + default: present + name: + description: + - Name to be given to the security group + required: true + default: None + tenant_name: + description: + - Name of the tenant for which the security group has to be created, + if none, the security group would be created for the login tenant. + required: false + default: None + rules: + description: + - "List of security group rules. Available parameters of a rule: + direction, port_range_min, port_range_max, ethertype, protocol, + remote_ip_prefix/remote_ip_group" + required: false + default: none +requirements: ["neutronclient", "keystoneclient"] +''' + +EXAMPLES = ''' +# Creates a security group with a number of rules +neutron_sec_group: + login_username: "demo" + login_password: "password" + login_tenant_name: "demo" + auth_url: "http://127.0.0.1:5000/v2.0" + name: "sg-test" + description: "Description of the security group" + state: "present" + rules: + - direction: "ingress" + port_range_min: "80" + port_range_max: "80" + ethertype: "IPv4" + protocol: "tcp" + remote_ip_prefix: "10.0.0.1/24" + - direction: "ingress" + port_range_min: "22" + port_range_max: "22" + ethertype: "IPv4" + protocol: "tcp" + remote_ip_prefix: "10.0.0.1/24" +''' + +try: + import neutronclient.v2_0.client + import keystoneclient.v2_0.client + from neutronclient.common import exceptions +except ImportError: + print "failed=True msg='neutronclient and keystoneclient are required'" + +def main(): + """ + Main function - entry point. The magic starts here ;-) + """ + module = AnsibleModule( + argument_spec=dict( + auth_url=dict(default="http://127.0.0.1:5000/v2.0/"), + login_username=dict(required=True), + login_password=dict(required=True), + login_tenant_name=dict(required=True), + name=dict(required=True), + description=dict(default=None), + region_name=dict(default=None), + rules=dict(default=None), + tenant_name=dict(required=False), + state=dict(default="present", choices=['present', 'absent']) + ), + supports_check_mode=True + ) + network_client = _get_network_client(module.params) + identity_client = _get_identity_client(module.params) + + try: + # Get id of security group (as a result check whether it exists) + params = { + 'name': module.params['name'], + 'tenant_id': _get_tenant_id(module, identity_client), + 'fields': 'id' + } + sec_groups = network_client.list_security_groups(**params)["security_groups"] + if len(sec_groups) > 1: + raise exceptions.NeutronClientNoUniqueMatch(resource='security_group',name=name) + elif len(sec_groups) == 0: + sec_group_exists = False + else: + sec_group = sec_groups[0] + sec_group_exists = True + + # state=present -> create or update depending on whether sg exists. + if module.params['state'] == "present": + # UPDATE + if sec_group_exists: + changed, sg = _update_sg(module, network_client, sec_group) + if changed: + module.exit_json(sec_group=sg, updated=True, changed=changed) + else: + module.exit_json(sec_group=sg, changed=changed) + # CREATE + else: + sg = _create_sg(module, network_client, identity_client) + module.exit_json(sec_group=sg, created=True, changed=True) + # DELETE + elif module.params['state'] == "absent" and sec_group_exists: + _delete_sg(module, network_client, sec_group) + module.exit_json(changed=True) + + module.exit_json(changed=False) + + except exceptions.Unauthorized as exc: + module.fail_json(msg="Authentication error: %s" % str(exc)) + except Exception as exc: + module.fail_json(msg="Error: %s" % str(exc)) + +def _delete_sg(module, network_client, sec_group): + """ + Deletes a security group. + :param module: module to get security group params from. + :param network_client: network client to use. + :param sec_group: security group to delete. + """ + if module.check_mode: + return + network_client.delete_security_group(sec_group['id']) + + +def _create_sg(module, network_client, identity_client): + """ + Creates a security group. + :param module: module to get security group params from. + :param network_client: network client to use. + :param: identity_client: identity_client used if an admin performs the + operation for a different tenant. + :return: newly created security group. + """ + if module.check_mode: + return None + # NOTE: we don't do explicit rule validation, the API server will take + # care of that for us :-) + rules = module.params['rules'] + + data = { + "security_group": { + "name": module.params['name'], + "description": module.params['description'], + 'tenant_id': _get_tenant_id(module, identity_client) + } + } + + sg = network_client.create_security_group(data) + sg = sg["security_group"] + + changed, sg = _update_sg(module, network_client, sg) + return sg + + +def _update_sg(module, network_client, sg): + """ + Updates a security group. + :param module: module to get updated security group param from. + :param network_client: network client to use. + :param sg: security group that needs to be updated. + :return: True/False, the updated security group. + """ + changed = False + sg = network_client.show_security_group(sg['id']) + sg = sg['security_group'] + + # We only allow description updating, no name updating + if module.params["description"] \ + and not module.params['description'] == sg['description'] \ + and module.check_mode: + + changed = True + elif module.params["description"] \ + and not module.params['description'] == sg['description'] \ + and not module.check_mode: + body = { + "security_group": { + "description": module.params["description"] + } + } + sg = network_client.update_security_group(sg['id'], body) + sg = sg['security_group'] + changed = True + + # Security rules group update + existing_rules = sg['security_group_rules'] + wanted_rules = module.params['rules'] + + #check ok + ok_rules = [] + for new_rule in wanted_rules: + # Ugly: define tenant also here so that matches + new_rule['tenant_id'] = sg['tenant_id'] + # protocol is in lowercase + if 'protocol' in new_rule: + new_rule['protocol'] = new_rule['protocol'].lower() + + matched_id = None + for old_rule in existing_rules: + clean_new_rule = new_rule.copy() + clean_old_rule = old_rule.copy() + old_id = clean_old_rule.pop('id') + clean_old_rule.pop('security_group_id') + for key in clean_old_rule.keys(): + if key not in clean_new_rule: + clean_new_rule[key] = None + continue + value = clean_new_rule[key] + if isinstance(value, (str, unicode)) and value.isdigit(): + clean_new_rule[key] = int(value) + if cmp(clean_old_rule, clean_new_rule) == 0: + matched_id = old_id + break + + if matched_id: + new_rule['done'] = True + ok_rules.append(matched_id) + + #apply new first + new_rules = [rule for rule in wanted_rules if 'done' not in rule] + if len(new_rules): + if not module.check_mode: + sg = _create_sg_rules(network_client, sg, new_rules) + changed = True + + #then delete not ok + for rule in existing_rules: + if rule['id'] in ok_rules: + continue + if not module.check_mode: + sg = network_client.delete_security_group_rule(rule['id']) + changed = True + + return changed, sg + +def _create_sg_rules(network_client, sg, rules): + """ + Creates a set of security group rules in a given security group. + :param network_client: network client to use to create rules. + :param sg: security group to create rules in. + :param rules: rules to create. + :return: the updated security group. + """ + if rules: + for rule in rules: + rule['tenant_id'] = sg['tenant_id'] + rule['security_group_id'] = sg['id'] + data = { + "security_group_rule": rule + } + network_client.create_security_group_rule(data) + + # fetch security group again to show end result + return network_client.show_security_group(sg['id'])['security_group'] + return sg + + +def _get_tenant_id(module, identity_client): + """ + Returns the tenant_id, given tenant_name. + if tenant_name is not specified in the module params uses tenant_id + from Keystone session + :param identity_client: identity_client used to get the tenant_id from its + name. + :param module_params: module parameters. + """ + if not module.params['tenant_name']: + tenant_id = identity_client.tenant_id + else: + tenant_name = module.params['tenant_name'] + tenant = _get_tenant(identity_client, tenant_name) + tenant_id = tenant.id + + return tenant_id + + +def _get_tenant(identity_client, tenant_name): + """ + Returns the tenant, given the tenant_name. + :param identity_client: identity client to use to do the required requests. + :param tenant_name: name of the tenant. + :return: tenant for which the name was given. + """ + tenants = identity_client.tenants.list() + tenant = next((t for t in tenants if t.name == tenant_name), None) + if not tenant: + raise Exception("Tenant with name '%s' not found." % tenant_name) + + return tenant + + +def _get_network_client(module_params): + """ + :param module_params: module params containing the openstack credentials + used to authenticate. + :return: a neutron client. + """ + client = neutronclient.v2_0.client.Client( + username=module_params.get('login_username'), + password=module_params.get('login_password'), + tenant_name=module_params.get('login_tenant_name'), + auth_url=module_params.get('auth_url'), + region_name=module_params.get('region_name')) + + return client + + +def _get_identity_client(module_params): + """ + :param module_params: module params containing the openstack credentials + used to authenticate. + :return: a keystone client. + """ + client = keystoneclient.v2_0.client.Client( + username=module_params.get('login_username'), + password=module_params.get('login_password'), + tenant_name=module_params.get('login_tenant_name'), + auth_url=module_params.get('auth_url'), + region_name=module_params.get('region_name')) + + return client + + +# Let's get the party started! +from ansible.module_utils.basic import * + +main() diff --git a/openstack/usr/share/openstack/modules/neutron_subnet b/openstack/usr/share/openstack/modules/neutron_subnet new file mode 100644 index 00000000..8cb622b5 --- /dev/null +++ b/openstack/usr/share/openstack/modules/neutron_subnet @@ -0,0 +1,294 @@ +#!/usr/bin/python +#coding: utf-8 -*- + +# (c) 2013, Benno Joy +# +# This module is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This software is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this software. If not, see . + +try: + from neutronclient.neutron import client + from keystoneclient.v2_0 import client as ksclient +except ImportError: + print("failed=True msg='neutron and keystone client are required'") + +DOCUMENTATION = ''' +--- +module: neutron_subnet +version_added: "1.2" +short_description: Add/Remove floating IP from an instance +description: + - Add or Remove a floating IP to an instance +options: + login_username: + description: + - login username to authenticate to keystone + required: true + default: admin + login_password: + description: + - Password of login user + required: true + default: True + login_tenant_name: + description: + - The tenant name of the login user + required: true + default: True + auth_url: + description: + - The keystone URL for authentication + required: false + default: 'http://127.0.0.1:35357/v2.0/' + region_name: + description: + - Name of the region + required: false + default: None + state: + description: + - Indicate desired state of the resource + choices: ['present', 'absent'] + default: present + network_name: + description: + - Name of the network to which the subnet should be attached + required: true + default: None + cidr: + description: + - The CIDR representation of the subnet that should be assigned to the subnet + required: true + default: None + tenant_name: + description: + - The name of the tenant for whom the subnet should be created + required: false + default: None + ip_version: + description: + - The IP version of the subnet 4 or 6 + required: false + default: 4 + enable_dhcp: + description: + - Whether DHCP should be enabled for this subnet. + required: false + default: true + gateway_ip: + description: + - The ip that would be assigned to the gateway for this subnet + required: false + default: None + dns_nameservers: + description: + - DNS nameservers for this subnet, comma-separated + required: false + default: None + allocation_pool_start: + description: + - From the subnet pool the starting address from which the IP should be allocated + required: false + default: None + allocation_pool_end: + description: + - From the subnet pool the last IP that should be assigned to the virtual machines + required: false + default: None + host_routes: + description: + - Host routes for this subnet, list of dictionaries, e.g. [{destination: 0.0.0.0/0, nexthop: 123.456.78.9}, {destination: 192.168.0.0/24, nexthop: 192.168.0.1}] + required: false + default: None +requirements: ["neutron", "keystoneclient"] +''' + +EXAMPLES = ''' +# Create a subnet for a tenant with the specified subnet +- neutron_subnet: state=present login_username=admin login_password=admin + login_tenant_name=admin tenant_name=tenant1 + network_name=network1 name=net1subnet cidr=192.168.0.0/24" +''' + +_os_keystone = None +_os_tenant_id = None +_os_network_id = None + +def _get_ksclient(module, kwargs): + try: + kclient = ksclient.Client(username=kwargs.get('login_username'), + password=kwargs.get('login_password'), + tenant_name=kwargs.get('login_tenant_name'), + auth_url=kwargs.get('auth_url')) + except Exception as e: + module.fail_json(msg = "Error authenticating to the keystone: %s" %e.message) + global _os_keystone + _os_keystone = kclient + return kclient + + +def _get_endpoint(module, ksclient): + try: + endpoint = ksclient.service_catalog.url_for(service_type='network', endpoint_type='publicURL') + except Exception as e: + module.fail_json(msg = "Error getting endpoint for glance: %s" % e.message) + return endpoint + +def _get_neutron_client(module, kwargs): + _ksclient = _get_ksclient(module, kwargs) + token = _ksclient.auth_token + endpoint = _get_endpoint(module, _ksclient) + kwargs = { + 'token': token, + 'endpoint_url': endpoint + } + try: + neutron = client.Client('2.0', **kwargs) + except Exception as e: + module.fail_json(msg = " Error in connecting to Neutron: %s" % e.message) + return neutron + +def _set_tenant_id(module): + global _os_tenant_id + if not module.params['tenant_name']: + tenant_name = module.params['login_tenant_name'] + else: + tenant_name = module.params['tenant_name'] + + for tenant in _os_keystone.tenants.list(): + if tenant.name == tenant_name: + _os_tenant_id = tenant.id + break + if not _os_tenant_id: + module.fail_json(msg = "The tenant id cannot be found, please check the paramters") + +def _get_net_id(neutron, module): + kwargs = { + 'tenant_id': _os_tenant_id, + 'name': module.params['network_name'], + } + try: + networks = neutron.list_networks(**kwargs) + except Exception as e: + module.fail_json("Error in listing Neutron networks: %s" % e.message) + if not networks['networks']: + return None + return networks['networks'][0]['id'] + + +def _get_subnet_id(module, neutron): + global _os_network_id + subnet_id = None + _os_network_id = _get_net_id(neutron, module) + if not _os_network_id: + module.fail_json(msg = "network id of network not found.") + else: + kwargs = { + 'tenant_id': _os_tenant_id, + 'name': module.params['name'], + } + try: + subnets = neutron.list_subnets(**kwargs) + except Exception as e: + module.fail_json( msg = " Error in getting the subnet list:%s " % e.message) + if not subnets['subnets']: + return None + return subnets['subnets'][0]['id'] + +def _create_subnet(module, neutron): + neutron.format = 'json' + subnet = { + 'name': module.params['name'], + 'ip_version': module.params['ip_version'], + 'enable_dhcp': module.params['enable_dhcp'], + 'tenant_id': _os_tenant_id, + 'gateway_ip': module.params['gateway_ip'], + 'dns_nameservers': module.params['dns_nameservers'], + 'network_id': _os_network_id, + 'cidr': module.params['cidr'], + 'host_routes': module.params['host_routes'], + } + if module.params['allocation_pool_start'] and module.params['allocation_pool_end']: + allocation_pools = [ + { + 'start' : module.params['allocation_pool_start'], + 'end' : module.params['allocation_pool_end'] + } + ] + subnet.update({'allocation_pools': allocation_pools}) + if not module.params['gateway_ip']: + subnet.pop('gateway_ip') + if module.params['dns_nameservers']: + subnet['dns_nameservers'] = module.params['dns_nameservers'].split(',') + else: + subnet.pop('dns_nameservers') + if not module.params['host_routes']: + subnet.pop('host_routes') + try: + new_subnet = neutron.create_subnet(dict(subnet=subnet)) + except Exception, e: + module.fail_json(msg = "Failure in creating subnet: %s" % e.message) + return new_subnet['subnet']['id'] + + +def _delete_subnet(module, neutron, subnet_id): + try: + neutron.delete_subnet(subnet_id) + except Exception as e: + module.fail_json( msg = "Error in deleting subnet: %s" % e.message) + return True + + +def main(): + + module = AnsibleModule( + argument_spec = dict( + login_username = dict(default='admin'), + login_password = dict(required=True), + login_tenant_name = dict(required='True'), + auth_url = dict(default='http://127.0.0.1:35357/v2.0/'), + region_name = dict(default=None), + name = dict(required=True), + network_name = dict(required=True), + cidr = dict(required=True), + tenant_name = dict(default=None), + state = dict(default='present', choices=['absent', 'present']), + ip_version = dict(default='4', choices=['4', '6']), + enable_dhcp = dict(default='true', choices=BOOLEANS), + gateway_ip = dict(default=None), + dns_nameservers = dict(default=None), + allocation_pool_start = dict(default=None), + allocation_pool_end = dict(default=None), + host_routes = dict(default=None), + ), + ) + neutron = _get_neutron_client(module, module.params) + _set_tenant_id(module) + if module.params['state'] == 'present': + subnet_id = _get_subnet_id(module, neutron) + if not subnet_id: + subnet_id = _create_subnet(module, neutron) + module.exit_json(changed = True, result = "Created" , id = subnet_id) + else: + module.exit_json(changed = False, result = "success" , id = subnet_id) + else: + subnet_id = _get_subnet_id(module, neutron) + if not subnet_id: + module.exit_json(changed = False, result = "success") + else: + _delete_subnet(module, neutron, subnet_id) + module.exit_json(changed = True, result = "deleted") + +# this is magic, see lib/ansible/module.params['common.py +from ansible.module_utils.basic import * +main() diff --git a/openstack/usr/share/openstack/modules/nova_flavor b/openstack/usr/share/openstack/modules/nova_flavor new file mode 100644 index 00000000..b71d648f --- /dev/null +++ b/openstack/usr/share/openstack/modules/nova_flavor @@ -0,0 +1,188 @@ +#!/usr/bin/python +#coding: utf-8 -*- + +# (c) 2014, Adam Samalik +# +# This module is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This software is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this software. If not, see . + +try: + from novaclient import client + from keystoneclient.v2_0 import client as ksclient +except ImportError: + print("failed=True msg='novaclient and keystone client are required'") + +DOCUMENTATION = ''' +--- +module: nova_flavor +short_description: Manage OpenStack flavours +description: + - Create VM flavours with OpenStack Nova service +requirements: [ python-novaclient ] +options: + login_username: + description: + - user name to authenticate against Identity service + required: True + aliases: [username] + login_password: + description: + - password to authenticate against Identity service + aliases: [password] + required: True + login_tenant_name: + description: + - tenant name of the login user + aliases: [tenant_name] + required: True + auth_url: + description: + - The keystone URL for authentication + required: false + default: 'http://127.0.0.1:35357/v2.0/' + region_name: + description: + - Name of the region + required: False + default: None + name: + description: + - Descriptive name of the flavor + required: True + ram: + description: + - Memory in MB for the flavor + required: True + vcpus: + description: + - Number of VCPUs for the flavor + required: True + disk: + description: + - Size of local disk in GB + required: True + swap: + description: + - Swap space in MB + required: False + default: 0 + id: + description: + - ID for the flavor (optional). + required: False + default: ID will be automatically generated + is_public: + description: + - Decide if the flavour is public +''' + +EXAMPLES = ''' + - nova_flavor: + login_username: admin + login_password: 1234 + login_tenant_name: admin + name: medium + ram: 2048 + vcpus: 2 + disk: 20 +''' + + +def authenticate(module, auth_url, username, password, tenant_name, region): + """ + Return a Nova client object. + """ + try: + keystone = ksclient.Client(auth_url=auth_url, + username=username, + password=password, + tenant_name=tenant_name, + region=region) + except Exception as e: + module.fail_json( + msg = "Could not authenticate with Keystone: {}".format( + e.message)) + + try: + nova = client.Client('2', keystone.username, + keystone.password, + keystone.tenant_name, + keystone.auth_url) + except Exception as e: + module.fail_json(msg = "Could not get Nova client: {}".format( + e.message)) + + return nova + +def get_flavors(nova, name, id=None): + if not id: + flavors = [x for x in nova.flavors.list() if x.name == name] + else: + flavors = [x for x in nova.flavors.list() if x.name == name and x.id == str(id)] + return flavors + +def create_flavor(module, nova, name, ram, vcpus, disk, swap, id, is_public): + flavors = get_flavors(nova, name, id) + if len(flavors) >0: + return False, flavors[0].id + + try: + flavor = nova.flavors.create(name, ram, vcpus, disk, swap=swap, + flavorid=id, is_public=is_public) + except Exception as e: + module.fail_json(msg = "Could not create a flavour: {}".format( + e.message)) + + return True, flavor.id + +def main(): + module = AnsibleModule( + argument_spec = dict( + login_username = dict(default='admin', aliases=["username"]), + login_password = dict(required=True, aliases=["password"]), + login_tenant_name = dict(required='True', aliases=["tenant_name"]), + auth_url = dict(default='http://127.0.0.1:35357/v2.0/'), + region_name = dict(default=None), + name = dict(required=True), + ram = dict(required=True), + vcpus = dict(required=True), + disk = dict(required=True), + swap = dict(default=0), + id = dict(default=None), + is_public = dict(default=True, choices=BOOLEANS), + ) + ) + auth_url = module.params['auth_url'] + region = module.params['region_name'] + username = module.params['login_username'] + password = module.params['login_password'] + tenant_name = module.params['login_tenant_name'] + name = module.params['name'] + ram = module.params['ram'] + vcpus = module.params['vcpus'] + disk = module.params['disk'] + swap = module.params['swap'] + id = module.params['id'] + is_public = module.params['is_public'] + + nova = authenticate(module, auth_url, username, password, tenant_name, region) + + changed, id = create_flavor(module, nova, name, ram, vcpus, disk, swap, id, + is_public) + + module.exit_json(changed=changed, name=name, id=id) + +# this is magic, see lib/ansible/module_common.py +#<> +if __name__ == '__main__': + main() diff --git a/openstack/usr/share/openstack/modules/nova_manage b/openstack/usr/share/openstack/modules/nova_manage new file mode 100644 index 00000000..6b1a297e --- /dev/null +++ b/openstack/usr/share/openstack/modules/nova_manage @@ -0,0 +1,93 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +DOCUMENTATION = ''' +--- +module: nova_manage +short_description: Initialize OpenStack Compute (nova) database +description: Create the tables for the database backend used by nova +options: + action: + description: + - action to perform. Currently only dbsync is supported + required: true +requirements: [ nova ] +''' + +EXAMPLES = ''' +nova_manage: action=dbsync +''' + +import subprocess + +try: + from nova.db.sqlalchemy import migration + from nova import config +except ImportError: + nova_found = False +else: + nova_found = True + + +def load_config_file(): + config.parse_args([]) + + +def will_db_change(): + """ Check if the database version will change after the sync. + + """ + # Load the config file options + current_version = migration.db_version() + repository = migration._find_migrate_repo() + repo_version = repository.latest + return current_version != repo_version + + +def do_dbsync(): + """Do the dbsync. Returns (returncode, stdout, stderr)""" + # We call nova-manage db_sync on the shell rather than trying to + # do this in Python since we have no guarantees about changes to the + # internals. + args = ['nova-manage', 'db', 'sync'] + + call = subprocess.Popen(args, shell=False, + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + out, err = call.communicate() + return (call.returncode, out, err) + + +def main(): + + module = AnsibleModule( + argument_spec=dict( + action=dict(required=True), + ), + supports_check_mode=True + ) + + if not nova_found: + module.fail_json(msg="nova package could not be found") + + action = module.params['action'] + + if action not in ['dbsync', 'db_sync']: + module.fail_json(msg="Only supported action is 'dbsync'") + + load_config_file() + + changed = will_db_change() + if module.check_mode: + module.exit_json(changed=changed) + + (res, stdout, stderr) = do_dbsync() + + if res == 0: + module.exit_json(changed=changed, stdout=stdout, stderr=stderr) + else: + module.fail_json(msg="nova-manage returned non-zero value: %d" % res, + stdout=stdout, stderr=stderr) + +# this is magic, see lib/ansible/module_common.py +#<> +main() diff --git a/openstack/usr/share/openstack/openstack-keystone-setup b/openstack/usr/share/openstack/openstack-keystone-setup deleted file mode 100644 index 9c034c5b..00000000 --- a/openstack/usr/share/openstack/openstack-keystone-setup +++ /dev/null @@ -1,92 +0,0 @@ -#!/bin/sh -# -# Copyright (C) 2014 Codethink Limited -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -set -e - -# Create required system users and groups - -getent group keystone >/dev/null || groupadd -r --gid 163 keystone -getent passwd keystone >/dev/null || \ - useradd --uid 163 -r -g keystone -d /var/lib/keystone -s /sbin/nologin \ - -c "OpenStack Keystone Daemons" keystone - -# Keystone compute configuration -if [ ! -d /var/run/keystone ]; then - mkdir -p /var/run/keystone - chown -R keystone:keystone /var/run/keystone -fi - -if [ ! -d /var/lock/keystone ]; then - mkdir -p /var/lock/keystone - chown -R keystone:keystone /var/lock/keystone -fi - -if [ ! -d /var/log/keystone ]; then - mkdir -p /var/log/keystone - chown -R keystone:keystone /var/log/keystone -fi - -# Setup the keystone database -if ! sudo -u postgres psql -lqt | grep -q keystone; then - # Create posgreSQL user - sudo -u postgres createuser \ - --pwprompt --encrypted \ - --no-adduser --no-createdb \ - --no-password \ - ##KEYSTONE_DB_USER## - - sudo -u postgres createdb \ - --owner=##KEYSTONE_DB_USER## \ - keystone - - sudo -u keystone keystone-manage db_sync -fi - -chown -R keystone:keystone /var/lib/keystone - -systemctl start openstack-keystone - -export OS_SERVICE_TOKEN=##KEYSTONE_TEMPORARY_ADMIN_TOKEN## -export OS_SERVICE_ENDPOINT='http://onenode:35357/v2.0' - -# This script creates a TEMPORARY admin user, with a password that may -# float arount on the system. Please delete this user once you have set up -# the real admin user with a real secure password. - -keystone tenant-create --name admin --description "Admin Tenant" -keystone role-create --name admin - -keystone user-create --name temporary_admin --pass ##KEYSTONE_TEMPORARY_ADMIN_PASSWORD## -keystone user-role-add --tenant admin --user temporary_admin --role admin - -keystone tenant-create --name service --description "Service Tenant" - -# Define a service for the Identity Service -keystone service-create --name keystone --type identity --description "Openstack Identity" - -# Specify an API endpoint for the Identity Service by using the returned service ID. -keystone endpoint-create --service-id $(keystone service-list | awk '/ identity / {print $2}') \ - --publicurl ##KEYSTONE_PUBLIC_URL## \ - --internalurl ##KEYSTONE_INTERNAL_URL## \ - --adminurl ##KEYSTONE_ADMIN_URL## - -rm /etc/systemd/system/multi-user.target.wants/openstack-keystone-setup.service - -ln -s "/etc/systemd/system/openstack-keystone.service" \ - "/etc/systemd/system/multi-user.target.wants/openstack-keystone.service" - -exit 0 -- cgit v1.2.1