refactoring final step

* added new logic into templates/default/keystone.conf.erb
* refactored attributes throughout all recipes that were connected to
  the attributes used for the keystone.conf.erb template to adapt the new
  template attribute syntax
* moved all attributes from attributes/default.rb that were used in
  keystone_conf.erb to attributes/keystone_conf.rb
* removed all attributes from default.rb and keystone.conf.erb which are set
  as default in attributes, openstack doc and used to render the template
* finished split between public, internal and admin endpoints
* refactored endpoint and bind_service logic to fit the new common cookbook
* adapted specs
* added endpoint and bind_service attributes (moved from common)
* removed keystone eventlet configuration (removed in mitaka)
* moved templated service catalog to its own section
* removed deprecated recipe for keystone server deployment without apache (also
  removed corresponding specs)
* moved recipe openrc (and template + specs) from common here, to remove inverse dependency in common
  cookbook
* adapted the specs (unit tests) to work again
* removed qpid as a messaging option (can be included in a wrapper)
* deleted default attributes from keystone.conf.rb originated in
  openstack-common
* removed suse as supported platform
* included current master of apache2 cookbook to utilize new listen logic
* removed rubocop exceptions in recipes and libraries and regenerated the
  .rubocop_todo.yaml conaining all remaining exceptions

Change-Id: I3262b2e6f792f37c32a446e6567790b82bdd4613
Implements: blueprint cookbook-refactoring
Depends-On: I0547182085eed91d05384fdd7734408a839a9a2c
This commit is contained in:
Jan Klare 2015-11-27 16:20:51 +01:00
parent 98030c26e0
commit a3f18966ea
22 changed files with 539 additions and 3763 deletions

View File

@ -1,15 +1,29 @@
# This configuration was generated by `rubocop --auto-gen-config`
# on 2015-05-28 16:50:06 -0500 using RuboCop version 0.29.1.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
# versions of RuboCop, may require this file to be generated again.
# Offense count: 1
Metrics/AbcSize:
Max: 19
# Offense count: 3
# Configuration parameters: EnforcedStyle, SupportedStyles.
Style/ClassAndModuleChildren:
Enabled: false
# This configuration was generated by
# `rubocop --auto-gen-config`
# on 2016-01-12 15:11:37 +0100 using RuboCop version 0.34.2.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
# versions of RuboCop, may require this file to be generated again.
# Offense count: 1
# Configuration parameters: CountKeywordArgs.
Metrics/ParameterLists:
Max: 6
# Offense count: 4
# Configuration parameters: EnforcedStyle, SupportedStyles.
Style/ClassAndModuleChildren:
Exclude:
- 'recipes/client.rb'
- 'recipes/openrc.rb'
- 'recipes/registration.rb'
- 'recipes/server-apache.rb'
# Offense count: 3
# Configuration parameters: Exclude.
Style/Documentation:
Exclude:
- 'recipes/client.rb'
- 'recipes/registration.rb'
- 'recipes/server-apache.rb'

View File

@ -4,3 +4,7 @@ metadata
cookbook "openstack-common",
github: "openstack/cookbook-openstack-common"
# use the current master branch until the new apache listen logic has been
# released
cookbook 'apache2',
github: "svanzoest-cookbooks/apache2"

14
Gemfile
View File

@ -1,14 +0,0 @@
## THIS GEMFILE IS DEPRECATED AND WILL BE REMOVED AFTER THE NEXT RELEASE
## THERE WON'T BE ANY UPDATES TO THIS FILE DURING THIS RELEASE CYCLE
## WE SWITCHED TO CHEFDK AS THE BUNDLE FOR THE NEEDED GEMS
source 'https://rubygems.org'
gem 'chef', '~> 11.18.6'
gem 'json', '<= 1.7.7' # chef 11 dependency
gem 'berkshelf', '~> 3.2.1'
gem 'hashie', '~> 2.0'
gem 'chefspec', '~> 4.0.0'
gem 'rspec', '~> 3.0.0'
gem 'foodcritic', '~> 4.0'
gem 'rubocop', '~> 0.29.1'

View File

@ -27,6 +27,25 @@ default['openstack']['identity']['custom_template_banner'] = "
# Do not edit, changes will be overwritten
"
# Set the endpoints for the identity service to allow all other cookbooks to
# access and use them
%w(public internal admin).each do |ep_type|
# openstack identity service endpoints (used by users and services)
default['openstack']['endpoints']['identity'][ep_type]['host'] = '127.0.0.1'
default['openstack']['endpoints']['identity'][ep_type]['scheme'] = 'http'
default['openstack']['endpoints']['identity'][ep_type]['path'] = '/v2.0'
# web-service (e.g. apache) listen address (can be different from openstack
# identity endpoints)
default['openstack']['bind_service']['identity'][ep_type]['host'] = '127.0.0.1'
end
%w(endpoints bind_service).each do |type|
default['openstack'][type]['identity']['public']['port'] = 5000
default['openstack'][type]['identity']['internal']['port'] = 5001
default['openstack'][type]['identity']['admin']['port'] = 35357
end
default['openstack']['identity']['catalog']['backend'] = 'sql'
default['openstack']['identity']['token']['backend'] = 'sql'
# Adding these as blank
# this needs to be here for the initial deep-merge to work
default['credentials']['EC2']['admin']['access'] = ''
@ -46,9 +65,6 @@ default['openstack']['identity']['start_delay'] = 10
# will be used (keystone-paste.ini.erb)
default['openstack']['identity']['pastefile_url'] = nil
# array of lines to add to templated version of keystone-paste.ini
default['openstack']['identity']['misc_paste'] = []
# This specify the pipeline of the keystone public API,
# all Identity public API requests will be processed by the order of the pipeline.
# this value will be used in the templated version of keystone-paste.ini
@ -69,64 +85,12 @@ default['openstack']['identity']['pipeline']['admin_api'] = 'sizelimit url_norma
default['openstack']['identity']['pipeline']['api_v3'] = 'sizelimit url_normalize request_id build_auth_context token_auth admin_token_auth json_body ec2_extension_v3 s3_extension simple_cert_extension revoke_extension federation_extension oauth1_extension endpoint_filter_extension service_v3'
default['openstack']['identity']['region'] = node['openstack']['region']
# Amount of time a token should remain valid in seconds)
default['openstack']['identity']['token']['expiration'] = '3600'
default['openstack']['identity']['token']['hash_algorithm'] = 'md5'
# Logging stuff
default['openstack']['identity']['syslog']['use'] = false
default['openstack']['identity']['syslog']['facility'] = 'LOG_LOCAL2'
default['openstack']['identity']['syslog']['config_facility'] = 'local2'
# Number of Workers
default['openstack']['identity']['admin_workers'] = nil
default['openstack']['identity']['public_workers'] = nil
# RPC attributes
default['openstack']['identity']['control_exchange'] = 'openstack'
default['openstack']['identity']['notification_driver'] = 'messaging'
default['openstack']['identity']['rpc_thread_pool_size'] = 64
default['openstack']['identity']['rpc_conn_pool_size'] = 30
default['openstack']['identity']['rpc_response_timeout'] = 60
case node['openstack']['mq']['service_type']
when 'rabbitmq'
default['openstack']['identity']['rpc_backend'] = 'rabbit'
when 'qpid'
default['openstack']['identity']['rpc_backend'] = 'qpid'
end
# 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['openstack']['identity']['identity']['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)
default['openstack']['identity']['identity']['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)
default['openstack']['identity']['identity']['domain_config_dir'] = '/etc/keystone/domains'
# Keystone Identity Mapping attributes
# # Keystone Identity Mapping backend driver, default is sql.
default['openstack']['identity']['identity_mapping']['driver'] = 'keystone.identity.mapping_backends.sql.Mapping'
# Public ID generator for user and group entities, default is sha256.
default['openstack']['identity']['identity_mapping']['generator'] = 'keystone.identity.id_generators.sha256.Generator'
# Setting this value to True makes that any user and group from default domain being handled by LDAP will still not be
# mapped to ensure their IDs remain backward compatible. You can only set it to False when configuring a fresh installation.
default['openstack']['identity']['identity_mapping']['backward_compatible_ids'] = 'True'
default['openstack']['identity']['admin_user'] = 'admin'
default['openstack']['identity']['admin_tenant_name'] = 'admin'
@ -140,6 +104,49 @@ default['openstack']['identity']['users'] = {
}
}
# SSL Options
# Specify whether to enable SSL for Keystone API endpoint
default['openstack']['identity']['ssl']['enabled'] = false
# Specify server whether to enforce client certificate requirement
default['openstack']['identity']['ssl']['cert_required'] = false
# SSL certificate, keyfile and CA certficate file locations
default['openstack']['identity']['ssl']['basedir'] = '/etc/keystone/ssl'
# Path of the cert file for SSL.
# Protocol for SSL (Apache)
default['openstack']['identity']['ssl']['protocol'] = 'All -SSLv2 -SSLv3'
# Which ciphers to use with the SSL/TLS protocol (Apache)
# Example: 'RSA:HIGH:MEDIUM:!LOW:!kEDH:!aNULL:!ADH:!eNULL:!EXP:!SSLv2:!SEED:!CAMELLIA:!PSK!RC4:!RC4-MD5:!RC4-SHA'
default['openstack']['identity']['ssl']['ciphers'] = nil
# PKI signing. Corresponds to the [signing] section of keystone.conf
# Note this section is only written if node['openstack']['auth']['strategy'] == 'pki'
default['openstack']['identity']['signing']['basedir'] = '/etc/keystone/ssl'
# The authorization configuration options
# The external (REMOTE_USER) auth plugin module. (String value)
default['openstack']['identity']['auth']['external'] = 'keystone.auth.plugins.external.DefaultDomain'
# Default auth methods. (List value)
default['openstack']['identity']['auth']['methods'] = 'external, password, token, oauth1'
# Token flushing cronjob
default['openstack']['identity']['token_flush_cron']['log_file'] = '/var/log/keystone/token-flush.log'
default['openstack']['identity']['token_flush_cron']['hour'] = '*'
default['openstack']['identity']['token_flush_cron']['minute'] = '0'
default['openstack']['identity']['token_flush_cron']['day'] = '*'
default['openstack']['identity']['token_flush_cron']['weekday'] = '*'
default['openstack']['identity']['token_flush_cron']['enabled'] = true
default['openstack']['identity']['identity']['domain_config_dir'] = '/etc/keystone/domains'
default['openstack']['identity']['signing']['basedir'] = '/etc/keystone/ssl'
default['openstack']['identity']['signing']['certfile'] = "#{node['openstack']['identity']['signing']['basedir']}/certs/signing_cert.pem"
default['openstack']['identity']['signing']['keyfile'] = "#{node['openstack']['identity']['signing']['basedir']}/private/signing_key.pem"
default['openstack']['identity']['signing']['ca_certs'] = "#{node['openstack']['identity']['signing']['basedir']}/certs/ca.pem"
# Misc option support
# Allow additional strings to be added to keystone.conf
# For example: ['# Comment', 'key=value']
default['openstack']['identity']['misc_keystone'] = []
# SSL Options
# Specify whether to enable SSL for Keystone API endpoint
default['openstack']['identity']['ssl']['enabled'] = false
@ -161,229 +168,6 @@ default['openstack']['identity']['ssl']['protocol'] = 'All -SSLv2 -SSLv3'
# Example: 'RSA:HIGH:MEDIUM:!LOW:!kEDH:!aNULL:!ADH:!eNULL:!EXP:!SSLv2:!SEED:!CAMELLIA:!PSK!RC4:!RC4-MD5:!RC4-SHA'
default['openstack']['identity']['ssl']['ciphers'] = nil
# Security Assertion Markup Language (SAML)
# Default TTL, in seconds, for any generated SAML assertion
# created by Keystone. (integer value)
default['openstack']['identity']['saml']['assertion_expiration_time'] = 3600
# Binary to be called for XML signing. Install the appropriate
# package, specify absolute path or adjust your PATH
# environment variable if the binary cannot be found. (string
# value)
# xmlsec1_binary=xmlsec1
default['openstack']['identity']['saml']['xmlsec1_binary'] = 'xmlsec1'
# Path of the certfile for SAML signing. For non-production
# environments, you may be interested in using `keystone-
# manage pki_setup` to generate self-signed certificates.
# Note, the path cannot contain a comma. (string value)
# certfile=/etc/keystone/ssl/certs/signing_cert.pem
default['openstack']['identity']['saml']['certfile'] = nil
# Path of the keyfile for SAML signing. Note, the path cannot
# contain a comma. (string value)
# keyfile=/etc/keystone/ssl/private/signing_key.pem
default['openstack']['identity']['saml']['keyfile'] = nil
# Entity ID value for unique Identity Provider identification.
# Usually FQDN is set with a suffix. A value is required to
# generate IDP Metadata. For example:
# https://keystone.example.com/v3/OS-FEDERATION/saml2/idp
# (string value)
default['openstack']['identity']['saml']['idp_entity_id'] = nil
# Identity Provider Single-Sign-On service value, required in
# the Identity Provider's metadata. A value is required to
# generate IDP Metadata. For example:
# https://keystone.example.com/v3/OS-FEDERATION/saml2/sso
# (string value)
default['openstack']['identity']['saml']['idp_sso_endpoint'] = nil
# Language used by the organization. (string value)
default['openstack']['identity']['saml']['idp_lang'] = nil
# Organization name the installation belongs to. (string
# value)
default['openstack']['identity']['saml']['idp_organization_name'] = nil
# Organization name to be displayed. (string value)
default['openstack']['identity']['saml']['idp_organization_display_name'] = nil
# URL of the organization. (string value)
default['openstack']['identity']['saml']['idp_organization_url'] = nil
# Company of contact person. (string value)
default['openstack']['identity']['saml']['idp_contact_company'] = nil
# Given name of contact person (string value)
default['openstack']['identity']['saml']['idp_contact_name'] = nil
# Surname of contact person. (string value)
default['openstack']['identity']['saml']['idp_contact_surname'] = nil
# Email address of contact person. (string value)
default['openstack']['identity']['saml']['idp_contact_email'] = nil
# Telephone number of contact person. (string value)
default['openstack']['identity']['saml']['idp_contact_telephone'] = nil
# Contact type. Allowed values are: technical, support,
# administrative billing, and other (string value)
default['openstack']['identity']['saml']['idp_contact_type'] = nil
# Path to the Identity Provider Metadata file. This file
# should be generated with the keystone-manage
# saml_idp_metadata command. (string value)
# idp_metadata_path=/etc/keystone/saml2_idp_metadata.xml
default['openstack']['identity']['saml']['idp_metadata_path'] = nil
# PKI signing. Corresponds to the [signing] section of keystone.conf
# Note this section is only written if node['openstack']['auth']['strategy'] == 'pki'
default['openstack']['identity']['signing']['basedir'] = '/etc/keystone/ssl'
default['openstack']['identity']['signing']['certfile'] = "#{node['openstack']['identity']['signing']['basedir']}/certs/signing_cert.pem"
default['openstack']['identity']['signing']['keyfile'] = "#{node['openstack']['identity']['signing']['basedir']}/private/signing_key.pem"
default['openstack']['identity']['signing']['ca_certs'] = "#{node['openstack']['identity']['signing']['basedir']}/certs/ca.pem"
default['openstack']['identity']['signing']['certfile_url'] = nil
default['openstack']['identity']['signing']['keyfile_url'] = nil
default['openstack']['identity']['signing']['ca_certs_url'] = nil
default['openstack']['identity']['signing']['key_size'] = '2048'
default['openstack']['identity']['signing']['valid_days'] = '3650'
default['openstack']['identity']['signing']['ca_password'] = nil
# These switches set the various drivers for the different Keystone components
default['openstack']['identity']['identity']['backend'] = 'sql'
default['openstack']['identity']['assignment']['backend'] = 'sql'
default['openstack']['identity']['token']['backend'] = 'sql'
default['openstack']['identity']['catalog']['backend'] = 'sql'
default['openstack']['identity']['policy']['backend'] = 'sql'
# 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 (identity, assignment,
# catalog or policy). (integer value)
default['openstack']['identity']['list_limit'] = nil
# The maximum number of entities that will be returned in an
# identity collection. (integer value)
default['openstack']['identity']['identity']['list_limit'] = nil
# Maximum number of entities that will be returned in an
# assignment collection.
default['openstack']['identity']['assignment']['list_limit'] = nil
# Maximum number of entities that will be returned in a
# catalog collection. (integer value)
default['openstack']['identity']['catalog']['list_limit'] = nil
# The maximum number of entities that will be returned in an
# policy collection. (integer value)
default['openstack']['identity']['policy']['list_limit'] = nil
# The authorization configuration options
# The external (REMOTE_USER) auth plugin module. (String value)
default['openstack']['identity']['auth']['external'] = 'keystone.auth.plugins.external.DefaultDomain'
# Default auth methods. (List value)
default['openstack']['identity']['auth']['methods'] = 'external, password, token, oauth1'
# LDAP backend general settings
default['openstack']['identity']['ldap']['url'] = 'ldap://localhost'
default['openstack']['identity']['ldap']['user'] = 'dc=Manager,dc=example,dc=com'
default['openstack']['identity']['ldap']['password'] = nil
default['openstack']['identity']['ldap']['suffix'] = 'cn=example,cn=com'
default['openstack']['identity']['ldap']['use_dumb_member'] = false
default['openstack']['identity']['ldap']['allow_subtree_delete'] = false
default['openstack']['identity']['ldap']['dumb_member'] = 'cn=dumb,dc=example,dc=com'
default['openstack']['identity']['ldap']['page_size'] = 0
default['openstack']['identity']['ldap']['alias_dereferencing'] = 'default'
default['openstack']['identity']['ldap']['query_scope'] = 'one'
default['openstack']['identity']['ldap']['use_tls'] = false
# If both tls_cacertfile and tls_cacertdir are set, then the cacertfile takes precedence and tls_cacertdir is not used
default['openstack']['identity']['ldap']['tls_cacertfile'] = nil
default['openstack']['identity']['ldap']['tls_cacertdir'] = nil
default['openstack']['identity']['ldap']['tls_req_cert'] = 'demand'
# LDAP backend user related settings
default['openstack']['identity']['ldap']['user_tree_dn'] = nil
default['openstack']['identity']['ldap']['user_filter'] = nil
default['openstack']['identity']['ldap']['user_objectclass'] = 'inetOrgPerson'
default['openstack']['identity']['ldap']['user_id_attribute'] = 'cn'
default['openstack']['identity']['ldap']['user_name_attribute'] = 'sn'
default['openstack']['identity']['ldap']['user_mail_attribute'] = 'email'
default['openstack']['identity']['ldap']['user_pass_attribute'] = 'userPassword'
default['openstack']['identity']['ldap']['user_enabled_attribute'] = 'enabled'
default['openstack']['identity']['ldap']['user_enabled_mask'] = 0
default['openstack']['identity']['ldap']['user_enabled_default'] = 'true'
default['openstack']['identity']['ldap']['user_attribute_ignore'] = 'tenant_id,tenants'
default['openstack']['identity']['ldap']['user_allow_create'] = true
default['openstack']['identity']['ldap']['user_allow_update'] = true
default['openstack']['identity']['ldap']['user_allow_delete'] = true
default['openstack']['identity']['ldap']['user_enabled_emulation'] = false
default['openstack']['identity']['ldap']['user_enabled_emulation_dn'] = nil
# LDAP backend tenant related settings
default['openstack']['identity']['ldap']['project_tree_dn'] = nil
default['openstack']['identity']['ldap']['project_filter'] = nil
default['openstack']['identity']['ldap']['project_objectclass'] = 'groupOfNames'
default['openstack']['identity']['ldap']['project_id_attribute'] = 'cn'
default['openstack']['identity']['ldap']['project_member_attribute'] = 'member'
default['openstack']['identity']['ldap']['project_name_attribute'] = 'ou'
default['openstack']['identity']['ldap']['project_desc_attribute'] = 'description'
default['openstack']['identity']['ldap']['project_enabled_attribute'] = 'enabled'
default['openstack']['identity']['ldap']['project_domain_id_attribute'] = 'businessCategory'
default['openstack']['identity']['ldap']['project_attribute_ignore'] = nil
default['openstack']['identity']['ldap']['project_allow_create'] = true
default['openstack']['identity']['ldap']['project_allow_update'] = true
default['openstack']['identity']['ldap']['project_allow_delete'] = true
default['openstack']['identity']['ldap']['project_enabled_emulation'] = false
default['openstack']['identity']['ldap']['project_enabled_emulation_dn'] = nil
# LDAP backend role related settings
default['openstack']['identity']['ldap']['role_tree_dn'] = nil
default['openstack']['identity']['ldap']['role_filter'] = nil
default['openstack']['identity']['ldap']['role_objectclass'] = 'organizationalRole'
default['openstack']['identity']['ldap']['role_id_attribute'] = 'cn'
default['openstack']['identity']['ldap']['role_name_attribute'] = 'ou'
default['openstack']['identity']['ldap']['role_member_attribute'] = 'roleOccupant'
default['openstack']['identity']['ldap']['role_attribute_ignore'] = nil
default['openstack']['identity']['ldap']['role_allow_create'] = true
default['openstack']['identity']['ldap']['role_allow_update'] = true
default['openstack']['identity']['ldap']['role_allow_delete'] = true
# LDAP backend group related settings
default['openstack']['identity']['ldap']['group_tree_dn'] = nil
default['openstack']['identity']['ldap']['group_filter'] = nil
default['openstack']['identity']['ldap']['group_objectclass'] = 'groupOfNames'
default['openstack']['identity']['ldap']['group_id_attribute'] = 'cn'
default['openstack']['identity']['ldap']['group_name_attribute'] = 'ou'
default['openstack']['identity']['ldap']['group_member_attribute'] = 'member'
default['openstack']['identity']['ldap']['group_desc_attribute'] = 'description'
default['openstack']['identity']['ldap']['group_attribute_ignore'] = nil
default['openstack']['identity']['ldap']['group_allow_create'] = true
default['openstack']['identity']['ldap']['group_allow_update'] = true
default['openstack']['identity']['ldap']['group_allow_delete'] = true
# LDAP connection pool settings
default['openstack']['identity']['ldap']['use_pool'] = false
default['openstack']['identity']['ldap']['pool_size'] = 10
default['openstack']['identity']['ldap']['pool_retry_max'] = 3
default['openstack']['identity']['ldap']['pool_retry_delay'] = 0.1
default['openstack']['identity']['ldap']['pool_connection_timeout'] = 3
default['openstack']['identity']['ldap']['pool_connection_lifetime'] = 600
default['openstack']['identity']['ldap']['use_auth_pool'] = false
default['openstack']['identity']['ldap']['auth_pool_size'] = 100
default['openstack']['identity']['ldap']['auth_pool_connection_lifetime'] = 60
# Token flushing cronjob
default['openstack']['identity']['token_flush_cron']['enabled'] = node['openstack']['identity']['token']['backend'] == 'sql'
default['openstack']['identity']['token_flush_cron']['log_file'] = '/var/log/keystone/token-flush.log'
default['openstack']['identity']['token_flush_cron']['hour'] = '*'
default['openstack']['identity']['token_flush_cron']['minute'] = '0'
default['openstack']['identity']['token_flush_cron']['day'] = '*'
default['openstack']['identity']['token_flush_cron']['weekday'] = '*'
# Misc option support
# Allow additional strings to be added to keystone.conf
# For example: ['# Comment', 'key=value']
default['openstack']['identity']['misc_keystone'] = []
# platform defaults
case platform_family
when 'fedora', 'rhel' # :pragma-foodcritic: ~FC024 - won't fix this
@ -398,18 +182,6 @@ when 'fedora', 'rhel' # :pragma-foodcritic: ~FC024 - won't fix this
'keystone_wsgi_file' => '/usr/share/keystone/keystone.wsgi',
'package_options' => ''
}
when 'suse'
default['openstack']['identity']['user'] = 'openstack-keystone'
default['openstack']['identity']['group'] = 'openstack-keystone'
default['openstack']['identity']['platform'] = {
'memcache_python_packages' => ['python-python-memcached'],
'keystone_packages' => ['openstack-keystone'],
'keystone_client_packages' => ['python-keystoneclient'],
'keystone_service' => 'openstack-keystone',
'keystone_process_name' => 'keystone-all',
'keystone_wsgi_file' => '/usr/share/keystone/wsgi.py',
'package_options' => ''
}
when 'debian'
default['openstack']['identity']['user'] = 'keystone'
default['openstack']['identity']['group'] = 'keystone'
@ -423,3 +195,14 @@ when 'debian'
'package_options' => "-o Dpkg::Options::='--force-confold' -o Dpkg::Options::='--force-confdef'"
}
end
# Array of bare options for openrc (e.g. 'option=value')
default['openstack']['misc_openrc'] = nil
# openrc location and owner
default['openstack']['openrc']['path'] = '/root'
default['openstack']['openrc']['file'] = 'openrc'
default['openstack']['openrc']['user'] = 'root'
default['openstack']['openrc']['group'] = 'root'
default['openstack']['openrc']['file_mode'] = '0600'
default['openstack']['openrc']['path_mode'] = '0700'

View File

@ -0,0 +1,30 @@
default['openstack']['identity']['conf_secrets'] = {}
default['openstack']['identity']['conf'].tap do |conf|
# [DEFAULT]
conf['DEFAULT']['verbose'] = false # true in docs
if node['openstack']['identity']['syslog']['use']
conf['DEFAULT']['log_config_append'] = '/etc/openstack/logging.conf'
else
conf['DEFAULT']['log_dir'] = '/var/log/keystone'
end
if node['openstack']['identity']['notification_driver'] == 'messaging'
conf['DEFAULT']['notification_topics'] = 'notifications'
end
conf['DEFAULT']['rpc_backend'] = node['openstack']['mq']['service_type']
# [assignment]
conf['assignment']['driver'] = 'keystone.assignment.backends.sql.Assignment'
# [auth]
conf['auth']['external'] = 'keystone.auth.plugins.external.DefaultDomain'
conf['auth']['methods'] = 'external, password, token, oauth1'
# [catalog]
conf['catalog']['driver'] = 'keystone.catalog.backends.sql.Catalog'
# [identity]
conf['identity']['domain_specific_drivers_enabled'] = false
# [policy]
conf['policy']['driver'] = 'keystone.policy.backends.sql.Policy'
end

View File

@ -4,16 +4,16 @@ maintainer_email 'openstack-dev@lists.openstack.org'
license 'Apache 2.0'
description 'The OpenStack Identity service Keystone.'
long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
version '12.0.0'
version '13.0.0'
recipe 'openstack-identity::client', 'Install packages required for keystone client'
recipe 'openstack-identity::server', 'Installs and Configures Keystone Service'
recipe 'openstack-identity::server-apache', 'Installs and Configures Keystone Service under Apache'
recipe 'openstack-identity::registration', 'Adds user, tenant, role and endpoint records to Keystone'
recipe 'openstack-identity::openrc', 'Creates openrc file'
%w(ubuntu fedora redhat centos suse).each do |os|
%w(ubuntu redhat centos).each do |os|
supports os
end
depends 'apache2', '~> 3.1.0'
depends 'openstack-common', '>= 12.0.0'
depends 'openstack-common', '>= 13.0.0'

View File

@ -25,119 +25,6 @@ require 'chef/mixin/shell_out'
include Chef::Mixin::ShellOut
include ::Openstack
private
def generate_boot_creds(resource)
{
'OS_SERVICE_ENDPOINT' => resource.auth_uri,
'OS_SERVICE_TOKEN' => resource.bootstrap_token
}
end
private
def generate_admin_creds(resource)
identity_endpoint = resource.identity_endpoint
identity_endpoint = endpoint('identity-admin').to_s unless identity_endpoint
{
'OS_USERNAME' => resource.admin_user,
'OS_PASSWORD' => resource.admin_pass,
'OS_TENANT_NAME' => resource.admin_tenant_name,
'OS_AUTH_URL' => identity_endpoint
}
end
private
def generate_user_creds(resource)
identity_endpoint = resource.identity_endpoint
identity_endpoint = endpoint('identity-api').to_s unless identity_endpoint
{
'OS_USERNAME' => resource.user_name,
'OS_PASSWORD' => resource.user_pass,
'OS_TENANT_NAME' => resource.tenant_name,
'OS_AUTH_URL' => identity_endpoint
}
end
private
def get_env(resource, env = 'boot')
case env
when 'boot'
generate_boot_creds(resource)
when 'user'
generate_user_creds(resource)
when 'admin'
generate_admin_creds(resource)
end
end
private
def identity_command(resource, cmd, args = {}, env = 'boot')
keystonecmd = ['keystone'] << '--insecure' << cmd
args.each do |key, val|
keystonecmd << "--#{key}" unless key.empty?
keystonecmd << val.to_s
end
cmd_env = get_env(resource, env)
Chef::Log.debug("Running identity command: #{keystonecmd} env: " + cmd_env.to_s)
rc = shell_out(keystonecmd, env: cmd_env)
fail "#{rc.stderr} (#{rc.exitstatus})" if rc.exitstatus != 0
rc.stdout
end
private
def identity_uuid(resource, type, key, value, args = {}, uuid_field = 'id') # rubocop: disable ParameterLists
rc = nil
begin
output = identity_command resource, "#{type}-list", args
output = prettytable_to_array(output)
rc = (type == 'endpoint') ? (search_uuid(output, uuid_field, key => value, 'region' => resource.endpoint_region)) : (search_uuid(output, uuid_field, key => value))
rescue RuntimeError => e
raise "Could not lookup uuid for #{type}:#{key}=>#{value}. Error was #{e.message}"
end
rc
end
private
def search_uuid(output, uuid_field, required_hash = {})
rc = nil
output.each do |obj|
rc = obj[uuid_field] if obj.key?(uuid_field) && required_hash.values - obj.values_at(*required_hash.keys) == []
end
rc
end
private
def service_need_updated?(resource, args = {}, uuid_field = 'id')
begin
output = identity_command resource, 'service-list', args
output = prettytable_to_array(output)
return search_uuid(output, uuid_field, 'name' => resource.service_name).nil?
rescue RuntimeError => e
raise "Could not check service attributes for service: type => #{resource.service_type}, name => #{resource.service_name}. Error was #{e.message}"
end
false
end
private
def endpoint_need_updated?(resource, key, value, args = {}, uuid_field = 'id')
begin
output = identity_command resource, 'endpoint-list', args
output = prettytable_to_array(output)
return search_uuid(output, uuid_field, key => value, 'region' => resource.endpoint_region, 'publicurl' => resource.endpoint_publicurl, 'internalurl' => resource.endpoint_internalurl, 'adminurl' => resource.endpoint_adminurl).nil?
rescue RuntimeError => e
raise "Could not check endpoint attributes for endpoint:#{key}=>#{value}. Error was #{e.message}"
end
false
end
action :create_service do
new_resource.updated_by_last_action(false)
if node['openstack']['identity']['catalog']['backend'] == 'templated'
@ -348,3 +235,105 @@ action :create_ec2_credentials do
raise "Unable to create EC2 Credentials for User '#{new_resource.user_name}' in Tenant '#{new_resource.tenant_name}' Error: " + e.message
end
end
private
def generate_boot_creds(resource)
{
'OS_SERVICE_ENDPOINT' => resource.auth_uri,
'OS_SERVICE_TOKEN' => resource.bootstrap_token
}
end
def generate_admin_creds(resource)
identity_endpoint = resource.identity_endpoint
identity_endpoint = admin_endpoint('identity').to_s unless identity_endpoint
{
'OS_USERNAME' => resource.admin_user,
'OS_PASSWORD' => resource.admin_pass,
'OS_TENANT_NAME' => resource.admin_tenant_name,
'OS_AUTH_URL' => identity_endpoint
}
end
def generate_user_creds(resource)
identity_endpoint = resource.identity_endpoint
identity_endpoint = public_endpoint('identity').to_s unless identity_endpoint
{
'OS_USERNAME' => resource.user_name,
'OS_PASSWORD' => resource.user_pass,
'OS_TENANT_NAME' => resource.tenant_name,
'OS_AUTH_URL' => identity_endpoint
}
end
def get_env(resource, env = 'boot')
case env
when 'boot'
generate_boot_creds(resource)
when 'user'
generate_user_creds(resource)
when 'admin'
generate_admin_creds(resource)
end
end
def identity_command(resource, cmd, args = {}, env = 'boot')
keystonecmd = build_keystone_cmd(cmd, args)
cmd_env = get_env(resource, env)
Chef::Log.debug("Running identity command: #{keystonecmd} env: " + cmd_env.to_s)
rc = shell_out(keystonecmd, env: cmd_env)
fail "#{rc.stderr} (#{rc.exitstatus})" if rc.exitstatus != 0
rc.stdout
end
def build_keystone_cmd(cmd, args)
keystonecmd = ['keystone'] << '--insecure' << cmd
args.each do |key, val|
keystonecmd << "--#{key}" unless key.empty?
keystonecmd << val.to_s
end
keystonecmd
end
def identity_uuid(resource, type, key, value, args = {}, uuid_field = 'id')
rc = nil
begin
output = identity_command resource, "#{type}-list", args
output = prettytable_to_array(output)
rc = (type == 'endpoint') ? (search_uuid(output, uuid_field, key => value, 'region' => resource.endpoint_region)) : (search_uuid(output, uuid_field, key => value))
rescue RuntimeError => e
raise "Could not lookup uuid for #{type}:#{key}=>#{value}. Error was #{e.message}"
end
rc
end
def search_uuid(output, uuid_field, required_hash = {})
rc = nil
output.each do |obj|
rc = obj[uuid_field] if obj.key?(uuid_field) && required_hash.values - obj.values_at(*required_hash.keys) == []
end
rc
end
def service_need_updated?(resource, args = {}, uuid_field = 'id')
begin
output = identity_command resource, 'service-list', args
output = prettytable_to_array(output)
return search_uuid(output, uuid_field, 'name' => resource.service_name).nil?
rescue RuntimeError => e
raise "Could not check service attributes for service: type => #{resource.service_type}, name => #{resource.service_name}. Error was #{e.message}"
end
false
end
def endpoint_need_updated?(resource, key, value, args = {}, uuid_field = 'id')
begin
output = identity_command resource, 'endpoint-list', args
output = prettytable_to_array(output)
return search_uuid(output, uuid_field, key => value, 'region' => resource.endpoint_region, 'publicurl' => resource.endpoint_publicurl, 'internalurl' => resource.endpoint_internalurl, 'adminurl' => resource.endpoint_adminurl).nil?
rescue RuntimeError => e
raise "Could not check endpoint attributes for endpoint:#{key}=>#{value}. Error was #{e.message}"
end
false
end

View File

@ -18,7 +18,7 @@
# limitations under the License.
#
class ::Chef::Recipe # rubocop:disable Documentation
class ::Chef::Recipe
include ::Openstack
end

65
recipes/openrc.rb Normal file
View File

@ -0,0 +1,65 @@
# encoding: UTF-8
#
# Cookbook Name:: openstack-identity
# recipe:: openrc
#
# Copyright 2014 IBM Corp.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Chef
class ::Chef::Recipe
include ::Openstack
end
# check attributes before searching
if node['openstack']['identity'] && node['openstack']['identity']['admin_tenant_name'] && node['openstack']['identity']['admin_user']
ksadmin_tenant_name = node['openstack']['identity']['admin_tenant_name']
ksadmin_user = node['openstack']['identity']['admin_user']
else
identity_service_role = node['openstack']['identity_service_chef_role']
keystone = search_for(identity_service_role).first
if keystone.nil?
Chef::Log.warn("openrc not created, identity role node not found: #{identity_service_role}")
return
end
ksadmin_tenant_name = keystone['openstack']['identity']['admin_tenant_name']
ksadmin_user = keystone['openstack']['identity']['admin_user']
end
ksadmin_pass = get_password 'user', ksadmin_user
identity_public_endpoint = public_endpoint 'identity'
directory node['openstack']['openrc']['path'] do
owner node['openstack']['openrc']['user']
group node['openstack']['openrc']['group']
mode node['openstack']['openrc']['path_mode']
recursive true
end
template "#{node['openstack']['openrc']['path']}/#{node['openstack']['openrc']['file']}" do
source 'openrc.erb'
owner node['openstack']['openrc']['user']
group node['openstack']['openrc']['group']
mode node['openstack']['openrc']['file_mode']
sensitive true
variables(
user: ksadmin_user,
tenant: ksadmin_tenant_name,
password: ksadmin_pass,
identity_endpoint: identity_public_endpoint
)
end

View File

@ -21,34 +21,27 @@
require 'uri'
class ::Chef::Recipe # rubocop:disable Documentation
class ::Chef::Recipe
include ::Openstack
end
# TBD clean up item...
# These should probably become admin, internal, public endpoints for a
# single service 'identity-api'. To minimize impact, I propose that we
# defer that work until later.
identity_admin_endpoint = admin_endpoint 'identity-admin'
identity_internal_endpoint = internal_endpoint 'identity-internal'
identity_public_endpoint = public_endpoint 'identity-api'
identity_admin_endpoint = admin_endpoint 'identity'
identity_internal_endpoint = internal_endpoint 'identity'
identity_public_endpoint = public_endpoint 'identity'
auth_uri = ::URI.decode identity_admin_endpoint.to_s
# FIXME(invsblduck): RuboCop gating was enabled mid-review;
# Remove these variables in a separate commit if really not needed.
admin_tenant_name = node['openstack']['identity']['admin_tenant_name']
admin_user = node['openstack']['identity']['admin_user']
admin_pass = get_password 'user', node['openstack']['identity']['admin_user']
# rubocop:enable UselessAssignment
bootstrap_token = get_password 'token', 'openstack_identity_bootstrap_token'
# FIXME(galstrom21): This needs to be refactored, to not use a
# MultilineBlockChain.
# Register all the tenants specified in the users hash
node['openstack']['identity']['users'].values.map do |user_info|
identity_tenants = node['openstack']['identity']['users'].values.map do |user_info|
user_info['roles'].values.push(user_info['default_tenant'])
end.flatten.uniq.each do |tenant_name| # rubocop: disable MultilineBlockChain
end
identity_tenants.flatten.uniq.each do |tenant_name|
openstack_identity_register "Register '#{tenant_name}' Tenant" do
auth_uri auth_uri
bootstrap_token bootstrap_token
@ -59,12 +52,12 @@ end.flatten.uniq.each do |tenant_name| # rubocop: disable MultilineBlockChain
end
end
# FIXME(galstrom21): This needs to be refactored, to not use a
# MultilineBlockChain.
# Register all the roles from the users hash
node['openstack']['identity']['users'].values.map do |user_info|
identity_roles = node['openstack']['identity']['users'].values.map do |user_info|
user_info['roles'].keys
end.flatten.uniq.each do |role_name| # rubocop: disable MultilineBlockChain
end
identity_roles.flatten.uniq.each do |role_name|
openstack_identity_register "Register '#{role_name}' Role" do
auth_uri auth_uri
bootstrap_token bootstrap_token

View File

@ -20,7 +20,7 @@
require 'uri'
class ::Chef::Recipe # rubocop:disable Documentation
class ::Chef::Recipe
include ::Openstack
end
@ -109,7 +109,7 @@ if node['openstack']['auth']['strategy'] == 'pki'
user node['openstack']['identity']['user']
group node['openstack']['identity']['group']
not_if { ::FileTest.exists? node['openstack']['identity']['signing']['keyfile'] }
not_if { ::FileTest.exists? "#{node['openstack']['identity']['signing']['basedir']}/private/signing_key.pem" }
end
else
remote_file node['openstack']['identity']['signing']['certfile'] do
@ -135,44 +135,30 @@ if node['openstack']['auth']['strategy'] == 'pki'
end
end
# Note that identity-bind and identity-admin-bind are not
# service endpoints where there could be separate 'admin',
# 'public', and 'internal'. (Well, actually I suppose we
# could shoehorn it into that infrastructure, but for now
# I propose that we leave them with the general endpoint
# lookup routine.)
bind_endpoint = endpoint 'identity-bind'
admin_bind_endpoint = endpoint 'identity-admin-bind'
identity_admin_endpoint = admin_endpoint 'identity-admin'
public_bind_service = node['openstack']['bind_service']['identity']['public']
internal_bind_service = node['openstack']['bind_service']['identity']['internal']
admin_bind_service = node['openstack']['bind_service']['identity']['admin']
# These values are going into the templated catalog and
# since they're the endpoints being used by the clients,
# we should put in the public endpoints for each service.
identity_endpoint = public_endpoint 'identity-api'
compute_endpoint = public_endpoint 'compute-api'
ec2_endpoint = public_endpoint 'compute-ec2-api'
image_endpoint = public_endpoint 'image-api'
network_endpoint = public_endpoint 'network-api'
volume_endpoint = public_endpoint 'block-storage-api'
identity_admin_endpoint = admin_endpoint 'identity'
db_user = node['openstack']['db']['identity']['username']
db_pass = get_password 'db', 'keystone'
sql_connection = db_uri('identity', db_user, db_pass)
node.default['openstack']['identity']['conf_secrets']
.[]('database')['connection'] =
db_uri('identity', db_user, db_pass)
bootstrap_token = get_password 'token', 'openstack_identity_bootstrap_token'
bind_address = bind_endpoint.host
admin_bind_address = admin_bind_endpoint.host
# If the search role is set, we search for memcache
# servers via a Chef search. If not, we look at the
# memcache.servers attribute.
memcache_servers = memcached_servers.join ',' # from openstack-common lib
memcache_servers = memcached_servers.join ',' # from openstack-common lib
# These configuration endpoints must not have the path (v2.0, etc)
# added to them, as these values are used in returning the version
# listing information from the root / endpoint.
ie = identity_endpoint
identity_public_endpoint = public_endpoint 'identity'
ie = identity_public_endpoint
public_endpoint = "#{ie.scheme}://#{ie.host}:#{ie.port}/"
ae = identity_admin_endpoint
admin_endpoint = "#{ae.scheme}://#{ae.host}:#{ae.port}/"
@ -198,60 +184,79 @@ else
end
end
mq_service_type = node['openstack']['mq']['identity']['service_type']
if mq_service_type == 'rabbitmq'
node['openstack']['mq']['identity']['rabbit']['ha'] && (rabbit_hosts = rabbit_servers)
mq_password = get_password 'user', node['openstack']['mq']['identity']['rabbit']['userid']
elsif mq_service_type == 'qpid'
mq_password = get_password 'user', node['openstack']['mq']['identity']['qpid']['username']
if node['openstack']['identity']['conf']['DEFAULT']['rpc_backend'] == 'rabbit'
user = node['openstack']['mq']['identity']['rabbit']['userid']
node.default['openstack']['identity']['conf_secrets']
.[]('oslo_messaging_rabbit')['rabbit_userid'] = user
node.default['openstack']['identity']['conf_secrets']
.[]('oslo_messaging_rabbit')['rabbit_password'] =
get_password 'user', user
end
node.default['openstack']['identity']['conf'].tap do |conf|
# [DEFAULT] section
conf['DEFAULT']['admin_token'] = bootstrap_token
conf['DEFAULT']['public_endpoint'] = public_endpoint
conf['DEFAULT']['admin_endpoint'] = admin_endpoint
# [memcache] section
conf['memcache']['servers'] = memcache_servers if memcache_servers
end
# merge all config options and secrets to be used in the nova.conf.erb
keystone_conf_options = merge_config_options 'identity'
template '/etc/keystone/keystone.conf' do
source 'keystone.conf.erb'
source 'openstack-service.conf.erb'
cookbook 'openstack-common'
owner node['openstack']['identity']['user']
group node['openstack']['identity']['group']
mode 00640
variables(
sql_connection: sql_connection,
bind_address: bind_address,
admin_bind_address: admin_bind_address,
bootstrap_token: bootstrap_token,
memcache_servers: memcache_servers,
public_endpoint: public_endpoint,
public_port: identity_endpoint.port,
admin_endpoint: admin_endpoint,
admin_port: identity_admin_endpoint.port,
ldap: node['openstack']['identity']['ldap'],
token_expiration: node['openstack']['identity']['token']['expiration'],
rabbit_hosts: rabbit_hosts,
notification_driver: node['openstack']['identity']['notification_driver'],
mq_service_type: mq_service_type,
mq_password: mq_password
service_config: keystone_conf_options
)
end
# populate the templated catlog, if you're using the templated catalog backend
uris = {
'identity-admin' => identity_admin_endpoint.to_s.gsub('%25', '%'),
'identity' => identity_endpoint.to_s.gsub('%25', '%'),
'image' => image_endpoint.to_s.gsub('%25', '%'),
'compute' => compute_endpoint.to_s.gsub('%25', '%'),
'ec2' => ec2_endpoint.to_s.gsub('%25', '%'),
'network' => network_endpoint.to_s.gsub('%25', '%'),
'volume' => volume_endpoint.to_s.gsub('%25', '%')
}
# delete all secrets saved in the attribute
# node['openstack']['identity']['conf_secrets'] after creating the keystone.conf
ruby_block "delete all attributes in node['openstack']['identity']['conf_secrets']" do
block do
node.rm(:openstack, :identity, :conf_secrets)
end
end
template '/etc/keystone/default_catalog.templates' do
source 'default_catalog.templates.erb'
owner node['openstack']['identity']['user']
group node['openstack']['identity']['group']
mode 00644
variables(
uris: uris
)
# TODO: (jklare) needs to be refactored and filled by the service cookbooks, to
# avoid dependencies on unused cookbooks
if node['openstack']['identity']['catalog']['backend'] == 'templated'
# These values are going into the templated catalog and
# since they're the endpoints being used by the clients,
# we should put in the public endpoints for each service.
compute_public_endpoint = public_endpoint 'compute'
ec2_public_endpoint = public_endpoint 'compute-ec2'
image_public_endpoint = public_endpoint 'image'
network_public_endpoint = public_endpoint 'network'
volume_public_endpoint = public_endpoint 'block-storage'
only_if { node['openstack']['identity']['catalog']['backend'] == 'templated' }
# populate the templated catlog, if you're using the templated catalog backend
# TODO: (jklare) this should be done in a helper method
uris = {
'identity-admin' => identity_admin_endpoint.to_s.gsub('%25', '%'),
'identity' => identity_public_endpoint.to_s.gsub('%25', '%'),
'image' => image_public_endpoint.to_s.gsub('%25', '%'),
'compute' => compute_public_endpoint.to_s.gsub('%25', '%'),
'ec2' => ec2_public_endpoint.to_s.gsub('%25', '%'),
'network' => network_public_endpoint.to_s.gsub('%25', '%'),
'volume' => volume_public_endpoint.to_s.gsub('%25', '%')
}
template '/etc/keystone/default_catalog.templates' do
source 'default_catalog.templates.erb'
owner node['openstack']['identity']['user']
group node['openstack']['identity']['group']
mode 00644
variables(
uris: uris
)
end
end
# sync db after keystone.conf is generated
@ -279,10 +284,13 @@ end
#### Start of Apache specific work
listen_addresses = node['apache']['listen_addresses'] - ['*'] + [bind_address, admin_bind_address]
listen_ports = node['apache']['listen_ports'] - ['80'] + [identity_endpoint.port, identity_admin_endpoint.port]
node.set['apache']['listen_addresses'] = listen_addresses.uniq
node.set['apache']['listen_ports'] = listen_ports.uniq
apache_listen_public = { public_bind_service.host => [public_bind_service.port.to_s] }
apache_listen_internal = { internal_bind_service.host => [internal_bind_service.port.to_s] }
apache_listen_admin = { admin_bind_service.host => [admin_bind_service.port.to_s] }
apache_listen = Chef::Mixin::DeepMerge.merge(Chef::Mixin::DeepMerge.merge(apache_listen_public, apache_listen_internal), apache_listen_admin)
node.normal['apache']['listen'] =
Chef::Mixin::DeepMerge.merge(node['apache']['listen'], apache_listen)
include_recipe 'apache2'
include_recipe 'apache2::mod_wsgi'
@ -296,11 +304,12 @@ directory keystone_apache_dir do
end
server_entry_public = "#{keystone_apache_dir}/main"
server_entry_internal = "#{keystone_apache_dir}/internal"
server_entry_admin = "#{keystone_apache_dir}/admin"
# Note: Using lazy here as the wsgi file is not available until after
# the keystone package is installed during execution phase.
[server_entry_public, server_entry_admin].each do |server_entry|
[server_entry_public, server_entry_internal, server_entry_admin].each do |server_entry|
file server_entry do
content lazy { IO.read(platform_options['keystone_wsgi_file']) }
owner 'root'
@ -311,13 +320,18 @@ end
wsgi_apps = {
'public' => {
server_host: bind_address,
server_port: identity_endpoint.port,
server_host: public_bind_service.host,
server_port: public_bind_service.port,
server_entry: server_entry_public
},
'internal' => {
server_host: internal_bind_service.host,
server_port: internal_bind_service.port,
server_entry: server_entry_internal
},
'admin' => {
server_host: admin_bind_address,
server_port: identity_admin_endpoint.port,
server_host: admin_bind_service.host,
server_port: admin_bind_service.port,
server_entry: server_entry_admin
}
}

View File

@ -1,301 +0,0 @@
# encoding: UTF-8
#
# Cookbook Name:: openstack-identity
# Recipe:: server
#
# Copyright 2012, Rackspace US, Inc.
# Copyright 2012-2013, Opscode, Inc.
# Copyright 2013-2014 SUSE LINUX Products GmbH.
#
# Licensed under the Apache License, Version 2.0 (the 'License');
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an 'AS IS' BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
require 'uri'
class ::Chef::Recipe # rubocop:disable Documentation
include ::Openstack
end
if node['openstack']['identity']['syslog']['use']
include_recipe 'openstack-common::logging'
end
platform_options = node['openstack']['identity']['platform']
db_type = node['openstack']['db']['identity']['service_type']
unless db_type == 'sqlite'
node['openstack']['db']['python_packages'][db_type].each do |pkg|
package "identity cookbook package #{pkg}" do
package_name pkg
options platform_options['package_options']
action :upgrade
end
end
end
platform_options['memcache_python_packages'].each do |pkg|
package "identity cookbook package #{pkg}" do
package_name pkg
options platform_options['package_options']
action :upgrade
end
end
platform_options['keystone_packages'].each do |pkg|
package "identity cookbook package #{pkg}" do
package_name pkg
options platform_options['package_options']
action :upgrade
end
end
execute 'Keystone: sleep' do
command "sleep #{node['openstack']['identity']['start_delay']}"
action :nothing
end
service 'keystone' do
service_name platform_options['keystone_service']
supports status: true, restart: true
action [:enable]
notifies :run, 'execute[Keystone: sleep]', :immediately
end
directory '/etc/keystone' do
owner node['openstack']['identity']['user']
group node['openstack']['identity']['group']
mode 00700
end
directory node['openstack']['identity']['identity']['domain_config_dir'] do
owner node['openstack']['identity']['user']
group node['openstack']['identity']['group']
mode 00700
only_if { node['openstack']['identity']['identity']['domain_specific_drivers_enabled'] }
end
file '/var/lib/keystone/keystone.db' do
action :delete
not_if { node['openstack']['db']['identity']['service_type'] == 'sqlite' }
end
if node['openstack']['auth']['strategy'] == 'pki'
certfile_url = node['openstack']['identity']['signing']['certfile_url']
keyfile_url = node['openstack']['identity']['signing']['keyfile_url']
ca_certs_url = node['openstack']['identity']['signing']['ca_certs_url']
signing_basedir = node['openstack']['identity']['signing']['basedir']
directory signing_basedir do
owner node['openstack']['identity']['user']
group node['openstack']['identity']['group']
mode 00700
end
directory "#{signing_basedir}/certs" do
owner node['openstack']['identity']['user']
group node['openstack']['identity']['group']
mode 00755
end
directory "#{signing_basedir}/private" do
owner node['openstack']['identity']['user']
group node['openstack']['identity']['group']
mode 00750
end
if certfile_url.nil? || keyfile_url.nil? || ca_certs_url.nil?
execute 'keystone-manage pki_setup' do
user node['openstack']['identity']['user']
group node['openstack']['identity']['group']
not_if { ::FileTest.exists? node['openstack']['identity']['signing']['keyfile'] }
end
else
remote_file node['openstack']['identity']['signing']['certfile'] do
source certfile_url
owner node['openstack']['identity']['user']
group node['openstack']['identity']['group']
mode 00640
notifies :restart, 'service[keystone]', :delayed
end
remote_file node['openstack']['identity']['signing']['keyfile'] do
source keyfile_url
owner node['openstack']['identity']['user']
group node['openstack']['identity']['group']
mode 00640
notifies :restart, 'service[keystone]', :delayed
end
remote_file node['openstack']['identity']['signing']['ca_certs'] do
source ca_certs_url
owner node['openstack']['identity']['user']
group node['openstack']['identity']['group']
mode 00640
notifies :restart, 'service[keystone]', :delayed
end
end
end
# Note that identity-bind and identity-admin-bind are not
# service endpoints where there could be separate 'admin',
# 'public', and 'internal'. (Well, actually I suppose we
# could shoehorn it into that infrastructure, but for now
# I propose that we leave them with the general endpoint
# lookup routine.)
bind_endpoint = endpoint 'identity-bind'
admin_bind_endpoint = endpoint 'identity-admin-bind'
identity_admin_endpoint = admin_endpoint 'identity-admin'
# These values are going into the templated catalog and
# since they're the endpoints being used by the clients,
# we should put in the public endpoints for each service.
identity_endpoint = public_endpoint 'identity-api'
compute_endpoint = public_endpoint 'compute-api'
ec2_endpoint = public_endpoint 'compute-ec2-api'
image_endpoint = public_endpoint 'image-api'
network_endpoint = public_endpoint 'network-api'
volume_endpoint = public_endpoint 'block-storage-api'
db_user = node['openstack']['db']['identity']['username']
db_pass = get_password 'db', 'keystone'
sql_connection = db_uri('identity', db_user, db_pass)
bootstrap_token = get_password 'token', 'openstack_identity_bootstrap_token'
bind_address = bind_endpoint.host
admin_bind_address = admin_bind_endpoint.host
# If the search role is set, we search for memcache
# servers via a Chef search. If not, we look at the
# memcache.servers attribute.
memcache_servers = memcached_servers.join ',' # from openstack-common lib
# These configuration endpoints must not have the path (v2.0, etc)
# added to them, as these values are used in returning the version
# listing information from the root / endpoint.
ie = identity_endpoint
public_endpoint = "#{ie.scheme}://#{ie.host}:#{ie.port}/"
ae = identity_admin_endpoint
admin_endpoint = "#{ae.scheme}://#{ae.host}:#{ae.port}/"
# If a keystone-paste.ini is specified use it.
# If platform_family is RHEL and we do not specify keystone-paste.ini,
# copy in /usr/share/keystone/keystone-dist-paste.ini since
# /etc/keystone/keystone-paste.ini is not packaged.
if node['openstack']['identity']['pastefile_url']
remote_file '/etc/keystone/keystone-paste.ini' do
action :create_if_missing
source node['openstack']['identity']['pastefile_url']
owner node['openstack']['identity']['user']
group node['openstack']['identity']['group']
mode 00644
notifies :restart, 'service[keystone]', :delayed
end
else
template '/etc/keystone/keystone-paste.ini' do
source 'keystone-paste.ini.erb'
owner node['openstack']['identity']['user']
group node['openstack']['identity']['group']
mode 00644
notifies :restart, 'service[keystone]', :delayed
end
end
mq_service_type = node['openstack']['mq']['identity']['service_type']
if mq_service_type == 'rabbitmq'
node['openstack']['mq']['identity']['rabbit']['ha'] && (rabbit_hosts = rabbit_servers)
mq_password = get_password 'user', node['openstack']['mq']['identity']['rabbit']['userid']
elsif mq_service_type == 'qpid'
mq_password = get_password 'user', node['openstack']['mq']['identity']['qpid']['username']
end
template '/etc/keystone/keystone.conf' do
source 'keystone.conf.erb'
owner node['openstack']['identity']['user']
group node['openstack']['identity']['group']
mode 00640
variables(
sql_connection: sql_connection,
bind_address: bind_address,
admin_bind_address: admin_bind_address,
bootstrap_token: bootstrap_token,
memcache_servers: memcache_servers,
public_endpoint: public_endpoint,
public_port: identity_endpoint.port,
admin_endpoint: admin_endpoint,
admin_port: identity_admin_endpoint.port,
ldap: node['openstack']['identity']['ldap'],
token_expiration: node['openstack']['identity']['token']['expiration'],
rabbit_hosts: rabbit_hosts,
notification_driver: node['openstack']['identity']['notification_driver'],
mq_service_type: mq_service_type,
mq_password: mq_password
)
notifies :restart, 'service[keystone]', :immediately
end
# populate the templated catlog, if you're using the templated catalog backend
uris = {
'identity-admin' => identity_admin_endpoint.to_s.gsub('%25', '%'),
'identity' => identity_endpoint.to_s.gsub('%25', '%'),
'image' => image_endpoint.to_s.gsub('%25', '%'),
'compute' => compute_endpoint.to_s.gsub('%25', '%'),
'ec2' => ec2_endpoint.to_s.gsub('%25', '%'),
'network' => network_endpoint.to_s.gsub('%25', '%'),
'volume' => volume_endpoint.to_s.gsub('%25', '%')
}
template '/etc/keystone/default_catalog.templates' do
source 'default_catalog.templates.erb'
owner node['openstack']['identity']['user']
group node['openstack']['identity']['group']
mode 00644
variables(
uris: uris
)
notifies :restart, 'service[keystone]', :immediately
only_if { node['openstack']['identity']['catalog']['backend'] == 'templated' }
end
# sync db after keystone.conf is generated
execute 'keystone-manage db_sync' do
user node['openstack']['identity']['user']
group node['openstack']['identity']['group']
only_if { node['openstack']['db']['identity']['migrate'] }
end
# Configure the flush tokens cronjob
should_run_cron = node['openstack']['identity']['token_flush_cron']['enabled'] && node['openstack']['identity']['token']['backend'] == 'sql'
log_file = node['openstack']['identity']['token_flush_cron']['log_file']
cron 'keystone-manage-token-flush' do
minute node['openstack']['identity']['token_flush_cron']['minute']
hour node['openstack']['identity']['token_flush_cron']['hour']
day node['openstack']['identity']['token_flush_cron']['day']
weekday node['openstack']['identity']['token_flush_cron']['weekday']
action should_run_cron ? :create : :delete
user node['openstack']['identity']['user']
command "keystone-manage token_flush > #{log_file} 2>&1; "\
"echo keystone-manage token_flush ran at $(/bin/date) with exit code $? >> #{log_file}"
end

65
spec/openrc_spec.rb Normal file
View File

@ -0,0 +1,65 @@
# encoding: UTF-8
require_relative 'spec_helper'
describe 'openstack-identity::openrc' do
describe 'ubuntu' do
let(:runner) { ChefSpec::SoloRunner.new(UBUNTU_OPTS) }
let(:node) { runner.node }
let(:chef_run) do
runner.converge(described_recipe)
end
include_context 'identity_stubs'
describe '/root/openrc' do
let(:file) { chef_run.template('/root/openrc') }
it 'creates the /root/openrc file' do
expect(chef_run).to create_directory('/root').with(
owner: 'root',
group: 'root',
mode: '0700',
recursive: true
)
expect(chef_run).to create_template(file.name).with(
sensitive: true,
user: 'root',
group: 'root',
mode: '0600'
)
end
it 'contains auth environment variables' do
[
/^export OS_USERNAME=admin$/,
/^export OS_TENANT_NAME=admin$/,
/^export OS_PASSWORD=admin$/,
%r{^export OS_AUTH_URL=http://127.0.0.1:5000/v2.0$},
/^export OS_REGION_NAME=RegionOne$/
].each do |line|
expect(chef_run).to render_file(file.name).with_content(line)
end
end
it 'templates misc_openrc array correctly' do
node.set['openstack']['misc_openrc'] = ['export MISC1=OPTION1', 'export MISC2=OPTION2']
expect(chef_run).to render_file(file.name).with_content(
/^export MISC1=OPTION1$/)
expect(chef_run).to render_file(file.name).with_content(
/^export MISC2=OPTION2$/)
end
it 'contains overridden auth environment variables' do
node.set['openstack']['identity']['admin_tenant_name'] = 'admin-tenant-name-override'
node.set['openstack']['identity']['admin_user'] = 'admin-user-override'
[
/^export OS_USERNAME=admin-user-override$/,
/^export OS_TENANT_NAME=admin-tenant-name-override$/
].each do |line|
expect(chef_run).to render_file(file.name).with_content(line)
end
end
end
end
end

View File

@ -11,6 +11,9 @@ describe 'openstack-identity::default' do
let(:cookbook_collection) { Chef::CookbookCollection.new([]) }
let(:run_context) { Chef::RunContext.new(node, cookbook_collection, events) }
# needed to create the provider class OpenstackIdentityRegister by chef magic
before { chef_run }
describe 'tenant_create' do
let(:resource) do
r = Chef::Resource::OpenstackIdentityRegister.new('tenant1',

View File

@ -104,7 +104,7 @@ describe 'openstack-identity::registration' do
auth_uri: 'http://127.0.0.1:35357/v2.0',
bootstrap_token: 'bootstrap-token',
user_name: user,
user_pass: '',
user_pass: 'admin',
tenant_name: tenant
)
end
@ -134,7 +134,7 @@ describe 'openstack-identity::registration' do
tenant_name: tenant,
admin_tenant_name: 'admin',
admin_user: 'admin',
admin_pass: ''
admin_pass: 'admin'
)
end
end
@ -178,7 +178,7 @@ describe 'openstack-identity::registration' do
tenant_name: 'default_tenant1',
admin_tenant_name: 'admin',
admin_user: 'admin',
admin_pass: ''
admin_pass: 'admin'
)
end
end
@ -239,7 +239,7 @@ describe 'openstack-identity::registration' do
service_type: 'identity',
endpoint_region: 'RegionOne',
endpoint_adminurl: 'http://127.0.0.1:35357/v2.0',
endpoint_internalurl: 'http://127.0.0.1:5000/v2.0',
endpoint_internalurl: 'http://127.0.0.1:5001/v2.0',
endpoint_publicurl: 'http://127.0.0.1:5000/v2.0'
)
end
@ -252,15 +252,15 @@ describe 'openstack-identity::registration' do
end
it 'overrides identity endpoints' do
node.set['openstack']['endpoints']['identity-admin']['host'] = '127.0.0.2'
node.set['openstack']['endpoints']['identity-admin']['port'] = '5002'
node.set['openstack']['endpoints']['identity-admin']['path'] = '/v2.2'
node.set['openstack']['endpoints']['identity-internal']['host'] = '127.0.0.3'
node.set['openstack']['endpoints']['identity-internal']['port'] = '5003'
node.set['openstack']['endpoints']['identity-internal']['path'] = '/v2.3'
node.set['openstack']['endpoints']['identity-api']['host'] = '127.0.0.4'
node.set['openstack']['endpoints']['identity-api']['port'] = '5004'
node.set['openstack']['endpoints']['identity-api']['path'] = '/v2.4'
node.set['openstack']['endpoints']['identity']['admin']['host'] = '127.0.0.2'
node.set['openstack']['endpoints']['identity']['admin']['port'] = '5002'
node.set['openstack']['endpoints']['identity']['admin']['path'] = '/v2.2'
node.set['openstack']['endpoints']['identity']['internal']['host'] = '127.0.0.3'
node.set['openstack']['endpoints']['identity']['internal']['port'] = '5003'
node.set['openstack']['endpoints']['identity']['internal']['path'] = '/v2.3'
node.set['openstack']['endpoints']['identity']['public']['host'] = '127.0.0.4'
node.set['openstack']['endpoints']['identity']['public']['port'] = '5004'
node.set['openstack']['endpoints']['identity']['public']['path'] = '/v2.4'
expect(chef_run).to create_endpoint_openstack_identity_register(
'Register Identity Endpoint'
).with(
@ -270,76 +270,13 @@ describe 'openstack-identity::registration' do
)
end
it 'register endpoint with different admin URL' do
admin_url = 'https://admin.host:123/admin_path'
general_url = 'http://general.host:456/general_path'
# Set the general endpoint
node.set['openstack']['endpoints']['identity-api']['uri'] = general_url
# TBD, clean this up so that admin is picked up from 'identiy-api'
node.set['openstack']['endpoints']['identity-admin']['uri'] = general_url
node.set['openstack']['endpoints']['identity-internal']['uri'] = general_url
# Set the admin endpoint override
node.set['openstack']['endpoints']['admin']['identity-admin']['uri'] = admin_url
expect(chef_run).to create_endpoint_openstack_identity_register(
'Register Identity Endpoint'
).with(
endpoint_adminurl: admin_url,
endpoint_internalurl: general_url,
endpoint_publicurl: general_url
)
end
it 'register endpoint with different internal URL' do
internal_url = 'http://internal.host:456/internal_path'
general_url = 'http://general.host:456/general_path'
# Set the general endpoint
node.set['openstack']['endpoints']['identity-api']['uri'] = general_url
node.set['openstack']['endpoints']['identity-admin']['uri'] = general_url
node.set['openstack']['endpoints']['identity-internal']['uri'] = general_url
# Set the internal endpoint override
node.set['openstack']['endpoints']['internal']['identity-internal']['uri'] = internal_url
expect(chef_run).to create_endpoint_openstack_identity_register(
'Register Identity Endpoint'
).with(
endpoint_adminurl: general_url,
endpoint_internalurl: internal_url,
endpoint_publicurl: general_url
)
end
it 'register endpoint with different public URL' do
public_url = 'https://public.host:789/public_path'
general_url = 'http://general.host:456/general_path'
# Set the general endpoint
node.set['openstack']['endpoints']['identity-api']['uri'] = general_url
node.set['openstack']['endpoints']['identity-admin']['uri'] = general_url
node.set['openstack']['endpoints']['identity-internal']['uri'] = general_url
# Set the public endpoint override
node.set['openstack']['endpoints']['public']['identity-api']['uri'] = public_url
expect(chef_run).to create_endpoint_openstack_identity_register(
'Register Identity Endpoint'
).with(
endpoint_adminurl: general_url,
endpoint_internalurl: general_url,
endpoint_publicurl: public_url
)
end
it 'register endpoint with all different URLs' do
public_url = 'https://public.host:789/public_path'
internal_url = 'http://internal.host:456/internal_path'
admin_url = 'https://admin.host:123/admin_path'
# Set the type specific overrides
node.set['openstack']['endpoints']['public']['identity-api']['uri'] = public_url
node.set['openstack']['endpoints']['internal']['identity-internal']['uri'] = internal_url
node.set['openstack']['endpoints']['admin']['identity-admin']['uri'] = admin_url
node.set['openstack']['endpoints']['identity']['public']['uri'] = public_url
node.set['openstack']['endpoints']['identity']['internal']['uri'] = internal_url
node.set['openstack']['endpoints']['identity']['admin']['uri'] = admin_url
expect(chef_run).to create_endpoint_openstack_identity_register(
'Register Identity Endpoint'

View File

@ -142,87 +142,6 @@ describe 'openstack-identity::server-apache' do
end
end
describe 'ssl files' do
describe 'with pki' do
describe 'with {certfile,keyfile,ca_certs}_url attributes set' do
before do
node.set['openstack']['identity']['signing']['certfile_url'] = 'http://www.test.com/signing_cert.pem'
node.set['openstack']['identity']['signing']['keyfile_url'] = 'http://www.test.com/signing_key.pem'
node.set['openstack']['identity']['signing']['ca_certs_url'] = 'http://www.test.com/ca.pem'
end
describe 'cert file' do
let(:cert_file) { node['openstack']['identity']['signing']['certfile'] }
let(:file_resource) { chef_run.remote_file(cert_file) }
it 'creates files' do
expect(chef_run).to create_remote_file(cert_file).with(
user: 'keystone',
group: 'keystone',
mode: 0640
)
end
end
describe 'key file' do
let(:key_file) { node['openstack']['identity']['signing']['keyfile'] }
let(:file_resource) { chef_run.remote_file(key_file) }
it 'creates file' do
expect(chef_run).to create_remote_file(key_file).with(
user: 'keystone',
group: 'keystone',
mode: 0640
)
end
end
describe 'ca_certs' do
let(:ca_certs) { node['openstack']['identity']['signing']['ca_certs'] }
let(:file_resource) { chef_run.remote_file(ca_certs) }
it 'creates file' do
expect(chef_run).to create_remote_file(ca_certs).with(
user: 'keystone',
group: 'keystone',
mode: 0640
)
end
end
end
describe 'without {certfile,keyfile,ca_certs}_url attributes set' do
it 'does not create cert file' do
expect(chef_run).not_to create_remote_file(node['openstack']['identity']['signing']['certfile'])
end
it 'does not create key file' do
expect(chef_run).not_to create_remote_file(node['openstack']['identity']['signing']['keyfile'])
end
it 'does not create ca_certs file' do
expect(chef_run).not_to create_remote_file(node['openstack']['identity']['signing']['ca_certs'])
end
end
end
describe 'without pki' do
before { node.set['openstack']['auth']['strategy'] = 'uuid' }
it 'does not create cert file' do
expect(chef_run).not_to create_remote_file(node['openstack']['identity']['signing']['certfile'])
end
it 'does not create key file' do
expect(chef_run).not_to create_remote_file(node['openstack']['identity']['signing']['keyfile'])
end
it 'does not create ca_certs file' do
expect(chef_run).not_to create_remote_file(node['openstack']['identity']['signing']['ca_certs'])
end
end
end
it 'deletes keystone.db' do
expect(chef_run).to delete_file('/var/lib/keystone/keystone.db')
end
@ -259,21 +178,6 @@ describe 'openstack-identity::server-apache' do
end
end
describe 'with {certfile,keyfile,ca_certs}_url attributes set' do
before do
node.set['openstack']['identity']['signing']['certfile_url'] = 'http://www.test.com/signing_cert.pem'
node.set['openstack']['identity']['signing']['keyfile_url'] = 'http://www.test.com/signing_key.pem'
node.set['openstack']['identity']['signing']['ca_certs_url'] = 'http://www.test.com/ca.pem'
end
it 'does not execute' do
expect(chef_run).to_not run_execute(cmd).with(
user: 'keystone',
group: 'keystone'
)
end
end
it 'does not execute when dir exists' do
expect(FileTest).to receive(:exists?)
.with('/etc/keystone/ssl/private/signing_key.pem')
@ -290,7 +194,6 @@ describe 'openstack-identity::server-apache' do
describe 'keystone.conf' do
let(:path) { '/etc/keystone/keystone.conf' }
let(:resource) { chef_run.template(path) }
describe 'file properties' do
it 'creates /etc/keystone/keystone.conf' do
expect(chef_run).to create_template(resource.name).with(
@ -301,167 +204,14 @@ describe 'openstack-identity::server-apache' do
end
end
describe '[eventlet_server_ssl] section' do
opts = {
enable: 'True',
certfile: '/etc/keystone/ssl/certs/sslcert.pem',
keyfile: '/etc/keystone/ssl/private/sslkey.pem',
ca_certs: '/etc/keystone/ssl/certs/sslca.pem',
cert_required: 'false'
}
describe 'with ssl enabled' do
before do
node.set['openstack']['identity']['ssl']['enabled'] = true
node.set['openstack']['identity']['ssl']['basedir'] = '/etc/keystone/ssl'
end
describe 'with client cert not required' do
it 'configures ssl options without client certificate' do
opts.each do |key, val|
r = line_regexp("#{key} = #{val}")
expect(chef_run).to render_config_file(path).with_section_content('eventlet_server_ssl', r)
end
end
end
describe 'with client cert required' do
before do
node.set['openstack']['identity']['ssl']['cert_required'] = true
opts['cert_required'.to_sym] = 'true'
end
it 'configures ssl options with client certificate' do
opts.each do |key, val|
r = line_regexp("#{key} = #{val}")
expect(chef_run).to render_config_file(path).with_section_content('eventlet_server_ssl', r)
end
end
end
end
describe 'without ssl disabled' do
before { node.set['openstack']['identity']['ssl']['enabled'] = false }
it 'does not configure ssl options' do
opts.each do |key|
expect(chef_run).not_to render_config_file(path).with_section_content('eventlet_server_ssl', /^#{key} = /)
end
end
end
end
describe '[saml] section' do
describe 'saml attributes' do
saml_default_attrs = %w(assertion_expiration_time=3600
xmlsec1_binary=xmlsec1
certfile=
keyfile=)
it 'default saml attributes' do
saml_default_attrs.each do |attr|
default_value = /^#{attr}$/
expect(chef_run).to render_config_file(path).with_section_content('saml', default_value)
end
end
saml_override_attrs = %w(assertion_expiration_time
xmlsec1_binary
certfile
keyfile)
it 'override saml attributes' do
saml_override_attrs.each do |attr|
node.set['openstack']['identity']['saml']["#{attr}"] = "value_for_#{attr}"
override_value = /^#{attr}=value_for_#{attr}$/
expect(chef_run).to render_config_file(path).with_section_content('saml', override_value)
end
end
end
describe 'optional saml ipd attributes' do
optional_attrs = %w(idp_entity_id idp_sso_endpoint idp_lang
idp_organization_name idp_organization_display_name
idp_organization_url idp_contact_company idp_contact_name
idp_contact_surname idp_contact_email idp_contact_telephone
idp_contact_type idp_metadata_path)
it 'empty default ipd attributes' do
optional_attrs.each do |attr|
default_value = /^#{attr}=$/
expect(chef_run).to render_config_file(path).with_section_content('saml', default_value)
end
end
it 'overridden ipd attributes' do
optional_attrs.each do |attr|
node.set['openstack']['identity']['saml']["#{attr}"] = "value_for_#{attr}"
override_value = /^#{attr}=value_for_#{attr}$/
expect(chef_run).to render_config_file(path).with_section_content('saml', override_value)
end
end
end
end
it 'has no list_limits by default' do
expect(chef_run).not_to render_config_file(path).with_section_content('DEFAULT', /^list_limit=/)
end
it 'sets list limits correctly' do
node.set['openstack']['identity']['list_limit'] = 111
node.set['openstack']['identity']['assignment']['list_limit'] = 222
node.set['openstack']['identity']['catalog']['list_limit'] = 333
node.set['openstack']['identity']['identity']['list_limit'] = 444
node.set['openstack']['identity']['policy']['list_limit'] = 555
expect(chef_run).to render_config_file(path).with_section_content('DEFAULT', /^list_limit=111$/)
expect(chef_run).to render_config_file(path).with_section_content('assignment', /^list_limit=222$/)
expect(chef_run).to render_config_file(path).with_section_content('catalog', /^list_limit=333$/)
expect(chef_run).to render_config_file(path).with_section_content('identity', /^list_limit=444$/)
expect(chef_run).to render_config_file(path).with_section_content('policy', /^list_limit=555$/)
end
it 'templates misc_keystone array correctly' do
node.set['openstack']['identity']['misc_keystone'] = ['MISC1=OPTION1', 'MISC2=OPTION2']
expect(chef_run).to render_file(path).with_content(
/^MISC1=OPTION1$/)
expect(chef_run).to render_file(path).with_content(
/^MISC2=OPTION2$/)
end
describe '[eventlet_server] section' do
it 'has default worker values' do
expect(chef_run).not_to render_config_file(path).with_section_content('eventlet_server', /^admin_workers=/)
expect(chef_run).not_to render_config_file(path).with_section_content('eventlet_server', /^public_workers=/)
end
it 'has specific worker values' do
node.set['openstack']['identity']['admin_workers'] = 123
node.set['openstack']['identity']['public_workers'] = 456
expect(chef_run).to render_config_file(path).with_section_content('eventlet_server', /^admin_workers=123$/)
expect(chef_run).to render_config_file(path).with_section_content('eventlet_server', /^public_workers=456$/)
end
it 'has bind host from endpoint' do
r = line_regexp('public_bind_host = 127.0.0.1')
expect(chef_run).to render_config_file(path).with_section_content('eventlet_server', r)
end
it 'has admin bind host from endpoint' do
r = line_regexp('admin_bind_host = 127.0.0.1')
expect(chef_run).to render_config_file(path).with_section_content('eventlet_server', r)
end
describe 'port numbers' do
['public_port = 5000', 'admin_port = 35357'].each do |port|
it "has #{port}" do
expect(chef_run).to render_config_file(path).with_section_content('eventlet_server', /^#{port}$/)
end
end
end
expect(chef_run).not_to render_config_file(path).with_section_content('DEFAULT', /^list_limit = /)
end
it 'has rpc_backend set for rabbit' do
node.set['openstack']['mq']['service_type'] = 'rabbitmq'
expect(chef_run).to render_config_file(path).with_section_content('DEFAULT', /^rpc_backend = rabbit$/)
end
it 'has rpc_backend set for qpid' do
node.set['openstack']['mq']['service_type'] = 'qpid'
expect(chef_run).to render_config_file(path).with_section_content('DEFAULT', /^rpc_backend = qpid$/)
end
describe '[DEFAULT] section' do
it 'has admin token' do
r = line_regexp('admin_token = bootstrap-token')
@ -469,16 +219,16 @@ describe 'openstack-identity::server-apache' do
end
describe 'logging verbosity' do
['verbose', 'debug'].each do |x|
['verbose'].each do |x|
it "has #{x} option" do
r = line_regexp("#{x} = False")
r = line_regexp("#{x} = false")
expect(chef_run).to render_config_file(path).with_section_content('DEFAULT', r)
end
end
end
describe 'syslog configuration' do
log_file = %r{^log_file = /\w+}
log_file = %r{^log_dir = /var/log/keystone$}
log_conf = %r{^log_config_append = /\w+}
it 'renders log_file correctly' do
@ -494,18 +244,6 @@ describe 'openstack-identity::server-apache' do
end
end
it 'has default for oslo.messaging configuration' do
[/^notification_driver = messaging$/,
/^notification_topics = notifications$/,
/^rpc_thread_pool_size = 64$/,
/^rpc_response_timeout = 60$/,
/^rpc_backend = rabbit$/,
/^control_exchange = openstack$/
].each do |line|
expect(chef_run).to render_config_file(path).with_section_content('DEFAULT', line)
end
end
it 'has correct endpoints' do
# values correspond to node attrs set in chef_run above
pub = line_regexp('public_endpoint = http://127.0.0.1:5000/')
@ -553,7 +291,7 @@ describe 'openstack-identity::server-apache' do
it 'does not configure attributes' do
optional_attrs.each do |a|
r = /^#{Regexp.quote(a)} =$/
r = /^#{Regexp.quote(a)} = $/
expect(chef_run).not_to render_config_file(path).with_section_content('ldap', r)
end
end
@ -571,77 +309,9 @@ describe 'openstack-identity::server-apache' do
before do
node.set['openstack']['identity']['ldap']['use_tls'] = true
end
context 'when cert paths are configured' do
it 'has a tls_cacertfile when configured' do
node.set['openstack']['identity']['ldap']['tls_cacertfile'] = 'tls_cacertfile_value'
expect(chef_run).to render_config_file(path).with_section_content('ldap', /^tls_cacertfile = tls_cacertfile_value$/)
expect(chef_run).not_to render_config_file(path).with_section_content('ldap', /^tls_cacertdir = /)
end
it 'has a tls_cacertdir when configured and tls_cacertfile unset' do
node.set['openstack']['identity']['ldap']['tls_cacertfile'] = nil
node.set['openstack']['identity']['ldap']['tls_cacertdir'] = 'tls_cacertdir_value'
expect(chef_run).to render_config_file(path).with_section_content('ldap', /^tls_cacertdir = tls_cacertdir_value$/)
expect(chef_run).not_to render_config_file(path).with_section_content('ldap', /^tls_cacertfile = /)
end
end
context 'when tls_req_cert validation disabled' do
it 'has a tls_req_cert set to never' do
node.set['openstack']['identity']['ldap']['tls_req_cert'] = 'never'
expect(chef_run).to render_config_file(path).with_section_content('ldap', /^tls_req_cert = never$/)
end
end
end
end
end
it 'has required attributes' do
required_attrs = %w(alias_dereferencing allow_subtree_delete
dumb_member group_allow_create group_allow_delete
group_allow_update group_desc_attribute
group_id_attribute
group_member_attribute group_name_attribute
group_objectclass page_size query_scope
role_allow_create role_allow_delete
role_allow_update role_id_attribute
role_member_attribute role_name_attribute
role_objectclass suffix project_allow_create
project_allow_delete project_allow_update
project_desc_attribute project_domain_id_attribute
project_enabled_attribute project_enabled_emulation
project_id_attribute project_member_attribute
project_name_attribute project_objectclass url
use_dumb_member user user_allow_create
user_allow_delete user_allow_update
user_attribute_ignore
user_enabled_attribute user_enabled_default
user_enabled_emulation user_enabled_mask
user_id_attribute user_mail_attribute
user_name_attribute user_objectclass
user_pass_attribute)
required_attrs.each do |a|
expect(chef_run).to render_config_file(path).with_section_content('ldap', /^#{Regexp.quote(a)} = \w+/)
end
end
end
describe '[identity] section' do
it 'configures driver' do
r = line_regexp('driver = keystone.identity.backends.sql.Identity')
expect(chef_run).to render_config_file(path).with_section_content('identity', r)
end
[
/^default_domain_id=default$/,
/^domain_specific_drivers_enabled=false$/,
%r{^domain_config_dir=/etc/keystone/domains$}
].each do |line|
it "has a #{line.source} line" do
expect(chef_run).to render_config_file(path).with_section_content('identity', line)
end
end
end
describe '[assignment] section' do
@ -665,30 +335,6 @@ describe 'openstack-identity::server-apache' do
expect(chef_run).to render_config_file(path).with_content(sql)
expect(chef_run).not_to render_config_file(path).with_section_content('catalog', templated)
end
it 'configures driver with templated backend' do
node.set['openstack']['identity']['catalog']['backend'] = 'templated'
expect(chef_run).to render_config_file(path).with_section_content('catalog', templated)
expect(chef_run).not_to render_config_file(path).with_section_content('catalog', sql)
end
end
describe '[token] section' do
it 'configures driver' do
r = line_regexp('driver = keystone.token.persistence.backends.sql.Token')
expect(chef_run).to render_config_file(path).with_section_content('token', r)
end
it 'sets token expiration time' do
r = line_regexp('expiration = 3600')
expect(chef_run).to render_config_file(path).with_section_content('token', r)
end
it 'sets token hash algorithm' do
r = line_regexp('hash_algorithm = md5')
expect(chef_run).to render_config_file(path).with_section_content('token', r)
end
end
describe '[policy] section' do
@ -698,118 +344,15 @@ describe 'openstack-identity::server-apache' do
end
end
describe '[signing] section' do
opts = {
certfile: '/etc/keystone/ssl/certs/signing_cert.pem',
keyfile: '/etc/keystone/ssl/private/signing_key.pem',
ca_certs: '/etc/keystone/ssl/certs/ca.pem',
key_size: '2048',
valid_days: '3650',
ca_password: nil
}
describe 'with pki' do
it 'configures cert options' do
opts.each do |key, val|
r = line_regexp("#{key} = #{val}")
expect(chef_run).to render_config_file(path).with_section_content('signing', r)
end
end
end
describe 'without pki' do
before { node.set['openstack']['auth']['strategy'] = 'uuid' }
it 'does not configure cert options' do
opts.each do |key|
expect(chef_run).not_to render_config_file(path).with_section_content('signing', /^#{key} = /)
end
end
end
end
describe '[oslo_messaging_qpid] section' do
it 'has defaults for oslo_messaging_qpid section' do
node.set['openstack']['mq']['service_type'] = 'qpid'
[/^amqp_durable_queues = false$/,
/^amqp_auto_delete = false$/,
/^rpc_conn_pool_size = 30$/,
/^qpid_hostname = 127.0.0.1$/,
/^qpid_port = 5672$/,
/^qpid_username = guest$/,
/^qpid_password = guest$/,
/^qpid_sasl_mechanisms = $/,
/^qpid_heartbeat = 60$/,
/^qpid_protocol = tcp$/,
/^qpid_tcp_nodelay = true$/,
/^qpid_topology_version = 1$/
].each do |line|
expect(chef_run).to render_config_file(path).with_section_content('oslo_messaging_qpid', line)
end
end
end
describe '[oslo_messaging_rabbit] section' do
it 'has defaults for oslo_messaging_rabbit section' do
[/^amqp_durable_queues = false$/,
/^amqp_auto_delete = false$/,
/^heartbeat_timeout_threshold=0$/,
/^heartbeat_rate=2$/,
/^rpc_conn_pool_size = 30$/,
/^rabbit_host = 127.0.0.1$/,
/^rabbit_port = 5672$/,
/^rabbit_userid = guest$/,
/^rabbit_password = guest$/,
%r{^rabbit_virtual_host = /$},
/^rabbit_max_retries = 0$/,
/^rabbit_retry_interval = 1$/
[
/^rabbit_userid = guest$/,
/^rabbit_password = guest$/
].each do |line|
expect(chef_run).to render_config_file(path).with_section_content('oslo_messaging_rabbit', line)
end
end
it 'has defaults for oslo_messaging_rabbit section with ha' do
node.set['openstack']['mq']['identity']['rabbit']['ha'] = true
[/^amqp_durable_queues = false$/,
/^amqp_auto_delete = false$/,
/^rpc_conn_pool_size = 30$/,
/^rabbit_hosts = rabbit_servers_value$/,
/^rabbit_userid = guest$/,
/^rabbit_password = guest$/,
%r{^rabbit_virtual_host = /$},
/^rabbit_ha_queues = true$/
].each do |line|
expect(chef_run).to render_config_file(path).with_section_content('oslo_messaging_rabbit', line)
end
end
it 'does not have ssl config set' do
[/^rabbit_use_ssl=/,
/^kombu_ssl_version=/,
/^kombu_ssl_keyfile=/,
/^kombu_ssl_certfile=/,
/^kombu_ssl_ca_certs=/,
/^kombu_reconnect_delay=/,
/^kombu_reconnect_timeout=/].each do |line|
expect(chef_run).not_to render_config_file(path).with_section_content('oslo_messaging_rabbit', line)
end
end
it 'sets ssl config' do
node.set['openstack']['mq']['identity']['rabbit']['use_ssl'] = true
node.set['openstack']['mq']['identity']['rabbit']['kombu_ssl_version'] = 'TLSv1.2'
node.set['openstack']['mq']['identity']['rabbit']['kombu_ssl_keyfile'] = 'keyfile'
node.set['openstack']['mq']['identity']['rabbit']['kombu_ssl_certfile'] = 'certfile'
node.set['openstack']['mq']['identity']['rabbit']['kombu_ssl_ca_certs'] = 'certsfile'
node.set['openstack']['mq']['identity']['rabbit']['kombu_reconnect_delay'] = 123.123
node.set['openstack']['mq']['identity']['rabbit']['kombu_reconnect_timeout'] = 123
[/^rabbit_use_ssl=true/,
/^kombu_ssl_version=TLSv1.2$/,
/^kombu_ssl_keyfile=keyfile$/,
/^kombu_ssl_certfile=certfile$/,
/^kombu_ssl_ca_certs=certsfile$/,
/^kombu_reconnect_delay=123.123$/,
/^kombu_reconnect_timeout=123$/].each do |line|
expect(chef_run).to render_config_file(path).with_section_content('oslo_messaging_rabbit', line)
end
end
end
end
@ -821,21 +364,6 @@ describe 'openstack-identity::server-apache' do
expect(chef_run).not_to render_file(file)
end
end
describe 'with templated backend' do
before do
node.set['openstack']['identity']['catalog']['backend'] = 'templated'
end
let(:template) { chef_run.template(file) }
it 'creates /etc/keystone/default_catalog.templates' do
expect(chef_run).to create_template(template.name).with(
user: 'keystone',
group: 'keystone',
mode: 0644
)
end
end
end
describe 'db_sync' do
@ -883,11 +411,11 @@ describe 'openstack-identity::server-apache' do
expect(chef_run).to render_file(path).with_content(/^pipeline = service_v3$/)
end
it 'template misc_paste array correctly' do
node.set['openstack']['identity']['misc_paste'] = ['MISC1=OPTION1', 'MISC2=OPTION2']
node.set['openstack']['identity']['misc_paste'] = ['MISC1 = OPTION1', 'MISC2 = OPTION2']
expect(chef_run).to render_file(path).with_content(
/^MISC1=OPTION1$/)
/^MISC1 = OPTION1$/)
expect(chef_run).to render_file(path).with_content(
/^MISC2=OPTION2$/)
/^MISC2 = OPTION2$/)
end
end
@ -912,8 +440,10 @@ describe 'openstack-identity::server-apache' do
end
it 'set apache addresses and ports' do
expect(chef_run.node['apache']['listen_addresses']).to eq ['127.0.0.1']
expect(chef_run.node['apache']['listen_ports']).to eq [5000, 35357]
expect(chef_run.node['apache']['listen']).to eq(
'*' => ['80'],
'127.0.0.1' => ['5000', '5001', '35357']
)
end
describe 'apache recipes' do
@ -975,23 +505,6 @@ describe 'openstack-identity::server-apache' do
expect(chef_run).not_to render_file(file).with_content(line)
end
end
it "configures #{file} triggered common lines" do
node.set['openstack']['identity']['debug'] = 'True'
node.set['openstack']['identity']['ssl']['cert_required'] = true
node.set['openstack']['identity']['ssl']['enabled'] = true
node.set['openstack']['identity']['ssl']['ciphers'] = 'ciphers'
[/^ LogLevel debug$/,
/^ SSLEngine On$/,
%r{^ SSLCertificateFile /etc/keystone/ssl/certs/sslcert.pem$},
%r{^ SSLCertificateKeyFile /etc/keystone/ssl/private/sslkey.pem$},
%r{^ SSLCACertificatePath /etc/keystone/ssl/certs/$},
/^ SSLProtocol All -SSLv2 -SSLv3$/,
/^ SSLCipherSuite ciphers$/,
/^ SSLVerifyClient require$/].each do |line|
expect(chef_run).to render_file(file).with_content(line)
end
end
end
describe 'keystone-public.conf' do

View File

@ -1,58 +0,0 @@
# encoding: UTF-8
#
require_relative 'spec_helper'
describe 'openstack-identity::server' do
describe 'redhat' do
let(:runner) { ChefSpec::SoloRunner.new(REDHAT_OPTS) }
let(:node) { runner.node }
let(:chef_run) { runner.converge(described_recipe) }
include_context 'identity_stubs'
it 'converges when configured to use sqlite db backend' do
node.set['openstack']['db']['identity']['service_type'] = 'sqlite'
expect { chef_run }.to_not raise_error
end
it 'upgrades mysql python packages' do
expect(chef_run).to upgrade_package('identity cookbook package MySQL-python')
end
it 'upgrades postgresql python packages if explicitly told' do
node.set['openstack']['db']['identity']['service_type'] = 'postgresql'
expect(chef_run).to upgrade_package('identity cookbook package python-psycopg2')
end
it 'upgrades memcache python packages' do
expect(chef_run).to upgrade_package('identity cookbook package python-memcached')
end
it 'upgrades keystone packages' do
expect(chef_run).to upgrade_package('identity cookbook package openstack-keystone')
end
it 'starts keystone on boot' do
expect(chef_run).to enable_service('openstack-keystone')
end
describe 'keystone-paste.ini' do
before { node.set['openstack']['identity']['pastefile_url'] = 'file:///usr/share/keystone/keystone-dist-paste.ini' }
paste_file = '/etc/keystone/keystone-paste.ini'
let(:file_resource) { chef_run.remote_file(paste_file) }
it 'copies local keystone-dist-paste.ini when keystone-paste pastefile_url is specified' do
expect(chef_run).to create_remote_file_if_missing(paste_file).with(
source: 'file:///usr/share/keystone/keystone-dist-paste.ini',
user: 'keystone',
group: 'keystone',
mode: 00644)
end
it 'restarts keystone when keystone-paste.ini is created' do
expect(file_resource).to notify('service[keystone]').to(:restart)
end
end
end
end

View File

@ -1,86 +0,0 @@
# encoding: UTF-8
#
require_relative 'spec_helper'
describe 'openstack-identity::server' do
describe 'suse' do
let(:runner) { ChefSpec::SoloRunner.new(SUSE_OPTS) }
let(:node) { runner.node }
let(:chef_run) { runner.converge(described_recipe) }
include_context 'identity_stubs'
it 'converges when configured to use sqlite db backend' do
node.set['openstack']['db']['identity']['service_type'] = 'sqlite'
expect { chef_run }.to_not raise_error
end
it 'upgrades mysql python packages' do
expect(chef_run).to upgrade_package('identity cookbook package python-mysql')
end
it 'upgrades postgresql python packages if explicitly told' do
node.set['openstack']['db']['identity']['service_type'] = 'postgresql'
expect(chef_run).to upgrade_package('identity cookbook package python-psycopg2')
end
it 'upgrades memcache python packages' do
expect(chef_run).to upgrade_package('identity cookbook package python-python-memcached')
end
it 'upgrades keystone packages' do
expect(chef_run).to upgrade_package('identity cookbook package openstack-keystone')
end
it 'starts keystone on boot' do
expect(chef_run).to enable_service('openstack-keystone')
end
describe '/etc/keystone' do
let(:dir) { chef_run.directory('/etc/keystone') }
it 'has proper owner' do
expect(dir.owner).to eq('openstack-keystone')
expect(dir.group).to eq('openstack-keystone')
end
end
describe '/etc/keystone/ssl' do
before { node.set['openstack']['auth']['strategy'] = 'pki' }
let(:dir) { chef_run.directory('/etc/keystone/ssl') }
it 'has proper owner' do
expect(dir.owner).to eq('openstack-keystone')
expect(dir.group).to eq('openstack-keystone')
end
end
it 'deletes keystone.db' do
expect(chef_run).to delete_file('/var/lib/keystone/keystone.db')
end
describe 'keystone.conf' do
let(:template) { chef_run.template '/etc/keystone/keystone.conf' }
it 'has proper owner' do
expect(template.owner).to eq('openstack-keystone')
expect(template.group).to eq('openstack-keystone')
end
end
describe 'default_catalog.templates' do
before do
node.set['openstack']['identity']['catalog']['backend'] = 'templated'
end
let(:template) do
chef_run.template('/etc/keystone/default_catalog.templates')
end
it 'has proper owner' do
expect(template.owner).to eq('openstack-keystone')
expect(template.group).to eq('openstack-keystone')
end
end
end
end

File diff suppressed because it is too large Load Diff

View File

@ -5,11 +5,6 @@ require 'chefspec/berkshelf'
ChefSpec::Coverage.start! { add_filter 'openstack-identity' }
LOG_LEVEL = :fatal
SUSE_OPTS = {
platform: 'suse',
version: '11.3',
log_level: LOG_LEVEL
}
REDHAT_OPTS = {
platform: 'redhat',
version: '7.1',
@ -55,5 +50,19 @@ shared_context 'identity_stubs' do
.with('token', 'openstack_identity_bootstrap_token')
.and_return('bootstrap-token')
stub_command('/usr/sbin/apache2 -t')
allow_any_instance_of(Chef::Recipe).to receive(:search_for)
.with('os-identity').and_return(
[{
'openstack' => {
'identity' => {
'admin_tenant_name' => 'admin',
'admin_user' => 'admin'
}
}
}]
)
allow_any_instance_of(Chef::Recipe).to receive(:get_password)
.with('user', 'admin')
.and_return('admin')
end
end

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,15 @@
<%= node['openstack']['identity']['custom_template_banner'] %>
# COMMON OPENSTACK ENVS
export OS_USERNAME=<%= @user %>
export OS_PASSWORD=<%= @password %>
export OS_TENANT_NAME=<%= @tenant %>
export OS_AUTH_URL=<%= @identity_endpoint %>
export OS_REGION_NAME=<%= node['openstack']['region'] %>
<% if node['openstack']['misc_openrc'] %>
# Misc options
<% node['openstack']['misc_openrc'].each do |m| %>
<%= m %>
<% end %>
<% end %>