sync keystone with upstream
master de419015bb96d83135b306d9fb34e77e033c26cb sources https://github.com/openstack/puppet-keystone Partially Implements: blueprint upgrade-openstack-puppet-modules Fuel-CI: disable Change-Id: Idedef32288e214486d05225b09147b5b1c30cdab
This commit is contained in:
parent
10a2fe87b9
commit
252969895a
@ -1,17 +1,14 @@
|
||||
fixtures:
|
||||
repositories:
|
||||
'apache': 'git://github.com/puppetlabs/puppetlabs-apache.git'
|
||||
'apt': 'git://github.com/puppetlabs/puppetlabs-apt.git'
|
||||
'mysql':
|
||||
repo: 'git://github.com/puppetlabs/puppetlabs-mysql.git'
|
||||
ref: 'origin/0.x'
|
||||
'stdlib': 'git://github.com/puppetlabs/puppetlabs-stdlib.git'
|
||||
'inifile': 'git://github.com/puppetlabs/puppetlabs-inifile'
|
||||
'postgresql':
|
||||
repo: 'git://github.com/puppetlabs/puppetlabs-postgresql.git'
|
||||
ref: '2.5.0'
|
||||
'concat':
|
||||
'repo': 'git://github.com/puppetlabs/puppetlabs-concat.git'
|
||||
'ref': '1.2.1'
|
||||
'apt': 'git://github.com/puppetlabs/puppetlabs-apt.git'
|
||||
'mysql': 'git://github.com/puppetlabs/puppetlabs-mysql.git'
|
||||
'openstacklib': 'git://github.com/stackforge/puppet-openstacklib.git'
|
||||
'stdlib': 'git://github.com/puppetlabs/puppetlabs-stdlib.git'
|
||||
'inifile': 'git://github.com/puppetlabs/puppetlabs-inifile'
|
||||
'postgresql': 'git://github.com/puppetlabs/puppetlabs-postgresql.git'
|
||||
symlinks:
|
||||
'keystone': "#{source_dir}"
|
||||
|
@ -1,4 +0,0 @@
|
||||
[gerrit]
|
||||
host=review.openstack.org
|
||||
port=29418
|
||||
project=stackforge/puppet-keystone.git
|
@ -2,8 +2,23 @@ source 'https://rubygems.org'
|
||||
|
||||
group :development, :test do
|
||||
gem 'puppetlabs_spec_helper', :require => false
|
||||
gem 'puppet-lint', '~> 0.3.2'
|
||||
gem 'rake', '10.1.1'
|
||||
gem 'rspec-puppet', '~> 2.1.0', :require => false
|
||||
|
||||
gem 'metadata-json-lint'
|
||||
gem 'puppet-lint-param-docs'
|
||||
gem 'puppet-lint-absolute_classname-check'
|
||||
gem 'puppet-lint-absolute_template_path'
|
||||
gem 'puppet-lint-trailing_newline-check'
|
||||
|
||||
# Puppet 4.x related lint checks
|
||||
gem 'puppet-lint-unquoted_string-check'
|
||||
gem 'puppet-lint-leading_zero-check'
|
||||
gem 'puppet-lint-variable_contains_upcase'
|
||||
gem 'puppet-lint-numericvariable'
|
||||
|
||||
gem 'json'
|
||||
gem 'webmock'
|
||||
gem 'beaker-rspec', :require => false
|
||||
end
|
||||
|
||||
if puppetversion = ENV['PUPPET_GEM_VERSION']
|
||||
|
@ -1,8 +1,4 @@
|
||||
Puppet Labs Keystone Module - Puppet module for managing Keystone
|
||||
|
||||
Copyright (C) 2012 Puppet Labs Inc
|
||||
|
||||
Puppet Labs can be contacted at: info@puppetlabs.com
|
||||
Copyright 2012 OpenStack Foundation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -1,13 +0,0 @@
|
||||
name 'puppetlabs-keystone'
|
||||
version '4.0.0'
|
||||
source 'https://github.com/stackforge/puppet-keystone'
|
||||
author 'Puppet Labs'
|
||||
license 'Apache License 2.0'
|
||||
summary 'Puppet Labs Keystone Module'
|
||||
description 'Puppet module to install and configure the Openstack identity service'
|
||||
project_page 'https://launchpad.net/puppet-keystone'
|
||||
|
||||
dependency 'puppetlabs/apache', '>=1.0.0 <2.0.0'
|
||||
dependency 'puppetlabs/inifile', '>=1.0.0 <2.0.0'
|
||||
dependency 'puppetlabs/mysql', '>=0.9.0 <3.0.0'
|
||||
dependency 'puppetlabs/stdlib', '>= 3.2.0'
|
@ -1,7 +1,7 @@
|
||||
keystone
|
||||
=======
|
||||
|
||||
4.0.0 - 2014.1.0 - Icehouse
|
||||
5.1.0 - 2014.2 - Juno
|
||||
|
||||
#### Table of Contents
|
||||
|
||||
@ -45,10 +45,10 @@ To utilize the keystone module's functionality you will need to declare multiple
|
||||
|
||||
```puppet
|
||||
class { 'keystone':
|
||||
verbose => True,
|
||||
catalog_type => 'sql',
|
||||
admin_token => 'random_uuid',
|
||||
sql_connection => 'mysql://keystone_admin:super_secret_db_password@openstack-controller.example.com/keystone',
|
||||
verbose => True,
|
||||
catalog_type => 'sql',
|
||||
admin_token => 'random_uuid',
|
||||
database_connection => 'mysql://keystone_admin:super_secret_db_password@openstack-controller.example.com/keystone',
|
||||
}
|
||||
|
||||
# Adds the admin credential to keystone.
|
||||
@ -59,10 +59,10 @@ class { 'keystone::roles::admin':
|
||||
|
||||
# Installs the service user endpoint.
|
||||
class { 'keystone::endpoint':
|
||||
public_address => '10.16.0.101',
|
||||
admin_address => '10.16.1.101',
|
||||
internal_address => '10.16.2.101',
|
||||
region => 'example-1',
|
||||
public_url => 'http://10.16.0.101:5000/v2.0',
|
||||
admin_url => 'http://10.16.1.101:35357/v2.0',
|
||||
internal_url => 'http://10.16.2.101:5000/v2.0',
|
||||
region => 'example-1',
|
||||
}
|
||||
```
|
||||
|
||||
@ -148,7 +148,17 @@ Limitations
|
||||
|
||||
* If you've setup Openstack using previous versions of this module you need to be aware that it used UUID as the dedault to the token_format parameter but now defaults to PKI. If you're using this module to manage a Grizzly Openstack deployment that was set up using a development release of the modules or are attempting an upgrade from Folsom then you'll need to make sure you set the token_format to UUID at classification time.
|
||||
|
||||
* The Keystone Openstack service depends on a sqlalchemy database. If you are using puppetlabs-mysql to achieve this, there is a parameter called mysql_module that can be used to swap between the two supported versions: 0.9 and 2.2. This is needed because the puppetlabs-mysql module was rewritten and the custom type names have changed between versions.
|
||||
Beaker-Rspec
|
||||
------------
|
||||
|
||||
This module has beaker-rspec tests
|
||||
|
||||
To run:
|
||||
|
||||
``shell
|
||||
bundle install
|
||||
bundle exec rspec spec/acceptance
|
||||
``
|
||||
|
||||
Development
|
||||
-----------
|
||||
@ -165,6 +175,78 @@ Contributors
|
||||
Release Notes
|
||||
-------------
|
||||
|
||||
**5.1.0**
|
||||
|
||||
* Allow disabling or delaying the token_flush cron
|
||||
* crontab: ensure the script is run with shell
|
||||
* Use openstackclient for keystone_* providers
|
||||
* Add lib directories to $LOAD_PATH if not present
|
||||
* Remove keystone.rb provider for keystone_endpoint
|
||||
* Add timeout to API requests
|
||||
* Test keystone_user password with Net::HTTP
|
||||
* service_identity: add user/role ordering
|
||||
* Fix password check for SSL endpoints
|
||||
* add require json for to_json dependency
|
||||
* spec: pin rspec-puppet to 1.0.1
|
||||
* Switch to TLSv1
|
||||
* handle missing project/tenant when using ldap backend
|
||||
* Add support for LDAP connection pools
|
||||
* Sync keystone.py with upstream to function with Juno
|
||||
* Create resource cache upon creation
|
||||
* Implement caching lookup for keystone_user_role
|
||||
* Remove warnings from openstack responses
|
||||
* Properly handle embedded newlines in csv
|
||||
* support the ldap user_enabled_invert parameter
|
||||
* Shorten HTTP request timeout length
|
||||
* Tag packages with 'openstack'
|
||||
* Allow Keystone to be queried when using IPv6 ::0
|
||||
* Add ::keystone::policy class for policy management
|
||||
* New option replace_password for keystone_user
|
||||
* Pin puppetlabs-concat to 1.2.1 in fixtures
|
||||
* Set WSGI process display-name
|
||||
* Rename resource instance variable
|
||||
* Add native types for keystone paste configuration
|
||||
* Update .gitreview file for project rename
|
||||
|
||||
**5.0.0**
|
||||
|
||||
* Stable Juno release
|
||||
* Updated token driver, logging, and ldap config parameters for Juno
|
||||
* Changed admin_roles parameter to accept an array in order to configure multiple admin roles
|
||||
* Installs python-ldappool package for ldap
|
||||
* Added new parameters to keystone class to configure pki signing
|
||||
* Changed keystone class to inherit from keystone::params
|
||||
* Changed pki_setup to run regardless of token provider
|
||||
* Made UUID the default token provider
|
||||
* Made keystone_user_role idempotent
|
||||
* Added parameters to control whether to configure users
|
||||
* Stopped managing _member_ role since it is created automatically
|
||||
* Stopped overriding token_flush log file
|
||||
* Changed the usage of admin_endpoint to not include the API version
|
||||
* Allowed keystone_user_role to accept email as username
|
||||
* Added ability to set up keystone using Apache mod_wsgi
|
||||
* Migrated the keystone::db::mysql class to use openstacklib::db::mysql and deprecated the mysql_module parameter
|
||||
* Installs python-memcache when using token driver memcache
|
||||
* Enabled setting cert and key paths for PKI token signing
|
||||
* Added parameters for SSL communication between keystone and rabbitmq
|
||||
* Added parameter ignore_default_tenant to keystone::role::admin
|
||||
* Added parameter service_provider to keystone class
|
||||
* Added parameters for service validation to keystone class
|
||||
|
||||
**4.2.0**
|
||||
|
||||
* Added class for extended logging options
|
||||
* Fixed rabbit password leaking
|
||||
* Added parameters to set tenant descriptions
|
||||
* Fixed keystone user authorization error handling
|
||||
|
||||
**4.1.0**
|
||||
|
||||
* Added token flushing with cron.
|
||||
* Updated database api for consistency with other projects.
|
||||
* Fixed admin_token with secret parameter.
|
||||
* Fixed deprecated catalog driver.
|
||||
|
||||
**4.0.0**
|
||||
|
||||
* Stable Icehouse release.
|
||||
|
@ -20,30 +20,30 @@
|
||||
|
||||
Exec { logoutput => 'on_failure' }
|
||||
|
||||
class { 'mysql::server': }
|
||||
class { 'keystone::db::mysql':
|
||||
class { '::mysql::server': }
|
||||
class { '::keystone::db::mysql':
|
||||
password => 'keystone',
|
||||
}
|
||||
class { 'keystone':
|
||||
verbose => true,
|
||||
debug => true,
|
||||
sql_connection => 'mysql://keystone:keystone@127.0.0.1/keystone',
|
||||
catalog_type => 'sql',
|
||||
admin_token => 'admin_token',
|
||||
enabled => false,
|
||||
class { '::keystone':
|
||||
verbose => true,
|
||||
debug => true,
|
||||
database_connection => 'mysql://keystone:keystone@127.0.0.1/keystone',
|
||||
catalog_type => 'sql',
|
||||
admin_token => 'admin_token',
|
||||
enabled => false,
|
||||
}
|
||||
class { 'keystone::roles::admin':
|
||||
class { '::keystone::roles::admin':
|
||||
email => 'test@puppetlabs.com',
|
||||
password => 'ChangeMe',
|
||||
}
|
||||
class { 'keystone::endpoint':
|
||||
class { '::keystone::endpoint':
|
||||
public_url => "https://${::fqdn}:5000/",
|
||||
admin_url => "https://${::fqdn}:35357/",
|
||||
}
|
||||
|
||||
keystone_config { 'ssl/enable': value => true }
|
||||
|
||||
include apache
|
||||
class { 'keystone::wsgi::apache':
|
||||
include ::apache
|
||||
class { '::keystone::wsgi::apache':
|
||||
ssl => true
|
||||
}
|
||||
|
@ -20,31 +20,32 @@
|
||||
|
||||
Exec { logoutput => 'on_failure' }
|
||||
|
||||
class { 'mysql::server': }
|
||||
class { 'keystone::db::mysql':
|
||||
class { '::mysql::server': }
|
||||
class { '::keystone::db::mysql':
|
||||
password => 'keystone',
|
||||
}
|
||||
class { 'keystone':
|
||||
verbose => true,
|
||||
debug => true,
|
||||
sql_connection => 'mysql://keystone_admin:keystone@127.0.0.1/keystone',
|
||||
catalog_type => 'sql',
|
||||
admin_token => 'admin_token',
|
||||
enabled => true,
|
||||
class { '::keystone':
|
||||
verbose => true,
|
||||
debug => true,
|
||||
database_connection => 'mysql://keystone_admin:keystone@127.0.0.1/keystone',
|
||||
catalog_type => 'sql',
|
||||
admin_token => 'admin_token',
|
||||
enabled => true,
|
||||
}
|
||||
class { 'keystone::roles::admin':
|
||||
class { '::keystone::cron::token_flush': }
|
||||
class { '::keystone::roles::admin':
|
||||
email => 'test@puppetlabs.com',
|
||||
password => 'ChangeMe',
|
||||
}
|
||||
class { 'keystone::endpoint':
|
||||
public_url => "https://${::fqdn}:443/main/",
|
||||
admin_address => "https://${::fqdn}:443/admin/",
|
||||
class { '::keystone::endpoint':
|
||||
public_url => "https://${::fqdn}:443/main/",
|
||||
admin_url => "https://${::fqdn}:443/admin/",
|
||||
}
|
||||
|
||||
keystone_config { 'ssl/enable': ensure => absent }
|
||||
|
||||
include apache
|
||||
class { 'keystone::wsgi::apache':
|
||||
include ::apache
|
||||
class { '::keystone::wsgi::apache':
|
||||
ssl => true,
|
||||
public_port => 443,
|
||||
admin_port => 443,
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
# Ensure this matches what is in LDAP or keystone will try to recreate
|
||||
# the admin user
|
||||
class { 'keystone::roles::admin':
|
||||
class { '::keystone::roles::admin':
|
||||
email => 'test@example.com',
|
||||
password => 'ChangeMe',
|
||||
}
|
||||
@ -12,55 +12,61 @@ class { 'keystone::roles::admin':
|
||||
# LDAP configurations are *highly* dependent on your setup and this file
|
||||
# will need to be tweaked. This sample talks to ldap.example.com, here is
|
||||
# an example of ldapsearch that will search users on this box:
|
||||
# ldapsearch -v -x -H 'ldap://69.134.70.154:389' -D \
|
||||
# ldapsearch -v -x -H 'ldap://example.com:389' -D \
|
||||
# "uid=bind,cn=users,cn=accounts,dc=example,dc=com" -w SecretPass \
|
||||
# -b cn=users,cn=accounts,dc=example,dc=com
|
||||
class { 'keystone:ldap':
|
||||
url => 'ldap://ldap.example.com:389',
|
||||
user => 'uid=bind,cn=users,cn=accounts,dc=example,dc=com',
|
||||
password => 'SecretPass',
|
||||
suffix => 'dc=example,dc=com',
|
||||
query_scope => 'sub',
|
||||
user_tree_dn => 'cn=users,cn=accounts,dc=example,dc=com',
|
||||
user_id_attribute => 'uid',
|
||||
user_name_attribute => 'uid',
|
||||
user_mail_attribute => 'mail',
|
||||
user_allow_create => 'False',
|
||||
user_allow_update => 'False',
|
||||
user_allow_delete => 'False',
|
||||
user_enabled_emulation => 'True',
|
||||
user_enabled_emulation_dn => 'cn=openstack-enabled,cn=groups,cn=accounts,dc=example,dc=com',
|
||||
group_tree_dn => 'ou=groups,ou=openstack,dc=example,dc=com',
|
||||
group_objectclass => 'organizationalRole',
|
||||
group_id_attribute => 'cn',
|
||||
group_name_attribute => 'cn',
|
||||
group_member_attribute => 'RoleOccupant',
|
||||
group_desc_attribute => 'description',
|
||||
group_allow_create => 'True',
|
||||
group_allow_update => 'True',
|
||||
group_allow_delete => 'True',
|
||||
tenant_tree_dn => 'ou=projects,ou=openstack,dc=example,dc=com',
|
||||
tenant_objectclass => 'organizationalUnit',
|
||||
tenant_id_attribute => 'ou',
|
||||
tenant_member_attribute => 'member',
|
||||
tenant_name_attribute => 'ou',
|
||||
tenant_desc_attribute => 'description',
|
||||
tenant_allow_create => 'True',
|
||||
tenant_allow_update => 'True',
|
||||
tenant_allow_delete => 'True',
|
||||
tenant_enabled_emulation => 'True',
|
||||
tenant_enabled_emulation_dn => 'cn=enabled,ou=openstack,dc=example,dc=com',
|
||||
role_tree_dn => 'ou=roles,ou=openstack,dc=example,dc=com',
|
||||
role_objectclass => 'organizationalRole',
|
||||
role_id_attribute => 'cn',
|
||||
role_name_attribute => 'cn',
|
||||
role_member_attribute => 'roleOccupant',
|
||||
role_allow_create => 'True',
|
||||
role_allow_update => 'True',
|
||||
role_allow_delete => 'True',
|
||||
identity_driver => 'keystone.identity.backends.ldap.Identity',
|
||||
assignment_driver => 'keystone.assignment.backends.ldap.Assignment',
|
||||
use_tls => 'True',
|
||||
tls_cacertfile => '/etc/ssl/certs/ca-certificates.crt',
|
||||
tls_req_cert => 'demand',
|
||||
class { '::keystone:ldap':
|
||||
url => 'ldap://ldap.example.com:389',
|
||||
user => 'uid=bind,cn=users,cn=accounts,dc=example,dc=com',
|
||||
password => 'SecretPass',
|
||||
suffix => 'dc=example,dc=com',
|
||||
query_scope => 'sub',
|
||||
user_tree_dn => 'cn=users,cn=accounts,dc=example,dc=com',
|
||||
user_id_attribute => 'uid',
|
||||
user_name_attribute => 'uid',
|
||||
user_mail_attribute => 'mail',
|
||||
user_allow_create => 'False',
|
||||
user_allow_update => 'False',
|
||||
user_allow_delete => 'False',
|
||||
user_enabled_emulation => 'True',
|
||||
user_enabled_emulation_dn => 'cn=openstack-enabled,cn=groups,cn=accounts,dc=example,dc=com',
|
||||
group_tree_dn => 'ou=groups,ou=openstack,dc=example,dc=com',
|
||||
group_objectclass => 'organizationalRole',
|
||||
group_id_attribute => 'cn',
|
||||
group_name_attribute => 'cn',
|
||||
group_member_attribute => 'RoleOccupant',
|
||||
group_desc_attribute => 'description',
|
||||
group_allow_create => 'True',
|
||||
group_allow_update => 'True',
|
||||
group_allow_delete => 'True',
|
||||
project_tree_dn => 'ou=projects,ou=openstack,dc=example,dc=com',
|
||||
project_objectclass => 'organizationalUnit',
|
||||
project_id_attribute => 'ou',
|
||||
project_member_attribute => 'member',
|
||||
project_name_attribute => 'ou',
|
||||
project_desc_attribute => 'description',
|
||||
project_allow_create => 'True',
|
||||
project_allow_update => 'True',
|
||||
project_allow_delete => 'True',
|
||||
project_enabled_emulation => 'True',
|
||||
project_enabled_emulation_dn => 'cn=enabled,ou=openstack,dc=example,dc=com',
|
||||
role_tree_dn => 'ou=roles,ou=openstack,dc=example,dc=com',
|
||||
role_objectclass => 'organizationalRole',
|
||||
role_id_attribute => 'cn',
|
||||
role_name_attribute => 'cn',
|
||||
role_member_attribute => 'roleOccupant',
|
||||
role_allow_create => 'True',
|
||||
role_allow_update => 'True',
|
||||
role_allow_delete => 'True',
|
||||
identity_driver => 'keystone.identity.backends.ldap.Identity',
|
||||
assignment_driver => 'keystone.assignment.backends.ldap.Assignment',
|
||||
use_tls => 'True',
|
||||
tls_cacertfile => '/etc/ssl/certs/ca-certificates.crt',
|
||||
tls_req_cert => 'demand',
|
||||
use_pool => 'True',
|
||||
use_auth_pool => 'True',
|
||||
pool_size => 5,
|
||||
auth_pool_size => 5,
|
||||
pool_retry_max => 3,
|
||||
pool_connection_timeout => 120,
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
# Ensure this matches what is in LDAP or keystone will try to recreate
|
||||
# the admin user
|
||||
class { 'keystone::roles::admin':
|
||||
class { '::keystone::roles::admin':
|
||||
email => 'test@example.com',
|
||||
password => 'ChangeMe',
|
||||
}
|
||||
@ -11,18 +11,18 @@ class { 'keystone::roles::admin':
|
||||
# You can test this connection with ldapsearch first to ensure it works.
|
||||
# This was tested against a FreeIPA box, you will likely need to change the
|
||||
# attributes to match your configuration.
|
||||
class { 'keystone:ldap':
|
||||
identity_driver => 'keystone.identity.backends.ldap.Identity',
|
||||
url => 'ldap://ldap.example.com:389',
|
||||
user => 'uid=bind,cn=users,cn=accounts,dc=example,dc=com',
|
||||
password => 'SecretPass',
|
||||
suffix => 'dc=example,dc=com',
|
||||
query_scope => 'sub',
|
||||
user_tree_dn => 'cn=users,cn=accounts,dc=example,dc=com',
|
||||
user_id_attribute => 'uid',
|
||||
user_name_attribute => 'uid',
|
||||
user_mail_attribute => 'mail',
|
||||
user_allow_create => 'False',
|
||||
user_allow_update => 'False',
|
||||
user_allow_delete => 'False'
|
||||
class { '::keystone:ldap':
|
||||
identity_driver => 'keystone.identity.backends.ldap.Identity',
|
||||
url => 'ldap://ldap.example.com:389',
|
||||
user => 'uid=bind,cn=users,cn=accounts,dc=example,dc=com',
|
||||
password => 'SecretPass',
|
||||
suffix => 'dc=example,dc=com',
|
||||
query_scope => 'sub',
|
||||
user_tree_dn => 'cn=users,cn=accounts,dc=example,dc=com',
|
||||
user_id_attribute => 'uid',
|
||||
user_name_attribute => 'uid',
|
||||
user_mail_attribute => 'mail',
|
||||
user_allow_create => 'False',
|
||||
user_allow_update => 'False',
|
||||
user_allow_delete => 'False'
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
# under the License.
|
||||
|
||||
#
|
||||
# This file was copied from https://github.com/openstack/keystone/raw/0b676730347c76c7f64a67c1ad0135663e99c4fc/httpd/keystone.py
|
||||
# It's only required for platforms on which it is not packaged yet.
|
||||
# It should be removed when available everywhere in a package.
|
||||
#
|
||||
|
@ -1,7 +1,35 @@
|
||||
require 'puppet/util/inifile'
|
||||
class Puppet::Provider::Keystone < Puppet::Provider
|
||||
require 'puppet/provider/openstack'
|
||||
require 'puppet/provider/openstack/auth'
|
||||
require 'puppet/provider/openstack/credentials'
|
||||
|
||||
class Puppet::Provider::Keystone < Puppet::Provider::Openstack
|
||||
|
||||
extend Puppet::Provider::Openstack::Auth
|
||||
|
||||
INI_FILENAME = '/etc/keystone/keystone.conf'
|
||||
|
||||
def self.get_endpoint
|
||||
endpoint = nil
|
||||
if ENV['OS_AUTH_URL']
|
||||
endpoint = ENV['OS_AUTH_URL']
|
||||
else
|
||||
endpoint = get_os_vars_from_rcfile(rc_filename)['OS_AUTH_URL']
|
||||
unless endpoint
|
||||
# This is from legacy but seems wrong, we want auth_url not url!
|
||||
endpoint = get_admin_endpoint
|
||||
end
|
||||
end
|
||||
unless endpoint
|
||||
raise(Puppet::Error::OpenstackAuthInputError, 'Could not find auth url to check user password.')
|
||||
end
|
||||
endpoint
|
||||
end
|
||||
|
||||
def self.admin_endpoint
|
||||
@admin_endpoint ||= get_admin_endpoint
|
||||
end
|
||||
|
||||
# retrieves the current token from keystone.conf
|
||||
def self.admin_token
|
||||
@admin_token ||= get_admin_token
|
||||
end
|
||||
@ -10,181 +38,79 @@ class Puppet::Provider::Keystone < Puppet::Provider
|
||||
if keystone_file and keystone_file['DEFAULT'] and keystone_file['DEFAULT']['admin_token']
|
||||
return "#{keystone_file['DEFAULT']['admin_token'].strip}"
|
||||
else
|
||||
raise(Puppet::Error, "File: /etc/keystone/keystone.conf does not contain a section DEFAULT with the admin_token specified. Keystone types will not work if keystone is not correctly configured")
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
def self.admin_endpoint
|
||||
@admin_endpoint ||= get_admin_endpoint
|
||||
end
|
||||
|
||||
def self.get_admin_endpoint
|
||||
admin_endpoint = keystone_file['DEFAULT']['admin_endpoint'] ? keystone_file['DEFAULT']['admin_endpoint'].strip : nil
|
||||
return admin_endpoint if admin_endpoint
|
||||
if keystone_file
|
||||
if keystone_file['DEFAULT']
|
||||
if keystone_file['DEFAULT']['admin_endpoint']
|
||||
auth_url = keystone_file['DEFAULT']['admin_endpoint'].strip.chomp('/')
|
||||
return "#{auth_url}/v#{@credentials.version}/"
|
||||
end
|
||||
|
||||
admin_port = keystone_file['DEFAULT']['admin_port'] ? keystone_file['DEFAULT']['admin_port'].strip : '35357'
|
||||
ssl = keystone_file['ssl'] && keystone_file['ssl']['enable'] ? keystone_file['ssl']['enable'].strip.downcase == 'true' : false
|
||||
protocol = ssl ? 'https' : 'http'
|
||||
if keystone_file and keystone_file['DEFAULT'] and keystone_file['DEFAULT']['admin_bind_host']
|
||||
host = keystone_file['DEFAULT']['admin_bind_host'].strip
|
||||
if host == "0.0.0.0"
|
||||
host = "127.0.0.1"
|
||||
if keystone_file['DEFAULT']['admin_port']
|
||||
admin_port = keystone_file['DEFAULT']['admin_port'].strip
|
||||
else
|
||||
admin_port = '35357'
|
||||
end
|
||||
|
||||
if keystone_file['DEFAULT']['admin_bind_host']
|
||||
host = keystone_file['DEFAULT']['admin_bind_host'].strip
|
||||
if host == "0.0.0.0"
|
||||
host = "127.0.0.1"
|
||||
elsif host == '::0'
|
||||
host = '[::1]'
|
||||
end
|
||||
else
|
||||
host = "127.0.0.1"
|
||||
end
|
||||
end
|
||||
|
||||
if keystone_file['ssl'] && keystone_file['ssl']['enable'] && keystone_file['ssl']['enable'].strip.downcase == 'true'
|
||||
protocol = 'https'
|
||||
else
|
||||
protocol = 'http'
|
||||
end
|
||||
else
|
||||
host = "127.0.0.1"
|
||||
end
|
||||
"#{protocol}://#{host}:#{admin_port}/v2.0/"
|
||||
|
||||
"#{protocol}://#{host}:#{admin_port}/v#{@credentials.version}/"
|
||||
end
|
||||
|
||||
def self.request(service, action, properties=nil)
|
||||
super
|
||||
rescue Puppet::Error::OpenstackAuthInputError => error
|
||||
request_by_service_token(service, action, error, properties)
|
||||
end
|
||||
|
||||
def self.request_by_service_token(service, action, error, properties=nil)
|
||||
properties ||= []
|
||||
@credentials.token = get_admin_token
|
||||
@credentials.url = get_admin_endpoint
|
||||
raise error unless @credentials.service_token_set?
|
||||
Puppet::Provider::Openstack.request(service, action, properties, @credentials)
|
||||
end
|
||||
|
||||
def self.ini_filename
|
||||
INI_FILENAME
|
||||
end
|
||||
|
||||
def self.keystone_file
|
||||
return @keystone_file if @keystone_file
|
||||
@keystone_file = Puppet::Util::IniConfig::File.new
|
||||
@keystone_file.read('/etc/keystone/keystone.conf')
|
||||
@keystone_file
|
||||
end
|
||||
|
||||
def self.tenant_hash
|
||||
@tenant_hash = build_tenant_hash
|
||||
end
|
||||
|
||||
def tenant_hash
|
||||
self.class.tenant_hash
|
||||
end
|
||||
|
||||
def self.reset
|
||||
@admin_endpoint = nil
|
||||
@tenant_hash = nil
|
||||
@admin_token = nil
|
||||
@keystone_file = nil
|
||||
end
|
||||
|
||||
# the path to withenv changes between versions of puppet, so redefining this function here,
|
||||
# Run some code with a specific environment. Resets the environment at the end of the code.
|
||||
def self.withenv(hash, &block)
|
||||
saved = ENV.to_hash
|
||||
hash.each do |name, val|
|
||||
ENV[name.to_s] = val
|
||||
end
|
||||
block.call
|
||||
ensure
|
||||
ENV.clear
|
||||
saved.each do |name, val|
|
||||
ENV[name] = val
|
||||
if File.exists?(ini_filename)
|
||||
@keystone_file = Puppet::Util::IniConfig::File.new
|
||||
@keystone_file.read(ini_filename)
|
||||
@keystone_file
|
||||
end
|
||||
end
|
||||
|
||||
def self.auth_keystone(*args)
|
||||
authenv = {:OS_SERVICE_TOKEN => admin_token}
|
||||
begin
|
||||
withenv authenv do
|
||||
remove_warnings(keystone('--os-endpoint', admin_endpoint, args))
|
||||
end
|
||||
rescue Exception => e
|
||||
if e.message =~ /(\(HTTP\s+400\))|(\[Errno 111\]\s+Connection\s+refused)|(503\s+Service\s+Unavailable)|(Max\s+retries\s+exceeded)|(Unable\s+to\s+establish\s+connection)/
|
||||
sleep 10
|
||||
withenv authenv do
|
||||
remove_warnings(keystone('--os-endpoint', admin_endpoint, args))
|
||||
end
|
||||
else
|
||||
raise(e)
|
||||
end
|
||||
end
|
||||
# Helper functions to use on the pre-validated enabled field
|
||||
def bool_to_sym(bool)
|
||||
bool == true ? :true : :false
|
||||
end
|
||||
|
||||
def auth_keystone(*args)
|
||||
self.class.auth_keystone(args)
|
||||
def sym_to_bool(sym)
|
||||
sym == :true ? true : false
|
||||
end
|
||||
|
||||
def self.creds_keystone(name, tenant, password, *args)
|
||||
authenv = {:OS_USERNAME => name, :OS_TENANT_NAME => tenant, :OS_PASSWORD => password}
|
||||
begin
|
||||
withenv authenv do
|
||||
remove_warnings(keystone('--os-auth-url', admin_endpoint, args))
|
||||
end
|
||||
rescue Exception => e
|
||||
if e.message =~ /(\(HTTP\s+400\))|(\[Errno 111\]\s+Connection\s+refused)|(503\s+Service\s+Unavailable)|(Max\s+retries\s+exceeded)|(Unable\s+to\s+establish\s+connection)/
|
||||
sleep 10
|
||||
withenv authenv do
|
||||
remove_warnings(keystone('--os-auth-url', admin_endpoint, args))
|
||||
end
|
||||
else
|
||||
raise(e)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def creds_keystone(name, tenant, password, *args)
|
||||
self.class.creds_keystone(name, tenant, password, args)
|
||||
end
|
||||
|
||||
def self.parse_keystone_object(data)
|
||||
# Parse the output of [type]-{create,get} into a hash
|
||||
attrs = {}
|
||||
header_lines = 3
|
||||
footer_lines = 1
|
||||
data.split("\n")[header_lines...-footer_lines].each do |line|
|
||||
if match_data = /\|\s([^|]+)\s\|\s([^|]+)\s\|/.match(line)
|
||||
attrs[match_data[1].strip] = match_data[2].strip
|
||||
end
|
||||
end
|
||||
attrs
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def self.list_keystone_objects(type, number_columns, *args)
|
||||
# this assumes that all returned objects are of the form
|
||||
# id, name, enabled_state, OTHER
|
||||
# number_columns can be a Fixnum or an Array of possible values that can be returned
|
||||
list = (auth_keystone("#{type}-list", args).split("\n")[3..-2] || []).collect do |line|
|
||||
row = line.split(/\|/)[1..-1]
|
||||
row = row.map {|x| x.strip }
|
||||
# if both checks fail then we have a mismatch between what was expected and what was received
|
||||
if (number_columns.class == Array and !number_columns.include? row.size) or (number_columns.class == Fixnum and row.size != number_columns)
|
||||
raise(Puppet::Error, "Expected #{number_columns} columns for #{type} row, found #{row.size}. Line #{line}")
|
||||
end
|
||||
row
|
||||
end
|
||||
list
|
||||
end
|
||||
|
||||
def self.get_keystone_object(type, id, attr)
|
||||
id = id.chomp
|
||||
auth_keystone("#{type}-get", id).split(/\|\n/m).each do |line|
|
||||
if line =~ /\|(\s+)?#{attr}(\s+)?\|/
|
||||
if line.kind_of?(Array)
|
||||
return line[0].split("|")[2].strip
|
||||
else
|
||||
return line.split("|")[2].strip
|
||||
end
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
raise(Puppet::Error, "Could not find colummn #{attr} when getting #{type} #{id}")
|
||||
end
|
||||
|
||||
# remove warning from the output. this is a temporary hack until
|
||||
# I refactor things to use the the rest API
|
||||
def self.remove_warnings(results)
|
||||
found_header = false
|
||||
in_warning = false
|
||||
results.split("\n").collect do |line|
|
||||
unless found_header
|
||||
if line =~ /^\+[-\+]+\+$/
|
||||
in_warning = false
|
||||
found_header = true
|
||||
line
|
||||
elsif line =~ /^WARNING/ or line =~ /UserWarning/ or in_warning
|
||||
# warnings can be multi line, we have to skip all of them
|
||||
in_warning = true
|
||||
nil
|
||||
else
|
||||
line
|
||||
end
|
||||
else
|
||||
line
|
||||
end
|
||||
end.compact.join("\n")
|
||||
end
|
||||
end
|
||||
|
@ -1,125 +0,0 @@
|
||||
$LOAD_PATH.push(File.join(File.dirname(__FILE__), '..', '..', '..'))
|
||||
require 'puppet/provider/keystone'
|
||||
Puppet::Type.type(:keystone_endpoint).provide(
|
||||
:keystone,
|
||||
:parent => Puppet::Provider::Keystone
|
||||
) do
|
||||
|
||||
desc <<-EOT
|
||||
Provider that uses the keystone client tool to
|
||||
manage keystone endpoints
|
||||
|
||||
This provider makes a few assumptions/
|
||||
1. assumes that the admin endpoint can be accessed via localhost.
|
||||
2. Assumes that the admin token and port can be accessed from
|
||||
/etc/keystone/keystone.conf
|
||||
EOT
|
||||
|
||||
optional_commands :keystone => "keystone"
|
||||
|
||||
def initialize(resource = nil)
|
||||
super(resource)
|
||||
@property_flush = {}
|
||||
end
|
||||
|
||||
def self.prefetch(resources)
|
||||
endpoints = instances
|
||||
resources.keys.each do |name|
|
||||
if provider = endpoints.find{ |endpoint| endpoint.name == name }
|
||||
resources[name].provider = provider
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def self.instances
|
||||
list_keystone_objects('endpoint', [5,6]).collect do |endpoint|
|
||||
service_name = get_keystone_object('service', endpoint[5], 'name')
|
||||
new(
|
||||
:name => "#{endpoint[1]}/#{service_name}",
|
||||
:ensure => :present,
|
||||
:id => endpoint[0],
|
||||
:region => endpoint[1],
|
||||
:public_url => endpoint[2],
|
||||
:internal_url => endpoint[3],
|
||||
:admin_url => endpoint[4],
|
||||
:service_id => endpoint[5],
|
||||
:service_name => service_name
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
optional_opts = []
|
||||
{
|
||||
:public_url => '--publicurl',
|
||||
:internal_url => '--internalurl',
|
||||
:admin_url => '--adminurl'
|
||||
}.each do |param, opt|
|
||||
if resource[param]
|
||||
optional_opts.push(opt).push(resource[param])
|
||||
end
|
||||
end
|
||||
|
||||
(region, service_name) = resource[:name].split('/')
|
||||
resource[:region] = region
|
||||
optional_opts.push('--region').push(resource[:region])
|
||||
|
||||
service_id = self.class.list_keystone_objects('service', 4).detect do |s|
|
||||
s[1] == service_name
|
||||
end.first
|
||||
|
||||
auth_keystone('endpoint-create', '--service-id', service_id, optional_opts)
|
||||
end
|
||||
|
||||
def exists?
|
||||
@property_hash[:ensure] == :present
|
||||
end
|
||||
|
||||
def destroy
|
||||
auth_keystone('endpoint-delete', @property_hash[:id])
|
||||
end
|
||||
|
||||
def flush
|
||||
if ! @property_flush.empty?
|
||||
destroy
|
||||
create
|
||||
@property_flush.clear
|
||||
end
|
||||
@property_hash = resource.to_hash
|
||||
end
|
||||
|
||||
def id
|
||||
@property_hash[:id]
|
||||
end
|
||||
|
||||
def region
|
||||
@property_hash[:region]
|
||||
end
|
||||
|
||||
def public_url
|
||||
@property_hash[:public_url]
|
||||
end
|
||||
|
||||
def internal_url
|
||||
@property_hash[:internal_url]
|
||||
end
|
||||
|
||||
def admin_url
|
||||
@property_hash[:admin_url]
|
||||
end
|
||||
|
||||
def public_url=(value)
|
||||
@property_hash[:public_url] = value
|
||||
@property_flush[:public_url] = value
|
||||
end
|
||||
|
||||
def internal_url=(value)
|
||||
@property_hash[:internal_url] = value
|
||||
@property_flush[:internal_url] = value
|
||||
end
|
||||
|
||||
def admin_url=(value)
|
||||
@property_hash[:admin_url] = value
|
||||
@property_flush[:admin_url] = value
|
||||
end
|
||||
end
|
@ -0,0 +1,112 @@
|
||||
require 'puppet/provider/keystone'
|
||||
|
||||
Puppet::Type.type(:keystone_endpoint).provide(
|
||||
:openstack,
|
||||
:parent => Puppet::Provider::Keystone
|
||||
) do
|
||||
|
||||
desc "Provider to manage keystone endpoints."
|
||||
|
||||
@credentials = Puppet::Provider::Openstack::CredentialsV2_0.new
|
||||
|
||||
def initialize(value={})
|
||||
super(value)
|
||||
@property_flush = {}
|
||||
end
|
||||
|
||||
def create
|
||||
properties = []
|
||||
# The region property is just ignored. We should fix this in kilo.
|
||||
region, name = resource[:name].split('/')
|
||||
properties << name
|
||||
properties << '--region'
|
||||
properties << region
|
||||
if resource[:public_url]
|
||||
properties << '--publicurl'
|
||||
properties << resource[:public_url]
|
||||
end
|
||||
if resource[:internal_url]
|
||||
properties << '--internalurl'
|
||||
properties << resource[:internal_url]
|
||||
end
|
||||
if resource[:admin_url]
|
||||
properties << '--adminurl'
|
||||
properties << resource[:admin_url]
|
||||
end
|
||||
self.class.request('endpoint', 'create', properties)
|
||||
@property_hash[:ensure] = :present
|
||||
end
|
||||
|
||||
def destroy
|
||||
self.class.request('endpoint', 'delete', @property_hash[:id])
|
||||
@property_hash.clear
|
||||
end
|
||||
|
||||
def exists?
|
||||
@property_hash[:ensure] == :present
|
||||
end
|
||||
|
||||
def region
|
||||
@property_hash[:region]
|
||||
end
|
||||
|
||||
def public_url=(value)
|
||||
@property_flush[:public_url] = value
|
||||
end
|
||||
|
||||
def public_url
|
||||
@property_hash[:public_url]
|
||||
end
|
||||
|
||||
def internal_url=(value)
|
||||
@property_flush[:internal_url] = value
|
||||
end
|
||||
|
||||
def internal_url
|
||||
@property_hash[:internal_url]
|
||||
end
|
||||
|
||||
def admin_url=(value)
|
||||
@property_flush[:admin_url] = value
|
||||
end
|
||||
|
||||
def admin_url
|
||||
@property_hash[:admin_url]
|
||||
end
|
||||
|
||||
def id
|
||||
@property_hash[:id]
|
||||
end
|
||||
|
||||
def self.instances
|
||||
list = request('endpoint', 'list', '--long')
|
||||
list.collect do |endpoint|
|
||||
new(
|
||||
:name => "#{endpoint[:region]}/#{endpoint[:service_name]}",
|
||||
:ensure => :present,
|
||||
:id => endpoint[:id],
|
||||
:region => endpoint[:region],
|
||||
:public_url => endpoint[:publicurl],
|
||||
:internal_url => endpoint[:internalurl],
|
||||
:admin_url => endpoint[:adminurl]
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def self.prefetch(resources)
|
||||
endpoints = instances
|
||||
resources.keys.each do |name|
|
||||
if provider = endpoints.find{ |endpoint| endpoint.name == name }
|
||||
resources[name].provider = provider
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def flush
|
||||
if ! @property_flush.empty?
|
||||
destroy
|
||||
create
|
||||
@property_flush.clear
|
||||
end
|
||||
end
|
||||
end
|
@ -0,0 +1,27 @@
|
||||
Puppet::Type.type(:keystone_paste_ini).provide(
|
||||
:ini_setting,
|
||||
:parent => Puppet::Type.type(:ini_setting).provider(:ruby)
|
||||
) do
|
||||
|
||||
def section
|
||||
resource[:name].split('/', 2).first
|
||||
end
|
||||
|
||||
def setting
|
||||
resource[:name].split('/', 2).last
|
||||
end
|
||||
|
||||
def separator
|
||||
'='
|
||||
end
|
||||
|
||||
def self.file_path
|
||||
'/etc/keystone/keystone-paste.ini'
|
||||
end
|
||||
|
||||
# this needs to be removed. This has been replaced with the class method
|
||||
def file_path
|
||||
self.class.file_path
|
||||
end
|
||||
|
||||
end
|
@ -1,65 +0,0 @@
|
||||
$LOAD_PATH.push(File.join(File.dirname(__FILE__), '..', '..', '..'))
|
||||
require 'puppet/provider/keystone'
|
||||
Puppet::Type.type(:keystone_role).provide(
|
||||
:keystone,
|
||||
:parent => Puppet::Provider::Keystone
|
||||
) do
|
||||
|
||||
desc <<-EOT
|
||||
Provider that uses the keystone client tool to
|
||||
manage keystone roles
|
||||
EOT
|
||||
|
||||
optional_commands :keystone => "keystone"
|
||||
|
||||
def self.prefetch(resource)
|
||||
# rebuild the cahce for every puppet run
|
||||
@role_hash = nil
|
||||
end
|
||||
|
||||
def self.role_hash
|
||||
@role_hash = build_role_hash
|
||||
end
|
||||
|
||||
def role_hash
|
||||
self.class.role_hash
|
||||
end
|
||||
|
||||
def self.instances
|
||||
role_hash.collect do |k, v|
|
||||
new(:name => k)
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
auth_keystone(
|
||||
'role-create',
|
||||
'--name', resource[:name]
|
||||
)
|
||||
end
|
||||
|
||||
def exists?
|
||||
role_hash[resource[:name]]
|
||||
end
|
||||
|
||||
def destroy
|
||||
auth_keystone('role-delete', role_hash[resource[:name]][:id])
|
||||
end
|
||||
|
||||
def id
|
||||
role_hash[resource[:name]][:id]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def self.build_role_hash
|
||||
hash = {}
|
||||
list_keystone_objects('role', 2).each do |role|
|
||||
hash[role[1]] = {
|
||||
:id => role[0],
|
||||
}
|
||||
end
|
||||
hash
|
||||
end
|
||||
|
||||
end
|
@ -0,0 +1,54 @@
|
||||
require 'puppet/provider/keystone'
|
||||
|
||||
Puppet::Type.type(:keystone_role).provide(
|
||||
:openstack,
|
||||
:parent => Puppet::Provider::Keystone
|
||||
) do
|
||||
|
||||
desc 'Provider for keystone roles.'
|
||||
|
||||
@credentials = Puppet::Provider::Openstack::CredentialsV2_0.new
|
||||
|
||||
def initialize(value={})
|
||||
super(value)
|
||||
@property_flush = {}
|
||||
end
|
||||
|
||||
def create
|
||||
self.class.request('role', 'create', name)
|
||||
@property_hash[:ensure] = :present
|
||||
end
|
||||
|
||||
def destroy
|
||||
self.class.request('role', 'delete', @property_hash[:id])
|
||||
@property_hash.clear
|
||||
end
|
||||
|
||||
def exists?
|
||||
@property_hash[:ensure] == :present
|
||||
end
|
||||
|
||||
def id
|
||||
@property_hash[:id]
|
||||
end
|
||||
|
||||
def self.instances
|
||||
list = request('role', 'list')
|
||||
list.collect do |role|
|
||||
new(
|
||||
:name => role[:name],
|
||||
:ensure => :present,
|
||||
:id => role[:id]
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def self.prefetch(resources)
|
||||
roles = instances
|
||||
resources.keys.each do |name|
|
||||
if provider = roles.find{ |role| role.name == name }
|
||||
resources[name].provider = provider
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -1,97 +0,0 @@
|
||||
$LOAD_PATH.push(File.join(File.dirname(__FILE__), '..', '..', '..'))
|
||||
require 'puppet/provider/keystone'
|
||||
Puppet::Type.type(:keystone_service).provide(
|
||||
:keystone,
|
||||
:parent => Puppet::Provider::Keystone
|
||||
) do
|
||||
|
||||
desc <<-EOT
|
||||
Provider that uses the keystone client tool to
|
||||
manage keystone services
|
||||
|
||||
This provider makes a few assumptions/
|
||||
1. assumes that the admin endpoint can be accessed via localhost.
|
||||
2. Assumes that the admin token and port can be accessed from
|
||||
/etc/keystone/keystone.conf
|
||||
|
||||
Does not support the ability to list all
|
||||
EOT
|
||||
|
||||
optional_commands :keystone => "keystone"
|
||||
|
||||
def self.prefetch(resource)
|
||||
# rebuild the cahce for every puppet run
|
||||
@service_hash = nil
|
||||
end
|
||||
|
||||
def self.service_hash
|
||||
@service_hash = build_service_hash
|
||||
end
|
||||
|
||||
def service_hash
|
||||
self.class.service_hash
|
||||
end
|
||||
|
||||
def self.instances
|
||||
service_hash.collect do |k, v|
|
||||
new(:name => k)
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
optional_opts = []
|
||||
raise(Puppet::Error, "Required property type not specified for KeystoneService[#{resource[:name]}]") unless resource[:type]
|
||||
if resource[:description]
|
||||
optional_opts.push('--description').push(resource[:description])
|
||||
end
|
||||
auth_keystone(
|
||||
'service-create',
|
||||
'--name', resource[:name],
|
||||
'--type', resource[:type],
|
||||
optional_opts
|
||||
)
|
||||
end
|
||||
|
||||
def exists?
|
||||
service_hash[resource[:name]]
|
||||
end
|
||||
|
||||
def destroy
|
||||
auth_keystone('service-delete', service_hash[resource[:name]][:id])
|
||||
end
|
||||
|
||||
def id
|
||||
service_hash[resource[:name]][:id]
|
||||
end
|
||||
|
||||
def type
|
||||
service_hash[resource[:name]][:type]
|
||||
end
|
||||
|
||||
def type=(value)
|
||||
raise(Puppet::Error, "service-update is not currently supported by the keystone sql driver")
|
||||
end
|
||||
|
||||
def description
|
||||
service_hash[resource[:name]][:description]
|
||||
end
|
||||
|
||||
def description=(value)
|
||||
raise(Puppet::Error, "service-update is not currently supported by the keystone sql driver")
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def self.build_service_hash
|
||||
hash = {}
|
||||
list_keystone_objects('service', 4).each do |user|
|
||||
hash[user[1]] = {
|
||||
:id => user[0],
|
||||
:type => user[2],
|
||||
:description => user[3]
|
||||
}
|
||||
end
|
||||
hash
|
||||
end
|
||||
|
||||
end
|
@ -0,0 +1,88 @@
|
||||
require 'puppet/provider/keystone'
|
||||
|
||||
Puppet::Type.type(:keystone_service).provide(
|
||||
:openstack,
|
||||
:parent => Puppet::Provider::Keystone
|
||||
) do
|
||||
|
||||
desc "Provider to manage keystone services."
|
||||
|
||||
@credentials = Puppet::Provider::Openstack::CredentialsV2_0.new
|
||||
|
||||
def initialize(value={})
|
||||
super(value)
|
||||
@property_flush = {}
|
||||
end
|
||||
|
||||
def create
|
||||
properties = ['--name']
|
||||
properties << resource[:name]
|
||||
if resource[:description]
|
||||
properties << '--description'
|
||||
properties << resource[:description]
|
||||
end
|
||||
raise(Puppet::Error, 'The service type is mandatory') unless resource[:type]
|
||||
properties << resource[:type]
|
||||
self.class.request('service', 'create', properties)
|
||||
@property_hash[:ensure] = :present
|
||||
end
|
||||
|
||||
def exists?
|
||||
@property_hash[:ensure] == :present
|
||||
end
|
||||
|
||||
def destroy
|
||||
self.class.request('service', 'delete', @property_hash[:id])
|
||||
@property_hash.clear
|
||||
end
|
||||
|
||||
def description=(value)
|
||||
@property_flush[:description] = value
|
||||
end
|
||||
|
||||
def description
|
||||
@property_hash[:description]
|
||||
end
|
||||
|
||||
def type=(value)
|
||||
@property_flush[:type] = value
|
||||
end
|
||||
|
||||
def type
|
||||
@property_hash[:type]
|
||||
end
|
||||
|
||||
def id
|
||||
@property_hash[:id]
|
||||
end
|
||||
|
||||
def self.instances
|
||||
list = request('service', 'list', '--long')
|
||||
list.collect do |service|
|
||||
new(
|
||||
:name => service[:name],
|
||||
:ensure => :present,
|
||||
:type => service[:type],
|
||||
:description => service[:description],
|
||||
:id => service[:id]
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def self.prefetch(resources)
|
||||
services = instances
|
||||
resources.keys.each do |name|
|
||||
if provider = services.find{ |service| service.name == name }
|
||||
resources[name].provider = provider
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def flush
|
||||
if ! @property_flush.empty?
|
||||
destroy
|
||||
create
|
||||
@property_flush.clear
|
||||
end
|
||||
end
|
||||
end
|
@ -1,120 +0,0 @@
|
||||
$LOAD_PATH.push(File.join(File.dirname(__FILE__), '..', '..', '..'))
|
||||
require 'puppet/provider/keystone'
|
||||
Puppet::Type.type(:keystone_tenant).provide(
|
||||
:keystone,
|
||||
:parent => Puppet::Provider::Keystone
|
||||
) do
|
||||
|
||||
desc <<-EOT
|
||||
Provider that uses the keystone client tool to
|
||||
manage keystone tenants
|
||||
|
||||
This provider makes a few assumptions/
|
||||
1. assumes that the admin endpoint can be accessed via localhost.
|
||||
2. Assumes that the admin token and port can be accessed from
|
||||
/etc/keystone/keystone.conf
|
||||
|
||||
One string difference, is that it does not know how to change the
|
||||
name of a tenant
|
||||
EOT
|
||||
|
||||
optional_commands :keystone => "keystone"
|
||||
|
||||
def self.prefetch(resource)
|
||||
# rebuild the cahce for every puppet run
|
||||
@tenant_hash = nil
|
||||
end
|
||||
|
||||
def self.tenant_hash
|
||||
@tenant_hash = build_tenant_hash
|
||||
end
|
||||
|
||||
def tenant_hash
|
||||
self.class.tenant_hash
|
||||
end
|
||||
|
||||
def instance
|
||||
tenant_hash[resource[:name]]
|
||||
end
|
||||
|
||||
def self.instances
|
||||
tenant_hash.collect do |k, v|
|
||||
new(
|
||||
:name => k,
|
||||
:id => v[:id]
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
optional_opts = []
|
||||
if resource[:description]
|
||||
optional_opts.push('--description').push(resource[:description])
|
||||
end
|
||||
results = auth_keystone(
|
||||
'tenant-create',
|
||||
'--name', resource[:name],
|
||||
'--enabled', resource[:enabled],
|
||||
optional_opts
|
||||
)
|
||||
|
||||
if results =~ /Property\s|\sValue/
|
||||
attrs = self.class.parse_keystone_object(results)
|
||||
tenant_hash[resource[:name]] = {
|
||||
:ensure => :present,
|
||||
:name => resource[:name],
|
||||
:id => attrs['id'],
|
||||
:enabled => attrs['enabled'],
|
||||
:description => attrs['description'],
|
||||
}
|
||||
else
|
||||
fail("did not get expected message on tenant creation, got #{results}")
|
||||
end
|
||||
end
|
||||
|
||||
def exists?
|
||||
instance
|
||||
end
|
||||
|
||||
def destroy
|
||||
auth_keystone('tenant-delete', instance[:id])
|
||||
instance[:ensure] = :absent
|
||||
end
|
||||
|
||||
def enabled=(value)
|
||||
Puppet.warning("I am not sure if this is supported yet")
|
||||
auth_keystone("tenant-update", '--enabled', value, instance[:id])
|
||||
instance[:enabled] = value
|
||||
end
|
||||
|
||||
def description
|
||||
self.class.get_keystone_object('tenant', instance[:id], 'description')
|
||||
end
|
||||
|
||||
def description=(value)
|
||||
auth_keystone("tenant-update", '--description', value, instance[:id])
|
||||
instance[:description] = value
|
||||
end
|
||||
|
||||
[
|
||||
:id,
|
||||
:enabled,
|
||||
].each do |attr|
|
||||
define_method(attr.to_s) do
|
||||
instance[attr] || :absent
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def self.build_tenant_hash
|
||||
hash = {}
|
||||
list_keystone_objects('tenant', 3).each do |tenant|
|
||||
hash[tenant[1]] = {
|
||||
:id => tenant[0],
|
||||
:enabled => tenant[2],
|
||||
}
|
||||
end
|
||||
hash
|
||||
end
|
||||
end
|
@ -0,0 +1,99 @@
|
||||
require 'puppet/provider/keystone'
|
||||
|
||||
Puppet::Type.type(:keystone_tenant).provide(
|
||||
:openstack,
|
||||
:parent => Puppet::Provider::Keystone
|
||||
) do
|
||||
|
||||
desc "Provider to manage keystone tenants/projects."
|
||||
|
||||
@credentials = Puppet::Provider::Openstack::CredentialsV2_0.new
|
||||
|
||||
def initialize(value={})
|
||||
super(value)
|
||||
@property_flush = {}
|
||||
end
|
||||
|
||||
def create
|
||||
properties = [resource[:name]]
|
||||
if resource[:enabled] == :true
|
||||
properties << '--enable'
|
||||
elsif resource[:enabled] == :false
|
||||
properties << '--disable'
|
||||
end
|
||||
if resource[:description]
|
||||
properties << '--description'
|
||||
properties << resource[:description]
|
||||
end
|
||||
self.class.request('project', 'create', properties)
|
||||
@property_hash[:ensure] = :present
|
||||
end
|
||||
|
||||
def exists?
|
||||
@property_hash[:ensure] == :present
|
||||
end
|
||||
|
||||
def destroy
|
||||
self.class.request('project', 'delete', @property_hash[:id])
|
||||
@property_hash.clear
|
||||
end
|
||||
|
||||
def enabled=(value)
|
||||
@property_flush[:enabled] = value
|
||||
end
|
||||
|
||||
def enabled
|
||||
bool_to_sym(@property_hash[:enabled])
|
||||
end
|
||||
|
||||
def description=(value)
|
||||
@property_flush[:description] = value
|
||||
end
|
||||
|
||||
def description
|
||||
@property_hash[:description]
|
||||
end
|
||||
|
||||
def id
|
||||
@property_hash[:id]
|
||||
end
|
||||
|
||||
def self.instances
|
||||
list = request('project', 'list', '--long')
|
||||
list.collect do |project|
|
||||
new(
|
||||
:name => project[:name],
|
||||
:ensure => :present,
|
||||
:enabled => project[:enabled].downcase.chomp == 'true' ? true : false,
|
||||
:description => project[:description],
|
||||
:id => project[:id]
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def self.prefetch(resources)
|
||||
tenants = instances
|
||||
resources.keys.each do |name|
|
||||
if provider = tenants.find{ |tenant| tenant.name == name }
|
||||
resources[name].provider = provider
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def flush
|
||||
options = []
|
||||
if @property_flush && !@property_flush.empty?
|
||||
case @property_flush[:enabled]
|
||||
when :true
|
||||
options << '--enable'
|
||||
when :false
|
||||
options << '--disable'
|
||||
end
|
||||
(options << "--description=#{resource[:description]}") if @property_flush[:description]
|
||||
options << @property_hash[:id]
|
||||
self.class.request('project', 'set', options) unless options.empty?
|
||||
@property_flush.clear
|
||||
end
|
||||
end
|
||||
|
||||
end
|
@ -1,172 +0,0 @@
|
||||
$LOAD_PATH.push(File.join(File.dirname(__FILE__), '..', '..', '..'))
|
||||
require 'puppet/provider/keystone'
|
||||
Puppet::Type.type(:keystone_user).provide(
|
||||
:keystone,
|
||||
:parent => Puppet::Provider::Keystone
|
||||
) do
|
||||
|
||||
desc <<-EOT
|
||||
Provider that uses the keystone client tool to
|
||||
manage keystone users
|
||||
|
||||
This provider makes a few assumptions/
|
||||
1. assumes that the admin endpoint can be accessed via localhost.
|
||||
2. Assumes that the admin token and port can be accessed from
|
||||
/etc/keystone/keystone.conf
|
||||
|
||||
Does not support the ability to update the user's name
|
||||
EOT
|
||||
|
||||
optional_commands :keystone => "keystone"
|
||||
|
||||
def self.prefetch(resource)
|
||||
# rebuild the cahce for every puppet run
|
||||
@user_hash = nil
|
||||
end
|
||||
|
||||
def self.user_hash
|
||||
@user_hash = build_user_hash
|
||||
end
|
||||
|
||||
def user_hash
|
||||
self.class.user_hash
|
||||
end
|
||||
|
||||
def self.instances
|
||||
user_hash.collect do |k, v|
|
||||
new(:name => k)
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
optional_opts = []
|
||||
if resource[:email]
|
||||
optional_opts.push('--email').push(resource[:email])
|
||||
end
|
||||
if resource[:password]
|
||||
optional_opts.push('--pass').push(resource[:password])
|
||||
end
|
||||
if resource[:tenant]
|
||||
tenant_id = self.class.list_keystone_objects('tenant', 3).collect {|x|
|
||||
x[0] if x[1] == resource[:tenant]
|
||||
}.compact[0]
|
||||
optional_opts.push('--tenant_id').push(tenant_id)
|
||||
end
|
||||
auth_keystone(
|
||||
'user-create',
|
||||
'--name', resource[:name],
|
||||
'--enabled', resource[:enabled],
|
||||
optional_opts
|
||||
)
|
||||
end
|
||||
|
||||
def exists?
|
||||
user_hash[resource[:name]]
|
||||
end
|
||||
|
||||
def destroy
|
||||
auth_keystone('user-delete', user_hash[resource[:name]][:id])
|
||||
end
|
||||
|
||||
def enabled
|
||||
user_hash[resource[:name]][:enabled]
|
||||
end
|
||||
|
||||
def enabled=(value)
|
||||
auth_keystone(
|
||||
"user-update",
|
||||
'--enabled', value,
|
||||
user_hash[resource[:name]][:id]
|
||||
)
|
||||
end
|
||||
|
||||
def password
|
||||
# if we don't know a password we can't test it
|
||||
return nil if resource[:password] == nil
|
||||
# we can't get the value of the password but we can test to see if the one we know
|
||||
# about works, if it doesn't then return nil, causing it to be reset
|
||||
begin
|
||||
token_out = creds_keystone(resource[:name], resource[:tenant], resource[:password], "token-get")
|
||||
rescue Exception => e
|
||||
return nil if e.message =~ /Not Authorized/ or e.message =~ /HTTP 401/
|
||||
raise e
|
||||
end
|
||||
return resource[:password]
|
||||
end
|
||||
|
||||
def password=(value)
|
||||
if resource[:replace_password] == 'True'
|
||||
auth_keystone('user-password-update', '--pass', value, user_hash[resource[:name]][:id])
|
||||
end
|
||||
end
|
||||
|
||||
def tenant
|
||||
return resource[:tenant] if resource[:ignore_default_tenant]
|
||||
user_id = user_hash[resource[:name]][:id]
|
||||
begin
|
||||
tenantId = self.class.get_keystone_object('user', user_id, 'tenantId')
|
||||
rescue
|
||||
tenantId = nil
|
||||
end
|
||||
if tenantId.nil? or tenantId == 'None' or tenantId.empty?
|
||||
tenant = 'None'
|
||||
else
|
||||
# this prevents is from failing if tenant no longer exists
|
||||
begin
|
||||
tenant = self.class.get_keystone_object('tenant', tenantId, 'name')
|
||||
rescue
|
||||
tenant = 'None'
|
||||
end
|
||||
end
|
||||
tenant
|
||||
end
|
||||
|
||||
def tenant=(value)
|
||||
fail("tenant cannot be updated. Transition requested: #{user_hash[resource[:name]][:tenant]} -> #{value}")
|
||||
end
|
||||
|
||||
def email
|
||||
user_hash[resource[:name]][:email]
|
||||
end
|
||||
|
||||
def email=(value)
|
||||
auth_keystone(
|
||||
"user-update",
|
||||
'--email', value,
|
||||
user_hash[resource[:name]][:id]
|
||||
)
|
||||
end
|
||||
|
||||
def replace_password
|
||||
user_hash[resource[:name]][:replace_password]
|
||||
end
|
||||
|
||||
def replace_password=(value)
|
||||
user_hash[resource[:name]][:replace_password]
|
||||
end
|
||||
|
||||
def id
|
||||
user_hash[resource[:name]][:id]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def self.build_user_hash
|
||||
hash = {}
|
||||
list_keystone_objects('user', 4).each do |user|
|
||||
password = 'nil'
|
||||
replace_password = 'True',
|
||||
hash[user[1]] = {
|
||||
:id => user[0],
|
||||
:enabled => user[2],
|
||||
:email => user[3],
|
||||
:name => user[1],
|
||||
:password => password,
|
||||
:replace_password => replace_password,
|
||||
}
|
||||
end
|
||||
hash
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -0,0 +1,204 @@
|
||||
require 'puppet/provider/keystone'
|
||||
|
||||
Puppet::Type.type(:keystone_user).provide(
|
||||
:openstack,
|
||||
:parent => Puppet::Provider::Keystone
|
||||
) do
|
||||
|
||||
desc "Provider to manage keystone users."
|
||||
|
||||
@credentials = Puppet::Provider::Openstack::CredentialsV2_0.new
|
||||
|
||||
def initialize(value={})
|
||||
super(value)
|
||||
@property_flush = {}
|
||||
end
|
||||
|
||||
def create
|
||||
properties = [resource[:name]]
|
||||
if resource[:enabled] == :true
|
||||
properties << '--enable'
|
||||
elsif resource[:enabled] == :false
|
||||
properties << '--disable'
|
||||
end
|
||||
if resource[:password]
|
||||
properties << '--password' << resource[:password]
|
||||
end
|
||||
if resource[:tenant]
|
||||
properties << '--project' << resource[:tenant]
|
||||
end
|
||||
if resource[:email]
|
||||
properties << '--email' << resource[:email]
|
||||
end
|
||||
self.class.request('user', 'create', properties)
|
||||
@property_hash[:ensure] = :present
|
||||
end
|
||||
|
||||
def destroy
|
||||
self.class.request('user', 'delete', @property_hash[:id])
|
||||
@property_hash.clear
|
||||
end
|
||||
|
||||
def flush
|
||||
options = []
|
||||
if @property_flush && !@property_flush.empty?
|
||||
options << '--enable' if @property_flush[:enabled] == :true
|
||||
options << '--disable' if @property_flush[:enabled] == :false
|
||||
# There is a --description flag for the set command, but it does not work if the value is empty
|
||||
options << '--password' << resource[:password] if @property_flush[:password]
|
||||
options << '--email' << resource[:email] if @property_flush[:email]
|
||||
# project handled in tenant= separately
|
||||
unless options.empty?
|
||||
options << @property_hash[:id]
|
||||
self.class.request('user', 'set', options)
|
||||
end
|
||||
@property_flush.clear
|
||||
end
|
||||
end
|
||||
|
||||
def exists?
|
||||
@property_hash[:ensure] == :present
|
||||
end
|
||||
|
||||
# Types properties
|
||||
def enabled
|
||||
bool_to_sym(@property_hash[:enabled])
|
||||
end
|
||||
|
||||
def enabled=(value)
|
||||
@property_flush[:enabled] = value
|
||||
end
|
||||
|
||||
def email
|
||||
@property_hash[:email]
|
||||
end
|
||||
|
||||
def email=(value)
|
||||
@property_flush[:email] = value
|
||||
end
|
||||
|
||||
def id
|
||||
@property_hash[:id]
|
||||
end
|
||||
|
||||
def password
|
||||
res = nil
|
||||
return res if resource[:password] == nil
|
||||
if resource[:enabled] == :false || resource[:replace_password] == :false
|
||||
# Unchanged password
|
||||
res = resource[:password]
|
||||
else
|
||||
# Password validation
|
||||
credentials = Puppet::Provider::Openstack::CredentialsV2_0.new
|
||||
credentials.auth_url = self.class.get_endpoint
|
||||
credentials.password = resource[:password]
|
||||
credentials.project_name = resource[:tenant]
|
||||
credentials.username = resource[:name]
|
||||
begin
|
||||
token = Puppet::Provider::Openstack.request('token', 'issue', ['--format', 'value'], credentials)
|
||||
rescue Puppet::Error::OpenstackUnauthorizedError
|
||||
# password is invalid
|
||||
else
|
||||
res = resource[:password] unless token.empty?
|
||||
end
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
def password=(value)
|
||||
@property_flush[:password] = value
|
||||
end
|
||||
|
||||
def replace_password
|
||||
@property_hash[:replace_password]
|
||||
end
|
||||
|
||||
def replace_password=(value)
|
||||
@property_flush[:replace_password] = value
|
||||
end
|
||||
|
||||
def tenant
|
||||
return resource[:tenant] if sym_to_bool(resource[:ignore_default_tenant])
|
||||
# use the one returned from instances
|
||||
tenant_name = @property_hash[:project]
|
||||
if tenant_name.nil? or tenant_name.empty?
|
||||
# if none (i.e. ldap backend) use the given one
|
||||
tenant_name = resource[:tenant]
|
||||
else
|
||||
return tenant_name
|
||||
end
|
||||
if tenant_name.nil? or tenant_name.empty?
|
||||
return nil # nothing found, nothing given
|
||||
end
|
||||
# If the user list command doesn't report the project, it might still be there
|
||||
# We don't need to know exactly what it is, we just need to know whether it's
|
||||
# the one we're trying to set.
|
||||
roles = self.class.request('user role', 'list', [resource[:name], '--project', tenant_name])
|
||||
if roles.empty?
|
||||
return nil
|
||||
else
|
||||
return tenant_name
|
||||
end
|
||||
end
|
||||
|
||||
def tenant=(value)
|
||||
self.class.request('user', 'set', [resource[:name], '--project', value])
|
||||
rescue Puppet::ExecutionFailure => e
|
||||
if e.message =~ /You are not authorized to perform the requested action: LDAP user update/
|
||||
# read-only LDAP identity backend - just fall through
|
||||
else
|
||||
raise e
|
||||
end
|
||||
# note: read-write ldap will silently fail, not raise an exception
|
||||
else
|
||||
@property_hash[:tenant] = self.class.set_project(value, resource[:name])
|
||||
end
|
||||
|
||||
def self.instances
|
||||
list = request('user', 'list', '--long')
|
||||
list.collect do |user|
|
||||
new(
|
||||
:name => user[:name],
|
||||
:ensure => :present,
|
||||
:enabled => user[:enabled].downcase.chomp == 'true' ? true : false,
|
||||
:password => user[:password],
|
||||
:project => user[:project],
|
||||
:email => user[:email],
|
||||
:id => user[:id]
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def self.prefetch(resources)
|
||||
users = instances
|
||||
resources.keys.each do |name|
|
||||
if provider = users.find{ |user| user.name == name }
|
||||
resources[name].provider = provider
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def self.set_project(newproject, name)
|
||||
# some backends do not store the project/tenant in the user object, so we have to
|
||||
# to modify the project/tenant instead
|
||||
# First, see if the project actually needs to change
|
||||
roles = request('user role', 'list', [name, '--project', newproject])
|
||||
unless roles.empty?
|
||||
return # if already set, just skip
|
||||
end
|
||||
# Currently the only way to assign a user to a tenant not using user-create
|
||||
# is to use user-role-add - this means we also need a role - there is usual
|
||||
# a default role called _member_ which can be used for this purpose. What
|
||||
# usually happens in a puppet module is that immediately after calling
|
||||
# keystone_user, the module will then assign a role to that user. It is
|
||||
# ok for a user to have the _member_ role and another role.
|
||||
default_role = "_member_"
|
||||
begin
|
||||
request('role', 'show', [default_role])
|
||||
rescue
|
||||
debug("Keystone role #{default_role} does not exist - creating")
|
||||
request('role', 'create', [default_role])
|
||||
end
|
||||
request('role', 'add', [default_role, '--project', newproject, '--user', name])
|
||||
end
|
||||
end
|
@ -1,229 +0,0 @@
|
||||
$LOAD_PATH.push(File.join(File.dirname(__FILE__), '..', '..', '..'))
|
||||
require 'puppet/provider/keystone'
|
||||
Puppet::Type.type(:keystone_user_role).provide(
|
||||
:keystone,
|
||||
:parent => Puppet::Provider::Keystone
|
||||
) do
|
||||
|
||||
desc <<-EOT
|
||||
Provider that uses the keystone client tool to
|
||||
manage keystone role assignments to users
|
||||
EOT
|
||||
|
||||
optional_commands :keystone => "keystone"
|
||||
|
||||
|
||||
def self.prefetch(resource)
|
||||
# rebuild the cahce for every puppet run
|
||||
@user_role_hash = nil
|
||||
end
|
||||
|
||||
def self.user_role_hash
|
||||
@user_role_hash = build_user_role_hash
|
||||
end
|
||||
|
||||
def user_role_hash
|
||||
self.class.user_role_hash
|
||||
end
|
||||
|
||||
def self.instances
|
||||
user_role_hash.collect do |k, v|
|
||||
new(:name => k)
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
user_id, tenant_id = get_user_and_tenant
|
||||
resource[:roles].each do |role_name|
|
||||
role_id = self.class.get_role(role_name)
|
||||
auth_keystone(
|
||||
'user-role-add',
|
||||
'--user-id', user_id,
|
||||
'--tenant-id', tenant_id,
|
||||
'--role-id', role_id
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def self.get_user_and_tenant(user, tenant)
|
||||
@tenant_hash ||= {}
|
||||
@user_hash ||= {}
|
||||
@tenant_hash[tenant] = @tenant_hash[tenant] || get_tenant(tenant)
|
||||
[
|
||||
get_user(@tenant_hash[tenant], user),
|
||||
@tenant_hash[tenant]
|
||||
]
|
||||
end
|
||||
|
||||
def get_user_and_tenant
|
||||
user, tenant = resource[:name].split('@', 2)
|
||||
self.class.get_user_and_tenant(user, tenant)
|
||||
end
|
||||
|
||||
def exists?
|
||||
user_id, tenant_id = get_user_and_tenant
|
||||
get_user_tenant_hash(user_id, tenant_id)
|
||||
end
|
||||
|
||||
def destroy
|
||||
user_id, tenant_id = get_user_and_tenant
|
||||
get_user_tenant_hash(user_id, tenant_id)[:role_ids].each do |role_id|
|
||||
auth_keystone(
|
||||
'user-role-remove',
|
||||
'--user-id', user_id,
|
||||
'--tenant-id', tenant_id,
|
||||
'--role-id', role_id
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def id
|
||||
user_id, tenant_id = get_user_and_tenant
|
||||
get_user_tenant_hash(user_id, tenant_id)[:id]
|
||||
end
|
||||
|
||||
def roles
|
||||
user_id, tenant_id = get_user_and_tenant
|
||||
get_user_tenant_hash(user_id, tenant_id)[:role_names]
|
||||
end
|
||||
|
||||
def roles=(value)
|
||||
# determine the roles to be added and removed
|
||||
remove = roles - Array(value)
|
||||
add = Array(value) - roles
|
||||
|
||||
user_id, tenant_id = get_user_and_tenant
|
||||
|
||||
add.each do |role_name|
|
||||
role_id = self.class.get_role(role_name)
|
||||
auth_keystone(
|
||||
'user-role-add',
|
||||
'--user-id', user_id,
|
||||
'--tenant-id', tenant_id,
|
||||
'--role-id', role_id
|
||||
)
|
||||
end
|
||||
remove.each do |role_name|
|
||||
role_id = self.class.get_role(role_name)
|
||||
auth_keystone(
|
||||
'user-role-remove',
|
||||
'--user-id', user_id,
|
||||
'--tenant-id', tenant_id,
|
||||
'--role-id', role_id
|
||||
)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def self.build_user_role_hash
|
||||
hash = {}
|
||||
get_tenants.each do |tenant_name, tenant_id|
|
||||
get_users(tenant_id).each do |user_name, user_id|
|
||||
list_user_roles(user_id, tenant_id).sort.each do |role|
|
||||
hash["#{user_name}@#{tenant_name}"] ||= {
|
||||
:user_id => user_id,
|
||||
:tenant_id => tenant_id,
|
||||
:role_names => [],
|
||||
:role_ids => []
|
||||
}
|
||||
hash["#{user_name}@#{tenant_name}"][:role_names].push(role[1])
|
||||
hash["#{user_name}@#{tenant_name}"][:role_ids].push(role[0])
|
||||
end
|
||||
end
|
||||
end
|
||||
hash
|
||||
end
|
||||
|
||||
# lookup the roles for a single tenant/user combination
|
||||
def get_user_tenant_hash(user_id, tenant_id)
|
||||
@user_tenant_hash ||= {}
|
||||
unless @user_tenant_hash["#{user_id}@#{tenant_id}"]
|
||||
list_user_roles(user_id, tenant_id).sort.each do |role|
|
||||
@user_tenant_hash["#{user_id}@#{tenant_id}"] ||= {
|
||||
:user_id => user_id,
|
||||
:tenant_id => tenant_id,
|
||||
:role_names => [],
|
||||
:role_ids => []
|
||||
}
|
||||
@user_tenant_hash["#{user_id}@#{tenant_id}"][:role_names].push(role[1])
|
||||
@user_tenant_hash["#{user_id}@#{tenant_id}"][:role_ids].push(role[0])
|
||||
end
|
||||
end
|
||||
@user_tenant_hash["#{user_id}@#{tenant_id}"]
|
||||
end
|
||||
|
||||
|
||||
def self.list_user_roles(user_id, tenant_id)
|
||||
# this assumes that all returned objects are of the form
|
||||
# id, name, enabled_state, OTHER
|
||||
number_columns = 4
|
||||
role_output = auth_keystone('user-role-list', '--user-id', user_id, '--tenant-id', tenant_id)
|
||||
list = (role_output.split("\n")[3..-2] || []).collect do |line|
|
||||
row = line.split(/\s*\|\s*/)[1..-1]
|
||||
if row.size != number_columns
|
||||
raise(Puppet::Error, "Expected #{number_columns} columns for #{type} row, found #{row.size}. Line #{line}")
|
||||
end
|
||||
row
|
||||
end
|
||||
list
|
||||
end
|
||||
|
||||
def list_user_roles(user_id, tenant_id)
|
||||
self.class.list_user_roles(user_id, tenant_id)
|
||||
end
|
||||
|
||||
def self.get_user(tenant_id, name)
|
||||
@users ||= {}
|
||||
user_key = "#{name}@#{tenant_id}"
|
||||
unless @users[user_key]
|
||||
list_keystone_objects('user', 4, '--tenant-id', tenant_id).each do |user|
|
||||
@users["#{user[1]}@#{tenant_id}"] = user[0]
|
||||
end
|
||||
end
|
||||
@users[user_key]
|
||||
end
|
||||
|
||||
def self.get_users(tenant_id='')
|
||||
@users = {}
|
||||
list_keystone_objects('user', 4, '--tenant-id', tenant_id).each do |user|
|
||||
@users[user[1]] = user[0]
|
||||
end
|
||||
@users
|
||||
end
|
||||
|
||||
def self.get_tenants
|
||||
unless @tenants
|
||||
@tenants = {}
|
||||
list_keystone_objects('tenant', 3).each do |tenant|
|
||||
@tenants[tenant[1]] = tenant[0]
|
||||
end
|
||||
end
|
||||
@tenants
|
||||
end
|
||||
|
||||
def self.get_tenant(name)
|
||||
unless (@tenants and @tenants[name])
|
||||
@tenants = {}
|
||||
list_keystone_objects('tenant', 3).each do |tenant|
|
||||
if tenant[1] == name
|
||||
@tenants[tenant[1]] = tenant[0]
|
||||
#tenant
|
||||
end
|
||||
end
|
||||
end
|
||||
@tenants[name]
|
||||
end
|
||||
|
||||
def self.get_role(name)
|
||||
@roles ||= {}
|
||||
unless @roles[name]
|
||||
list_keystone_objects('role', 2).each do |role|
|
||||
@roles[role[1]] = role[0]
|
||||
end
|
||||
end
|
||||
@roles[name]
|
||||
end
|
||||
|
||||
end
|
@ -0,0 +1,131 @@
|
||||
require 'puppet/provider/keystone'
|
||||
|
||||
Puppet::Type.type(:keystone_user_role).provide(
|
||||
:openstack,
|
||||
:parent => Puppet::Provider::Keystone
|
||||
) do
|
||||
|
||||
desc "Provider to manage keystone role assignments to users."
|
||||
|
||||
@credentials = Puppet::Provider::Openstack::CredentialsV2_0.new
|
||||
|
||||
def initialize(value={})
|
||||
super(value)
|
||||
@property_flush = {}
|
||||
end
|
||||
|
||||
def create
|
||||
properties = []
|
||||
properties << '--project' << get_project
|
||||
properties << '--user' << get_user
|
||||
if resource[:roles]
|
||||
resource[:roles].each do |role|
|
||||
self.class.request('role', 'add', [role] + properties)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
properties = []
|
||||
properties << '--project' << get_project
|
||||
properties << '--user' << get_user
|
||||
if @property_hash[:roles]
|
||||
@property_hash[:roles].each do |role|
|
||||
self.class.request('role', 'remove', [role] + properties)
|
||||
end
|
||||
end
|
||||
@property_hash[:ensure] = :absent
|
||||
end
|
||||
|
||||
def exists?
|
||||
if @user_role_hash
|
||||
return ! @property_hash[:name].empty?
|
||||
else
|
||||
roles = self.class.request('user role', 'list', [get_user, '--project', get_project])
|
||||
# Since requesting every combination of users, roles, and
|
||||
# projects is so expensive, construct the property hash here
|
||||
# instead of in self.instances so it can be used in the role
|
||||
# and destroy methods
|
||||
@property_hash[:name] = resource[:name]
|
||||
if roles.empty?
|
||||
@property_hash[:ensure] = :absent
|
||||
else
|
||||
@property_hash[:ensure] = :present
|
||||
@property_hash[:roles] = roles.collect do |role|
|
||||
role[:name]
|
||||
end
|
||||
end
|
||||
return @property_hash[:ensure] == :present
|
||||
end
|
||||
end
|
||||
|
||||
def roles
|
||||
@property_hash[:roles]
|
||||
end
|
||||
|
||||
def roles=(value)
|
||||
current_roles = roles
|
||||
# determine the roles to be added and removed
|
||||
remove = current_roles - Array(value)
|
||||
add = Array(value) - current_roles
|
||||
user = get_user
|
||||
project = get_project
|
||||
add.each do |role_name|
|
||||
self.class.request('role', 'add', [role_name, '--project', project, '--user', user])
|
||||
end
|
||||
remove.each do |role_name|
|
||||
self.class.request('role', 'remove', [role_name, '--project', project, '--user', user])
|
||||
end
|
||||
end
|
||||
|
||||
def self.instances
|
||||
instances = build_user_role_hash
|
||||
instances.collect do |title, roles|
|
||||
new(
|
||||
:name => title,
|
||||
:ensure => :present,
|
||||
:roles => roles
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get_user
|
||||
resource[:name].rpartition('@').first
|
||||
end
|
||||
|
||||
def get_project
|
||||
resource[:name].rpartition('@').last
|
||||
end
|
||||
|
||||
def self.get_projects
|
||||
request('project', 'list').collect { |project| project[:name] }
|
||||
end
|
||||
|
||||
def self.get_users(project)
|
||||
request('user', 'list', ['--project', project]).collect { |user| user[:name] }
|
||||
end
|
||||
|
||||
def self.set_user_role_hash(user_role_hash)
|
||||
@user_role_hash = user_role_hash
|
||||
end
|
||||
|
||||
def self.build_user_role_hash
|
||||
hash = @user_role_hash || {}
|
||||
return hash unless hash.empty?
|
||||
projects = get_projects
|
||||
projects.each do |project|
|
||||
users = get_users(project)
|
||||
users.each do |user|
|
||||
user_roles = request('user role', 'list', [user, '--project', project])
|
||||
hash["#{user}@#{project}"] = []
|
||||
user_roles.each do |role|
|
||||
hash["#{user}@#{project}"] << role[:name]
|
||||
end
|
||||
end
|
||||
end
|
||||
set_user_role_hash(hash)
|
||||
hash
|
||||
end
|
||||
end
|
@ -1,9 +1,10 @@
|
||||
# LP#1408531
|
||||
File.expand_path('../..', File.dirname(__FILE__)).tap { |dir| $LOAD_PATH.unshift(dir) unless $LOAD_PATH.include?(dir) }
|
||||
File.expand_path('../../../../openstacklib/lib', File.dirname(__FILE__)).tap { |dir| $LOAD_PATH.unshift(dir) unless $LOAD_PATH.include?(dir) }
|
||||
|
||||
Puppet::Type.newtype(:keystone_endpoint) do
|
||||
|
||||
desc <<-EOT
|
||||
This is currently used to model the management of
|
||||
keystone endpoint.
|
||||
EOT
|
||||
desc 'Type for managing keystone endpoints.'
|
||||
|
||||
ensurable
|
||||
|
||||
@ -20,7 +21,6 @@ Puppet::Type.newtype(:keystone_endpoint) do
|
||||
newproperty(:region) do
|
||||
end
|
||||
|
||||
# TODO I should do some url validation
|
||||
newproperty(:public_url) do
|
||||
end
|
||||
|
||||
@ -39,5 +39,4 @@ Puppet::Type.newtype(:keystone_endpoint) do
|
||||
(region, service_name) = self[:name].split('/')
|
||||
[service_name]
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -0,0 +1,43 @@
|
||||
Puppet::Type.newtype(:keystone_paste_ini) do
|
||||
|
||||
ensurable
|
||||
|
||||
newparam(:name, :namevar => true) do
|
||||
desc 'Section/setting name to manage from keystone/keystone-paste.ini'
|
||||
newvalues(/\S+\/\S+/)
|
||||
end
|
||||
|
||||
newproperty(:value) do
|
||||
desc 'The value of the setting to be defined.'
|
||||
munge do |value|
|
||||
value = value.to_s.strip
|
||||
value.capitalize! if value =~ /^(true|false)$/i
|
||||
value
|
||||
end
|
||||
|
||||
def is_to_s( currentvalue )
|
||||
if resource.secret?
|
||||
return '[old secret redacted]'
|
||||
else
|
||||
return currentvalue
|
||||
end
|
||||
end
|
||||
|
||||
def should_to_s( newvalue )
|
||||
if resource.secret?
|
||||
return '[new secret redacted]'
|
||||
else
|
||||
return newvalue
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
newparam(:secret, :boolean => true) do
|
||||
desc 'Whether to hide the value from Puppet logs. Defaults to `false`.'
|
||||
|
||||
newvalues(:true, :false)
|
||||
|
||||
defaultto false
|
||||
end
|
||||
|
||||
end
|
@ -1,3 +1,7 @@
|
||||
# LP#1408531
|
||||
File.expand_path('../..', File.dirname(__FILE__)).tap { |dir| $LOAD_PATH.unshift(dir) unless $LOAD_PATH.include?(dir) }
|
||||
File.expand_path('../../../../openstacklib/lib', File.dirname(__FILE__)).tap { |dir| $LOAD_PATH.unshift(dir) unless $LOAD_PATH.include?(dir) }
|
||||
|
||||
Puppet::Type.newtype(:keystone_role) do
|
||||
|
||||
desc <<-EOT
|
||||
@ -21,5 +25,4 @@ Puppet::Type.newtype(:keystone_role) do
|
||||
autorequire(:service) do
|
||||
['keystone']
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -1,13 +1,15 @@
|
||||
# LP#1408531
|
||||
File.expand_path('../..', File.dirname(__FILE__)).tap { |dir| $LOAD_PATH.unshift(dir) unless $LOAD_PATH.include?(dir) }
|
||||
File.expand_path('../../../../openstacklib/lib', File.dirname(__FILE__)).tap { |dir| $LOAD_PATH.unshift(dir) unless $LOAD_PATH.include?(dir) }
|
||||
|
||||
Puppet::Type.newtype(:keystone_service) do
|
||||
|
||||
desc <<-EOT
|
||||
This is currently used to model the management of
|
||||
keystone services.
|
||||
EOT
|
||||
desc 'This type can be used to manage keystone services.'
|
||||
|
||||
ensurable
|
||||
|
||||
newparam(:name, :namevar => true) do
|
||||
desc 'The name of the service.'
|
||||
newvalues(/\S+/)
|
||||
end
|
||||
|
||||
@ -18,14 +20,22 @@ Puppet::Type.newtype(:keystone_service) do
|
||||
end
|
||||
|
||||
newproperty(:type) do
|
||||
desc 'The type of service'
|
||||
validate do |value|
|
||||
fail('The service type is required.') unless value
|
||||
end
|
||||
end
|
||||
|
||||
newproperty(:description) do
|
||||
desc 'A description of the service.'
|
||||
defaultto('')
|
||||
end
|
||||
|
||||
# we should not do anything until the keystone service is started
|
||||
# This ensures the service is started and therefore the keystone
|
||||
# config is configured IF we need them for authentication.
|
||||
# If there is no keystone config, authentication credentials
|
||||
# need to come from another source.
|
||||
autorequire(:service) do
|
||||
['keystone']
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -1,38 +1,44 @@
|
||||
# LP#1408531
|
||||
File.expand_path('../..', File.dirname(__FILE__)).tap { |dir| $LOAD_PATH.unshift(dir) unless $LOAD_PATH.include?(dir) }
|
||||
File.expand_path('../../../../openstacklib/lib', File.dirname(__FILE__)).tap { |dir| $LOAD_PATH.unshift(dir) unless $LOAD_PATH.include?(dir) }
|
||||
|
||||
Puppet::Type.newtype(:keystone_tenant) do
|
||||
|
||||
desc <<-EOT
|
||||
This type can be used to manage
|
||||
keystone tenants.
|
||||
|
||||
This is assumed to be running on the same node
|
||||
as your keystone API server.
|
||||
EOT
|
||||
desc 'This type can be used to manage keystone tenants.'
|
||||
|
||||
ensurable
|
||||
|
||||
newparam(:name, :namevar => true) do
|
||||
desc 'The name of the tenant.'
|
||||
newvalues(/\w+/)
|
||||
end
|
||||
|
||||
newproperty(:enabled) do
|
||||
newvalues(/(t|T)rue/, /(f|F)alse/)
|
||||
defaultto('True')
|
||||
desc 'Whether the tenant should be enabled. Defaults to true.'
|
||||
newvalues(/(t|T)rue/, /(f|F)alse/, true, false )
|
||||
defaultto(true)
|
||||
munge do |value|
|
||||
value.to_s.capitalize
|
||||
value.to_s.downcase.to_sym
|
||||
end
|
||||
end
|
||||
|
||||
newproperty(:description)
|
||||
newproperty(:description) do
|
||||
desc 'A description of the tenant.'
|
||||
defaultto('')
|
||||
end
|
||||
|
||||
newproperty(:id) do
|
||||
desc 'Read-only property of the tenant.'
|
||||
validate do |v|
|
||||
raise(Puppet::Error, 'This is a read only property')
|
||||
end
|
||||
end
|
||||
|
||||
# we should not do anything until the keystone service is started
|
||||
# This ensures the service is started and therefore the keystone
|
||||
# config is configured IF we need them for authentication.
|
||||
# If there is no keystone config, authentication credentials
|
||||
# need to come from another source.
|
||||
autorequire(:service) do
|
||||
['keystone']
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -1,14 +1,10 @@
|
||||
# LP#1408531
|
||||
File.expand_path('../..', File.dirname(__FILE__)).tap { |dir| $LOAD_PATH.unshift(dir) unless $LOAD_PATH.include?(dir) }
|
||||
File.expand_path('../../../../openstacklib/lib', File.dirname(__FILE__)).tap { |dir| $LOAD_PATH.unshift(dir) unless $LOAD_PATH.include?(dir) }
|
||||
|
||||
Puppet::Type.newtype(:keystone_user) do
|
||||
|
||||
desc <<-EOT
|
||||
This is currently used to model the creation of
|
||||
keystone users.
|
||||
|
||||
It currently requires that both the password
|
||||
as well as the tenant are specified.
|
||||
EOT
|
||||
|
||||
# TODO support description??
|
||||
desc 'Type for managing keystone users.'
|
||||
|
||||
ensurable
|
||||
|
||||
@ -16,16 +12,19 @@ Puppet::Type.newtype(:keystone_user) do
|
||||
newvalues(/\S+/)
|
||||
end
|
||||
|
||||
newparam(:ignore_default_tenant, :boolean => true) do
|
||||
newvalues(:true, :false)
|
||||
defaultto false
|
||||
newparam(:ignore_default_tenant) do
|
||||
newvalues(/(t|T)rue/, /(f|F)alse/, true, false)
|
||||
defaultto(false)
|
||||
munge do |value|
|
||||
value.to_s.downcase.to_sym
|
||||
end
|
||||
end
|
||||
|
||||
newproperty(:enabled) do
|
||||
newvalues(/(t|T)rue/, /(f|F)alse/)
|
||||
defaultto('True')
|
||||
newvalues(/(t|T)rue/, /(f|F)alse/, true, false)
|
||||
defaultto(true)
|
||||
munge do |value|
|
||||
value.to_s.capitalize
|
||||
value.to_s.downcase.to_sym
|
||||
end
|
||||
end
|
||||
|
||||
@ -53,7 +52,7 @@ Puppet::Type.newtype(:keystone_user) do
|
||||
end
|
||||
|
||||
newproperty(:email) do
|
||||
newvalues(/\S+@\S+/)
|
||||
newvalues(/^(\S+@\S+)|$/)
|
||||
end
|
||||
|
||||
newproperty(:id) do
|
||||
@ -62,11 +61,11 @@ Puppet::Type.newtype(:keystone_user) do
|
||||
end
|
||||
end
|
||||
|
||||
newproperty(:replace_password) do
|
||||
newvalues(/(t|T)rue/, /(f|F)alse/)
|
||||
defaultto('True')
|
||||
newparam(:replace_password) do
|
||||
newvalues(/(t|T)rue/, /(f|F)alse/, true, false)
|
||||
defaultto(true)
|
||||
munge do |value|
|
||||
value.to_s.capitalize
|
||||
value.to_s.downcase.to_sym
|
||||
end
|
||||
end
|
||||
|
||||
@ -78,5 +77,4 @@ Puppet::Type.newtype(:keystone_user) do
|
||||
autorequire(:service) do
|
||||
['keystone']
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -1,42 +1,37 @@
|
||||
# LP#1408531
|
||||
File.expand_path('../..', File.dirname(__FILE__)).tap { |dir| $LOAD_PATH.unshift(dir) unless $LOAD_PATH.include?(dir) }
|
||||
File.expand_path('../../../../openstacklib/lib', File.dirname(__FILE__)).tap { |dir| $LOAD_PATH.unshift(dir) unless $LOAD_PATH.include?(dir) }
|
||||
|
||||
Puppet::Type.newtype(:keystone_user_role) do
|
||||
|
||||
desc <<-EOT
|
||||
This is currently used to model the creation of
|
||||
keystone users roles.
|
||||
|
||||
User roles are an assigment of a role to a user on
|
||||
a certain tenant. The combintation of all of these
|
||||
User roles are an assignment of a role to a user on
|
||||
a certain tenant. The combination of all of these
|
||||
attributes is unique.
|
||||
EOT
|
||||
|
||||
ensurable
|
||||
|
||||
newparam(:name, :namevar => true) do
|
||||
newvalues(/^\S+@\S+$/)
|
||||
#munge do |value|
|
||||
# matchdata = /(\S+)@(\S+)/.match(value)
|
||||
# {
|
||||
# :user => matchdata[1],
|
||||
# :tenant => matchdata[2]
|
||||
# }
|
||||
#nd
|
||||
end
|
||||
|
||||
newproperty(:roles, :array_matching => :all) do
|
||||
end
|
||||
|
||||
newproperty(:id) do
|
||||
validate do |v|
|
||||
raise(Puppet::Error, 'This is a read only property')
|
||||
def insync?(is)
|
||||
return false unless is.is_a? Array
|
||||
# order of roles does not matter
|
||||
is.sort == self.should.sort
|
||||
end
|
||||
end
|
||||
|
||||
autorequire(:keystone_user) do
|
||||
self[:name].split('@', 2).first
|
||||
self[:name].rpartition('@').first
|
||||
end
|
||||
|
||||
autorequire(:keystone_tenant) do
|
||||
self[:name].split('@', 2).last
|
||||
self[:name].rpartition('@').last
|
||||
end
|
||||
|
||||
autorequire(:keystone_role) do
|
||||
@ -47,5 +42,4 @@ Puppet::Type.newtype(:keystone_user_role) do
|
||||
autorequire(:service) do
|
||||
['keystone']
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -5,7 +5,8 @@
|
||||
# === Parameters
|
||||
#
|
||||
# [*ensure*]
|
||||
# (optional) Ensure state of the package. Defaults to 'present'.
|
||||
# (optional) Ensure state of the package.
|
||||
# Defaults to 'present'.
|
||||
#
|
||||
class keystone::client (
|
||||
$ensure = 'present'
|
||||
@ -13,5 +14,6 @@ class keystone::client (
|
||||
|
||||
package { 'python-keystoneclient':
|
||||
ensure => $ensure,
|
||||
tag => 'openstack',
|
||||
}
|
||||
}
|
||||
|
75
deployment/puppet/keystone/manifests/cron/token_flush.pp
Normal file
75
deployment/puppet/keystone/manifests/cron/token_flush.pp
Normal file
@ -0,0 +1,75 @@
|
||||
#
|
||||
# Copyright (C) 2014 eNovance SAS <licensing@enovance.com>
|
||||
#
|
||||
# Author: Emilien Macchi <emilien.macchi@enovance.com>
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# == Class: keystone::cron::token_flush
|
||||
#
|
||||
# Installs a cron job to purge expired tokens.
|
||||
#
|
||||
# === Parameters
|
||||
#
|
||||
# [*ensure*]
|
||||
# (optional) Defaults to present.
|
||||
# Valid values are present, absent.
|
||||
#
|
||||
# [*minute*]
|
||||
# (optional) Defaults to '1'.
|
||||
#
|
||||
# [*hour*]
|
||||
# (optional) Defaults to '0'.
|
||||
#
|
||||
# [*monthday*]
|
||||
# (optional) Defaults to '*'.
|
||||
#
|
||||
# [*month*]
|
||||
# (optional) Defaults to '*'.
|
||||
#
|
||||
# [*weekday*]
|
||||
# (optional) Defaults to '*'.
|
||||
#
|
||||
# [*maxdelay*]
|
||||
# (optional) Seconds. Defaults to 0. Should be a positive integer.
|
||||
# Induces a random delay before running the cronjob to avoid running all
|
||||
# cron jobs at the same time on all hosts this job is configured.
|
||||
#
|
||||
class keystone::cron::token_flush (
|
||||
$ensure = present,
|
||||
$minute = 1,
|
||||
$hour = 0,
|
||||
$monthday = '*',
|
||||
$month = '*',
|
||||
$weekday = '*',
|
||||
$maxdelay = 0,
|
||||
) {
|
||||
|
||||
if $maxdelay == 0 {
|
||||
$sleep = ''
|
||||
} else {
|
||||
$sleep = "sleep `expr \${RANDOM} \\% ${maxdelay}`; "
|
||||
}
|
||||
|
||||
cron { 'keystone-manage token_flush':
|
||||
ensure => $ensure,
|
||||
command => "${sleep}keystone-manage token_flush >>/var/log/keystone/keystone-tokenflush.log 2>&1",
|
||||
environment => 'PATH=/bin:/usr/bin:/usr/sbin SHELL=/bin/sh',
|
||||
user => 'keystone',
|
||||
minute => $minute,
|
||||
hour => $hour,
|
||||
monthday => $monthday,
|
||||
month => $month,
|
||||
weekday => $weekday
|
||||
}
|
||||
}
|
@ -1,27 +1,43 @@
|
||||
#
|
||||
# implements mysql backend for keystone
|
||||
# The keystone::db::mysql class implements mysql backend for keystone
|
||||
#
|
||||
# This class can be used to create tables, users and grant
|
||||
# privelege for a mysql keystone database.
|
||||
#
|
||||
# == parameters
|
||||
#
|
||||
# [password] Password that will be used for the keystone db user.
|
||||
# Optional. Defaults to: 'keystone_default_password'
|
||||
# [*password*]
|
||||
# (Mandatory) Password to connect to the database.
|
||||
# Defaults to 'false'.
|
||||
#
|
||||
# [dbname] Name of keystone database. Optional. Defaults to keystone.
|
||||
# [*dbname*]
|
||||
# (Optional) Name of the database.
|
||||
# Defaults to 'keystone'.
|
||||
#
|
||||
# [user] Name of keystone user. Optional. Defaults to keystone.
|
||||
# [*user*]
|
||||
# (Optional) User to connect to the database.
|
||||
# Defaults to 'keystone'.
|
||||
#
|
||||
# [host] Host where user should be allowed all priveleges for database.
|
||||
# Optional. Defaults to 127.0.0.1.
|
||||
# [*host*]
|
||||
# (Optional) The default source host user is allowed to connect from.
|
||||
# Defaults to '127.0.0.1'
|
||||
#
|
||||
# [allowed_hosts] Hosts allowed to use the database
|
||||
# [*allowed_hosts*]
|
||||
# (Optional) Other hosts the user is allowed to connect from.
|
||||
# Defaults to 'undef'.
|
||||
#
|
||||
# [*mysql_module*]
|
||||
# (optional) The mysql puppet module version to use
|
||||
# Tested versions include 0.9 and 2.2
|
||||
# Default to '0.9'
|
||||
# [*charset*]
|
||||
# (Optional) The database charset.
|
||||
# Defaults to 'utf8'
|
||||
#
|
||||
# [*collate*]
|
||||
# (Optional) The database collate.
|
||||
# Only used with mysql modules >= 2.2.
|
||||
# Defaults to 'utf8_general_ci'
|
||||
#
|
||||
# === Deprecated Parameters
|
||||
#
|
||||
# [*mysql_module*]
|
||||
# (Optional) Does nothing.
|
||||
#
|
||||
# == Dependencies
|
||||
# Class['mysql::server']
|
||||
@ -41,53 +57,26 @@ class keystone::db::mysql(
|
||||
$user = 'keystone',
|
||||
$host = '127.0.0.1',
|
||||
$charset = 'utf8',
|
||||
$collate = 'utf8_unicode_ci',
|
||||
$mysql_module = '0.9',
|
||||
$collate = 'utf8_general_ci',
|
||||
$mysql_module = undef,
|
||||
$allowed_hosts = undef
|
||||
) {
|
||||
|
||||
Class['keystone::db::mysql'] -> Exec<| title == 'keystone-manage db_sync' |>
|
||||
Class['keystone::db::mysql'] -> Service<| title == 'keystone' |>
|
||||
Mysql::Db[$dbname] ~> Exec<| title == 'keystone-manage db_sync' |>
|
||||
|
||||
if ($mysql_module >= 2.2) {
|
||||
mysql::db { $dbname:
|
||||
user => $user,
|
||||
password => $password,
|
||||
host => $host,
|
||||
charset => $charset,
|
||||
collate => $collate,
|
||||
require => Service['mysqld'],
|
||||
}
|
||||
} else {
|
||||
require mysql::python
|
||||
|
||||
mysql::db { $dbname:
|
||||
user => $user,
|
||||
password => $password,
|
||||
host => $host,
|
||||
charset => $charset,
|
||||
require => Class['mysql::config'],
|
||||
}
|
||||
if $mysql_module {
|
||||
warning('The mysql_module parameter is deprecated. The latest 2.x mysql module will be used.')
|
||||
}
|
||||
|
||||
# Check allowed_hosts to avoid duplicate resource declarations
|
||||
if is_array($allowed_hosts) and delete($allowed_hosts,$host) != [] {
|
||||
$real_allowed_hosts = delete($allowed_hosts,$host)
|
||||
} elsif is_string($allowed_hosts) and ($allowed_hosts != $host) {
|
||||
$real_allowed_hosts = $allowed_hosts
|
||||
}
|
||||
|
||||
if $real_allowed_hosts {
|
||||
keystone::db::mysql::host_access { $real_allowed_hosts:
|
||||
user => $user,
|
||||
password => $password,
|
||||
database => $dbname,
|
||||
mysql_module => $mysql_module,
|
||||
}
|
||||
|
||||
Keystone::Db::Mysql::Host_access[$real_allowed_hosts] -> Exec<| title == 'keystone-manage db_sync' |>
|
||||
|
||||
validate_string($password)
|
||||
|
||||
::openstacklib::db::mysql { 'keystone':
|
||||
user => $user,
|
||||
password_hash => mysql_password($password),
|
||||
dbname => $dbname,
|
||||
host => $host,
|
||||
charset => $charset,
|
||||
collate => $collate,
|
||||
allowed_hosts => $allowed_hosts,
|
||||
}
|
||||
|
||||
::Openstacklib::Db::Mysql['keystone'] ~> Exec<| title == 'keystone-manage db_sync' |>
|
||||
}
|
||||
|
@ -1,34 +0,0 @@
|
||||
#
|
||||
define keystone::db::mysql::host_access(
|
||||
$user,
|
||||
$password,
|
||||
$database,
|
||||
$mysql_module = '0.9'
|
||||
) {
|
||||
if ($mysql_module >= 2.2) {
|
||||
mysql_user { "${user}@${name}":
|
||||
password_hash => mysql_password($password),
|
||||
require => Mysql_database[$database],
|
||||
}
|
||||
|
||||
mysql_grant { "${user}@${name}/${database}.*":
|
||||
privileges => ['ALL'],
|
||||
options => ['GRANT'],
|
||||
table => "${database}.*",
|
||||
require => Mysql_user["${user}@${name}"],
|
||||
user => "${user}@${name}"
|
||||
}
|
||||
} else {
|
||||
database_user { "${user}@${name}":
|
||||
password_hash => mysql_password($password),
|
||||
provider => 'mysql',
|
||||
require => Database[$database],
|
||||
}
|
||||
database_grant { "${user}@${name}/${database}":
|
||||
# TODO figure out which privileges to grant.
|
||||
privileges => 'all',
|
||||
provider => 'mysql',
|
||||
require => Database_user["${user}@${name}"]
|
||||
}
|
||||
}
|
||||
}
|
@ -1,47 +1,57 @@
|
||||
# == Class: keystone::db::postgresql
|
||||
#
|
||||
# implements postgresql backend for keystone
|
||||
# Class that configures postgresql for keystone
|
||||
# Requires the Puppetlabs postgresql module.
|
||||
#
|
||||
# This class can be used to create tables, users and grant
|
||||
# privelege for a postgresql keystone database.
|
||||
#
|
||||
# Requires Puppetlabs Postgresql module.
|
||||
#
|
||||
# [*Parameters*]
|
||||
#
|
||||
# [password] Password that will be used for the keystone db user.
|
||||
# Optional. Defaults to: 'keystone_default_password'
|
||||
#
|
||||
# [dbname] Name of keystone database. Optional. Defaults to keystone.
|
||||
#
|
||||
# [user] Name of keystone user. Optional. Defaults to keystone.
|
||||
#
|
||||
# == Dependencies
|
||||
# Class['postgresql::server']
|
||||
#
|
||||
# == Examples
|
||||
# == Authors
|
||||
#
|
||||
# Stackforge Contributors puppet-openstack@puppetlabs.com
|
||||
# Etienne Pelletier epelletier@morphlabs.com
|
||||
#
|
||||
# == Copyright
|
||||
#
|
||||
# Copyright 2013-2014 Stackforge Contributors
|
||||
# Copyright 2012 Etienne Pelletier, unless otherwise noted.
|
||||
#
|
||||
# === Parameters
|
||||
#
|
||||
# [*password*]
|
||||
# (Required) Password to connect to the database.
|
||||
#
|
||||
# [*dbname*]
|
||||
# (Optional) Name of the database.
|
||||
# Defaults to 'keystone'.
|
||||
#
|
||||
# [*user*]
|
||||
# (Optional) User to connect to the database.
|
||||
# Defaults to 'keystone'.
|
||||
#
|
||||
# [*encoding*]
|
||||
# (Optional) The charset to use for the database.
|
||||
# Default to undef.
|
||||
#
|
||||
# [*privileges*]
|
||||
# (Optional) Privileges given to the database user.
|
||||
# Default to 'ALL'
|
||||
#
|
||||
class keystone::db::postgresql(
|
||||
$password,
|
||||
$dbname = 'keystone',
|
||||
$user = 'keystone'
|
||||
$dbname = 'keystone',
|
||||
$user = 'keystone',
|
||||
$encoding = undef,
|
||||
$privileges = 'ALL',
|
||||
) {
|
||||
|
||||
Class['keystone::db::postgresql'] -> Service<| title == 'keystone' |>
|
||||
|
||||
require postgresql::python
|
||||
|
||||
postgresql::db { $dbname:
|
||||
user => $user,
|
||||
password => $password,
|
||||
::openstacklib::db::postgresql { 'keystone':
|
||||
password_hash => postgresql_password($user, $password),
|
||||
dbname => $dbname,
|
||||
user => $user,
|
||||
encoding => $encoding,
|
||||
privileges => $privileges,
|
||||
}
|
||||
|
||||
Postgresql::Server::Db[$dbname] ~> Exec<| title == 'keystone-manage db_sync' |>
|
||||
::Openstacklib::Db::Postgresql['keystone'] ~> Exec<| title == 'keystone-manage db_sync' |>
|
||||
|
||||
}
|
||||
|
@ -9,4 +9,6 @@ class keystone::db::sync {
|
||||
subscribe => [Package['keystone'], Keystone_config['database/connection']],
|
||||
require => User['keystone'],
|
||||
}
|
||||
|
||||
Exec['keystone-manage db_sync'] ~> Service<| title == 'keystone' |>
|
||||
}
|
||||
|
@ -1,6 +1,12 @@
|
||||
#
|
||||
# Installs keystone from source. This is not yet fully implemented
|
||||
#
|
||||
# == Parameters
|
||||
#
|
||||
# [*source_dir*]
|
||||
# (optional) The source dire for dev installation
|
||||
# Defaults to '/usr/local/keystone'
|
||||
#
|
||||
# == Dependencies
|
||||
# == Examples
|
||||
# == Authors
|
||||
|
@ -6,12 +6,15 @@
|
||||
#
|
||||
# [*public_url*]
|
||||
# (optional) Public url for keystone endpoint. (Defaults to 'http://127.0.0.1:5000')
|
||||
# This url should *not* contain any version or trailing '/'.
|
||||
#
|
||||
# [*internal_url*]
|
||||
# (optional) Internal url for keystone endpoint. (Defaults to $public_url)
|
||||
# This url should *not* contain any version or trailing '/'.
|
||||
#
|
||||
# [*admin_url*]
|
||||
# (optional) Admin url for keystone endpoint. (Defaults to 'http://127.0.0.1:35357')
|
||||
# This url should *not* contain any version or trailing '/'.
|
||||
#
|
||||
# [*region*]
|
||||
# (optional) Region for endpoint. (Defaults to 'RegionOne')
|
||||
@ -19,58 +22,6 @@
|
||||
# [*version*]
|
||||
# (optional) API version for endpoint. Appended to all endpoint urls. (Defaults to 'v2.0')
|
||||
#
|
||||
# [*public_url*]
|
||||
# (optional) The endpoint's public url. (Defaults to 'http://127.0.0.1:5000')
|
||||
# This url should *not* contain any version or trailing '/'.
|
||||
#
|
||||
# [*admin_url*]
|
||||
# (optional) The endpoint's admin url. (Defaults to 'http://127.0.0.1:5000')
|
||||
# This url should *not* contain any version or trailing '/'.
|
||||
#
|
||||
# [*internal_url*]
|
||||
# (optional) The endpoint's internal url. (Defaults to 'http://127.0.0.1:35357')
|
||||
# This url should *not* contain any version or trailing '/'.
|
||||
#
|
||||
# [*public_protocol*]
|
||||
# (optional) DEPRECATED: Use public_url instead.
|
||||
# Protocol for public access to keystone endpoint. (Defaults to 'http')
|
||||
# Setting this parameter overrides public_url parameter.
|
||||
#
|
||||
# [*public_address*]
|
||||
# (optional) DEPRECATED: Use public_url instead.
|
||||
# Public address for keystone endpoint. (Defaults to '127.0.0.1')
|
||||
# Setting this parameter overrides public_url parameter.
|
||||
#
|
||||
# [*public_port*]
|
||||
# (optional) DEPRECATED: Use public_url instead.
|
||||
# Port for non-admin access to keystone endpoint. (Defaults to 5000)
|
||||
# Setting this parameter overrides public_url parameter.
|
||||
#
|
||||
# [*internal_address*]
|
||||
# (optional) DEPRECATED: Use internal_url instead.
|
||||
# Internal address for keystone endpoint. (Defaults to '127.0.0.1')
|
||||
# Setting this parameter overrides internal_url parameter.
|
||||
#
|
||||
# [*internal_port*]
|
||||
# (optional) DEPRECATED: Use internal_url instead.
|
||||
# Port for internal access to keystone endpoint. (Defaults to $public_port)
|
||||
# Setting this parameter overrides internal_url parameter.
|
||||
#
|
||||
# [*admin_address*]
|
||||
# (optional) DEPRECATED: Use admin_url instead.
|
||||
# Admin address for keystone endpoint. (Defaults to '127.0.0.1')
|
||||
# Setting this parameter overrides admin_url parameter.
|
||||
#
|
||||
# [*admin_port*]
|
||||
# (optional) DEPRECATED: Use admin_url instead.
|
||||
# Port for admin access to keystone endpoint. (Defaults to 35357)
|
||||
# Setting this parameter overrides admin_url parameter.
|
||||
#
|
||||
# === Deprecation notes
|
||||
#
|
||||
# If any value is provided for public_protocol, public_address or public_port parameters,
|
||||
# public_url will be completely ignored. The same applies for internal and admin parameters.
|
||||
#
|
||||
# === Examples
|
||||
#
|
||||
# class { 'keystone::endpoint':
|
||||
@ -85,85 +36,26 @@ class keystone::endpoint (
|
||||
$admin_url = 'http://127.0.0.1:35357',
|
||||
$version = 'v2.0',
|
||||
$region = 'RegionOne',
|
||||
# DEPRECATED PARAMETERS
|
||||
$public_protocol = undef,
|
||||
$public_address = undef,
|
||||
$public_port = undef,
|
||||
$internal_address = undef,
|
||||
$internal_port = undef,
|
||||
$admin_address = undef,
|
||||
$admin_port = undef,
|
||||
) {
|
||||
|
||||
if $public_port {
|
||||
warning('The public_port parameter is deprecated, use public_url instead.')
|
||||
$public_url_real = "${public_url}/${version}"
|
||||
$admin_url_real = "${admin_url}/${version}"
|
||||
|
||||
if $internal_url {
|
||||
$internal_url_real = "${internal_url}/${version}"
|
||||
} else {
|
||||
$internal_url_real = "${public_url}/${version}"
|
||||
}
|
||||
|
||||
if $public_protocol {
|
||||
warning('The public_protocol parameter is deprecated, use public_url instead.')
|
||||
keystone::resource::service_identity { 'keystone':
|
||||
configure_user => false,
|
||||
configure_user_role => false,
|
||||
service_type => 'identity',
|
||||
service_description => 'OpenStack Identity Service',
|
||||
public_url => $public_url_real,
|
||||
admin_url => $admin_url_real,
|
||||
internal_url => $internal_url_real,
|
||||
region => $region,
|
||||
}
|
||||
|
||||
if $public_address {
|
||||
warning('The public_address parameter is deprecated, use public_url instead.')
|
||||
}
|
||||
|
||||
if $internal_address {
|
||||
warning('The internal_address parameter is deprecated, use internal_url instead.')
|
||||
}
|
||||
|
||||
if $internal_port {
|
||||
warning('The internal_port parameter is deprecated, use internal_url instead.')
|
||||
}
|
||||
|
||||
if $admin_address {
|
||||
warning('The admin_address parameter is deprecated, use admin_url instead.')
|
||||
}
|
||||
|
||||
if $admin_port {
|
||||
warning('The admin_port parameter is deprecated, use admin_url instead.')
|
||||
}
|
||||
|
||||
$public_url_real = inline_template('<%=
|
||||
if (!@public_protocol.nil?) || (!@public_address.nil?) || (!@public_port.nil?)
|
||||
@public_protocol ||= "http"
|
||||
@public_address ||= "127.0.0.1"
|
||||
@public_port ||= "5000"
|
||||
"#{@public_protocol}://#{@public_address}:#{@public_port}/#{@version}"
|
||||
else
|
||||
"#{@public_url}/#{@version}"
|
||||
end %>')
|
||||
|
||||
$internal_url_real = inline_template('<%=
|
||||
if (!@internal_address.nil?) || (!@internal_port.nil?) || (!@public_port.nil?)
|
||||
@internal_address ||= @public_address ||= "127.0.0.1"
|
||||
@internal_port ||= @public_port ||= "5000"
|
||||
"http://#{@internal_address}:#{@internal_port}/#{@version}"
|
||||
elsif (!@internal_url.nil?)
|
||||
"#{@internal_url}/#{@version}"
|
||||
else
|
||||
"#{@public_url}/#{@version}"
|
||||
end %>')
|
||||
|
||||
$admin_url_real = inline_template('<%=
|
||||
if (!@admin_address.nil?) || (!@admin_port.nil?)
|
||||
@admin_address ||= "127.0.0.1"
|
||||
@admin_port ||= "35357"
|
||||
"http://#{@admin_address}:#{@admin_port}/#{@version}"
|
||||
else
|
||||
"#{@admin_url}/#{@version}"
|
||||
end %>')
|
||||
|
||||
keystone_service { 'keystone':
|
||||
ensure => present,
|
||||
type => 'identity',
|
||||
description => 'OpenStack Identity Service',
|
||||
}
|
||||
|
||||
keystone_endpoint { "${region}/keystone":
|
||||
ensure => present,
|
||||
public_url => $public_url_real,
|
||||
admin_url => $admin_url_real,
|
||||
internal_url => $internal_url_real,
|
||||
region => $region,
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,380 @@
|
||||
# == class: keystone::ldap
|
||||
#
|
||||
# Implements ldap configuration for keystone.
|
||||
#
|
||||
# === parameters:
|
||||
#
|
||||
# [*url*]
|
||||
# URL for connecting to the LDAP server. (string value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*user*]
|
||||
# User BindDN to query the LDAP server. (string value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*password*]
|
||||
# Password for the BindDN to query the LDAP server. (string value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*suffix*]
|
||||
# LDAP server suffix (string value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*query_scope*]
|
||||
# The LDAP scope for queries, this can be either "one"
|
||||
# (onelevel/singleLevel) or "sub" (subtree/wholeSubtree). (string value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*page_size*]
|
||||
# Maximum results per page; a value of zero ("0") disables paging. (integer value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*user_tree_dn*]
|
||||
# Search base for users. (string value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*user_filter*]
|
||||
# LDAP search filter for users. (string value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*user_objectclass*]
|
||||
# LDAP objectclass for users. (string value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*user_id_attribute*]
|
||||
# LDAP attribute mapped to user id. WARNING: must not be a multivalued attribute. (string value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*user_name_attribute*]
|
||||
# LDAP attribute mapped to user name. (string value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*user_mail_attribute*]
|
||||
# LDAP attribute mapped to user email. (string value)
|
||||
#
|
||||
# [*user_enabled_attribute*]
|
||||
# LDAP attribute mapped to user enabled flag. (string value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*user_enabled_mask*]
|
||||
# Bitmask integer to indicate the bit that the enabled value is stored in if
|
||||
# the LDAP server represents "enabled" as a bit on an integer rather than a
|
||||
# boolean. A value of "0" indicates the mask is not used. If this is not set
|
||||
# to "0" the typical value is "2". This is typically used when
|
||||
# "user_enabled_attribute = userAccountControl". (integer value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*user_enabled_default*]
|
||||
# Default value to enable users. This should match an appropriate int value
|
||||
# if the LDAP server uses non-boolean (bitmask) values to indicate if a user
|
||||
# is enabled or disabled. If this is not set to "True" the typical value is
|
||||
# "512". This is typically used when "user_enabled_attribute =
|
||||
# userAccountControl". (string value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*user_enabled_invert*]
|
||||
# Invert the meaning of the boolean enabled values. Some LDAP servers use a
|
||||
# boolean lock attribute where "true" means an account is disabled. Setting
|
||||
# "user_enabled_invert = true" will allow these lock attributes to be used.
|
||||
# This setting will have no effect if "user_enabled_mask" or
|
||||
# "user_enabled_emulation" settings are in use. (boolean value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*user_attribute_ignore*]
|
||||
# List of attributes stripped off the user on update. (list value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*user_default_project_id_attribute*]
|
||||
# LDAP attribute mapped to default_project_id for users. (string value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*user_allow_create*]
|
||||
# Allow user creation in LDAP backend. (boolean value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*user_allow_update*]
|
||||
# Allow user updates in LDAP backend. (boolean value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*user_allow_delete*]
|
||||
# Allow user deletion in LDAP backend. (boolean value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*user_pass_attribute*]
|
||||
# LDAP attribute mapped to password. (string value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*user_enabled_emulation*]
|
||||
# If true, Keystone uses an alternative method to determine if
|
||||
# a user is enabled or not by checking if they are a member of
|
||||
# the "user_enabled_emulation_dn" group. (boolean value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*user_enabled_emulation_dn*]
|
||||
# DN of the group entry to hold enabled users when using enabled emulation.
|
||||
# (string value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*user_additional_attribute_mapping*]
|
||||
# List of additional LDAP attributes used for mapping
|
||||
# additional attribute mappings for users. Attribute mapping
|
||||
# format is <ldap_attr>:<user_attr>, where ldap_attr is the
|
||||
# attribute in the LDAP entry and user_attr is the Identity
|
||||
# API attribute. (list value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*project_tree_dn*]
|
||||
# Search base for projects (string value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*project_filter*]
|
||||
# LDAP search filter for projects. (string value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*project_objectclass*]
|
||||
# LDAP objectclass for projects. (string value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*project_id_attribute*]
|
||||
# LDAP attribute mapped to project id. (string value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*project_member_attribute*]
|
||||
# LDAP attribute mapped to project membership for user. (string value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*project_name_attribute*]
|
||||
# LDAP attribute mapped to project name. (string value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*project_desc_attribute*]
|
||||
# LDAP attribute mapped to project description. (string value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*project_enabled_attribute*]
|
||||
# LDAP attribute mapped to project enabled. (string value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*project_domain_id_attribute*]
|
||||
# LDAP attribute mapped to project domain_id. (string value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*project_attribute_ignore*]
|
||||
# List of attributes stripped off the project on update. (list value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*project_allow_create*]
|
||||
# Allow project creation in LDAP backend. (boolean value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*project_allow_update*]
|
||||
# Allow project update in LDAP backend. (boolean value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*project_allow_delete*]
|
||||
# Allow project deletion in LDAP backend. (boolean value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*project_enabled_emulation*]
|
||||
# If true, Keystone uses an alternative method to determine if
|
||||
# a project is enabled or not by checking if they are a member
|
||||
# of the "project_enabled_emulation_dn" group. (boolean value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*project_enabled_emulation_dn*]
|
||||
# DN of the group entry to hold enabled projects when using
|
||||
# enabled emulation. (string value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*project_additional_attribute_mapping*]
|
||||
# Additional attribute mappings for projects. Attribute
|
||||
# mapping format is <ldap_attr>:<user_attr>, where ldap_attr
|
||||
# is the attribute in the LDAP entry and user_attr is the
|
||||
# Identity API attribute. (list value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*role_tree_dn*]
|
||||
# Search base for roles. (string value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*role_filter*]
|
||||
# LDAP search filter for roles. (string value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*role_objectclass*]
|
||||
# LDAP objectclass for roles. (string value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*role_id_attribute*]
|
||||
# LDAP attribute mapped to role id. (string value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*role_name_attribute*]
|
||||
# LDAP attribute mapped to role name. (string value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*role_member_attribute*]
|
||||
# LDAP attribute mapped to role membership. (string value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*role_attribute_ignore*]
|
||||
# List of attributes stripped off the role on update. (list value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*role_allow_create*]
|
||||
# Allow role creation in LDAP backend. (boolean value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*role_allow_update*]
|
||||
# Allow role update in LDAP backend. (boolean value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*role_allow_delete*]
|
||||
# Allow role deletion in LDAP backend. (boolean value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*role_additional_attribute_mapping*]
|
||||
# Additional attribute mappings for roles. Attribute mapping
|
||||
# format is <ldap_attr>:<user_attr>, where ldap_attr is the
|
||||
# attribute in the LDAP entry and user_attr is the Identity
|
||||
# API attribute. (list value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*group_tree_dn*]
|
||||
# Search base for groups. (string value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*group_filter*]
|
||||
# LDAP search filter for groups. (string value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*group_objectclass*]
|
||||
# LDAP objectclass for groups. (string value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*group_id_attribute*]
|
||||
# LDAP attribute mapped to group id. (string value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*group_name_attribute*]
|
||||
# LDAP attribute mapped to group name. (string value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*group_member_attribute*]
|
||||
# LDAP attribute mapped to show group membership. (string value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*group_desc_attribute*]
|
||||
# LDAP attribute mapped to group description. (string value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*group_attribute_ignore*]
|
||||
# List of attributes stripped off the group on update. (list value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*group_allow_create*]
|
||||
# Allow group creation in LDAP backend. (boolean value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*group_allow_update*]
|
||||
# Allow group update in LDAP backend. (boolean value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*group_allow_delete*]
|
||||
# Allow group deletion in LDAP backend. (boolean value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*group_additional_attribute_mapping*]
|
||||
# Additional attribute mappings for groups. Attribute mapping
|
||||
# format is <ldap_attr>:<user_attr>, where ldap_attr is the
|
||||
# attribute in the LDAP entry and user_attr is the Identity
|
||||
# API attribute. (list value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*use_tls*]
|
||||
# Enable TLS for communicating with LDAP servers. (boolean value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*tls_cacertfile*]
|
||||
# CA certificate file path for communicating with LDAP servers. (string value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*tls_cacertdir*]
|
||||
# CA certificate directory path for communicating with LDAP servers. (string value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*tls_req_cert*]
|
||||
# Valid options for tls_req_cert are demand, never, and allow. (string value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*identity_driver*]
|
||||
# Identity backend driver. (string value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*credential_driver*]
|
||||
# Credential backend driver. (string value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*assignment_driver*]
|
||||
# Assignment backend driver. (string value)
|
||||
# Defaults to 'undef'
|
||||
#
|
||||
# [*use_pool*]
|
||||
# Enable LDAP connection pooling. (boolean value)
|
||||
# Defaults to false
|
||||
#
|
||||
# [*pool_size*]
|
||||
# Connection pool size. (integer value)
|
||||
# Defaults to '10'
|
||||
#
|
||||
# [*pool_retry_max*]
|
||||
# Maximum count of reconnect trials. (integer value)
|
||||
# Defaults to '3'
|
||||
#
|
||||
# [*pool_retry_delay*]
|
||||
# Time span in seconds to wait between two reconnect trials. (floating point value)
|
||||
# Defaults to '0.1'
|
||||
#
|
||||
# [*pool_connection_timeout*]
|
||||
# Connector timeout in seconds. Value -1 indicates indefinite wait for response. (integer value)
|
||||
# Defaults to '-1'
|
||||
#
|
||||
# [*pool_connection_lifetime*]
|
||||
# Connection lifetime in seconds. (integer value)
|
||||
# Defaults to '600'
|
||||
#
|
||||
# [*use_auth_pool*]
|
||||
# Enable LDAP connection pooling for end user authentication.
|
||||
# If use_pool is disabled, then this setting is meaningless and is not used at all. (boolean value)
|
||||
# Defaults to false
|
||||
#
|
||||
# [*auth_pool_size*]
|
||||
# End user auth connection pool size. (integer value)
|
||||
# Defaults to '100'
|
||||
#
|
||||
# [*auth_pool_connection_lifetime*]
|
||||
# End user auth connection lifetime in seconds. (integer value)
|
||||
# Defaults to '60'
|
||||
#
|
||||
# === DEPRECATED group/name
|
||||
#
|
||||
# [*tenant_tree_dn*]
|
||||
# [*tenant_filter*]
|
||||
# [*tenant_objectclass*]
|
||||
# [*tenant_id_attribute*]
|
||||
# [*tenant_member_attribute*]
|
||||
# [*tenant_name_attribute*]
|
||||
# [*tenant_desc_attribute*]
|
||||
# [*tenant_enabled_attribute*]
|
||||
# [*tenant_domain_id_attribute*]
|
||||
# [*tenant_attribute_ignore*]
|
||||
# [*tenant_allow_create*]
|
||||
# [*tenant_allow_update*]
|
||||
# [*tenant_enabled_emulation*]
|
||||
# [*tenant_enabled_emulation_dn*]
|
||||
# [*tenant_additional_attribute_mapping*]
|
||||
# [*tenant_allow_delete*]
|
||||
#
|
||||
# == Dependencies
|
||||
# == Examples
|
||||
# == Authors
|
||||
@ -28,6 +402,7 @@ class keystone::ldap(
|
||||
$user_enabled_attribute = undef,
|
||||
$user_enabled_mask = undef,
|
||||
$user_enabled_default = undef,
|
||||
$user_enabled_invert = undef,
|
||||
$user_attribute_ignore = undef,
|
||||
$user_default_project_id_attribute = undef,
|
||||
$user_allow_create = undef,
|
||||
@ -37,22 +412,38 @@ class keystone::ldap(
|
||||
$user_enabled_emulation = undef,
|
||||
$user_enabled_emulation_dn = undef,
|
||||
$user_additional_attribute_mapping = undef,
|
||||
$tenant_tree_dn = undef,
|
||||
$tenant_filter = undef,
|
||||
$tenant_objectclass = undef,
|
||||
$tenant_id_attribute = undef,
|
||||
$tenant_member_attribute = undef,
|
||||
$tenant_desc_attribute = undef,
|
||||
$tenant_name_attribute = undef,
|
||||
$tenant_enabled_attribute = undef,
|
||||
$tenant_domain_id_attribute = undef,
|
||||
$tenant_attribute_ignore = undef,
|
||||
$tenant_allow_create = undef,
|
||||
$tenant_allow_update = undef,
|
||||
$tenant_allow_delete = undef,
|
||||
$tenant_enabled_emulation = undef,
|
||||
$tenant_enabled_emulation_dn = undef,
|
||||
$tenant_additional_attribute_mapping = undef,
|
||||
$tenant_tree_dn = undef, #DEPRECATED
|
||||
$project_tree_dn = undef,
|
||||
$tenant_filter = undef, #DEPRECATED
|
||||
$project_filter = undef,
|
||||
$tenant_objectclass = undef, #DEPRECATED
|
||||
$project_objectclass = undef,
|
||||
$tenant_id_attribute = undef, #DEPRECATED
|
||||
$project_id_attribute = undef,
|
||||
$tenant_member_attribute = undef, #DEPRECATED
|
||||
$project_member_attribute = undef,
|
||||
$tenant_desc_attribute = undef, #DEPRECATED
|
||||
$project_desc_attribute = undef,
|
||||
$tenant_name_attribute = undef, #DEPRECATED
|
||||
$project_name_attribute = undef,
|
||||
$tenant_enabled_attribute = undef, #DEPRECATED
|
||||
$project_enabled_attribute = undef,
|
||||
$tenant_domain_id_attribute = undef, #DEPRECATED
|
||||
$project_domain_id_attribute = undef,
|
||||
$tenant_attribute_ignore = undef, #DEPRECATED
|
||||
$project_attribute_ignore = undef,
|
||||
$tenant_allow_create = undef, #DEPRECATED
|
||||
$project_allow_create = undef,
|
||||
$tenant_allow_update = undef, #DEPRECATED
|
||||
$project_allow_update = undef,
|
||||
$tenant_allow_delete = undef, #DEPRECATED
|
||||
$project_allow_delete = undef,
|
||||
$tenant_enabled_emulation = undef, #DEPRECATED
|
||||
$project_enabled_emulation = undef,
|
||||
$tenant_enabled_emulation_dn = undef, #DEPRECATED
|
||||
$project_enabled_emulation_dn = undef,
|
||||
$tenant_additional_attribute_mapping = undef, #DEPRECATED
|
||||
$project_additional_attribute_mapping= undef,
|
||||
$role_tree_dn = undef,
|
||||
$role_filter = undef,
|
||||
$role_objectclass = undef,
|
||||
@ -76,17 +467,205 @@ class keystone::ldap(
|
||||
$group_allow_update = undef,
|
||||
$group_allow_delete = undef,
|
||||
$group_additional_attribute_mapping = undef,
|
||||
$tenant_tree_dn = undef,
|
||||
$role_tree_dn = undef,
|
||||
$use_tls = undef,
|
||||
$tls_cacertdir = undef,
|
||||
$tls_cacertfile = undef,
|
||||
$tls_req_cert = undef,
|
||||
$identity_driver = undef,
|
||||
$assignment_driver = undef,
|
||||
$credential_driver = undef,
|
||||
$use_pool = false,
|
||||
$pool_size = 10,
|
||||
$pool_retry_max = 3,
|
||||
$pool_retry_delay = 0.1,
|
||||
$pool_connection_timeout = -1,
|
||||
$pool_connection_lifetime = 600,
|
||||
$use_auth_pool = false,
|
||||
$auth_pool_size = 100,
|
||||
$auth_pool_connection_lifetime = 60,
|
||||
) {
|
||||
|
||||
package { 'python-ldap':
|
||||
# In Juno the term "tenant" was deprecated in the config in favor of "project"
|
||||
# Let's assume project_ is being used and warning otherwise. If both are set we will
|
||||
# fail, because having both set may cause unexpected results in Keystone.
|
||||
if ($tenant_tree_dn) {
|
||||
$project_tree_dn_real = $tenant_tree_dn
|
||||
warning ('tenant_tree_dn is deprecated in Juno. switch to project_tree_dn')
|
||||
if ($project_tree_dn) {
|
||||
fail ('tenant_tree_dn and project_tree_dn are both set. results may be unexpected')
|
||||
}
|
||||
}
|
||||
else {
|
||||
$project_tree_dn_real = $project_tree_dn
|
||||
}
|
||||
|
||||
if ($tenant_filter) {
|
||||
$project_filter_real = $tenant_filter
|
||||
warning ('tenant_filter is deprecated in Juno. switch to project_filter')
|
||||
if ($project_filter) {
|
||||
fail ('tenant_filter and project_filter are both set. results may be unexpected')
|
||||
}
|
||||
}
|
||||
else {
|
||||
$project_filter_real = $project_filter
|
||||
}
|
||||
|
||||
if ($tenant_objectclass) {
|
||||
$project_objectclass_real = $tenant_objectclass
|
||||
warning ('tenant_objectclass is deprecated in Juno. switch to project_objectclass')
|
||||
if ($project_objectclass) {
|
||||
fail ('tenant_objectclass and project_objectclass are both set. results may be unexpected')
|
||||
}
|
||||
}
|
||||
else {
|
||||
$project_objectclass_real = $project_objectclass
|
||||
}
|
||||
|
||||
if ($tenant_id_attribute) {
|
||||
$project_id_attribute_real = $tenant_id_attribute
|
||||
warning ('tenant_id_attribute is deprecated in Juno. switch to project_id_attribute')
|
||||
if ($project_id_attribute) {
|
||||
fail ('tenant_id_attribute and project_id_attribute are both set. results may be unexpected')
|
||||
}
|
||||
}
|
||||
else {
|
||||
$project_id_attribute_real = $project_id_attribute
|
||||
}
|
||||
|
||||
if ($tenant_member_attribute) {
|
||||
$project_member_attribute_real = $tenant_member_attribute
|
||||
warning ('tenant_member_attribute is deprecated in Juno. switch to project_member_attribute')
|
||||
if ($project_member_attribute) {
|
||||
fail ('tenant_member_attribute and project_member_attribute are both set. results may be unexpected')
|
||||
}
|
||||
}
|
||||
else {
|
||||
$project_member_attribute_real = $project_member_attribute
|
||||
}
|
||||
|
||||
if ($tenant_desc_attribute) {
|
||||
$project_desc_attribute_real = $tenant_desc_attribute
|
||||
warning ('tenant_desc_attribute is deprecated in Juno. switch to project_desc_attribute')
|
||||
if ($project_desc_attribute) {
|
||||
fail ('tenant_desc_attribute and project_desc_attribute are both set. results may be unexpected')
|
||||
}
|
||||
}
|
||||
else {
|
||||
$project_desc_attribute_real = $project_desc_attribute
|
||||
}
|
||||
|
||||
if ($tenant_name_attribute) {
|
||||
$project_name_attribute_real = $tenant_name_attribute
|
||||
warning ('tenant_name_attribute is deprecated in Juno. switch to project_name_attribute')
|
||||
if ($project_name_attribute) {
|
||||
fail ('tenant_name_attribute and project_name_attribute are both set. results may be unexpected')
|
||||
}
|
||||
}
|
||||
else {
|
||||
$project_name_attribute_real = $project_name_attribute
|
||||
}
|
||||
|
||||
if ($tenant_enabled_attribute) {
|
||||
$project_enabled_attribute_real = $tenant_enabled_attribute
|
||||
warning ('tenant_enabled_attribute is deprecated in Juno. switch to project_enabled_attribute')
|
||||
if ($project_enabled_attribute) {
|
||||
fail ('tenant_enabled_attribute and project_enabled_attribute are both set. results may be unexpected')
|
||||
}
|
||||
}
|
||||
else {
|
||||
$project_enabled_attribute_real = $project_enabled_attribute
|
||||
}
|
||||
|
||||
if ($tenant_attribute_ignore) {
|
||||
$project_attribute_ignore_real = $tenant_attribute_ignore
|
||||
warning ('tenant_attribute_ignore is deprecated in Juno. switch to project_attribute_ignore')
|
||||
if ($project_attribute_ignore) {
|
||||
fail ('tenant_attribute_ignore and project_attribute_ignore are both set. results may be unexpected')
|
||||
}
|
||||
}
|
||||
else {
|
||||
$project_attribute_ignore_real = $project_attribute_ignore
|
||||
}
|
||||
|
||||
if ($tenant_domain_id_attribute) {
|
||||
$project_domain_id_attribute_real = $tenant_domain_id_attribute
|
||||
warning ('tenant_domain_id_attribute is deprecated in Juno. switch to project_domain_id_attribute')
|
||||
if ($project_domain_id_attribute) {
|
||||
fail ('tenant_domain_id_attribute and project_domain_id_attribute are both set. results may be unexpected')
|
||||
}
|
||||
}
|
||||
else {
|
||||
$project_domain_id_attribute_real = $project_domain_id_attribute
|
||||
}
|
||||
|
||||
if ($tenant_allow_create) {
|
||||
$project_allow_create_real = $tenant_allow_create
|
||||
warning ('tenant_allow_create is deprecated in Juno. switch to project_allow_create')
|
||||
if ($project_allow_create) {
|
||||
fail ('tenant_allow_create and project_allow_create are both set. results may be unexpected')
|
||||
}
|
||||
}
|
||||
else {
|
||||
$project_allow_create_real = $project_allow_create
|
||||
}
|
||||
|
||||
if ($tenant_allow_update) {
|
||||
$project_allow_update_real = $tenant_allow_update
|
||||
warning ('tenant_allow_update is deprecated in Juno. switch to project_allow_update')
|
||||
if ($project_allow_update) {
|
||||
fail ('tenant_allow_update and project_allow_update are both set. results may be unexpected')
|
||||
}
|
||||
}
|
||||
else {
|
||||
$project_allow_update_real = $project_allow_update
|
||||
}
|
||||
|
||||
if ($tenant_allow_delete) {
|
||||
$project_allow_delete_real = $tenant_allow_delete
|
||||
warning ('tenant_allow_delete is deprecated in Juno. switch to project_allow_delete')
|
||||
if ($project_allow_delete) {
|
||||
fail ('tenant_allow_delete and project_allow_delete are both set. results may be unexpected')
|
||||
}
|
||||
}
|
||||
else {
|
||||
$project_allow_delete_real = $project_allow_delete
|
||||
}
|
||||
|
||||
if ($tenant_enabled_emulation) {
|
||||
$project_enabled_emulation_real = $tenant_enabled_emulation
|
||||
warning ('tenant_enabled_emulation is deprecated in Juno. switch to project_enabled_emulation')
|
||||
if ($project_enabled_emulation) {
|
||||
fail ('tenant_enabled_emulation and project_enabled_emulation are both set. results may be unexpected')
|
||||
}
|
||||
}
|
||||
else {
|
||||
$project_enabled_emulation_real = $project_enabled_emulation
|
||||
}
|
||||
|
||||
if ($tenant_enabled_emulation_dn) {
|
||||
$project_enabled_emulation_dn_real = $tenant_enabled_emulation_dn
|
||||
warning ('tenant_enabled_emulation_dn is deprecated in Juno. switch to project_enabled_emulation_dn')
|
||||
if ($project_enabled_emulation_dn) {
|
||||
fail ('tenant_enabled_emulation_dn and project_enabled_emulation_dn are both set. results may be unexpected')
|
||||
}
|
||||
}
|
||||
else {
|
||||
$project_enabled_emulation_dn_real = $project_enabled_emulation_dn
|
||||
}
|
||||
|
||||
if ($tenant_additional_attribute_mapping) {
|
||||
$project_additional_attribute_mapping_real = $tenant_additional_attribute_mapping
|
||||
warning ('tenant_additional_attribute_mapping is deprecated in Juno. switch to project_additional_attribute_mapping')
|
||||
if ($project_additional_attribute_mapping) {
|
||||
fail ('tenant_additional_attribute_mapping and project_additional_attribute_mapping are both set. results may be unexpected')
|
||||
}
|
||||
}
|
||||
else {
|
||||
$project_additional_attribute_mapping_real = $project_additional_attribute_mapping
|
||||
}
|
||||
|
||||
$ldap_packages = ['python-ldap', 'python-ldappool']
|
||||
package { $ldap_packages:
|
||||
ensure => present,
|
||||
}
|
||||
|
||||
@ -103,6 +682,12 @@ class keystone::ldap(
|
||||
}
|
||||
}
|
||||
|
||||
if ($credential_driver != undef) {
|
||||
if ! ($credential_driver =~ /^keystone.credential.backends.*Credential$/) {
|
||||
fail('credential driver should be of the form \'keystone.credential.backends.*Credential\'')
|
||||
}
|
||||
}
|
||||
|
||||
if ($tls_cacertdir != undef) {
|
||||
file { $tls_cacertdir:
|
||||
ensure => directory
|
||||
@ -110,74 +695,85 @@ class keystone::ldap(
|
||||
}
|
||||
|
||||
keystone_config {
|
||||
'ldap/url': value => $url;
|
||||
'ldap/user': value => $user;
|
||||
'ldap/password': value => $password, secret => true;
|
||||
'ldap/suffix': value => $suffix;
|
||||
'ldap/query_scope': value => $query_scope;
|
||||
'ldap/page_size': value => $page_size;
|
||||
'ldap/user_tree_dn': value => $user_tree_dn;
|
||||
'ldap/user_filter': value => $user_filter;
|
||||
'ldap/user_objectclass': value => $user_objectclass;
|
||||
'ldap/user_id_attribute': value => $user_id_attribute;
|
||||
'ldap/user_name_attribute': value => $user_name_attribute;
|
||||
'ldap/user_mail_attribute': value => $user_mail_attribute;
|
||||
'ldap/user_enabled_attribute': value => $user_enabled_attribute;
|
||||
'ldap/user_enabled_mask': value => $user_enabled_mask;
|
||||
'ldap/user_enabled_default': value => $user_enabled_default;
|
||||
'ldap/user_attribute_ignore': value => $user_attribute_ignore;
|
||||
'ldap/user_default_project_id_attribute': value => $user_default_project_id_attribute;
|
||||
'ldap/user_allow_create': value => $user_allow_create;
|
||||
'ldap/user_allow_update': value => $user_allow_update;
|
||||
'ldap/user_allow_delete': value => $user_allow_delete;
|
||||
'ldap/user_pass_attribute': value => $user_pass_attribute;
|
||||
'ldap/user_enabled_emulation': value => $user_enabled_emulation;
|
||||
'ldap/user_enabled_emulation_dn': value => $user_enabled_emulation_dn;
|
||||
'ldap/user_additional_attribute_mapping': value => $user_additional_attribute_mapping;
|
||||
'ldap/tenant_tree_dn': value => $tenant_tree_dn;
|
||||
'ldap/tenant_filter': value => $tenant_filter;
|
||||
'ldap/tenant_objectclass': value => $tenant_objectclass;
|
||||
'ldap/tenant_id_attribute': value => $tenant_id_attribute;
|
||||
'ldap/tenant_member_attribute': value => $tenant_member_attribute;
|
||||
'ldap/tenant_desc_attribute': value => $tenant_desc_attribute;
|
||||
'ldap/tenant_name_attribute': value => $tenant_name_attribute;
|
||||
'ldap/tenant_enabled_attribute': value => $tenant_enabled_attribute;
|
||||
'ldap/tenant_attribute_ignore': value => $tenant_attribute_ignore;
|
||||
'ldap/tenant_domain_id_attribute': value => $tenant_domain_id_attribute;
|
||||
'ldap/tenant_allow_create': value => $tenant_allow_create;
|
||||
'ldap/tenant_allow_update': value => $tenant_allow_update;
|
||||
'ldap/tenant_allow_delete': value => $tenant_allow_delete;
|
||||
'ldap/tenant_enabled_emulation': value => $tenant_enabled_emulation;
|
||||
'ldap/tenant_enabled_emulation_dn': value => $tenant_enabled_emulation_dn;
|
||||
'ldap/tenant_additional_attribute_mapping': value => $tenant_additional_attribute_mapping;
|
||||
'ldap/role_tree_dn': value => $role_tree_dn;
|
||||
'ldap/role_filter': value => $role_filter;
|
||||
'ldap/role_objectclass': value => $role_objectclass;
|
||||
'ldap/role_id_attribute': value => $role_id_attribute;
|
||||
'ldap/role_name_attribute': value => $role_name_attribute;
|
||||
'ldap/role_member_attribute': value => $role_member_attribute;
|
||||
'ldap/role_attribute_ignore': value => $role_attribute_ignore;
|
||||
'ldap/role_allow_create': value => $role_allow_create;
|
||||
'ldap/role_allow_update': value => $role_allow_update;
|
||||
'ldap/role_allow_delete': value => $role_allow_delete;
|
||||
'ldap/role_additional_attribute_mapping': value => $role_additional_attribute_mapping;
|
||||
'ldap/group_tree_dn': value => $group_tree_dn;
|
||||
'ldap/group_filter': value => $group_filter;
|
||||
'ldap/group_objectclass': value => $group_objectclass;
|
||||
'ldap/group_id_attribute': value => $group_id_attribute;
|
||||
'ldap/group_name_attribute': value => $group_name_attribute;
|
||||
'ldap/group_member_attribute': value => $group_member_attribute;
|
||||
'ldap/group_desc_attribute': value => $group_desc_attribute;
|
||||
'ldap/group_attribute_ignore': value => $group_attribute_ignore;
|
||||
'ldap/group_allow_create': value => $group_allow_create;
|
||||
'ldap/group_allow_update': value => $group_allow_update;
|
||||
'ldap/group_allow_delete': value => $group_allow_delete;
|
||||
'ldap/group_additional_attribute_mapping': value => $group_additional_attribute_mapping;
|
||||
'ldap/use_tls': value => $use_tls;
|
||||
'ldap/tls_cacertdir': value => $tls_cacertdir;
|
||||
'ldap/tls_cacertfile': value => $tls_cacertfile;
|
||||
'ldap/tls_req_cert': value => $tls_req_cert;
|
||||
'identity/driver': value => $identity_driver;
|
||||
'assignment/driver': value => $assignment_driver;
|
||||
'ldap/url': value => $url;
|
||||
'ldap/user': value => $user;
|
||||
'ldap/password': value => $password, secret => true;
|
||||
'ldap/suffix': value => $suffix;
|
||||
'ldap/query_scope': value => $query_scope;
|
||||
'ldap/page_size': value => $page_size;
|
||||
'ldap/user_tree_dn': value => $user_tree_dn;
|
||||
'ldap/user_filter': value => $user_filter;
|
||||
'ldap/user_objectclass': value => $user_objectclass;
|
||||
'ldap/user_id_attribute': value => $user_id_attribute;
|
||||
'ldap/user_name_attribute': value => $user_name_attribute;
|
||||
'ldap/user_mail_attribute': value => $user_mail_attribute;
|
||||
'ldap/user_enabled_attribute': value => $user_enabled_attribute;
|
||||
'ldap/user_enabled_mask': value => $user_enabled_mask;
|
||||
'ldap/user_enabled_default': value => $user_enabled_default;
|
||||
'ldap/user_enabled_invert': value => $user_enabled_invert;
|
||||
'ldap/user_attribute_ignore': value => $user_attribute_ignore;
|
||||
'ldap/user_default_project_id_attribute': value => $user_default_project_id_attribute;
|
||||
'ldap/user_allow_create': value => $user_allow_create;
|
||||
'ldap/user_allow_update': value => $user_allow_update;
|
||||
'ldap/user_allow_delete': value => $user_allow_delete;
|
||||
'ldap/user_pass_attribute': value => $user_pass_attribute;
|
||||
'ldap/user_enabled_emulation': value => $user_enabled_emulation;
|
||||
'ldap/user_enabled_emulation_dn': value => $user_enabled_emulation_dn;
|
||||
'ldap/user_additional_attribute_mapping': value => $user_additional_attribute_mapping;
|
||||
'ldap/project_tree_dn': value => $project_tree_dn_real;
|
||||
'ldap/project_filter': value => $project_filter_real;
|
||||
'ldap/project_objectclass': value => $project_objectclass_real;
|
||||
'ldap/project_id_attribute': value => $project_id_attribute_real;
|
||||
'ldap/project_member_attribute': value => $project_member_attribute_real;
|
||||
'ldap/project_desc_attribute': value => $project_desc_attribute_real;
|
||||
'ldap/project_name_attribute': value => $project_name_attribute_real;
|
||||
'ldap/project_enabled_attribute': value => $project_enabled_attribute_real;
|
||||
'ldap/project_attribute_ignore': value => $project_attribute_ignore_real;
|
||||
'ldap/project_domain_id_attribute': value => $project_domain_id_attribute_real;
|
||||
'ldap/project_allow_create': value => $project_allow_create_real;
|
||||
'ldap/project_allow_update': value => $project_allow_update_real;
|
||||
'ldap/project_allow_delete': value => $project_allow_delete_real;
|
||||
'ldap/project_enabled_emulation': value => $project_enabled_emulation_real;
|
||||
'ldap/project_enabled_emulation_dn': value => $project_enabled_emulation_dn_real;
|
||||
'ldap/project_additional_attribute_mapping': value => $project_additional_attribute_mapping_real;
|
||||
'ldap/role_tree_dn': value => $role_tree_dn;
|
||||
'ldap/role_filter': value => $role_filter;
|
||||
'ldap/role_objectclass': value => $role_objectclass;
|
||||
'ldap/role_id_attribute': value => $role_id_attribute;
|
||||
'ldap/role_name_attribute': value => $role_name_attribute;
|
||||
'ldap/role_member_attribute': value => $role_member_attribute;
|
||||
'ldap/role_attribute_ignore': value => $role_attribute_ignore;
|
||||
'ldap/role_allow_create': value => $role_allow_create;
|
||||
'ldap/role_allow_update': value => $role_allow_update;
|
||||
'ldap/role_allow_delete': value => $role_allow_delete;
|
||||
'ldap/role_additional_attribute_mapping': value => $role_additional_attribute_mapping;
|
||||
'ldap/group_tree_dn': value => $group_tree_dn;
|
||||
'ldap/group_filter': value => $group_filter;
|
||||
'ldap/group_objectclass': value => $group_objectclass;
|
||||
'ldap/group_id_attribute': value => $group_id_attribute;
|
||||
'ldap/group_name_attribute': value => $group_name_attribute;
|
||||
'ldap/group_member_attribute': value => $group_member_attribute;
|
||||
'ldap/group_desc_attribute': value => $group_desc_attribute;
|
||||
'ldap/group_attribute_ignore': value => $group_attribute_ignore;
|
||||
'ldap/group_allow_create': value => $group_allow_create;
|
||||
'ldap/group_allow_update': value => $group_allow_update;
|
||||
'ldap/group_allow_delete': value => $group_allow_delete;
|
||||
'ldap/group_additional_attribute_mapping': value => $group_additional_attribute_mapping;
|
||||
'ldap/use_tls': value => $use_tls;
|
||||
'ldap/tls_cacertdir': value => $tls_cacertdir;
|
||||
'ldap/tls_cacertfile': value => $tls_cacertfile;
|
||||
'ldap/tls_req_cert': value => $tls_req_cert;
|
||||
'ldap/use_pool': value => $use_pool;
|
||||
'ldap/pool_size': value => $pool_size;
|
||||
'ldap/pool_retry_max': value => $pool_retry_max;
|
||||
'ldap/pool_retry_delay': value => $pool_retry_delay;
|
||||
'ldap/pool_connection_timeout': value => $pool_connection_timeout;
|
||||
'ldap/pool_connection_lifetime': value => $pool_connection_lifetime;
|
||||
'ldap/use_auth_pool': value => $use_auth_pool;
|
||||
'ldap/auth_pool_size': value => $auth_pool_size;
|
||||
'ldap/auth_pool_connection_lifetime': value => $auth_pool_connection_lifetime;
|
||||
'identity/driver': value => $identity_driver;
|
||||
'credential/driver': value => $credential_driver;
|
||||
'assignment/driver': value => $assignment_driver;
|
||||
}
|
||||
}
|
||||
|
211
deployment/puppet/keystone/manifests/logging.pp
Normal file
211
deployment/puppet/keystone/manifests/logging.pp
Normal file
@ -0,0 +1,211 @@
|
||||
# Class keystone::logging
|
||||
#
|
||||
# keystone extended logging configuration
|
||||
#
|
||||
# == parameters
|
||||
#
|
||||
# [*logging_context_format_string*]
|
||||
# (optional) Format string to use for log messages with context.
|
||||
# Defaults to undef.
|
||||
# Example: '%(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s\
|
||||
# [%(request_id)s %(user_identity)s] %(instance)s%(message)s'
|
||||
#
|
||||
# [*logging_default_format_string*]
|
||||
# (optional) Format string to use for log messages without context.
|
||||
# Defaults to undef.
|
||||
# Example: '%(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s\
|
||||
# [-] %(instance)s%(message)s'
|
||||
#
|
||||
# [*logging_debug_format_suffix*]
|
||||
# (optional) Formatted data to append to log format when level is DEBUG.
|
||||
# Defaults to undef.
|
||||
# Example: '%(funcName)s %(pathname)s:%(lineno)d'
|
||||
#
|
||||
# [*logging_exception_prefix*]
|
||||
# (optional) Prefix each line of exception output with this format.
|
||||
# Defaults to undef.
|
||||
# Example: '%(asctime)s.%(msecs)03d %(process)d TRACE %(name)s %(instance)s'
|
||||
#
|
||||
# [*log_config_append*]
|
||||
# The name of an additional logging configuration file.
|
||||
# Defaults to undef.
|
||||
# See https://docs.python.org/2/howto/logging.html
|
||||
#
|
||||
# [*default_log_levels*]
|
||||
# (optional) Hash of logger (keys) and level (values) pairs.
|
||||
# Defaults to undef.
|
||||
# Example:
|
||||
# { 'amqp' => 'WARN', 'amqplib' => 'WARN', 'boto' => 'WARN',
|
||||
# 'qpid' => 'WARN', 'sqlalchemy' => 'WARN', 'suds' => 'INFO',
|
||||
# 'oslo.messaging' => 'INFO', 'iso8601' => 'WARN',
|
||||
# 'requests.packages.urllib3.connectionpool' => 'WARN',
|
||||
# 'urllib3.connectionpool' => 'WARN',
|
||||
# 'websocket' => 'WARN', 'keystonemiddleware' => 'WARN',
|
||||
# 'routes.middleware' => 'WARN', stevedore => 'WARN' }
|
||||
#
|
||||
# [*publish_errors*]
|
||||
# (optional) Publish error events (boolean value).
|
||||
# Defaults to undef (false if unconfigured).
|
||||
#
|
||||
# [*fatal_deprecations*]
|
||||
# (optional) Make deprecations fatal (boolean value)
|
||||
# Defaults to undef (false if unconfigured).
|
||||
#
|
||||
# [*instance_format*]
|
||||
# (optional) If an instance is passed with the log message, format it
|
||||
# like this (string value).
|
||||
# Defaults to undef.
|
||||
# Example: '[instance: %(uuid)s] '
|
||||
#
|
||||
# [*instance_uuid_format*]
|
||||
# (optional) If an instance UUID is passed with the log message, format
|
||||
# it like this (string value).
|
||||
# Defaults to undef.
|
||||
# Example: instance_uuid_format='[instance: %(uuid)s] '
|
||||
|
||||
# [*log_date_format*]
|
||||
# (optional) Format string for %%(asctime)s in log records.
|
||||
# Defaults to undef.
|
||||
# Example: 'Y-%m-%d %H:%M:%S'
|
||||
|
||||
class keystone::logging(
|
||||
$logging_context_format_string = undef,
|
||||
$logging_default_format_string = undef,
|
||||
$logging_debug_format_suffix = undef,
|
||||
$logging_exception_prefix = undef,
|
||||
$log_config_append = undef,
|
||||
$default_log_levels = undef,
|
||||
$publish_errors = undef,
|
||||
$fatal_deprecations = undef,
|
||||
$instance_format = undef,
|
||||
$instance_uuid_format = undef,
|
||||
$log_date_format = undef,
|
||||
) {
|
||||
|
||||
if $logging_context_format_string {
|
||||
keystone_config {
|
||||
'DEFAULT/logging_context_format_string' :
|
||||
value => $logging_context_format_string;
|
||||
}
|
||||
}
|
||||
else {
|
||||
keystone_config {
|
||||
'DEFAULT/logging_context_format_string' : ensure => absent;
|
||||
}
|
||||
}
|
||||
|
||||
if $logging_default_format_string {
|
||||
keystone_config {
|
||||
'DEFAULT/logging_default_format_string' :
|
||||
value => $logging_default_format_string;
|
||||
}
|
||||
}
|
||||
else {
|
||||
keystone_config {
|
||||
'DEFAULT/logging_default_format_string' : ensure => absent;
|
||||
}
|
||||
}
|
||||
|
||||
if $logging_debug_format_suffix {
|
||||
keystone_config {
|
||||
'DEFAULT/logging_debug_format_suffix' :
|
||||
value => $logging_debug_format_suffix;
|
||||
}
|
||||
}
|
||||
else {
|
||||
keystone_config {
|
||||
'DEFAULT/logging_debug_format_suffix' : ensure => absent;
|
||||
}
|
||||
}
|
||||
|
||||
if $logging_exception_prefix {
|
||||
keystone_config {
|
||||
'DEFAULT/logging_exception_prefix' : value => $logging_exception_prefix;
|
||||
}
|
||||
}
|
||||
else {
|
||||
keystone_config {
|
||||
'DEFAULT/logging_exception_prefix' : ensure => absent;
|
||||
}
|
||||
}
|
||||
|
||||
if $log_config_append {
|
||||
keystone_config {
|
||||
'DEFAULT/log_config_append' : value => $log_config_append;
|
||||
}
|
||||
}
|
||||
else {
|
||||
keystone_config {
|
||||
'DEFAULT/log_config_append' : ensure => absent;
|
||||
}
|
||||
}
|
||||
|
||||
if $default_log_levels {
|
||||
keystone_config {
|
||||
'DEFAULT/default_log_levels' :
|
||||
value => join(sort(join_keys_to_values($default_log_levels, '=')), ',');
|
||||
}
|
||||
}
|
||||
else {
|
||||
keystone_config {
|
||||
'DEFAULT/default_log_levels' : ensure => absent;
|
||||
}
|
||||
}
|
||||
|
||||
if $publish_errors {
|
||||
keystone_config {
|
||||
'DEFAULT/publish_errors' : value => $publish_errors;
|
||||
}
|
||||
}
|
||||
else {
|
||||
keystone_config {
|
||||
'DEFAULT/publish_errors' : ensure => absent;
|
||||
}
|
||||
}
|
||||
|
||||
if $fatal_deprecations {
|
||||
keystone_config {
|
||||
'DEFAULT/fatal_deprecations' : value => $fatal_deprecations;
|
||||
}
|
||||
}
|
||||
else {
|
||||
keystone_config {
|
||||
'DEFAULT/fatal_deprecations' : ensure => absent;
|
||||
}
|
||||
}
|
||||
|
||||
if $instance_format {
|
||||
keystone_config {
|
||||
'DEFAULT/instance_format' : value => $instance_format;
|
||||
}
|
||||
}
|
||||
else {
|
||||
keystone_config {
|
||||
'DEFAULT/instance_format' : ensure => absent;
|
||||
}
|
||||
}
|
||||
|
||||
if $instance_uuid_format {
|
||||
keystone_config {
|
||||
'DEFAULT/instance_uuid_format' : value => $instance_uuid_format;
|
||||
}
|
||||
}
|
||||
else {
|
||||
keystone_config {
|
||||
'DEFAULT/instance_uuid_format' : ensure => absent;
|
||||
}
|
||||
}
|
||||
|
||||
if $log_date_format {
|
||||
keystone_config {
|
||||
'DEFAULT/log_date_format' : value => $log_date_format;
|
||||
}
|
||||
}
|
||||
else {
|
||||
keystone_config {
|
||||
'DEFAULT/log_date_format' : ensure => absent;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -6,26 +6,33 @@ class keystone::params {
|
||||
|
||||
case $::osfamily {
|
||||
'Debian': {
|
||||
$package_name = 'keystone'
|
||||
$service_name = 'keystone'
|
||||
$keystone_wsgi_script_path = '/usr/lib/cgi-bin/keystone'
|
||||
$package_name = 'keystone'
|
||||
$service_name = 'keystone'
|
||||
$keystone_wsgi_script_path = '/usr/lib/cgi-bin/keystone'
|
||||
$python_memcache_package_name = 'python-memcache'
|
||||
$paste_config = undef
|
||||
case $::operatingsystem {
|
||||
'Debian': {
|
||||
$service_provider = undef
|
||||
$keystone_wsgi_script_source = '/usr/share/keystone/wsgi.py'
|
||||
}
|
||||
default: {
|
||||
# NOTE: Ubuntu does not currently provide the keystone wsgi script in the
|
||||
# keystone packages. When Ubuntu does provide the script, change this
|
||||
# to use the correct path (which I'm assuming will be the same as Debian).
|
||||
$service_provider = 'upstart'
|
||||
$keystone_wsgi_script_source = 'puppet:///modules/keystone/httpd/keystone.py'
|
||||
}
|
||||
}
|
||||
}
|
||||
'RedHat': {
|
||||
$package_name = 'openstack-keystone'
|
||||
$service_name = 'openstack-keystone'
|
||||
$keystone_wsgi_script_path = '/var/www/cgi-bin/keystone'
|
||||
$service_provider = undef
|
||||
$keystone_wsgi_script_source = 'puppet:///modules/keystone/httpd/keystone.py'
|
||||
$package_name = 'openstack-keystone'
|
||||
$service_name = 'openstack-keystone'
|
||||
$keystone_wsgi_script_path = '/var/www/cgi-bin/keystone'
|
||||
$python_memcache_package_name = 'python-memcached'
|
||||
$service_provider = undef
|
||||
$keystone_wsgi_script_source = '/usr/share/keystone/keystone.wsgi'
|
||||
$paste_config = '/usr/share/keystone/keystone-dist-paste.ini'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
39
deployment/puppet/keystone/manifests/policy.pp
Normal file
39
deployment/puppet/keystone/manifests/policy.pp
Normal file
@ -0,0 +1,39 @@
|
||||
# == Class: keystone::policy
|
||||
#
|
||||
# Configure the keystone policies
|
||||
#
|
||||
# === Parameters
|
||||
#
|
||||
# [*policies*]
|
||||
# (optional) Set of policies to configure for keystone
|
||||
# Example :
|
||||
# {
|
||||
# 'keystone-context_is_admin' => {
|
||||
# 'key' => 'context_is_admin',
|
||||
# 'value' => 'true'
|
||||
# },
|
||||
# 'keystone-default' => {
|
||||
# 'key' => 'default',
|
||||
# 'value' => 'rule:admin_or_owner'
|
||||
# }
|
||||
# }
|
||||
# Defaults to empty hash.
|
||||
#
|
||||
# [*policy_path*]
|
||||
# (optional) Path to the nova policy.json file
|
||||
# Defaults to /etc/keystone/policy.json
|
||||
#
|
||||
class keystone::policy (
|
||||
$policies = {},
|
||||
$policy_path = '/etc/keystone/policy.json',
|
||||
) {
|
||||
|
||||
validate_hash($policies)
|
||||
|
||||
Openstacklib::Policy::Base {
|
||||
file_path => $policy_path,
|
||||
}
|
||||
|
||||
create_resources('openstacklib::policy::base', $policies)
|
||||
|
||||
}
|
@ -1,6 +1,16 @@
|
||||
# == Class keystone::python
|
||||
#
|
||||
# installs client python libraries for keystone
|
||||
#
|
||||
# === Parameters:
|
||||
#
|
||||
# [*client_package_name*]
|
||||
# (optional) The name of python keystone client package
|
||||
# Defaults to $keystone::params::client_package_name
|
||||
#
|
||||
# [*ensure*]
|
||||
# (optional) The state for the keystone client package
|
||||
# Defaults to 'present'
|
||||
#
|
||||
class keystone::python (
|
||||
$client_package_name = $keystone::params::client_package_name,
|
||||
|
@ -0,0 +1,164 @@
|
||||
#
|
||||
# Copyright (C) 2014 eNovance SAS <licensing@enovance.com>
|
||||
#
|
||||
# Author: Emilien Macchi <emilien.macchi@enovance.com>
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# == Definition: keystone::resource::service_identity
|
||||
#
|
||||
# This resource configures Keystone resources for an OpenStack service.
|
||||
#
|
||||
# == Parameters:
|
||||
#
|
||||
# [*password*]
|
||||
# Password to create for the service user;
|
||||
# string; required
|
||||
#
|
||||
# [*auth_name*]
|
||||
# The name of the service user;
|
||||
# string; optional; default to the $title of the resource, i.e. 'nova'
|
||||
#
|
||||
# [*service_name*]
|
||||
# Name of the service;
|
||||
# string; required
|
||||
#
|
||||
# [*service_type*]
|
||||
# Type of the service;
|
||||
# string; required
|
||||
#
|
||||
# [*service_description*]
|
||||
# Description of the service;
|
||||
# string; optional: default to '$name service'
|
||||
#
|
||||
# [*public_url*]
|
||||
# Public endpoint URL;
|
||||
# string; required
|
||||
#
|
||||
# [*internal_url*]
|
||||
# Internal endpoint URL;
|
||||
# string; required
|
||||
#
|
||||
# [*admin_url*]
|
||||
# Admin endpoint URL;
|
||||
# string; required
|
||||
#
|
||||
# [*region*]
|
||||
# Endpoint region;
|
||||
# string; optional: default to 'RegionOne'
|
||||
#
|
||||
# [*tenant*]
|
||||
# Service tenant;
|
||||
# string; optional: default to 'services'
|
||||
#
|
||||
# [*ignore_default_tenant*]
|
||||
# Ignore setting the default tenant value when the user is created.
|
||||
# string; optional: default to false
|
||||
#
|
||||
# [*roles*]
|
||||
# List of roles;
|
||||
# string; optional: default to ['admin']
|
||||
#
|
||||
# [*domain*]
|
||||
# User domain (keystone v3), not implemented yet.
|
||||
# string; optional: default to undef
|
||||
#
|
||||
# [*email*]
|
||||
# Service email;
|
||||
# string; optional: default to '$auth_name@localhost'
|
||||
#
|
||||
# [*configure_endpoint*]
|
||||
# Whether to create the endpoint.
|
||||
# string; optional: default to True
|
||||
#
|
||||
# [*configure_user*]
|
||||
# Whether to create the user.
|
||||
# string; optional: default to True
|
||||
#
|
||||
# [*configure_user_role*]
|
||||
# Whether to create the user role.
|
||||
# string; optional: default to True
|
||||
#
|
||||
# [*configure_service*]
|
||||
# Whether to create the service.
|
||||
# string; optional: default to True
|
||||
#
|
||||
define keystone::resource::service_identity(
|
||||
$admin_url = false,
|
||||
$internal_url = false,
|
||||
$password = false,
|
||||
$public_url = false,
|
||||
$service_type = false,
|
||||
$auth_name = $name,
|
||||
$configure_endpoint = true,
|
||||
$configure_user = true,
|
||||
$configure_user_role = true,
|
||||
$configure_service = true,
|
||||
$domain = undef,
|
||||
$email = "${name}@localhost",
|
||||
$region = 'RegionOne',
|
||||
$service_name = undef,
|
||||
$service_description = "${name} service",
|
||||
$tenant = 'services',
|
||||
$ignore_default_tenant = false,
|
||||
$roles = ['admin'],
|
||||
) {
|
||||
|
||||
if $domain {
|
||||
warning('Keystone domains are not yet managed by puppet-keystone.')
|
||||
}
|
||||
|
||||
if $service_name == undef {
|
||||
$service_name_real = $auth_name
|
||||
} else {
|
||||
$service_name_real = $service_name
|
||||
}
|
||||
|
||||
if $configure_user {
|
||||
ensure_resource('keystone_user', $auth_name, {
|
||||
'ensure' => 'present',
|
||||
'enabled' => true,
|
||||
'password' => $password,
|
||||
'email' => $email,
|
||||
'tenant' => $tenant,
|
||||
'ignore_default_tenant' => $ignore_default_tenant,
|
||||
})
|
||||
}
|
||||
|
||||
if $configure_user_role {
|
||||
ensure_resource('keystone_user_role', "${auth_name}@${tenant}", {
|
||||
'ensure' => 'present',
|
||||
'roles' => $roles,
|
||||
})
|
||||
if $configure_user {
|
||||
Keystone_user[$auth_name] -> Keystone_user_role["${auth_name}@${tenant}"]
|
||||
}
|
||||
}
|
||||
|
||||
if $configure_service {
|
||||
ensure_resource('keystone_service', $service_name_real, {
|
||||
'ensure' => 'present',
|
||||
'type' => $service_type,
|
||||
'description' => $service_description,
|
||||
})
|
||||
}
|
||||
|
||||
if $configure_endpoint {
|
||||
ensure_resource('keystone_endpoint', "${region}/${service_name_real}", {
|
||||
'ensure' => 'present',
|
||||
'public_url' => $public_url,
|
||||
'admin_url' => $admin_url,
|
||||
'internal_url' => $internal_url,
|
||||
})
|
||||
}
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
# == Class: keystone::roles::admin
|
||||
#
|
||||
# This class implements some reasonable admin defaults for keystone.
|
||||
#
|
||||
@ -8,12 +9,49 @@
|
||||
# * admin role
|
||||
# * adds admin role to admin user on the "admin" tenant
|
||||
#
|
||||
# [*Parameters*]
|
||||
# === Parameters:
|
||||
#
|
||||
# [email] The email address for the admin. Required.
|
||||
# [password] The admin password. Required.
|
||||
# [admin_tenant] The name of the tenant to be used for admin privileges. Optional. Defaults to openstack.
|
||||
# [admin] Admin user. Optional. Defaults to admin.
|
||||
# [*email*]
|
||||
# The email address for the admin. Required.
|
||||
#
|
||||
# [*password*]
|
||||
# The admin password. Required.
|
||||
#
|
||||
# [*admin_roles*]
|
||||
# The list of the roles with admin privileges. Optional.
|
||||
# Defaults to ['admin'].
|
||||
#
|
||||
# [*admin_tenant*]
|
||||
# The name of the tenant to be used for admin privileges. Optional.
|
||||
# Defaults to openstack.
|
||||
#
|
||||
# [*service_tenant*]
|
||||
# The name of service keystone tenant. Optional.
|
||||
# Defaults to 'services'.
|
||||
#
|
||||
# [*admin*]
|
||||
# Admin user. Optional.
|
||||
# Defaults to admin.
|
||||
#
|
||||
# [*ignore_default_tenant*]
|
||||
# Ignore setting the default tenant value when the user is created. Optional.
|
||||
# Defaults to false.
|
||||
#
|
||||
# [*admin_tenant_desc*]
|
||||
# Optional. Description for admin tenant,
|
||||
# Defaults to 'admin tenant'
|
||||
#
|
||||
# [*service_tenant_desc*]
|
||||
# Optional. Description for admin tenant,
|
||||
# Defaults to 'Tenant for the openstack services'
|
||||
#
|
||||
# [*configure_user*]
|
||||
# Optional. Should the admin user be created?
|
||||
# Defaults to 'true'.
|
||||
#
|
||||
# [*configure_user_role*]
|
||||
# Optional. Should the admin role be configured for the admin user?
|
||||
# Defaulst to 'true'.
|
||||
#
|
||||
# == Dependencies
|
||||
# == Examples
|
||||
@ -28,34 +66,47 @@
|
||||
class keystone::roles::admin(
|
||||
$email,
|
||||
$password,
|
||||
$admin = 'admin',
|
||||
$admin_tenant = 'openstack',
|
||||
$service_tenant = 'services'
|
||||
$admin = 'admin',
|
||||
$admin_tenant = 'openstack',
|
||||
$admin_roles = ['admin'],
|
||||
$service_tenant = 'services',
|
||||
$ignore_default_tenant = false,
|
||||
$admin_tenant_desc = 'admin tenant',
|
||||
$service_tenant_desc = 'Tenant for the openstack services',
|
||||
$configure_user = true,
|
||||
$configure_user_role = true,
|
||||
) {
|
||||
|
||||
keystone_tenant { $service_tenant:
|
||||
ensure => present,
|
||||
enabled => true,
|
||||
description => 'Tenant for the openstack services',
|
||||
description => $service_tenant_desc,
|
||||
}
|
||||
keystone_tenant { $admin_tenant:
|
||||
ensure => present,
|
||||
enabled => true,
|
||||
description => 'admin tenant',
|
||||
}
|
||||
keystone_user { $admin:
|
||||
ensure => present,
|
||||
enabled => true,
|
||||
tenant => $admin_tenant,
|
||||
email => $email,
|
||||
password => $password,
|
||||
description => $admin_tenant_desc,
|
||||
}
|
||||
keystone_role { 'admin':
|
||||
ensure => present,
|
||||
}
|
||||
keystone_user_role { "${admin}@${admin_tenant}":
|
||||
ensure => present,
|
||||
roles => 'admin',
|
||||
|
||||
if $configure_user {
|
||||
keystone_user { $admin:
|
||||
ensure => present,
|
||||
enabled => true,
|
||||
tenant => $admin_tenant,
|
||||
email => $email,
|
||||
password => $password,
|
||||
ignore_default_tenant => $ignore_default_tenant,
|
||||
}
|
||||
}
|
||||
|
||||
if $configure_user_role {
|
||||
keystone_user_role { "${admin}@${admin_tenant}":
|
||||
ensure => present,
|
||||
roles => $admin_roles,
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
123
deployment/puppet/keystone/manifests/service.pp
Normal file
123
deployment/puppet/keystone/manifests/service.pp
Normal file
@ -0,0 +1,123 @@
|
||||
# == Class keystone::service
|
||||
#
|
||||
# Encapsulates the keystone service to a class.
|
||||
# This allows resources that require keystone to
|
||||
# require this class, which can optionally
|
||||
# validate that the service can actually accept
|
||||
# connections.
|
||||
#
|
||||
# === Parameters
|
||||
#
|
||||
# [*ensure*]
|
||||
# (optional) The desired state of the keystone service
|
||||
# Defaults to undef
|
||||
#
|
||||
# [*service_name*]
|
||||
# (optional) The name of the keystone service
|
||||
# Defaults to $::keystone::params::service_name
|
||||
#
|
||||
# [*enable*]
|
||||
# (optional) Whether to enable the keystone service
|
||||
# Defaults to true
|
||||
#
|
||||
# [*hasstatus*]
|
||||
# (optional) Whether the keystone service has status
|
||||
# Defaults to true
|
||||
#
|
||||
# [*hasrestart*]
|
||||
# (optional) Whether the keystone service has restart
|
||||
# Defaults to true
|
||||
#
|
||||
# [*provider*]
|
||||
# (optional) Provider for keystone service
|
||||
# Defaults to $::keystone::params::service_provider
|
||||
#
|
||||
# [*validate*]
|
||||
# (optional) Whether to validate the service is working after any service refreshes
|
||||
# Defaults to false
|
||||
#
|
||||
# [*admin_token*]
|
||||
# (optional) The admin token to use for validation
|
||||
# Defaults to undef
|
||||
#
|
||||
# [*admin_endpoint*]
|
||||
# (optional) The admin endpont to use for validation
|
||||
# Defaults to 'http://localhost:35357/v2.0'
|
||||
#
|
||||
# [*retries*]
|
||||
# (optional) Number of times to retry validation
|
||||
# Defaults to 10
|
||||
#
|
||||
# [*delay*]
|
||||
# (optional) Number of seconds between validation attempts
|
||||
# Defaults to 2
|
||||
#
|
||||
# [*insecure*]
|
||||
# (optional) Whether to validate keystone connections
|
||||
# using the --insecure option with keystone client.
|
||||
# Defaults to false
|
||||
#
|
||||
# [*cacert*]
|
||||
# (optional) Whether to validate keystone connections
|
||||
# using the specified argument with the --os-cacert option
|
||||
# with keystone client.
|
||||
# Defaults to undef
|
||||
#
|
||||
class keystone::service(
|
||||
$ensure = undef,
|
||||
$service_name = $::keystone::params::service_name,
|
||||
$enable = true,
|
||||
$hasstatus = true,
|
||||
$hasrestart = true,
|
||||
$provider = $::keystone::params::service_provider,
|
||||
$validate = false,
|
||||
$admin_token = undef,
|
||||
$admin_endpoint = 'http://localhost:35357/v2.0',
|
||||
$retries = 10,
|
||||
$delay = 2,
|
||||
$insecure = false,
|
||||
$cacert = undef,
|
||||
) {
|
||||
include ::keystone::params
|
||||
|
||||
service { 'keystone':
|
||||
ensure => $ensure,
|
||||
name => $service_name,
|
||||
enable => $enable,
|
||||
hasstatus => $hasstatus,
|
||||
hasrestart => $hasrestart,
|
||||
provider => $provider
|
||||
}
|
||||
|
||||
if $insecure {
|
||||
$insecure_s = '--insecure'
|
||||
} else {
|
||||
$insecure_s = ''
|
||||
}
|
||||
|
||||
if $cacert {
|
||||
$cacert_s = "--os-cacert ${cacert}"
|
||||
} else {
|
||||
$cacert_s = ''
|
||||
}
|
||||
|
||||
if $validate and $admin_token and $admin_endpoint {
|
||||
$cmd = "openstack --os-auth-url ${admin_endpoint} --os-token ${admin_token} ${insecure_s} ${cacert_s} user list"
|
||||
$catch = 'name'
|
||||
exec { 'validate_keystone_connection':
|
||||
path => '/usr/bin:/bin:/usr/sbin:/sbin',
|
||||
provider => shell,
|
||||
command => $cmd,
|
||||
subscribe => Service['keystone'],
|
||||
refreshonly => true,
|
||||
tries => $retries,
|
||||
try_sleep => $delay
|
||||
}
|
||||
|
||||
Exec['validate_keystone_connection'] -> Keystone_user<||>
|
||||
Exec['validate_keystone_connection'] -> Keystone_role<||>
|
||||
Exec['validate_keystone_connection'] -> Keystone_tenant<||>
|
||||
Exec['validate_keystone_connection'] -> Keystone_service<||>
|
||||
Exec['validate_keystone_connection'] -> Keystone_endpoint<||>
|
||||
}
|
||||
}
|
@ -46,15 +46,41 @@
|
||||
# Optional. Defaults to 1
|
||||
#
|
||||
# [*ssl_cert*]
|
||||
# (optional) Path to SSL certificate
|
||||
# Default to apache::vhost 'ssl_*' defaults.
|
||||
#
|
||||
# [*ssl_key*]
|
||||
# (optional) Path to SSL key
|
||||
# Default to apache::vhost 'ssl_*' defaults.
|
||||
#
|
||||
# [*ssl_chain*]
|
||||
# (optional) SSL chain
|
||||
# Default to apache::vhost 'ssl_*' defaults.
|
||||
#
|
||||
# [*ssl_ca*]
|
||||
# (optional) Path to SSL certificate authority
|
||||
# Default to apache::vhost 'ssl_*' defaults.
|
||||
#
|
||||
# [*ssl_crl_path*]
|
||||
# (optional) Path to SSL certificate revocation list
|
||||
# Default to apache::vhost 'ssl_*' defaults.
|
||||
#
|
||||
# [*ssl_crl*]
|
||||
# (optional) SSL certificate revocation list name
|
||||
# Default to apache::vhost 'ssl_*' defaults.
|
||||
#
|
||||
# [*ssl_certs_dir*]
|
||||
# apache::vhost ssl parameters.
|
||||
# Optional. Default to apache::vhost 'ssl_*' defaults.
|
||||
#
|
||||
# [*priority*]
|
||||
# (optional) The priority for the vhost.
|
||||
# Defaults to '10'
|
||||
#
|
||||
# [*threads*]
|
||||
# (optional) The number of threads for the vhost.
|
||||
# Defaults to $::processorcount
|
||||
#
|
||||
# == Dependencies
|
||||
#
|
||||
# requires Class['apache'] & Class['keystone']
|
||||
@ -72,41 +98,40 @@
|
||||
#
|
||||
# == Authors
|
||||
#
|
||||
# François Charlier <francois.charlier@enovance.com>
|
||||
# Francois Charlier <francois.charlier@enovance.com>
|
||||
#
|
||||
# == Copyright
|
||||
#
|
||||
# Copyright 2013 eNovance <licensing@enovance.com>
|
||||
#
|
||||
class keystone::wsgi::apache (
|
||||
$servername = $::fqdn,
|
||||
$public_port = 5000,
|
||||
$admin_port = 35357,
|
||||
$bind_host = undef,
|
||||
$public_path = '/',
|
||||
$admin_path = '/',
|
||||
$ssl = true,
|
||||
$workers = 1,
|
||||
$ssl_cert = undef,
|
||||
$ssl_key = undef,
|
||||
$ssl_chain = undef,
|
||||
$ssl_ca = undef,
|
||||
$ssl_crl_path = undef,
|
||||
$ssl_crl = undef,
|
||||
$ssl_certs_dir = undef,
|
||||
$threads = $::processorcount,
|
||||
$priority = '10',
|
||||
$wsgi_script_ensure = 'file',
|
||||
$wsgi_script_source = undef,
|
||||
$servername = $::fqdn,
|
||||
$public_port = 5000,
|
||||
$admin_port = 35357,
|
||||
$bind_host = undef,
|
||||
$public_path = '/',
|
||||
$admin_path = '/',
|
||||
$ssl = true,
|
||||
$workers = 1,
|
||||
$ssl_cert = undef,
|
||||
$ssl_key = undef,
|
||||
$ssl_chain = undef,
|
||||
$ssl_ca = undef,
|
||||
$ssl_crl_path = undef,
|
||||
$ssl_crl = undef,
|
||||
$ssl_certs_dir = undef,
|
||||
$threads = $::processorcount,
|
||||
$priority = '10',
|
||||
) {
|
||||
|
||||
include keystone::params
|
||||
include ::keystone::params
|
||||
include ::apache
|
||||
include ::apache::mod::wsgi
|
||||
include keystone::db::sync
|
||||
if $ssl {
|
||||
include ::apache::mod::ssl
|
||||
}
|
||||
|
||||
Exec <| title == 'keystone-manage pki_setup' |> ~> Service['httpd']
|
||||
Exec <| title == 'keystone-manage db_sync' |> ~> Service['httpd']
|
||||
Package['keystone'] -> Package['httpd']
|
||||
Package['keystone'] ~> Service['httpd']
|
||||
Keystone_config <| |> ~> Service['httpd']
|
||||
Service['httpd'] -> Keystone_endpoint <| |>
|
||||
@ -134,41 +159,44 @@ class keystone::wsgi::apache (
|
||||
require => Package['httpd'],
|
||||
}
|
||||
|
||||
$wsgi_files = {
|
||||
'keystone_wsgi_admin' => {
|
||||
'path' => "${::keystone::params::keystone_wsgi_script_path}/admin",
|
||||
},
|
||||
'keystone_wsgi_main' => {
|
||||
'path' => "${::keystone::params::keystone_wsgi_script_path}/main",
|
||||
},
|
||||
file { 'keystone_wsgi_admin':
|
||||
ensure => file,
|
||||
path => "${::keystone::params::keystone_wsgi_script_path}/admin",
|
||||
source => $::keystone::params::keystone_wsgi_script_source,
|
||||
owner => 'keystone',
|
||||
group => 'keystone',
|
||||
mode => '0644',
|
||||
# source file provided by keystone package
|
||||
require => [File[$::keystone::params::keystone_wsgi_script_path], Package['keystone']],
|
||||
}
|
||||
|
||||
$wsgi_file_defaults = {
|
||||
'ensure' => $wsgi_script_ensure,
|
||||
'owner' => 'keystone',
|
||||
'group' => 'keystone',
|
||||
'mode' => '0644',
|
||||
'require' => File[$::keystone::params::keystone_wsgi_script_path],
|
||||
file { 'keystone_wsgi_main':
|
||||
ensure => file,
|
||||
path => "${::keystone::params::keystone_wsgi_script_path}/main",
|
||||
source => $::keystone::params::keystone_wsgi_script_source,
|
||||
owner => 'keystone',
|
||||
group => 'keystone',
|
||||
mode => '0644',
|
||||
# source file provided by keystone package
|
||||
require => [File[$::keystone::params::keystone_wsgi_script_path], Package['keystone']],
|
||||
}
|
||||
|
||||
$wsgi_script_source_real = $wsgi_script_source ? {
|
||||
default => $wsgi_script_source,
|
||||
undef => $::keystone::params::keystone_wsgi_script_source,
|
||||
$wsgi_daemon_process_options_main = {
|
||||
user => 'keystone',
|
||||
group => 'keystone',
|
||||
processes => $workers,
|
||||
threads => $threads,
|
||||
display-name => 'keystone-main',
|
||||
}
|
||||
|
||||
case $wsgi_script_ensure {
|
||||
default: { $wsgi_file_source = { 'source' => $wsgi_script_source_real } }
|
||||
'link': { $wsgi_file_source = { 'target' => $wsgi_script_source_real } }
|
||||
$wsgi_daemon_process_options_admin = {
|
||||
user => 'keystone',
|
||||
group => 'keystone',
|
||||
processes => $workers,
|
||||
threads => $threads,
|
||||
display-name => 'keystone-admin',
|
||||
}
|
||||
|
||||
create_resources('file', $wsgi_files, merge($wsgi_file_defaults, $wsgi_file_source))
|
||||
|
||||
$wsgi_daemon_process_options = {
|
||||
user => 'keystone',
|
||||
group => 'keystone',
|
||||
processes => $workers,
|
||||
threads => $threads
|
||||
}
|
||||
$wsgi_script_aliases_main = hash([$public_path_real,"${::keystone::params::keystone_wsgi_script_path}/main"])
|
||||
$wsgi_script_aliases_admin = hash([$admin_path_real, "${::keystone::params::keystone_wsgi_script_path}/admin"])
|
||||
|
||||
@ -178,7 +206,8 @@ class keystone::wsgi::apache (
|
||||
$wsgi_script_aliases_main_real = $wsgi_script_aliases_main
|
||||
}
|
||||
|
||||
apache::vhost { 'keystone_wsgi_main':
|
||||
::apache::vhost { 'keystone_wsgi_main':
|
||||
ensure => 'present',
|
||||
servername => $servername,
|
||||
ip => $bind_host,
|
||||
port => $public_port,
|
||||
@ -195,14 +224,15 @@ class keystone::wsgi::apache (
|
||||
ssl_crl => $ssl_crl,
|
||||
ssl_certs_dir => $ssl_certs_dir,
|
||||
wsgi_daemon_process => 'keystone_main',
|
||||
wsgi_daemon_process_options => $wsgi_daemon_process_options,
|
||||
wsgi_daemon_process_options => $wsgi_daemon_process_options_main,
|
||||
wsgi_process_group => 'keystone_main',
|
||||
wsgi_script_aliases => $wsgi_script_aliases_main_real,
|
||||
require => [Class['apache::mod::wsgi'], File['keystone_wsgi_main']],
|
||||
require => File['keystone_wsgi_main'],
|
||||
}
|
||||
|
||||
if $public_port != $admin_port {
|
||||
apache::vhost { 'keystone_wsgi_admin':
|
||||
::apache::vhost { 'keystone_wsgi_admin':
|
||||
ensure => 'present',
|
||||
servername => $servername,
|
||||
ip => $bind_host,
|
||||
port => $admin_port,
|
||||
@ -219,10 +249,10 @@ class keystone::wsgi::apache (
|
||||
ssl_crl => $ssl_crl,
|
||||
ssl_certs_dir => $ssl_certs_dir,
|
||||
wsgi_daemon_process => 'keystone_admin',
|
||||
wsgi_daemon_process_options => $wsgi_daemon_process_options,
|
||||
wsgi_daemon_process_options => $wsgi_daemon_process_options_admin,
|
||||
wsgi_process_group => 'keystone_admin',
|
||||
wsgi_script_aliases => $wsgi_script_aliases_admin,
|
||||
require => [Class['apache::mod::wsgi'], File['keystone_wsgi_admin']],
|
||||
require => File['keystone_wsgi_admin'],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
39
deployment/puppet/keystone/metadata.json
Normal file
39
deployment/puppet/keystone/metadata.json
Normal file
@ -0,0 +1,39 @@
|
||||
{
|
||||
"name": "stackforge-keystone",
|
||||
"version": "5.1.0",
|
||||
"author": "Puppet Labs and OpenStack Contributors",
|
||||
"summary": "Puppet module for OpenStack Keystone",
|
||||
"license": "Apache-2.0",
|
||||
"source": "git://github.com/openstack/puppet-keystone.git",
|
||||
"project_page": "https://launchpad.net/puppet-keystone",
|
||||
"issues_url": "https://bugs.launchpad.net/puppet-keystone",
|
||||
"requirements": [
|
||||
{ "name": "pe","version_requirement": "3.x" },
|
||||
{ "name": "puppet","version_requirement": "3.x" }
|
||||
],
|
||||
"operatingsystem_support": [
|
||||
{
|
||||
"operatingsystem": "Debian",
|
||||
"operatingsystemrelease": ["7"]
|
||||
},
|
||||
{
|
||||
"operatingsystem": "Fedora",
|
||||
"operatingsystemrelease": ["20"]
|
||||
},
|
||||
{
|
||||
"operatingsystem": "RedHat",
|
||||
"operatingsystemrelease": ["6.5","7"]
|
||||
},
|
||||
{
|
||||
"operatingsystem": "Ubuntu",
|
||||
"operatingsystemrelease": ["12.04","14.04"]
|
||||
}
|
||||
],
|
||||
"description": "Installs and configures OpenStack Keystone (Identity).",
|
||||
"dependencies": [
|
||||
{ "name": "puppetlabs/apache", "version_requirement": ">=1.0.0 <2.0.0" },
|
||||
{ "name": "puppetlabs/inifile", "version_requirement": ">=1.0.0 <2.0.0" },
|
||||
{ "name": "puppetlabs/stdlib", "version_requirement": ">=4.0.0 <5.0.0" },
|
||||
{ "name": "stackforge/openstacklib", "version_requirement": ">=5.0.0 <6.0.0" }
|
||||
]
|
||||
}
|
@ -0,0 +1,92 @@
|
||||
require 'spec_helper_acceptance'
|
||||
|
||||
describe 'basic keystone server with resources' do
|
||||
|
||||
context 'default parameters' do
|
||||
|
||||
it 'should work with no errors' do
|
||||
pp= <<-EOS
|
||||
Exec { logoutput => 'on_failure' }
|
||||
|
||||
# Common resources
|
||||
case $::osfamily {
|
||||
'Debian': {
|
||||
include ::apt
|
||||
class { '::openstack_extras::repo::debian::ubuntu':
|
||||
release => 'kilo',
|
||||
package_require => true,
|
||||
}
|
||||
}
|
||||
'RedHat': {
|
||||
class { '::openstack_extras::repo::redhat::redhat':
|
||||
# Kilo is not GA yet, so let's use the testing repo
|
||||
manage_rdo => false,
|
||||
repo_hash => {
|
||||
'rdo-kilo-testing' => {
|
||||
'baseurl' => 'https://repos.fedorapeople.org/repos/openstack/openstack-kilo/testing/el7/',
|
||||
# packages are not GA so not signed
|
||||
'gpgcheck' => '0',
|
||||
'priority' => 97,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
default: {
|
||||
fail("Unsupported osfamily (${::osfamily})")
|
||||
}
|
||||
}
|
||||
|
||||
class { '::mysql::server': }
|
||||
|
||||
# Keystone resources
|
||||
class { '::keystone::client': }
|
||||
class { '::keystone::cron::token_flush': }
|
||||
class { '::keystone::db::mysql':
|
||||
password => 'keystone',
|
||||
}
|
||||
class { '::keystone':
|
||||
verbose => true,
|
||||
debug => true,
|
||||
database_connection => 'mysql://keystone:keystone@127.0.0.1/keystone',
|
||||
admin_token => 'admin_token',
|
||||
enabled => true,
|
||||
}
|
||||
class { '::keystone::roles::admin':
|
||||
email => 'test@example.tld',
|
||||
password => 'a_big_secret',
|
||||
}
|
||||
class { '::keystone::endpoint':
|
||||
public_url => "https://${::fqdn}:5000/",
|
||||
admin_url => "https://${::fqdn}:35357/",
|
||||
}
|
||||
::keystone::resource::service_identity { 'beaker-ci':
|
||||
service_type => 'beaker',
|
||||
service_description => 'beaker service',
|
||||
service_name => 'beaker',
|
||||
password => 'secret',
|
||||
public_url => 'http://127.0.0.1:1234',
|
||||
admin_url => 'http://127.0.0.1:1234',
|
||||
internal_url => 'http://127.0.0.1:1234',
|
||||
}
|
||||
EOS
|
||||
|
||||
|
||||
# Run it twice and test for idempotency
|
||||
apply_manifest(pp, :catch_failures => true)
|
||||
apply_manifest(pp, :catch_changes => true)
|
||||
end
|
||||
|
||||
describe port(5000) do
|
||||
it { is_expected.to be_listening.with('tcp') }
|
||||
end
|
||||
|
||||
describe port(35357) do
|
||||
it { is_expected.to be_listening.with('tcp') }
|
||||
end
|
||||
|
||||
describe cron do
|
||||
it { should have_entry('1 0 * * * keystone-manage token_flush >>/var/log/keystone/keystone-tokenflush.log 2>&1').with_user('keystone') }
|
||||
end
|
||||
|
||||
end
|
||||
end
|
@ -0,0 +1,9 @@
|
||||
HOSTS:
|
||||
ubuntu-14.04-amd64:
|
||||
roles:
|
||||
- master
|
||||
platform: ubuntu-14.04-amd64
|
||||
hypervisor : none
|
||||
ip: 127.0.0.1
|
||||
CONFIG:
|
||||
type: foss
|
@ -0,0 +1,10 @@
|
||||
HOSTS:
|
||||
centos-70-x64:
|
||||
roles:
|
||||
- master
|
||||
platform: el-7-x86_64
|
||||
hypervisor : none
|
||||
ip: 127.0.0.1
|
||||
CONFIG:
|
||||
type: foss
|
||||
set_env: false
|
@ -0,0 +1,10 @@
|
||||
HOSTS:
|
||||
ubuntu-14.04-amd64:
|
||||
roles:
|
||||
- master
|
||||
platform: ubuntu-14.04-amd64
|
||||
hypervisor : none
|
||||
ip: 127.0.0.1
|
||||
CONFIG:
|
||||
type: foss
|
||||
set_env: false
|
@ -3,7 +3,10 @@ require 'spec_helper'
|
||||
describe 'keystone::client' do
|
||||
|
||||
describe "with default parameters" do
|
||||
it { should contain_package('python-keystoneclient').with_ensure('present') }
|
||||
it { is_expected.to contain_package('python-keystoneclient').with(
|
||||
'ensure' => 'present',
|
||||
'tag' => 'openstack'
|
||||
) }
|
||||
end
|
||||
|
||||
describe "with specified version" do
|
||||
@ -11,6 +14,9 @@ describe 'keystone::client' do
|
||||
{:ensure => '2013.1'}
|
||||
end
|
||||
|
||||
it { should contain_package('python-keystoneclient').with_ensure('2013.1') }
|
||||
it { is_expected.to contain_package('python-keystoneclient').with(
|
||||
'ensure' => '2013.1',
|
||||
'tag' => 'openstack'
|
||||
) }
|
||||
end
|
||||
end
|
||||
|
@ -0,0 +1,68 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe 'keystone::cron::token_flush' do
|
||||
|
||||
let :facts do
|
||||
{ :osfamily => 'Debian' }
|
||||
end
|
||||
|
||||
describe 'with default parameters' do
|
||||
it 'configures a cron' do
|
||||
is_expected.to contain_cron('keystone-manage token_flush').with(
|
||||
:ensure => 'present',
|
||||
:command => 'keystone-manage token_flush >>/var/log/keystone/keystone-tokenflush.log 2>&1',
|
||||
:environment => 'PATH=/bin:/usr/bin:/usr/sbin SHELL=/bin/sh',
|
||||
:user => 'keystone',
|
||||
:minute => 1,
|
||||
:hour => 0,
|
||||
:monthday => '*',
|
||||
:month => '*',
|
||||
:weekday => '*'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'when specifying a maxdelay param' do
|
||||
let :params do
|
||||
{
|
||||
:maxdelay => 600
|
||||
}
|
||||
end
|
||||
|
||||
it 'configures a cron with delay' do
|
||||
is_expected.to contain_cron('keystone-manage token_flush').with(
|
||||
:ensure => 'present',
|
||||
:command => 'sleep `expr ${RANDOM} \\% 600`; keystone-manage token_flush >>/var/log/keystone/keystone-tokenflush.log 2>&1',
|
||||
:environment => 'PATH=/bin:/usr/bin:/usr/sbin SHELL=/bin/sh',
|
||||
:user => 'keystone',
|
||||
:minute => 1,
|
||||
:hour => 0,
|
||||
:monthday => '*',
|
||||
:month => '*',
|
||||
:weekday => '*'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'when specifying a maxdelay param' do
|
||||
let :params do
|
||||
{
|
||||
:ensure => 'absent'
|
||||
}
|
||||
end
|
||||
|
||||
it 'configures a cron with delay' do
|
||||
is_expected.to contain_cron('keystone-manage token_flush').with(
|
||||
:ensure => 'absent',
|
||||
:command => 'keystone-manage token_flush >>/var/log/keystone/keystone-tokenflush.log 2>&1',
|
||||
:environment => 'PATH=/bin:/usr/bin:/usr/sbin SHELL=/bin/sh',
|
||||
:user => 'keystone',
|
||||
:minute => 1,
|
||||
:hour => 0,
|
||||
:monthday => '*',
|
||||
:month => '*',
|
||||
:weekday => '*'
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
@ -13,48 +13,23 @@ describe 'keystone::db::mysql' do
|
||||
{ :osfamily => 'Debian' }
|
||||
end
|
||||
|
||||
let :param_defaults do
|
||||
let :params do
|
||||
{
|
||||
'password' => 'keystone_default_password',
|
||||
'dbname' => 'keystone',
|
||||
}
|
||||
end
|
||||
|
||||
describe 'with only required params' do
|
||||
it { is_expected.to contain_openstacklib__db__mysql('keystone').with(
|
||||
'user' => 'keystone',
|
||||
'charset' => 'utf8',
|
||||
'collate' => 'utf8_unicode_ci',
|
||||
'password_hash' => '*B552157B14BCEDDCEAA06767A012F31BDAA9CE3D',
|
||||
'dbname' => 'keystone',
|
||||
'host' => '127.0.0.1',
|
||||
'allowed_hosts' => ['127.0.0.%', '192.168.1.%']
|
||||
}
|
||||
end
|
||||
|
||||
[
|
||||
{},
|
||||
{
|
||||
'password' => 'password',
|
||||
'dbname' => 'not_keystone',
|
||||
'user' => 'dan',
|
||||
'host' => '127.0.0.2',
|
||||
'charset' => 'utf8'
|
||||
}
|
||||
].each do |p|
|
||||
|
||||
let :params do
|
||||
p
|
||||
end
|
||||
|
||||
let :param_values do
|
||||
param_defaults.merge(p)
|
||||
end
|
||||
|
||||
it { should contain_class('mysql::python') }
|
||||
|
||||
it { should contain_mysql__db(param_values['dbname']).with(
|
||||
'user' => param_values['user'],
|
||||
'password' => param_values['password'],
|
||||
'host' => param_values['host'],
|
||||
'charset' => param_values['charset'],
|
||||
'require' => 'Class[Mysql::Config]'
|
||||
'charset' => 'utf8',
|
||||
:collate => 'utf8_general_ci',
|
||||
)}
|
||||
|
||||
end
|
||||
|
||||
describe "overriding allowed_hosts param to array" do
|
||||
let :params do
|
||||
{
|
||||
@ -63,16 +38,6 @@ describe 'keystone::db::mysql' do
|
||||
}
|
||||
end
|
||||
|
||||
it {should_not contain_keystone__db__mysql__host_access("127.0.0.1").with(
|
||||
:user => 'keystone',
|
||||
:password => 'keystonepass',
|
||||
:database => 'keystone'
|
||||
)}
|
||||
it {should contain_keystone__db__mysql__host_access("%").with(
|
||||
:user => 'keystone',
|
||||
:password => 'keystonepass',
|
||||
:database => 'keystone'
|
||||
)}
|
||||
end
|
||||
describe "overriding allowed_hosts param to string" do
|
||||
let :params do
|
||||
@ -82,11 +47,6 @@ describe 'keystone::db::mysql' do
|
||||
}
|
||||
end
|
||||
|
||||
it {should contain_keystone__db__mysql__host_access("192.168.1.1").with(
|
||||
:user => 'keystone',
|
||||
:password => 'keystonepass2',
|
||||
:database => 'keystone'
|
||||
)}
|
||||
end
|
||||
|
||||
describe "overriding allowed_hosts param equals to host param " do
|
||||
@ -97,11 +57,6 @@ describe 'keystone::db::mysql' do
|
||||
}
|
||||
end
|
||||
|
||||
it {should_not contain_keystone__db__mysql__host_access("127.0.0.1").with(
|
||||
:user => 'keystone',
|
||||
:password => 'keystonepass2',
|
||||
:database => 'keystone'
|
||||
)}
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -3,24 +3,56 @@ require 'spec_helper'
|
||||
describe 'keystone::db::postgresql' do
|
||||
|
||||
let :req_params do
|
||||
{:password => 'pw'}
|
||||
{ :password => 'pw' }
|
||||
end
|
||||
|
||||
let :facts do
|
||||
{
|
||||
:postgres_default_version => '8.4',
|
||||
:osfamily => 'RedHat',
|
||||
}
|
||||
let :pre_condition do
|
||||
'include postgresql::server'
|
||||
end
|
||||
|
||||
describe 'with only required params' do
|
||||
let :params do
|
||||
req_params
|
||||
context 'on a RedHat osfamily' do
|
||||
let :facts do
|
||||
{
|
||||
:osfamily => 'RedHat',
|
||||
:operatingsystemrelease => '7.0',
|
||||
:concat_basedir => '/var/lib/puppet/concat'
|
||||
}
|
||||
end
|
||||
it { should contain_postgresql__db('keystone').with(
|
||||
:user => 'keystone',
|
||||
:password => 'pw'
|
||||
) }
|
||||
|
||||
context 'with only required parameters' do
|
||||
let :params do
|
||||
req_params
|
||||
end
|
||||
|
||||
it { is_expected.to contain_postgresql__server__db('keystone').with(
|
||||
:user => 'keystone',
|
||||
:password => 'md5c530c33636c58ae83ca933f39319273e'
|
||||
)}
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context 'on a Debian osfamily' do
|
||||
let :facts do
|
||||
{
|
||||
:operatingsystemrelease => '7.8',
|
||||
:operatingsystem => 'Debian',
|
||||
:osfamily => 'Debian',
|
||||
:concat_basedir => '/var/lib/puppet/concat'
|
||||
}
|
||||
end
|
||||
|
||||
context 'with only required parameters' do
|
||||
let :params do
|
||||
req_params
|
||||
end
|
||||
|
||||
it { is_expected.to contain_postgresql__server__db('keystone').with(
|
||||
:user => 'keystone',
|
||||
:password => 'md5c530c33636c58ae83ca933f39319273e'
|
||||
)}
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -2,14 +2,14 @@ require 'spec_helper'
|
||||
|
||||
describe 'keystone::endpoint' do
|
||||
|
||||
it { should contain_keystone_service('keystone').with(
|
||||
it { is_expected.to contain_keystone_service('keystone').with(
|
||||
:ensure => 'present',
|
||||
:type => 'identity',
|
||||
:description => 'OpenStack Identity Service'
|
||||
)}
|
||||
|
||||
describe 'with default parameters' do
|
||||
it { should contain_keystone_endpoint('RegionOne/keystone').with(
|
||||
it { is_expected.to contain_keystone_endpoint('RegionOne/keystone').with(
|
||||
:ensure => 'present',
|
||||
:public_url => 'http://127.0.0.1:5000/v2.0',
|
||||
:admin_url => 'http://127.0.0.1:35357/v2.0',
|
||||
@ -26,7 +26,7 @@ describe 'keystone::endpoint' do
|
||||
:internal_url => 'https://identity-int.some.tld/some/internal/endpoint' }
|
||||
end
|
||||
|
||||
it { should contain_keystone_endpoint('RegionOne/keystone').with(
|
||||
it { is_expected.to contain_keystone_endpoint('RegionOne/keystone').with(
|
||||
:ensure => 'present',
|
||||
:public_url => 'https://identity.some.tld/the/main/endpoint/v42.6',
|
||||
:admin_url => 'https://identity-int.some.tld/some/admin/endpoint/v42.6',
|
||||
@ -41,59 +41,11 @@ describe 'keystone::endpoint' do
|
||||
end
|
||||
|
||||
it 'internal_url should default to public_url' do
|
||||
should contain_keystone_endpoint('RegionOne/keystone').with(
|
||||
is_expected.to contain_keystone_endpoint('RegionOne/keystone').with(
|
||||
:ensure => 'present',
|
||||
:public_url => 'https://identity.some.tld/the/main/endpoint/v2.0',
|
||||
:internal_url => 'https://identity.some.tld/the/main/endpoint/v2.0'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'with deprecated parameters' do
|
||||
|
||||
let :params do
|
||||
{ :public_address => '10.0.0.1',
|
||||
:admin_address => '10.0.0.2',
|
||||
:internal_address => '10.0.0.3',
|
||||
:public_port => '23456',
|
||||
:admin_port => '12345',
|
||||
:region => 'RegionTwo',
|
||||
:version => 'v3.0' }
|
||||
end
|
||||
|
||||
it { should contain_keystone_endpoint('RegionTwo/keystone').with(
|
||||
:ensure => 'present',
|
||||
:public_url => 'http://10.0.0.1:23456/v3.0',
|
||||
:admin_url => 'http://10.0.0.2:12345/v3.0',
|
||||
:internal_url => 'http://10.0.0.3:23456/v3.0'
|
||||
)}
|
||||
|
||||
describe 'public_address overrides public_url' do
|
||||
let :params do
|
||||
{ :public_address => '10.0.0.1',
|
||||
:public_port => '12345',
|
||||
:public_url => 'http://10.10.10.10:23456/v3.0' }
|
||||
end
|
||||
|
||||
it { should contain_keystone_endpoint('RegionOne/keystone').with(
|
||||
:ensure => 'present',
|
||||
:public_url => 'http://10.0.0.1:12345/v2.0'
|
||||
)}
|
||||
end
|
||||
end
|
||||
|
||||
describe 'with overridden deprecated internal_port' do
|
||||
|
||||
let :params do
|
||||
{ :internal_port => '12345' }
|
||||
end
|
||||
|
||||
it { should contain_keystone_endpoint('RegionOne/keystone').with(
|
||||
:ensure => 'present',
|
||||
:public_url => 'http://127.0.0.1:5000/v2.0',
|
||||
:admin_url => 'http://127.0.0.1:35357/v2.0',
|
||||
:internal_url => 'http://127.0.0.1:12345/v2.0'
|
||||
)}
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -2,7 +2,7 @@ require 'spec_helper'
|
||||
|
||||
describe 'keystone::ldap' do
|
||||
describe 'with basic params' do
|
||||
let :params do
|
||||
let :params do
|
||||
{
|
||||
:url => 'ldap://foo',
|
||||
:user => 'cn=foo,dc=example,dc=com',
|
||||
@ -19,6 +19,7 @@ describe 'keystone::ldap' do
|
||||
:user_enabled_attribute => 'UserAccountControl',
|
||||
:user_enabled_mask => '2',
|
||||
:user_enabled_default => '512',
|
||||
:user_enabled_invert => 'False',
|
||||
:user_attribute_ignore => '',
|
||||
:user_default_project_id_attribute => 'defaultProject',
|
||||
:user_allow_create => 'False',
|
||||
@ -28,22 +29,22 @@ describe 'keystone::ldap' do
|
||||
:user_enabled_emulation => 'True',
|
||||
:user_enabled_emulation_dn => 'cn=openstack-enabled,cn=groups,cn=accounts,dc=example,dc=com',
|
||||
:user_additional_attribute_mapping => 'description:name, gecos:name',
|
||||
:tenant_tree_dn => 'ou=projects,ou=openstack,dc=example,dc=com',
|
||||
:tenant_filter => '',
|
||||
:tenant_objectclass => 'organizationalUnit',
|
||||
:tenant_id_attribute => 'ou',
|
||||
:tenant_member_attribute => 'member',
|
||||
:tenant_desc_attribute => 'description',
|
||||
:tenant_name_attribute => 'ou',
|
||||
:tenant_enabled_attribute => 'enabled',
|
||||
:tenant_domain_id_attribute => 'businessCategory',
|
||||
:tenant_attribute_ignore => '',
|
||||
:tenant_allow_create => 'True',
|
||||
:tenant_allow_update => 'True',
|
||||
:tenant_allow_delete => 'True',
|
||||
:tenant_enabled_emulation => 'False',
|
||||
:tenant_enabled_emulation_dn => 'True',
|
||||
:tenant_additional_attribute_mapping => 'cn=enabled,ou=openstack,dc=example,dc=com',
|
||||
:project_tree_dn => 'ou=projects,ou=openstack,dc=example,dc=com',
|
||||
:project_filter => '',
|
||||
:project_objectclass => 'organizationalUnit',
|
||||
:project_id_attribute => 'ou',
|
||||
:project_member_attribute => 'member',
|
||||
:project_desc_attribute => 'description',
|
||||
:project_name_attribute => 'ou',
|
||||
:project_enabled_attribute => 'enabled',
|
||||
:project_domain_id_attribute => 'businessCategory',
|
||||
:project_attribute_ignore => '',
|
||||
:project_allow_create => 'True',
|
||||
:project_allow_update => 'True',
|
||||
:project_allow_delete => 'True',
|
||||
:project_enabled_emulation => 'False',
|
||||
:project_enabled_emulation_dn => 'True',
|
||||
:project_additional_attribute_mapping => 'cn=enabled,ou=openstack,dc=example,dc=com',
|
||||
:role_tree_dn => 'ou=roles,ou=openstack,dc=example,dc=com',
|
||||
:role_filter => '',
|
||||
:role_objectclass => 'organizationalRole',
|
||||
@ -72,85 +73,170 @@ describe 'keystone::ldap' do
|
||||
:tls_cacertfile => '/etc/ssl/certs/ca-certificates.crt',
|
||||
:tls_req_cert => 'demand',
|
||||
:identity_driver => 'keystone.identity.backends.ldap.Identity',
|
||||
:credential_driver => 'keystone.credential.backends.ldap.Credential',
|
||||
:assignment_driver => 'keystone.assignment.backends.ldap.Assignment',
|
||||
:use_pool => 'True',
|
||||
:pool_size => 20,
|
||||
:pool_retry_max => 2,
|
||||
:pool_retry_delay => 0.2,
|
||||
:pool_connection_timeout => 222,
|
||||
:pool_connection_lifetime => 222,
|
||||
:use_auth_pool => 'True',
|
||||
:auth_pool_size => 20,
|
||||
:auth_pool_connection_lifetime => 200,
|
||||
}
|
||||
end
|
||||
it { should contain_package('python-ldap') }
|
||||
it { is_expected.to contain_package('python-ldap') }
|
||||
it { is_expected.to contain_package('python-ldappool') }
|
||||
it 'should have basic params' do
|
||||
should contain_keystone_config('ldap/url').with_value('ldap://foo')
|
||||
should contain_keystone_config('ldap/user').with_value('cn=foo,dc=example,dc=com')
|
||||
should contain_keystone_config('ldap/password').with_value('abcdefg').with_secret(true)
|
||||
should contain_keystone_config('ldap/suffix').with_value('dc=example,dc=com')
|
||||
should contain_keystone_config('ldap/query_scope').with_value('sub')
|
||||
should contain_keystone_config('ldap/page_size').with_value('50')
|
||||
# basic params
|
||||
is_expected.to contain_keystone_config('ldap/url').with_value('ldap://foo')
|
||||
is_expected.to contain_keystone_config('ldap/user').with_value('cn=foo,dc=example,dc=com')
|
||||
is_expected.to contain_keystone_config('ldap/password').with_value('abcdefg').with_secret(true)
|
||||
is_expected.to contain_keystone_config('ldap/suffix').with_value('dc=example,dc=com')
|
||||
is_expected.to contain_keystone_config('ldap/query_scope').with_value('sub')
|
||||
is_expected.to contain_keystone_config('ldap/page_size').with_value('50')
|
||||
|
||||
should contain_keystone_config('ldap/user_tree_dn').with_value('cn=users,dc=example,dc=com')
|
||||
should contain_keystone_config('ldap/user_filter').with_value('(memberOf=cn=openstack,cn=groups,cn=accounts,dc=example,dc=com)')
|
||||
should contain_keystone_config('ldap/user_objectclass').with_value('inetUser')
|
||||
should contain_keystone_config('ldap/user_id_attribute').with_value('uid')
|
||||
should contain_keystone_config('ldap/user_name_attribute').with_value('cn')
|
||||
should contain_keystone_config('ldap/user_mail_attribute').with_value('mail')
|
||||
should contain_keystone_config('ldap/user_enabled_attribute').with_value('UserAccountControl')
|
||||
should contain_keystone_config('ldap/user_enabled_mask').with_value('2')
|
||||
should contain_keystone_config('ldap/user_enabled_default').with_value('512')
|
||||
should contain_keystone_config('ldap/user_attribute_ignore').with_value('')
|
||||
should contain_keystone_config('ldap/user_default_project_id_attribute').with_value('defaultProject')
|
||||
should contain_keystone_config('ldap/user_tree_dn').with_value('cn=users,dc=example,dc=com')
|
||||
should contain_keystone_config('ldap/user_allow_create').with_value('False')
|
||||
should contain_keystone_config('ldap/user_allow_update').with_value('False')
|
||||
should contain_keystone_config('ldap/user_allow_delete').with_value('False')
|
||||
should contain_keystone_config('ldap/user_pass_attribute').with_value('krbPassword')
|
||||
should contain_keystone_config('ldap/user_enabled_emulation').with_value('True')
|
||||
should contain_keystone_config('ldap/user_enabled_emulation_dn').with_value('cn=openstack-enabled,cn=groups,cn=accounts,dc=example,dc=com')
|
||||
should contain_keystone_config('ldap/user_additional_attribute_mapping').with_value('description:name, gecos:name')
|
||||
# users
|
||||
is_expected.to contain_keystone_config('ldap/user_tree_dn').with_value('cn=users,dc=example,dc=com')
|
||||
is_expected.to contain_keystone_config('ldap/user_filter').with_value('(memberOf=cn=openstack,cn=groups,cn=accounts,dc=example,dc=com)')
|
||||
is_expected.to contain_keystone_config('ldap/user_objectclass').with_value('inetUser')
|
||||
is_expected.to contain_keystone_config('ldap/user_id_attribute').with_value('uid')
|
||||
is_expected.to contain_keystone_config('ldap/user_name_attribute').with_value('cn')
|
||||
is_expected.to contain_keystone_config('ldap/user_mail_attribute').with_value('mail')
|
||||
is_expected.to contain_keystone_config('ldap/user_enabled_attribute').with_value('UserAccountControl')
|
||||
is_expected.to contain_keystone_config('ldap/user_enabled_mask').with_value('2')
|
||||
is_expected.to contain_keystone_config('ldap/user_enabled_default').with_value('512')
|
||||
is_expected.to contain_keystone_config('ldap/user_enabled_invert').with_value('False')
|
||||
is_expected.to contain_keystone_config('ldap/user_attribute_ignore').with_value('')
|
||||
is_expected.to contain_keystone_config('ldap/user_default_project_id_attribute').with_value('defaultProject')
|
||||
is_expected.to contain_keystone_config('ldap/user_tree_dn').with_value('cn=users,dc=example,dc=com')
|
||||
is_expected.to contain_keystone_config('ldap/user_allow_create').with_value('False')
|
||||
is_expected.to contain_keystone_config('ldap/user_allow_update').with_value('False')
|
||||
is_expected.to contain_keystone_config('ldap/user_allow_delete').with_value('False')
|
||||
is_expected.to contain_keystone_config('ldap/user_pass_attribute').with_value('krbPassword')
|
||||
is_expected.to contain_keystone_config('ldap/user_enabled_emulation').with_value('True')
|
||||
is_expected.to contain_keystone_config('ldap/user_enabled_emulation_dn').with_value('cn=openstack-enabled,cn=groups,cn=accounts,dc=example,dc=com')
|
||||
is_expected.to contain_keystone_config('ldap/user_additional_attribute_mapping').with_value('description:name, gecos:name')
|
||||
|
||||
should contain_keystone_config('ldap/tenant_tree_dn').with_value('ou=projects,ou=openstack,dc=example,dc=com')
|
||||
should contain_keystone_config('ldap/tenant_filter').with_value('')
|
||||
should contain_keystone_config('ldap/tenant_objectclass').with_value('organizationalUnit')
|
||||
should contain_keystone_config('ldap/tenant_id_attribute').with_value('ou')
|
||||
should contain_keystone_config('ldap/tenant_member_attribute').with_value('member')
|
||||
should contain_keystone_config('ldap/tenant_desc_attribute').with_value('description')
|
||||
should contain_keystone_config('ldap/tenant_name_attribute').with_value('ou')
|
||||
should contain_keystone_config('ldap/tenant_enabled_attribute').with_value('enabled')
|
||||
should contain_keystone_config('ldap/tenant_domain_id_attribute').with_value('businessCategory')
|
||||
should contain_keystone_config('ldap/tenant_attribute_ignore').with_value('')
|
||||
should contain_keystone_config('ldap/tenant_allow_create').with_value('True')
|
||||
should contain_keystone_config('ldap/tenant_allow_update').with_value('True')
|
||||
should contain_keystone_config('ldap/tenant_allow_delete').with_value('True')
|
||||
should contain_keystone_config('ldap/tenant_enabled_emulation').with_value('False')
|
||||
should contain_keystone_config('ldap/tenant_enabled_emulation_dn').with_value('True')
|
||||
should contain_keystone_config('ldap/tenant_additional_attribute_mapping').with_value('cn=enabled,ou=openstack,dc=example,dc=com')
|
||||
should contain_keystone_config('ldap/role_tree_dn').with_value('ou=roles,ou=openstack,dc=example,dc=com')
|
||||
should contain_keystone_config('ldap/role_filter').with_value('')
|
||||
should contain_keystone_config('ldap/role_objectclass').with_value('organizationalRole')
|
||||
should contain_keystone_config('ldap/role_id_attribute').with_value('cn')
|
||||
should contain_keystone_config('ldap/role_name_attribute').with_value('ou')
|
||||
should contain_keystone_config('ldap/role_member_attribute').with_value('roleOccupant')
|
||||
should contain_keystone_config('ldap/role_attribute_ignore').with_value('description')
|
||||
should contain_keystone_config('ldap/role_allow_create').with_value('True')
|
||||
should contain_keystone_config('ldap/role_allow_update').with_value('True')
|
||||
should contain_keystone_config('ldap/role_allow_delete').with_value('True')
|
||||
should contain_keystone_config('ldap/role_additional_attribute_mapping').with_value('')
|
||||
# projects/tenants
|
||||
is_expected.to contain_keystone_config('ldap/project_tree_dn').with_value('ou=projects,ou=openstack,dc=example,dc=com')
|
||||
is_expected.to contain_keystone_config('ldap/project_filter').with_value('')
|
||||
is_expected.to contain_keystone_config('ldap/project_objectclass').with_value('organizationalUnit')
|
||||
is_expected.to contain_keystone_config('ldap/project_id_attribute').with_value('ou')
|
||||
is_expected.to contain_keystone_config('ldap/project_member_attribute').with_value('member')
|
||||
is_expected.to contain_keystone_config('ldap/project_desc_attribute').with_value('description')
|
||||
is_expected.to contain_keystone_config('ldap/project_name_attribute').with_value('ou')
|
||||
is_expected.to contain_keystone_config('ldap/project_enabled_attribute').with_value('enabled')
|
||||
is_expected.to contain_keystone_config('ldap/project_domain_id_attribute').with_value('businessCategory')
|
||||
is_expected.to contain_keystone_config('ldap/project_attribute_ignore').with_value('')
|
||||
is_expected.to contain_keystone_config('ldap/project_allow_create').with_value('True')
|
||||
is_expected.to contain_keystone_config('ldap/project_allow_update').with_value('True')
|
||||
is_expected.to contain_keystone_config('ldap/project_allow_delete').with_value('True')
|
||||
is_expected.to contain_keystone_config('ldap/project_enabled_emulation').with_value('False')
|
||||
is_expected.to contain_keystone_config('ldap/project_enabled_emulation_dn').with_value('True')
|
||||
is_expected.to contain_keystone_config('ldap/project_additional_attribute_mapping').with_value('cn=enabled,ou=openstack,dc=example,dc=com')
|
||||
|
||||
should contain_keystone_config('ldap/group_tree_dn').with_value('ou=groups,ou=openstack,dc=example,dc=com')
|
||||
should contain_keystone_config('ldap/group_filter').with_value('cn=enabled-groups,cn=groups,cn=accounts,dc=example,dc=com')
|
||||
should contain_keystone_config('ldap/group_objectclass').with_value('organizationalRole')
|
||||
should contain_keystone_config('ldap/group_id_attribute').with_value('cn')
|
||||
should contain_keystone_config('ldap/group_member_attribute').with_value('roleOccupant')
|
||||
should contain_keystone_config('ldap/group_desc_attribute').with_value('description')
|
||||
should contain_keystone_config('ldap/group_name_attribute').with_value('cn')
|
||||
should contain_keystone_config('ldap/group_attribute_ignore').with_value('')
|
||||
should contain_keystone_config('ldap/group_allow_create').with_value('False')
|
||||
should contain_keystone_config('ldap/group_allow_update').with_value('False')
|
||||
should contain_keystone_config('ldap/group_allow_delete').with_value('False')
|
||||
should contain_keystone_config('ldap/group_additional_attribute_mapping').with_value('')
|
||||
should contain_keystone_config('ldap/use_tls').with_value('False')
|
||||
should contain_keystone_config('ldap/tls_cacertdir').with_value('/etc/ssl/certs/')
|
||||
should contain_keystone_config('ldap/tls_cacertfile').with_value('/etc/ssl/certs/ca-certificates.crt')
|
||||
should contain_keystone_config('ldap/tls_req_cert').with_value('demand')
|
||||
should contain_keystone_config('identity/driver').with_value('keystone.identity.backends.ldap.Identity')
|
||||
should contain_keystone_config('assignment/driver').with_value('keystone.assignment.backends.ldap.Assignment')
|
||||
# roles
|
||||
is_expected.to contain_keystone_config('ldap/role_tree_dn').with_value('ou=roles,ou=openstack,dc=example,dc=com')
|
||||
is_expected.to contain_keystone_config('ldap/role_filter').with_value('')
|
||||
is_expected.to contain_keystone_config('ldap/role_objectclass').with_value('organizationalRole')
|
||||
is_expected.to contain_keystone_config('ldap/role_id_attribute').with_value('cn')
|
||||
is_expected.to contain_keystone_config('ldap/role_name_attribute').with_value('ou')
|
||||
is_expected.to contain_keystone_config('ldap/role_member_attribute').with_value('roleOccupant')
|
||||
is_expected.to contain_keystone_config('ldap/role_attribute_ignore').with_value('description')
|
||||
is_expected.to contain_keystone_config('ldap/role_allow_create').with_value('True')
|
||||
is_expected.to contain_keystone_config('ldap/role_allow_update').with_value('True')
|
||||
is_expected.to contain_keystone_config('ldap/role_allow_delete').with_value('True')
|
||||
is_expected.to contain_keystone_config('ldap/role_additional_attribute_mapping').with_value('')
|
||||
|
||||
# groups
|
||||
is_expected.to contain_keystone_config('ldap/group_tree_dn').with_value('ou=groups,ou=openstack,dc=example,dc=com')
|
||||
is_expected.to contain_keystone_config('ldap/group_filter').with_value('cn=enabled-groups,cn=groups,cn=accounts,dc=example,dc=com')
|
||||
is_expected.to contain_keystone_config('ldap/group_objectclass').with_value('organizationalRole')
|
||||
is_expected.to contain_keystone_config('ldap/group_id_attribute').with_value('cn')
|
||||
is_expected.to contain_keystone_config('ldap/group_member_attribute').with_value('roleOccupant')
|
||||
is_expected.to contain_keystone_config('ldap/group_desc_attribute').with_value('description')
|
||||
is_expected.to contain_keystone_config('ldap/group_name_attribute').with_value('cn')
|
||||
is_expected.to contain_keystone_config('ldap/group_attribute_ignore').with_value('')
|
||||
is_expected.to contain_keystone_config('ldap/group_allow_create').with_value('False')
|
||||
is_expected.to contain_keystone_config('ldap/group_allow_update').with_value('False')
|
||||
is_expected.to contain_keystone_config('ldap/group_allow_delete').with_value('False')
|
||||
is_expected.to contain_keystone_config('ldap/group_additional_attribute_mapping').with_value('')
|
||||
|
||||
# tls
|
||||
is_expected.to contain_keystone_config('ldap/use_tls').with_value('False')
|
||||
is_expected.to contain_keystone_config('ldap/tls_cacertdir').with_value('/etc/ssl/certs/')
|
||||
is_expected.to contain_keystone_config('ldap/tls_cacertfile').with_value('/etc/ssl/certs/ca-certificates.crt')
|
||||
is_expected.to contain_keystone_config('ldap/tls_req_cert').with_value('demand')
|
||||
|
||||
# ldap pooling
|
||||
is_expected.to contain_keystone_config('ldap/use_pool').with_value('True')
|
||||
is_expected.to contain_keystone_config('ldap/pool_size').with_value('20')
|
||||
is_expected.to contain_keystone_config('ldap/pool_retry_max').with_value('2')
|
||||
is_expected.to contain_keystone_config('ldap/pool_retry_delay').with_value('0.2')
|
||||
is_expected.to contain_keystone_config('ldap/pool_connection_timeout').with_value('222')
|
||||
is_expected.to contain_keystone_config('ldap/pool_connection_lifetime').with_value('222')
|
||||
is_expected.to contain_keystone_config('ldap/use_auth_pool').with_value('True')
|
||||
is_expected.to contain_keystone_config('ldap/auth_pool_size').with_value('20')
|
||||
is_expected.to contain_keystone_config('ldap/auth_pool_connection_lifetime').with_value('200')
|
||||
|
||||
# drivers
|
||||
is_expected.to contain_keystone_config('identity/driver').with_value('keystone.identity.backends.ldap.Identity')
|
||||
is_expected.to contain_keystone_config('credential/driver').with_value('keystone.credential.backends.ldap.Credential')
|
||||
is_expected.to contain_keystone_config('assignment/driver').with_value('keystone.assignment.backends.ldap.Assignment')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'with deprecated params' do
|
||||
let :params do
|
||||
{
|
||||
:tenant_tree_dn => 'ou=projects,ou=openstack,dc=example,dc=com',
|
||||
:tenant_filter => '',
|
||||
:tenant_objectclass => 'organizationalUnit',
|
||||
:tenant_id_attribute => 'ou',
|
||||
:tenant_member_attribute => 'member',
|
||||
:tenant_desc_attribute => 'description',
|
||||
:tenant_name_attribute => 'ou',
|
||||
:tenant_enabled_attribute => 'enabled',
|
||||
:tenant_domain_id_attribute => 'businessCategory',
|
||||
:tenant_attribute_ignore => '',
|
||||
:tenant_allow_create => 'True',
|
||||
:tenant_allow_update => 'True',
|
||||
:tenant_allow_delete => 'True',
|
||||
:tenant_enabled_emulation => 'False',
|
||||
:tenant_enabled_emulation_dn => 'True',
|
||||
:tenant_additional_attribute_mapping => 'cn=enabled,ou=openstack,dc=example,dc=com',
|
||||
}
|
||||
end
|
||||
it 'should work with deprecated params' do
|
||||
is_expected.to contain_keystone_config('ldap/project_tree_dn').with_value('ou=projects,ou=openstack,dc=example,dc=com')
|
||||
is_expected.to contain_keystone_config('ldap/project_filter')
|
||||
is_expected.to contain_keystone_config('ldap/project_objectclass').with_value('organizationalUnit')
|
||||
is_expected.to contain_keystone_config('ldap/project_id_attribute').with_value('ou')
|
||||
is_expected.to contain_keystone_config('ldap/project_member_attribute').with_value('member')
|
||||
is_expected.to contain_keystone_config('ldap/project_desc_attribute').with_value('description')
|
||||
is_expected.to contain_keystone_config('ldap/project_name_attribute').with_value('ou')
|
||||
is_expected.to contain_keystone_config('ldap/project_enabled_attribute').with_value('enabled')
|
||||
is_expected.to contain_keystone_config('ldap/project_domain_id_attribute').with_value('businessCategory')
|
||||
is_expected.to contain_keystone_config('ldap/project_attribute_ignore')
|
||||
is_expected.to contain_keystone_config('ldap/project_allow_create').with_value('True')
|
||||
is_expected.to contain_keystone_config('ldap/project_allow_update').with_value('True')
|
||||
is_expected.to contain_keystone_config('ldap/project_allow_delete').with_value('True')
|
||||
is_expected.to contain_keystone_config('ldap/project_enabled_emulation').with_value('False')
|
||||
is_expected.to contain_keystone_config('ldap/project_enabled_emulation_dn').with_value('True')
|
||||
is_expected.to contain_keystone_config('ldap/project_additional_attribute_mapping').with_value('cn=enabled,ou=openstack,dc=example,dc=com')
|
||||
end
|
||||
end
|
||||
|
||||
describe 'with deprecated and new params both set' do
|
||||
let :params do
|
||||
{
|
||||
:tenant_tree_dn => 'ou=projects,ou=old-openstack,dc=example,dc=com',
|
||||
:project_tree_dn => 'ou=projects,ou=new-openstack,dc=example,dc=com',
|
||||
}
|
||||
end
|
||||
|
||||
it_raises 'a Puppet::Error', /tenant_tree_dn and project_tree_dn are both set. results may be unexpected/
|
||||
end
|
||||
end
|
||||
|
107
deployment/puppet/keystone/spec/classes/keystone_logging_spec.rb
Normal file
107
deployment/puppet/keystone/spec/classes/keystone_logging_spec.rb
Normal file
@ -0,0 +1,107 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe 'keystone::logging' do
|
||||
|
||||
let :params do
|
||||
{
|
||||
}
|
||||
end
|
||||
|
||||
let :log_params do
|
||||
{
|
||||
:logging_context_format_string => '%(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s [%(request_id)s %(user_identity)s] %(instance)s%(message)s',
|
||||
:logging_default_format_string => '%(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s [-] %(instance)s%(message)s',
|
||||
:logging_debug_format_suffix => '%(funcName)s %(pathname)s:%(lineno)d',
|
||||
:logging_exception_prefix => '%(asctime)s.%(msecs)03d %(process)d TRACE %(name)s %(instance)s',
|
||||
:log_config_append => '/etc/keystone/logging.conf',
|
||||
:publish_errors => true,
|
||||
:default_log_levels => {
|
||||
'amqp' => 'WARN', 'amqplib' => 'WARN', 'boto' => 'WARN',
|
||||
'qpid' => 'WARN', 'sqlalchemy' => 'WARN', 'suds' => 'INFO',
|
||||
'iso8601' => 'WARN',
|
||||
'requests.packages.urllib3.connectionpool' => 'WARN' },
|
||||
:fatal_deprecations => true,
|
||||
:instance_format => '[instance: %(uuid)s] ',
|
||||
:instance_uuid_format => '[instance: %(uuid)s] ',
|
||||
:log_date_format => '%Y-%m-%d %H:%M:%S',
|
||||
}
|
||||
end
|
||||
|
||||
shared_examples_for 'keystone-logging' do
|
||||
|
||||
context 'with extended logging options' do
|
||||
before { params.merge!( log_params ) }
|
||||
it_configures 'logging params set'
|
||||
end
|
||||
|
||||
context 'without extended logging options' do
|
||||
it_configures 'logging params unset'
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
shared_examples_for 'logging params set' do
|
||||
it 'enables logging params' do
|
||||
is_expected.to contain_keystone_config('DEFAULT/logging_context_format_string').with_value(
|
||||
'%(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s [%(request_id)s %(user_identity)s] %(instance)s%(message)s')
|
||||
|
||||
is_expected.to contain_keystone_config('DEFAULT/logging_default_format_string').with_value(
|
||||
'%(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s [-] %(instance)s%(message)s')
|
||||
|
||||
is_expected.to contain_keystone_config('DEFAULT/logging_debug_format_suffix').with_value(
|
||||
'%(funcName)s %(pathname)s:%(lineno)d')
|
||||
|
||||
is_expected.to contain_keystone_config('DEFAULT/logging_exception_prefix').with_value(
|
||||
'%(asctime)s.%(msecs)03d %(process)d TRACE %(name)s %(instance)s')
|
||||
|
||||
is_expected.to contain_keystone_config('DEFAULT/log_config_append').with_value(
|
||||
'/etc/keystone/logging.conf')
|
||||
is_expected.to contain_keystone_config('DEFAULT/publish_errors').with_value(
|
||||
true)
|
||||
|
||||
is_expected.to contain_keystone_config('DEFAULT/default_log_levels').with_value(
|
||||
'amqp=WARN,amqplib=WARN,boto=WARN,iso8601=WARN,qpid=WARN,requests.packages.urllib3.connectionpool=WARN,sqlalchemy=WARN,suds=INFO')
|
||||
|
||||
is_expected.to contain_keystone_config('DEFAULT/fatal_deprecations').with_value(
|
||||
true)
|
||||
|
||||
is_expected.to contain_keystone_config('DEFAULT/instance_format').with_value(
|
||||
'[instance: %(uuid)s] ')
|
||||
|
||||
is_expected.to contain_keystone_config('DEFAULT/instance_uuid_format').with_value(
|
||||
'[instance: %(uuid)s] ')
|
||||
|
||||
is_expected.to contain_keystone_config('DEFAULT/log_date_format').with_value(
|
||||
'%Y-%m-%d %H:%M:%S')
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
shared_examples_for 'logging params unset' do
|
||||
[ :logging_context_format_string, :logging_default_format_string,
|
||||
:logging_debug_format_suffix, :logging_exception_prefix,
|
||||
:log_config_append, :publish_errors,
|
||||
:default_log_levels, :fatal_deprecations,
|
||||
:instance_format, :instance_uuid_format,
|
||||
:log_date_format, ].each { |param|
|
||||
it { is_expected.to contain_keystone_config("DEFAULT/#{param}").with_ensure('absent') }
|
||||
}
|
||||
end
|
||||
|
||||
context 'on Debian platforms' do
|
||||
let :facts do
|
||||
{ :osfamily => 'Debian' }
|
||||
end
|
||||
|
||||
it_configures 'keystone-logging'
|
||||
end
|
||||
|
||||
context 'on RedHat platforms' do
|
||||
let :facts do
|
||||
{ :osfamily => 'RedHat' }
|
||||
end
|
||||
|
||||
it_configures 'keystone-logging'
|
||||
end
|
||||
|
||||
end
|
@ -0,0 +1,41 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe 'keystone::policy' do
|
||||
|
||||
shared_examples_for 'keystone policies' do
|
||||
let :params do
|
||||
{
|
||||
:policy_path => '/etc/keystone/policy.json',
|
||||
:policies => {
|
||||
'context_is_admin' => {
|
||||
'key' => 'context_is_admin',
|
||||
'value' => 'foo:bar'
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
it 'set up the policies' do
|
||||
is_expected.to contain_openstacklib__policy__base('context_is_admin').with({
|
||||
:key => 'context_is_admin',
|
||||
:value => 'foo:bar'
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
context 'on Debian platforms' do
|
||||
let :facts do
|
||||
{ :osfamily => 'Debian' }
|
||||
end
|
||||
|
||||
it_configures 'keystone policies'
|
||||
end
|
||||
|
||||
context 'on RedHat platforms' do
|
||||
let :facts do
|
||||
{ :osfamily => 'RedHat' }
|
||||
end
|
||||
|
||||
it_configures 'keystone policies'
|
||||
end
|
||||
end
|
@ -6,12 +6,12 @@ describe 'keystone::python' do
|
||||
{ :osfamily => 'Debian' }
|
||||
end
|
||||
|
||||
it { should contain_package('python-keystone').with_ensure("present") }
|
||||
it { is_expected.to contain_package('python-keystone').with_ensure("present") }
|
||||
|
||||
describe 'override ensure' do
|
||||
let(:params) { { :ensure => "latest" } }
|
||||
|
||||
it { should contain_package('python-keystone').with_ensure("latest") }
|
||||
it { is_expected.to contain_package('python-keystone').with_ensure("latest") }
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -11,26 +11,27 @@ describe 'keystone::roles::admin' do
|
||||
}
|
||||
end
|
||||
|
||||
it { should contain_keystone_tenant('services').with(
|
||||
it { is_expected.to contain_keystone_tenant('services').with(
|
||||
:ensure => 'present',
|
||||
:enabled => true,
|
||||
:description => 'Tenant for the openstack services'
|
||||
)}
|
||||
it { should contain_keystone_tenant('openstack').with(
|
||||
it { is_expected.to contain_keystone_tenant('openstack').with(
|
||||
:ensure => 'present',
|
||||
:enabled => true,
|
||||
:description => 'admin tenant'
|
||||
)}
|
||||
it { should contain_keystone_user('admin').with(
|
||||
:ensure => 'present',
|
||||
:enabled => true,
|
||||
:tenant => 'openstack',
|
||||
:email => 'foo@bar',
|
||||
:password => 'ChangeMe'
|
||||
it { is_expected.to contain_keystone_user('admin').with(
|
||||
:ensure => 'present',
|
||||
:enabled => true,
|
||||
:tenant => 'openstack',
|
||||
:email => 'foo@bar',
|
||||
:password => 'ChangeMe',
|
||||
:ignore_default_tenant => 'false'
|
||||
)}
|
||||
it { should contain_keystone_role('admin').with_ensure('present') }
|
||||
it { should contain_keystone_user_role('admin@openstack').with(
|
||||
:roles => 'admin',
|
||||
it { is_expected.to contain_keystone_role('admin').with_ensure('present') }
|
||||
it { is_expected.to contain_keystone_user_role('admin@openstack').with(
|
||||
:roles => ['admin'],
|
||||
:ensure => 'present'
|
||||
)}
|
||||
|
||||
@ -40,36 +41,68 @@ describe 'keystone::roles::admin' do
|
||||
|
||||
let :params do
|
||||
{
|
||||
:admin => 'admin',
|
||||
:email => 'foo@baz',
|
||||
:password => 'foo',
|
||||
:admin_tenant => 'admin',
|
||||
:service_tenant => 'foobar'
|
||||
:admin => 'admin',
|
||||
:email => 'foo@baz',
|
||||
:password => 'foo',
|
||||
:admin_tenant => 'admin',
|
||||
:admin_roles => ['admin', 'heat_stack_owner'],
|
||||
:service_tenant => 'foobar',
|
||||
:ignore_default_tenant => 'true',
|
||||
:admin_tenant_desc => 'admin something else',
|
||||
:service_tenant_desc => 'foobar description',
|
||||
}
|
||||
end
|
||||
|
||||
it { should contain_keystone_tenant('foobar').with(
|
||||
it { is_expected.to contain_keystone_tenant('foobar').with(
|
||||
:ensure => 'present',
|
||||
:enabled => true,
|
||||
:description => 'Tenant for the openstack services'
|
||||
:description => 'foobar description'
|
||||
)}
|
||||
it { should contain_keystone_tenant('admin').with(
|
||||
it { is_expected.to contain_keystone_tenant('admin').with(
|
||||
:ensure => 'present',
|
||||
:enabled => true,
|
||||
:description => 'admin tenant'
|
||||
:description => 'admin something else'
|
||||
)}
|
||||
it { should contain_keystone_user('admin').with(
|
||||
:ensure => 'present',
|
||||
:enabled => true,
|
||||
:tenant => 'admin',
|
||||
:email => 'foo@baz',
|
||||
:password => 'foo'
|
||||
it { is_expected.to contain_keystone_user('admin').with(
|
||||
:ensure => 'present',
|
||||
:enabled => true,
|
||||
:tenant => 'admin',
|
||||
:email => 'foo@baz',
|
||||
:password => 'foo',
|
||||
:ignore_default_tenant => 'true'
|
||||
)}
|
||||
it { should contain_keystone_user_role('admin@admin').with(
|
||||
:roles => 'admin',
|
||||
it { is_expected.to contain_keystone_user_role('admin@admin').with(
|
||||
:roles => ['admin', 'heat_stack_owner'],
|
||||
:ensure => 'present'
|
||||
)}
|
||||
|
||||
end
|
||||
|
||||
describe 'when disabling user configuration' do
|
||||
before do
|
||||
let :params do
|
||||
{
|
||||
:configure_user => false
|
||||
}
|
||||
end
|
||||
|
||||
it { is_expected.to_not contain_keystone_user('keystone') }
|
||||
it { is_expected.to contain_keystone_user_role('keystone@openstack') }
|
||||
end
|
||||
end
|
||||
|
||||
describe 'when disabling user and role configuration' do
|
||||
before do
|
||||
let :params do
|
||||
{
|
||||
:configure_user => false,
|
||||
:configure_user_role => false
|
||||
}
|
||||
end
|
||||
|
||||
it { is_expected.to_not contain_keystone_user('keystone') }
|
||||
it { is_expected.to_not contain_keystone_user_role('keystone@openstack') }
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -0,0 +1,31 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe 'keystone::service' do
|
||||
|
||||
describe "with default parameters" do
|
||||
it { is_expected.to contain_service('keystone').with(
|
||||
:ensure => nil,
|
||||
:enable => true,
|
||||
:hasstatus => true,
|
||||
:hasrestart => true
|
||||
) }
|
||||
it { is_expected.to_not contain_exec('validate_keystone_connection') }
|
||||
end
|
||||
|
||||
describe "with validation on" do
|
||||
let :params do
|
||||
{
|
||||
:validate => 'true',
|
||||
:admin_token => 'admintoken'
|
||||
}
|
||||
end
|
||||
|
||||
it { is_expected.to contain_service('keystone').with(
|
||||
:ensure => nil,
|
||||
:enable => true,
|
||||
:hasstatus => true,
|
||||
:hasrestart => true
|
||||
) }
|
||||
it { is_expected.to contain_exec('validate_keystone_connection') }
|
||||
end
|
||||
end
|
File diff suppressed because it is too large
Load Diff
@ -11,47 +11,48 @@ describe 'keystone::wsgi::apache' do
|
||||
end
|
||||
|
||||
let :pre_condition do
|
||||
'include apache
|
||||
class { keystone: admin_token => "dummy" }'
|
||||
[
|
||||
'class { keystone: admin_token => "dummy", service_name => "httpd", enable_ssl => true }'
|
||||
]
|
||||
end
|
||||
|
||||
shared_examples_for 'apache serving keystone with mod_wsgi' do
|
||||
it { should contain_service('httpd').with_name(platform_parameters[:httpd_service_name]) }
|
||||
it { should contain_class('keystone::params') }
|
||||
it { should contain_class('apache') }
|
||||
it { should contain_class('apache::mod::wsgi') }
|
||||
it { should contain_class('keystone::db::sync') }
|
||||
it { is_expected.to contain_service('httpd').with_name(platform_parameters[:httpd_service_name]) }
|
||||
it { is_expected.to contain_class('keystone::params') }
|
||||
it { is_expected.to contain_class('apache') }
|
||||
it { is_expected.to contain_class('apache::mod::wsgi') }
|
||||
it { is_expected.to contain_class('keystone::db::sync') }
|
||||
|
||||
describe 'with default parameters' do
|
||||
|
||||
it { should contain_file("#{platform_parameters[:wsgi_script_path]}").with(
|
||||
it { is_expected.to contain_file("#{platform_parameters[:wsgi_script_path]}").with(
|
||||
'ensure' => 'directory',
|
||||
'owner' => 'keystone',
|
||||
'group' => 'keystone',
|
||||
'require' => 'Package[httpd]'
|
||||
)}
|
||||
|
||||
it { should contain_file('keystone_wsgi_admin').with(
|
||||
it { is_expected.to contain_file('keystone_wsgi_admin').with(
|
||||
'ensure' => 'file',
|
||||
'path' => "#{platform_parameters[:wsgi_script_path]}/admin",
|
||||
'source' => platform_parameters[:wsgi_script_source],
|
||||
'owner' => 'keystone',
|
||||
'group' => 'keystone',
|
||||
'mode' => '0644',
|
||||
'require' => "File[#{platform_parameters[:wsgi_script_path]}]"
|
||||
'require' => ["File[#{platform_parameters[:wsgi_script_path]}]", "Package[keystone]"]
|
||||
)}
|
||||
|
||||
it { should contain_file('keystone_wsgi_main').with(
|
||||
it { is_expected.to contain_file('keystone_wsgi_main').with(
|
||||
'ensure' => 'file',
|
||||
'path' => "#{platform_parameters[:wsgi_script_path]}/main",
|
||||
'source' => platform_parameters[:wsgi_script_source],
|
||||
'owner' => 'keystone',
|
||||
'group' => 'keystone',
|
||||
'mode' => '0644',
|
||||
'require' => "File[#{platform_parameters[:wsgi_script_path]}]"
|
||||
'require' => ["File[#{platform_parameters[:wsgi_script_path]}]", "Package[keystone]"]
|
||||
)}
|
||||
|
||||
it { should contain_apache__vhost('keystone_wsgi_admin').with(
|
||||
it { is_expected.to contain_apache__vhost('keystone_wsgi_admin').with(
|
||||
'servername' => 'some.host.tld',
|
||||
'ip' => nil,
|
||||
'port' => '35357',
|
||||
@ -59,12 +60,20 @@ describe 'keystone::wsgi::apache' do
|
||||
'docroot_owner' => 'keystone',
|
||||
'docroot_group' => 'keystone',
|
||||
'ssl' => 'true',
|
||||
'wsgi_daemon_process' => 'keystone_admin',
|
||||
'wsgi_daemon_process_options' => {
|
||||
'user' => 'keystone',
|
||||
'group' => 'keystone',
|
||||
'processes' => '1',
|
||||
'threads' => '42',
|
||||
'display-name' => 'keystone-admin',
|
||||
},
|
||||
'wsgi_process_group' => 'keystone_admin',
|
||||
'wsgi_script_aliases' => { '/' => "#{platform_parameters[:wsgi_script_path]}/admin" },
|
||||
'require' => ['Class[Apache::Mod::Wsgi]', 'File[keystone_wsgi_admin]']
|
||||
'require' => 'File[keystone_wsgi_admin]'
|
||||
)}
|
||||
|
||||
it { should contain_apache__vhost('keystone_wsgi_main').with(
|
||||
it { is_expected.to contain_apache__vhost('keystone_wsgi_main').with(
|
||||
'servername' => 'some.host.tld',
|
||||
'ip' => nil,
|
||||
'port' => '5000',
|
||||
@ -73,15 +82,18 @@ describe 'keystone::wsgi::apache' do
|
||||
'docroot_group' => 'keystone',
|
||||
'ssl' => 'true',
|
||||
'wsgi_daemon_process' => 'keystone_main',
|
||||
'wsgi_daemon_process_options' => {
|
||||
'user' => 'keystone',
|
||||
'group' => 'keystone',
|
||||
'processes' => '1',
|
||||
'threads' => '42',
|
||||
'display-name' => 'keystone-main',
|
||||
},
|
||||
'wsgi_process_group' => 'keystone_main',
|
||||
'wsgi_script_aliases' => { '/' => "#{platform_parameters[:wsgi_script_path]}/main" },
|
||||
'require' => ['Class[Apache::Mod::Wsgi]', 'File[keystone_wsgi_main]']
|
||||
'require' => 'File[keystone_wsgi_main]'
|
||||
)}
|
||||
it "should set keystone wsgi options" do
|
||||
contain_file('25-keystone_wsgi_main.conf').with_content(
|
||||
/^ WSGIDaemonProcess keystone group=keystone processes=1 threads=1 user=keystone$/
|
||||
)
|
||||
end
|
||||
it { is_expected.to contain_file("#{platform_parameters[:httpd_ports_file]}") }
|
||||
end
|
||||
|
||||
describe 'when overriding parameters using different ports' do
|
||||
@ -96,7 +108,7 @@ describe 'keystone::wsgi::apache' do
|
||||
}
|
||||
end
|
||||
|
||||
it { should contain_apache__vhost('keystone_wsgi_admin').with(
|
||||
it { is_expected.to contain_apache__vhost('keystone_wsgi_admin').with(
|
||||
'servername' => 'dummy.host',
|
||||
'ip' => '10.42.51.1',
|
||||
'port' => '4142',
|
||||
@ -104,12 +116,20 @@ describe 'keystone::wsgi::apache' do
|
||||
'docroot_owner' => 'keystone',
|
||||
'docroot_group' => 'keystone',
|
||||
'ssl' => 'false',
|
||||
'wsgi_daemon_process' => 'keystone_admin',
|
||||
'wsgi_daemon_process_options' => {
|
||||
'user' => 'keystone',
|
||||
'group' => 'keystone',
|
||||
'processes' => '37',
|
||||
'threads' => '42',
|
||||
'display-name' => 'keystone-admin',
|
||||
},
|
||||
'wsgi_process_group' => 'keystone_admin',
|
||||
'wsgi_script_aliases' => { '/' => "#{platform_parameters[:wsgi_script_path]}/admin" },
|
||||
'require' => ['Class[Apache::Mod::Wsgi]', 'File[keystone_wsgi_admin]']
|
||||
'require' => 'File[keystone_wsgi_admin]'
|
||||
)}
|
||||
|
||||
it { should contain_apache__vhost('keystone_wsgi_main').with(
|
||||
it { is_expected.to contain_apache__vhost('keystone_wsgi_main').with(
|
||||
'servername' => 'dummy.host',
|
||||
'ip' => '10.42.51.1',
|
||||
'port' => '12345',
|
||||
@ -118,15 +138,19 @@ describe 'keystone::wsgi::apache' do
|
||||
'docroot_group' => 'keystone',
|
||||
'ssl' => 'false',
|
||||
'wsgi_daemon_process' => 'keystone_main',
|
||||
'wsgi_daemon_process_options' => {
|
||||
'user' => 'keystone',
|
||||
'group' => 'keystone',
|
||||
'processes' => '37',
|
||||
'threads' => '42',
|
||||
'display-name' => 'keystone-main',
|
||||
},
|
||||
'wsgi_process_group' => 'keystone_main',
|
||||
'wsgi_script_aliases' => { '/' => "#{platform_parameters[:wsgi_script_path]}/main" },
|
||||
'require' => ['Class[Apache::Mod::Wsgi]', 'File[keystone_wsgi_main]']
|
||||
'require' => 'File[keystone_wsgi_main]'
|
||||
)}
|
||||
it "should set keystone wsgi options" do
|
||||
contain_file('25-keystone_wsgi_main.conf').with_content(
|
||||
/^ WSGIDaemonProcess keystone group=keystone processes=37 threads=1 user=keystone$/
|
||||
)
|
||||
end
|
||||
|
||||
it { is_expected.to contain_file("#{platform_parameters[:httpd_ports_file]}") }
|
||||
end
|
||||
|
||||
describe 'when overriding parameters using same port' do
|
||||
@ -142,9 +166,9 @@ describe 'keystone::wsgi::apache' do
|
||||
}
|
||||
end
|
||||
|
||||
it { should_not contain_apache__vhost('keystone_wsgi_admin') }
|
||||
it { is_expected.to_not contain_apache__vhost('keystone_wsgi_admin') }
|
||||
|
||||
it { should contain_apache__vhost('keystone_wsgi_main').with(
|
||||
it { is_expected.to contain_apache__vhost('keystone_wsgi_main').with(
|
||||
'servername' => 'dummy.host',
|
||||
'ip' => nil,
|
||||
'port' => '4242',
|
||||
@ -153,18 +177,20 @@ describe 'keystone::wsgi::apache' do
|
||||
'docroot_group' => 'keystone',
|
||||
'ssl' => 'true',
|
||||
'wsgi_daemon_process' => 'keystone_main',
|
||||
'wsgi_daemon_process_options' => {
|
||||
'user' => 'keystone',
|
||||
'group' => 'keystone',
|
||||
'processes' => '37',
|
||||
'threads' => '42',
|
||||
'display-name' => 'keystone-main',
|
||||
},
|
||||
'wsgi_process_group' => 'keystone_main',
|
||||
'wsgi_script_aliases' => {
|
||||
'/main/endpoint' => "#{platform_parameters[:wsgi_script_path]}/main",
|
||||
'/admin/endpoint' => "#{platform_parameters[:wsgi_script_path]}/admin"
|
||||
},
|
||||
'require' => ['Class[Apache::Mod::Wsgi]', 'File[keystone_wsgi_main]']
|
||||
},
|
||||
'require' => 'File[keystone_wsgi_main]'
|
||||
)}
|
||||
it "should set keystone wsgi options" do
|
||||
contain_file('25-keystone_wsgi_main.conf').with_content(
|
||||
/^ WSGIDaemonProcess keystone group=keystone processes=37 threads=1 user=keystone$/
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'when overriding parameters using same port and same path' do
|
||||
@ -182,35 +208,6 @@ describe 'keystone::wsgi::apache' do
|
||||
|
||||
it_raises 'a Puppet::Error', /When using the same port for public & private endpoints, public_path and admin_path should be different\./
|
||||
end
|
||||
|
||||
describe 'when overriding parameters using symlink and custom file source' do
|
||||
let :params do
|
||||
{
|
||||
:wsgi_script_ensure => 'link',
|
||||
:wsgi_script_source => '/opt/keystone/httpd/keystone.py',
|
||||
}
|
||||
end
|
||||
|
||||
it { is_expected.to contain_file('keystone_wsgi_admin').with(
|
||||
'ensure' => 'link',
|
||||
'path' => "#{platform_parameters[:wsgi_script_path]}/admin",
|
||||
'target' => '/opt/keystone/httpd/keystone.py',
|
||||
'owner' => 'keystone',
|
||||
'group' => 'keystone',
|
||||
'mode' => '0644',
|
||||
'require' => "File[#{platform_parameters[:wsgi_script_path]}]"
|
||||
)}
|
||||
|
||||
it { is_expected.to contain_file('keystone_wsgi_main').with(
|
||||
'ensure' => 'link',
|
||||
'path' => "#{platform_parameters[:wsgi_script_path]}/main",
|
||||
'target' => '/opt/keystone/httpd/keystone.py',
|
||||
'owner' => 'keystone',
|
||||
'group' => 'keystone',
|
||||
'mode' => '0644',
|
||||
'require' => "File[#{platform_parameters[:wsgi_script_path]}]"
|
||||
)}
|
||||
end
|
||||
end
|
||||
|
||||
context 'on RedHat platforms' do
|
||||
@ -224,8 +221,9 @@ describe 'keystone::wsgi::apache' do
|
||||
let :platform_parameters do
|
||||
{
|
||||
:httpd_service_name => 'httpd',
|
||||
:httpd_ports_file => '/etc/httpd/conf/ports.conf',
|
||||
:wsgi_script_path => '/var/www/cgi-bin/keystone',
|
||||
:wsgi_script_source => 'puppet:///modules/keystone/httpd/keystone.py'
|
||||
:wsgi_script_source => '/usr/share/keystone/keystone.wsgi'
|
||||
}
|
||||
end
|
||||
|
||||
@ -244,6 +242,7 @@ describe 'keystone::wsgi::apache' do
|
||||
let :platform_parameters do
|
||||
{
|
||||
:httpd_service_name => 'apache2',
|
||||
:httpd_ports_file => '/etc/apache2/ports.conf',
|
||||
:wsgi_script_path => '/usr/lib/cgi-bin/keystone',
|
||||
:wsgi_script_source => '/usr/share/keystone/wsgi.py'
|
||||
}
|
||||
|
@ -0,0 +1,89 @@
|
||||
#
|
||||
# Copyright (C) 2014 eNovance SAS <licensing@enovance.com>
|
||||
#
|
||||
# Author: Emilien Macchi <emilien.macchi@enovance.com>
|
||||
#
|
||||
# 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 'spec_helper'
|
||||
|
||||
describe 'keystone::resource::service_identity' do
|
||||
|
||||
let (:title) { 'neutron' }
|
||||
|
||||
let :required_params do
|
||||
{ :password => 'secrete',
|
||||
:service_type => 'network',
|
||||
:admin_url => 'http://192.168.0.1:9696',
|
||||
:internal_url => 'http://10.0.0.1:9696',
|
||||
:public_url => 'http://7.7.7.7:9696' }
|
||||
end
|
||||
|
||||
shared_examples 'keystone::resource::service_identity examples' do
|
||||
|
||||
context 'with only required parameters' do
|
||||
let :params do
|
||||
required_params
|
||||
end
|
||||
|
||||
it { is_expected.to contain_keystone_user(title).with(
|
||||
:ensure => 'present',
|
||||
:password => 'secrete',
|
||||
:email => 'neutron@localhost',
|
||||
:tenant => 'services',
|
||||
)}
|
||||
|
||||
it { is_expected.to contain_keystone_user_role("#{title}@services").with(
|
||||
:ensure => 'present',
|
||||
:roles => ['admin'],
|
||||
)}
|
||||
|
||||
it { is_expected.to contain_keystone_service(title).with(
|
||||
:ensure => 'present',
|
||||
:type => 'network',
|
||||
:description => 'neutron service',
|
||||
)}
|
||||
|
||||
it { is_expected.to contain_keystone_endpoint("RegionOne/#{title}").with(
|
||||
:ensure => 'present',
|
||||
:public_url => 'http://7.7.7.7:9696',
|
||||
:internal_url => 'http://10.0.0.1:9696',
|
||||
:admin_url => 'http://192.168.0.1:9696',
|
||||
)}
|
||||
end
|
||||
|
||||
context 'when omitting a required parameter password' do
|
||||
let :params do
|
||||
required_params.delete(:password)
|
||||
end
|
||||
it { expect { is_expected.to raise_error(Puppet::Error) } }
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context 'on a Debian osfamily' do
|
||||
let :facts do
|
||||
{ :osfamily => "Debian" }
|
||||
end
|
||||
|
||||
include_examples 'keystone::resource::service_identity examples'
|
||||
end
|
||||
|
||||
context 'on a RedHat osfamily' do
|
||||
let :facts do
|
||||
{ :osfamily => 'RedHat' }
|
||||
end
|
||||
|
||||
include_examples 'keystone::resource::service_identity examples'
|
||||
end
|
||||
end
|
@ -1,5 +1,5 @@
|
||||
shared_examples_for "a Puppet::Error" do |description|
|
||||
it "with message matching #{description.inspect}" do
|
||||
expect { should have_class_count(1) }.to raise_error(Puppet::Error, description)
|
||||
expect { is_expected.to have_class_count(1) }.to raise_error(Puppet::Error, description)
|
||||
end
|
||||
end
|
||||
|
@ -1,8 +1,9 @@
|
||||
# Load libraries from openstacklib here to simulate how they live together in a real puppet run (for provider unit tests)
|
||||
$LOAD_PATH.push(File.join(File.dirname(__FILE__), 'fixtures', 'modules', 'openstacklib', 'lib'))
|
||||
require 'puppetlabs_spec_helper/module_spec_helper'
|
||||
require 'shared_examples'
|
||||
|
||||
RSpec.configure do |c|
|
||||
c.alias_it_should_behave_like_to :it_configures, 'configures'
|
||||
c.alias_it_should_behave_like_to :it_raises, 'raises'
|
||||
c.alias_it_should_behave_like_to :it_configures, 'configures'
|
||||
c.alias_it_should_behave_like_to :it_raises, 'raises'
|
||||
end
|
||||
|
||||
|
46
deployment/puppet/keystone/spec/spec_helper_acceptance.rb
Normal file
46
deployment/puppet/keystone/spec/spec_helper_acceptance.rb
Normal file
@ -0,0 +1,46 @@
|
||||
require 'beaker-rspec'
|
||||
|
||||
hosts.each do |host|
|
||||
|
||||
install_puppet
|
||||
|
||||
on host, "mkdir -p #{host['distmoduledir']}"
|
||||
end
|
||||
|
||||
RSpec.configure do |c|
|
||||
# Project root
|
||||
proj_root = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
||||
|
||||
# Readable test descriptions
|
||||
c.formatter = :documentation
|
||||
|
||||
# Configure all nodes in nodeset
|
||||
c.before :suite do
|
||||
# Install module and dependencies
|
||||
hosts.each do |host|
|
||||
|
||||
# install git
|
||||
install_package host, 'git'
|
||||
|
||||
# clean out any module cruft
|
||||
shell('rm -fr /etc/puppet/modules/*')
|
||||
|
||||
# install library modules from the forge
|
||||
on host, puppet('module','install','puppetlabs-mysql'), { :acceptable_exit_codes => 0 }
|
||||
on host, puppet('module','install','dprince/qpid'), { :acceptable_exit_codes => 0 }
|
||||
on host, puppet('module','install','duritong/sysctl'), { :acceptable_exit_codes => 0 }
|
||||
on host, puppet('module','install','puppetlabs-inifile'), { :acceptable_exit_codes => 0 }
|
||||
on host, puppet('module','install','puppetlabs-rabbitmq'), { :acceptable_exit_codes => 0 }
|
||||
on host, puppet('module','install','puppetlabs-apache'), { :acceptable_exit_codes => 0 }
|
||||
|
||||
# install puppet modules from git, use master
|
||||
shell('git clone https://git.openstack.org/openstack/puppet-openstacklib /etc/puppet/modules/openstacklib')
|
||||
shell('git clone https://git.openstack.org/openstack/puppet-openstack_extras /etc/puppet/modules/openstack_extras')
|
||||
|
||||
# Install the module being tested
|
||||
puppet_module_install(:source => proj_root, :module_name => 'keystone')
|
||||
# List modules installed to help with debugging
|
||||
on hosts[0], puppet('module','list'), { :acceptable_exit_codes => 0 }
|
||||
end
|
||||
end
|
||||
end
|
@ -1,74 +0,0 @@
|
||||
require 'puppet'
|
||||
require 'spec_helper'
|
||||
require 'puppet/provider/keystone_endpoint/keystone'
|
||||
|
||||
|
||||
describe Puppet::Type.type(:keystone_endpoint).provider(:keystone) do
|
||||
|
||||
let :resource do
|
||||
Puppet::Type::Keystone_endpoint.new(
|
||||
:provider => :keystone,
|
||||
:name => 'region/foo',
|
||||
:ensure => :present,
|
||||
:public_url => 'public_url',
|
||||
:internal_url => 'internal_url',
|
||||
:admin_url => 'admin_url'
|
||||
)
|
||||
end
|
||||
|
||||
let :provider do
|
||||
described_class.new(resource)
|
||||
end
|
||||
|
||||
before :each do
|
||||
# keystone endpoint-list
|
||||
described_class.stubs(:list_keystone_objects).with('endpoint', [5,6]).returns([
|
||||
['endpoint-id', 'region', 'public_url', 'internal_url', 'admin_url', 4]
|
||||
])
|
||||
# keystone service-list
|
||||
described_class.stubs(:list_keystone_objects).with('service', 4).returns([
|
||||
[4, 'foo', 'type', 'description']
|
||||
])
|
||||
described_class.stubs(:get_keystone_object).with('service', 4, 'name').returns('foo')
|
||||
described_class.prefetch('region/foo' => resource)
|
||||
end
|
||||
|
||||
after :each do
|
||||
described_class.prefetch({})
|
||||
end
|
||||
|
||||
describe "self.instances" do
|
||||
it "should have an instances method" do
|
||||
provider.class.should respond_to(:instances)
|
||||
end
|
||||
|
||||
it "should list instances" do
|
||||
endpoints = described_class.instances
|
||||
endpoints.size.should == 1
|
||||
endpoints.map {|provider| provider.name} == ['region/foo']
|
||||
end
|
||||
end
|
||||
|
||||
describe '#create' do
|
||||
it 'should call endpoint-create' do
|
||||
provider.expects(:auth_keystone).with(
|
||||
'endpoint-create', '--service-id', 4, includes(
|
||||
'--publicurl', 'public_url', '--internalurl', 'internal_url',
|
||||
'--region', 'region')
|
||||
)
|
||||
provider.create
|
||||
end
|
||||
end
|
||||
|
||||
describe '#flush' do
|
||||
it 'should delete and create the endpoint once when any url gets updated' do
|
||||
provider.expects(:destroy).times(1)
|
||||
provider.expects(:create).times(1)
|
||||
|
||||
provider.public_url=('new-public_url')
|
||||
provider.internal_url=('new-internal_url')
|
||||
provider.admin_url=('new-admin_url')
|
||||
provider.flush
|
||||
end
|
||||
end
|
||||
end
|
@ -0,0 +1,100 @@
|
||||
require 'puppet'
|
||||
require 'spec_helper'
|
||||
require 'puppet/provider/keystone_endpoint/openstack'
|
||||
|
||||
provider_class = Puppet::Type.type(:keystone_endpoint).provider(:openstack)
|
||||
|
||||
describe provider_class do
|
||||
|
||||
shared_examples 'authenticated with environment variables' do
|
||||
ENV['OS_USERNAME'] = 'test'
|
||||
ENV['OS_PASSWORD'] = 'abc123'
|
||||
ENV['OS_PROJECT_NAME'] = 'test'
|
||||
ENV['OS_AUTH_URL'] = 'http://127.0.0.1:35357/v2.0'
|
||||
end
|
||||
|
||||
describe 'when managing an endpoint' do
|
||||
|
||||
let(:endpoint_attrs) do
|
||||
{
|
||||
:name => 'foo/bar',
|
||||
:ensure => 'present',
|
||||
:public_url => 'http://127.0.0.1:5000/v2.0',
|
||||
:internal_url => 'http://127.0.0.1:5001/v2.0',
|
||||
:admin_url => 'http://127.0.0.1:5002/v2.0',
|
||||
}
|
||||
end
|
||||
|
||||
let(:resource) do
|
||||
Puppet::Type::Keystone_endpoint.new(endpoint_attrs)
|
||||
end
|
||||
|
||||
let(:provider) do
|
||||
provider_class.new(resource)
|
||||
end
|
||||
|
||||
it_behaves_like 'authenticated with environment variables' do
|
||||
describe '#create' do
|
||||
it 'creates an endpoint' do
|
||||
provider.class.stubs(:openstack)
|
||||
.with('endpoint', 'list', '--quiet', '--format', 'csv', '--long')
|
||||
.returns('"ID","Region","Service Name","Service Type","PublicURL","AdminURL","InternalURL"
|
||||
"1cb05cfed7c24279be884ba4f6520262","foo","bar","","http://127.0.0.1:5000/v2.0","http://127.0.0.1:5001/v2.0","http://127.0.0.1:5002/v2.0"
|
||||
')
|
||||
provider.class.stubs(:openstack)
|
||||
.with('endpoint', 'create', '--format', 'shell', ['bar', '--region', 'foo', '--publicurl', 'http://127.0.0.1:5000/v2.0', '--internalurl', 'http://127.0.0.1:5001/v2.0', '--adminurl', 'http://127.0.0.1:5002/v2.0'])
|
||||
.returns('adminurl="http://127.0.0.1:5002/v2.0"
|
||||
id="3a5c4378981e4112a0d44902a43e16ef"
|
||||
internalurl="http://127.0.0.1:5001/v2.0"
|
||||
publicurl="http://127.0.0.1:5000/v2.0"
|
||||
region="foo"
|
||||
service_id="8137d72980fd462192f276585a002426"
|
||||
service_name="bar"
|
||||
service_type="test"
|
||||
')
|
||||
provider.create
|
||||
expect(provider.exists?).to be_truthy
|
||||
end
|
||||
end
|
||||
|
||||
describe '#destroy' do
|
||||
it 'destroys an endpoint' do
|
||||
provider.class.stubs(:openstack)
|
||||
.with('endpoint', 'list', '--quiet', '--format', 'csv', '--long')
|
||||
.returns('"ID","Region","Service Name","Service Type","PublicURL","AdminURL","InternalURL"
|
||||
"1cb05cfed7c24279be884ba4f6520262","foo","bar","test","http://127.0.0.1:5000/v2.0","http://127.0.0.1:5001/v2.0","http://127.0.0.1:5002/v2.0"
|
||||
')
|
||||
provider.class.stubs(:openstack)
|
||||
.with('endpoint', 'delete', [])
|
||||
provider.destroy
|
||||
expect(provider.exists?).to be_falsey
|
||||
end
|
||||
end
|
||||
|
||||
describe '#exists' do
|
||||
context 'when tenant does not exist' do
|
||||
subject(:response) do
|
||||
provider.class.stubs(:openstack)
|
||||
.with('endpoint', 'list', '--quiet', '--format', 'csv', '--long')
|
||||
.returns('"ID","Region","Service Name","Service Type","PublicURL","AdminURL","InternalURL"')
|
||||
response = provider.exists?
|
||||
end
|
||||
|
||||
it { is_expected.to be_falsey }
|
||||
end
|
||||
end
|
||||
|
||||
describe '#instances' do
|
||||
it 'finds every tenant' do
|
||||
provider.class.stubs(:openstack)
|
||||
.with('endpoint', 'list', '--quiet', '--format', 'csv', '--long')
|
||||
.returns('"ID","Region","Service Name","Service Type","PublicURL","AdminURL","InternalURL"
|
||||
"3a5c4378981e4112a0d44902a43e16ef","foo","bar","test","http://127.0.0.1:5000/v2.0","http://127.0.0.1:5001/v2.0","http://127.0.0.1:5002/v2.0"
|
||||
')
|
||||
instances = Puppet::Type::Keystone_endpoint::ProviderOpenstack.instances
|
||||
expect(instances.count).to eq(1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -0,0 +1,29 @@
|
||||
#
|
||||
# these tests are a little concerning b/c they are hacking around the
|
||||
# modulepath, so these tests will not catch issues that may eventually arise
|
||||
# related to loading these plugins.
|
||||
# I could not, for the life of me, figure out how to programatcally set the modulepath
|
||||
$LOAD_PATH.push(
|
||||
File.join(
|
||||
File.dirname(__FILE__),
|
||||
'..',
|
||||
'..',
|
||||
'..',
|
||||
'fixtures',
|
||||
'modules',
|
||||
'inifile',
|
||||
'lib')
|
||||
)
|
||||
require 'spec_helper'
|
||||
provider_class = Puppet::Type.type(:keystone_paste_ini).provider(:ini_setting)
|
||||
describe provider_class do
|
||||
|
||||
it 'should allow setting to be set explicitly' do
|
||||
resource = Puppet::Type::Keystone_paste_ini.new(
|
||||
{:name => 'dude/foo', :value => 'bar'}
|
||||
)
|
||||
provider = provider_class.new(resource)
|
||||
provider.section.should == 'dude'
|
||||
provider.setting.should == 'foo'
|
||||
end
|
||||
end
|
@ -1,16 +0,0 @@
|
||||
require 'puppet'
|
||||
require 'spec_helper'
|
||||
require 'puppet/provider/keystone_role/keystone'
|
||||
|
||||
provider_class = Puppet::Type.type(:keystone_role).provider(:keystone)
|
||||
|
||||
describe provider_class do
|
||||
describe 'when query keystone objects' do
|
||||
it 'should not cache keystone objects in catalog' do
|
||||
provider_class.stubs(:build_role_hash).returns({ 'foo' => 'bar' })
|
||||
provider_class.role_hash.should == ({ 'foo' => 'bar' })
|
||||
provider_class.stubs(:build_role_hash).returns({ 'baz' => 'qux' })
|
||||
provider_class.role_hash.should == ({ 'baz' => 'qux' })
|
||||
end
|
||||
end
|
||||
end
|
@ -0,0 +1,86 @@
|
||||
require 'puppet'
|
||||
require 'spec_helper'
|
||||
require 'puppet/provider/keystone_role/openstack'
|
||||
|
||||
provider_class = Puppet::Type.type(:keystone_role).provider(:openstack)
|
||||
|
||||
describe provider_class do
|
||||
|
||||
shared_examples 'authenticated with environment variables' do
|
||||
ENV['OS_USERNAME'] = 'test'
|
||||
ENV['OS_PASSWORD'] = 'abc123'
|
||||
ENV['OS_PROJECT_NAME'] = 'test'
|
||||
ENV['OS_AUTH_URL'] = 'http://127.0.0.1:5000'
|
||||
end
|
||||
|
||||
describe 'when creating a role' do
|
||||
it_behaves_like 'authenticated with environment variables' do
|
||||
let(:role_attrs) do
|
||||
{
|
||||
:name => 'foo',
|
||||
:ensure => 'present',
|
||||
}
|
||||
end
|
||||
|
||||
let(:resource) do
|
||||
Puppet::Type::Keystone_role.new(role_attrs)
|
||||
end
|
||||
|
||||
let(:provider) do
|
||||
provider_class.new(resource)
|
||||
end
|
||||
|
||||
describe '#create' do
|
||||
it 'creates a role' do
|
||||
provider.class.stubs(:openstack)
|
||||
.with('role', 'list', '--quiet', '--format', 'csv', [])
|
||||
.returns('"ID","Name"
|
||||
"1cb05cfed7c24279be884ba4f6520262","foo"
|
||||
')
|
||||
provider.class.stubs(:openstack)
|
||||
.with('role', 'create', '--format', 'shell', 'foo')
|
||||
.returns('name="foo"')
|
||||
provider.create
|
||||
expect(provider.exists?).to be_truthy
|
||||
end
|
||||
end
|
||||
|
||||
describe '#destroy' do
|
||||
it 'destroys a role' do
|
||||
provider.class.stubs(:openstack)
|
||||
.with('role', 'list', '--quiet', '--format', 'csv', [])
|
||||
.returns('"ID","Name"')
|
||||
provider.class.stubs(:openstack)
|
||||
.with('role', 'delete', [])
|
||||
provider.destroy
|
||||
expect(provider.exists?).to be_falsey
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe '#exists' do
|
||||
context 'when role does not exist' do
|
||||
subject(:response) do
|
||||
provider.class.stubs(:openstack)
|
||||
.with('role', 'list', '--quiet', '--format', 'csv', [])
|
||||
.returns('"ID","Name"')
|
||||
response = provider.exists?
|
||||
end
|
||||
it { is_expected.to be_falsey }
|
||||
end
|
||||
end
|
||||
|
||||
describe '#instances' do
|
||||
it 'finds every role' do
|
||||
provider.class.stubs(:openstack)
|
||||
.with('role', 'list', '--quiet', '--format', 'csv', [])
|
||||
.returns('"ID","Name"
|
||||
"1cb05cfed7c24279be884ba4f6520262","foo"
|
||||
')
|
||||
instances = Puppet::Type::Keystone_role::ProviderOpenstack.instances
|
||||
expect(instances.count).to eq(1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -1,16 +0,0 @@
|
||||
require 'puppet'
|
||||
require 'spec_helper'
|
||||
require 'puppet/provider/keystone_service/keystone'
|
||||
|
||||
provider_class = Puppet::Type.type(:keystone_service).provider(:keystone)
|
||||
|
||||
describe provider_class do
|
||||
describe 'when query keystone objects' do
|
||||
it 'should not cache keystone objects in catalog' do
|
||||
provider_class.stubs(:build_service_hash).returns({ 'foo' => 'bar' })
|
||||
provider_class.service_hash.should == ({ 'foo' => 'bar' })
|
||||
provider_class.stubs(:build_service_hash).returns({ 'baz' => 'qux' })
|
||||
provider_class.service_hash.should == ({ 'baz' => 'qux' })
|
||||
end
|
||||
end
|
||||
end
|
@ -0,0 +1,93 @@
|
||||
require 'puppet'
|
||||
require 'spec_helper'
|
||||
require 'puppet/provider/keystone_service/openstack'
|
||||
|
||||
provider_class = Puppet::Type.type(:keystone_service).provider(:openstack)
|
||||
|
||||
describe provider_class do
|
||||
|
||||
shared_examples 'authenticated with environment variables' do
|
||||
ENV['OS_USERNAME'] = 'test'
|
||||
ENV['OS_PASSWORD'] = 'abc123'
|
||||
ENV['OS_PROJECT_NAME'] = 'test'
|
||||
ENV['OS_AUTH_URL'] = 'http://127.0.0.1:35357/v2.0'
|
||||
end
|
||||
|
||||
describe 'when managing a service' do
|
||||
|
||||
let(:service_attrs) do
|
||||
{
|
||||
:name => 'foo',
|
||||
:description => 'foo',
|
||||
:ensure => 'present',
|
||||
:type => 'foo',
|
||||
}
|
||||
end
|
||||
|
||||
let(:resource) do
|
||||
Puppet::Type::Keystone_service.new(service_attrs)
|
||||
end
|
||||
|
||||
let(:provider) do
|
||||
provider_class.new(resource)
|
||||
end
|
||||
|
||||
it_behaves_like 'authenticated with environment variables' do
|
||||
describe '#create' do
|
||||
it 'creates a service' do
|
||||
provider.class.stubs(:openstack)
|
||||
.with('service', 'list', '--quiet', '--format', 'csv', '--long')
|
||||
.returns('"ID","Name","Type","Description"
|
||||
"1cb05cfed7c24279be884ba4f6520262","foo","foo","foo"
|
||||
')
|
||||
provider.class.stubs(:openstack)
|
||||
.with('service', 'create', '--format', 'shell', ['--name', 'foo', '--description', 'foo', 'foo'])
|
||||
.returns('description="foo"
|
||||
enabled="True"
|
||||
id="8f0dd4c0abc44240998fbb3f5089ecbf"
|
||||
name="foo"
|
||||
type="foo"
|
||||
')
|
||||
provider.create
|
||||
expect(provider.exists?).to be_truthy
|
||||
end
|
||||
end
|
||||
|
||||
describe '#destroy' do
|
||||
it 'destroys a service' do
|
||||
provider.class.stubs(:openstack)
|
||||
.with('service', 'list', '--quiet', '--format', 'csv', '--long')
|
||||
.returns('"ID","Name","Type","Description"
|
||||
"1cb05cfed7c24279be884ba4f6520262","foo","foo","foo"
|
||||
')
|
||||
provider.class.stubs(:openstack)
|
||||
.with('service', 'delete', [])
|
||||
provider.destroy
|
||||
expect(provider.exists?).to be_falsey
|
||||
end
|
||||
|
||||
context 'when service does not exist' do
|
||||
subject(:response) do
|
||||
provider.class.stubs(:openstack)
|
||||
.with('service', 'list', '--quiet', '--format', 'csv', '--long')
|
||||
.returns('"ID","Name","Type","Description"')
|
||||
response = provider.exists?
|
||||
end
|
||||
it { is_expected.to be_falsey }
|
||||
end
|
||||
end
|
||||
|
||||
describe '#instances' do
|
||||
it 'finds every service' do
|
||||
provider.class.stubs(:openstack)
|
||||
.with('service', 'list', '--quiet', '--format', 'csv', '--long')
|
||||
.returns('"ID","Name","Type","Description"
|
||||
"8f0dd4c0abc44240998fbb3f5089ecbf","foo","foo","foo"
|
||||
')
|
||||
instances = Puppet::Type::Keystone_service::ProviderOpenstack.instances
|
||||
expect(instances.count).to eq(1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -3,164 +3,119 @@ require 'spec_helper'
|
||||
require 'puppet/provider/keystone'
|
||||
require 'tempfile'
|
||||
|
||||
|
||||
klass = Puppet::Provider::Keystone
|
||||
|
||||
class Puppet::Provider::Keystone
|
||||
@credentials = Puppet::Provider::Openstack::CredentialsV2_0.new
|
||||
|
||||
def self.reset
|
||||
@admin_endpoint = nil
|
||||
@tenant_hash = nil
|
||||
@admin_token = nil
|
||||
@keystone_file = nil
|
||||
end
|
||||
end
|
||||
|
||||
describe Puppet::Provider::Keystone do
|
||||
|
||||
after :each do
|
||||
klass.reset
|
||||
end
|
||||
|
||||
|
||||
describe 'when retrieving the security token' do
|
||||
|
||||
it 'should fail if there is no keystone config file' do
|
||||
ini_file = Puppet::Util::IniConfig::File.new
|
||||
t = Tempfile.new('foo')
|
||||
path = t.path
|
||||
t.unlink
|
||||
ini_file.read(path)
|
||||
expect do
|
||||
klass.get_admin_token
|
||||
end.to raise_error(Puppet::Error, /Keystone types will not work/)
|
||||
it 'should return nothing if there is no keystone config file' do
|
||||
File.expects(:exists?).with("/etc/keystone/keystone.conf").returns(false)
|
||||
expect(klass.get_admin_token).to be_nil
|
||||
end
|
||||
|
||||
it 'should fail if the keystone config file does not have a DEFAULT section' do
|
||||
it 'should return nothing if the keystone config file does not have a DEFAULT section' do
|
||||
mock = {}
|
||||
File.expects(:exists?).with("/etc/keystone/keystone.conf").returns(true)
|
||||
Puppet::Util::IniConfig::File.expects(:new).returns(mock)
|
||||
mock.expects(:read).with('/etc/keystone/keystone.conf')
|
||||
expect do
|
||||
|
||||
klass.get_admin_token
|
||||
end.to raise_error(Puppet::Error, /Keystone types will not work/)
|
||||
expect(klass.get_admin_token).to be_nil
|
||||
end
|
||||
|
||||
it 'should fail if the keystone config file does not contain an admin token' do
|
||||
mock = {'DEFAULT' => {'not_a_token' => 'foo'}}
|
||||
File.expects(:exists?).with("/etc/keystone/keystone.conf").returns(true)
|
||||
Puppet::Util::IniConfig::File.expects(:new).returns(mock)
|
||||
mock.expects(:read).with('/etc/keystone/keystone.conf')
|
||||
expect do
|
||||
klass.get_admin_token
|
||||
end.to raise_error(Puppet::Error, /Keystone types will not work/)
|
||||
expect(klass.get_admin_token).to be_nil
|
||||
end
|
||||
|
||||
it 'should parse the admin token if it is in the config file' do
|
||||
mock = {'DEFAULT' => {'admin_token' => 'foo'}}
|
||||
File.expects(:exists?).with("/etc/keystone/keystone.conf").returns(true)
|
||||
Puppet::Util::IniConfig::File.expects(:new).returns(mock)
|
||||
mock.expects(:read).with('/etc/keystone/keystone.conf')
|
||||
klass.get_admin_token.should == 'foo'
|
||||
expect(klass.get_admin_token).to eq('foo')
|
||||
end
|
||||
|
||||
it 'should use the specified bind_host in the admin endpoint' do
|
||||
mock = {'DEFAULT' => {'admin_bind_host' => '192.168.56.210', 'admin_port' => '35357' }}
|
||||
File.expects(:exists?).with("/etc/keystone/keystone.conf").returns(true)
|
||||
Puppet::Util::IniConfig::File.expects(:new).returns(mock)
|
||||
mock.expects(:read).with('/etc/keystone/keystone.conf')
|
||||
klass.get_admin_endpoint.should == 'http://192.168.56.210:35357/v2.0/'
|
||||
expect(klass.get_admin_endpoint).to eq('http://192.168.56.210:35357/v2.0/')
|
||||
end
|
||||
|
||||
it 'should use localhost in the admin endpoint if bind_host is 0.0.0.0' do
|
||||
mock = {'DEFAULT' => { 'admin_bind_host' => '0.0.0.0', 'admin_port' => '35357' }}
|
||||
File.expects(:exists?).with("/etc/keystone/keystone.conf").returns(true)
|
||||
Puppet::Util::IniConfig::File.expects(:new).returns(mock)
|
||||
mock.expects(:read).with('/etc/keystone/keystone.conf')
|
||||
klass.get_admin_endpoint.should == 'http://127.0.0.1:35357/v2.0/'
|
||||
expect(klass.get_admin_endpoint).to eq('http://127.0.0.1:35357/v2.0/')
|
||||
end
|
||||
|
||||
it 'should use [::1] in the admin endpoint if bind_host is ::0' do
|
||||
mock = {'DEFAULT' => { 'admin_bind_host' => '::0', 'admin_port' => '35357' }}
|
||||
File.expects(:exists?).with("/etc/keystone/keystone.conf").returns(true)
|
||||
Puppet::Util::IniConfig::File.expects(:new).returns(mock)
|
||||
mock.expects(:read).with('/etc/keystone/keystone.conf')
|
||||
expect(klass.get_admin_endpoint).to eq('http://[::1]:35357/v2.0/')
|
||||
end
|
||||
|
||||
it 'should use localhost in the admin endpoint if bind_host is unspecified' do
|
||||
mock = {'DEFAULT' => { 'admin_port' => '35357' }}
|
||||
File.expects(:exists?).with("/etc/keystone/keystone.conf").returns(true)
|
||||
Puppet::Util::IniConfig::File.expects(:new).returns(mock)
|
||||
mock.expects(:read).with('/etc/keystone/keystone.conf')
|
||||
klass.get_admin_endpoint.should == 'http://127.0.0.1:35357/v2.0/'
|
||||
expect(klass.get_admin_endpoint).to eq('http://127.0.0.1:35357/v2.0/')
|
||||
end
|
||||
|
||||
it 'should use https if ssl is enabled' do
|
||||
mock = {'DEFAULT' => {'admin_bind_host' => '192.168.56.210', 'admin_port' => '35357' }, 'ssl' => {'enable' => 'True'}}
|
||||
File.expects(:exists?).with("/etc/keystone/keystone.conf").returns(true)
|
||||
Puppet::Util::IniConfig::File.expects(:new).returns(mock)
|
||||
mock.expects(:read).with('/etc/keystone/keystone.conf')
|
||||
klass.get_admin_endpoint.should == 'https://192.168.56.210:35357/v2.0/'
|
||||
expect(klass.get_admin_endpoint).to eq('https://192.168.56.210:35357/v2.0/')
|
||||
end
|
||||
|
||||
it 'should use http if ssl is disabled' do
|
||||
mock = {'DEFAULT' => {'admin_bind_host' => '192.168.56.210', 'admin_port' => '35357' }, 'ssl' => {'enable' => 'False'}}
|
||||
File.expects(:exists?).with("/etc/keystone/keystone.conf").returns(true)
|
||||
Puppet::Util::IniConfig::File.expects(:new).returns(mock)
|
||||
mock.expects(:read).with('/etc/keystone/keystone.conf')
|
||||
klass.get_admin_endpoint.should == 'http://192.168.56.210:35357/v2.0/'
|
||||
expect(klass.get_admin_endpoint).to eq('http://192.168.56.210:35357/v2.0/')
|
||||
end
|
||||
|
||||
it 'should use the defined admin_endpoint if available' do
|
||||
mock = {'DEFAULT' => {'admin_endpoint' => 'https://keystone.example.com/v2.0/' }, 'ssl' => {'enable' => 'False'}}
|
||||
mock = {'DEFAULT' => {'admin_endpoint' => 'https://keystone.example.com' }, 'ssl' => {'enable' => 'False'}}
|
||||
File.expects(:exists?).with("/etc/keystone/keystone.conf").returns(true)
|
||||
Puppet::Util::IniConfig::File.expects(:new).returns(mock)
|
||||
mock.expects(:read).with('/etc/keystone/keystone.conf')
|
||||
klass.get_admin_endpoint.should == 'https://keystone.example.com/v2.0/'
|
||||
expect(klass.get_admin_endpoint).to eq('https://keystone.example.com/v2.0/')
|
||||
end
|
||||
|
||||
describe 'when testing keystone connection retries' do
|
||||
|
||||
['(HTTP 400)',
|
||||
'[Errno 111] Connection refused',
|
||||
'503 Service Unavailable',
|
||||
'Max retries exceeded',
|
||||
'HTTP Unable to establish connection',
|
||||
'Unable to establish connection to http://127.0.0.1:35357/v2.0/OS-KSADM/roles'
|
||||
].reverse.each do |valid_message|
|
||||
it "should retry when keystone is not ready with error #{valid_message}" do
|
||||
mock = {'DEFAULT' => {'admin_token' => 'foo'}}
|
||||
Puppet::Util::IniConfig::File.expects(:new).returns(mock)
|
||||
mock.expects(:read).with('/etc/keystone/keystone.conf')
|
||||
klass.expects(:sleep).with(10).returns(nil)
|
||||
klass.expects(:keystone).twice.with('--os-endpoint', 'http://127.0.0.1:35357/v2.0/', ['test_retries']).raises(Exception, valid_message).then.returns('')
|
||||
klass.auth_keystone('test_retries')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe 'when keystone cli has warnings' do
|
||||
it "should remove errors from results" do
|
||||
mock = {'DEFAULT' => {'admin_token' => 'foo'}}
|
||||
it 'should handle an admin_endpoint with a trailing slash' do
|
||||
mock = {'DEFAULT' => {'admin_endpoint' => 'https://keystone.example.com/' }, 'ssl' => {'enable' => 'False'}}
|
||||
File.expects(:exists?).with("/etc/keystone/keystone.conf").returns(true)
|
||||
Puppet::Util::IniConfig::File.expects(:new).returns(mock)
|
||||
mock.expects(:read).with('/etc/keystone/keystone.conf')
|
||||
klass.expects(
|
||||
:keystone
|
||||
).with(
|
||||
'--os-endpoint',
|
||||
'http://127.0.0.1:35357/v2.0/',
|
||||
['test_retries']
|
||||
).returns("WARNING\n+-+-+\nWARNING")
|
||||
klass.auth_keystone('test_retries').should == "+-+-+\nWARNING"
|
||||
expect(klass.get_admin_endpoint).to eq('https://keystone.example.com/v2.0/')
|
||||
end
|
||||
end
|
||||
|
||||
describe 'when query keystone objects' do
|
||||
it 'should not cache keystone objects in catalog' do
|
||||
klass.stubs(:build_tenant_hash).returns({ 'foo' => 'bar' })
|
||||
klass.tenant_hash.should == ({ 'foo' => 'bar' })
|
||||
klass.stubs(:build_tenant_hash).returns({ 'baz' => 'qux' })
|
||||
klass.tenant_hash.should == ({ 'baz' => 'qux' })
|
||||
end
|
||||
end
|
||||
|
||||
describe 'when parsing keystone objects' do
|
||||
it 'should parse valid output into a hash' do
|
||||
data = <<-EOT
|
||||
+-------------+----------------------------------+
|
||||
| Property | Value |
|
||||
+-------------+----------------------------------+
|
||||
| description | default tenant |
|
||||
| enabled | True |
|
||||
| id | b71040f47e144399b7f10182918b5e2f |
|
||||
| name | demo |
|
||||
+-------------+----------------------------------+
|
||||
EOT
|
||||
expected = {
|
||||
'description' => 'default tenant',
|
||||
'enabled' => 'True',
|
||||
'id' => 'b71040f47e144399b7f10182918b5e2f',
|
||||
'name' => 'demo'
|
||||
}
|
||||
klass.parse_keystone_object(data).should == expected
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -1,65 +0,0 @@
|
||||
require 'puppet'
|
||||
require 'spec_helper'
|
||||
require 'puppet/provider/keystone_tenant/keystone'
|
||||
|
||||
provider_class = Puppet::Type.type(:keystone_tenant).provider(:keystone)
|
||||
|
||||
describe provider_class do
|
||||
|
||||
describe 'when updating a tenant' do
|
||||
|
||||
let :tenant_name do
|
||||
'foo'
|
||||
end
|
||||
|
||||
let :tenant_attrs do
|
||||
{
|
||||
:name => tenant_name,
|
||||
:description => '',
|
||||
:ensure => 'present',
|
||||
:enabled => 'True',
|
||||
}
|
||||
end
|
||||
|
||||
let :tenant_hash do
|
||||
{ tenant_name => {
|
||||
:id => 'id',
|
||||
:name => tenant_name,
|
||||
:description => '',
|
||||
:ensure => 'present',
|
||||
:enabled => 'True',
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
let :resource do
|
||||
Puppet::Type::Keystone_tenant.new(tenant_attrs)
|
||||
end
|
||||
|
||||
let :provider do
|
||||
provider_class.new(resource)
|
||||
end
|
||||
|
||||
before :each do
|
||||
provider_class.expects(:build_tenant_hash).at_least(1).returns(tenant_hash)
|
||||
end
|
||||
|
||||
it 'should call tenant-update to set enabled' do
|
||||
provider.expects(:auth_keystone).with('tenant-update',
|
||||
'--enabled',
|
||||
'False',
|
||||
'id')
|
||||
provider.enabled=('False')
|
||||
end
|
||||
end
|
||||
|
||||
describe 'when query keystone objects' do
|
||||
it 'should not cache keystone objects in catalog' do
|
||||
provider_class.stubs(:build_tenant_hash).returns({ 'foo' => 'bar' })
|
||||
provider_class.tenant_hash.should == ({ 'foo' => 'bar' })
|
||||
provider_class.stubs(:build_tenant_hash).returns({ 'baz' => 'qux' })
|
||||
provider_class.tenant_hash.should == ({ 'baz' => 'qux' })
|
||||
end
|
||||
end
|
||||
|
||||
end
|
@ -0,0 +1,90 @@
|
||||
require 'puppet'
|
||||
require 'spec_helper'
|
||||
require 'puppet/provider/keystone_tenant/openstack'
|
||||
|
||||
provider_class = Puppet::Type.type(:keystone_tenant).provider(:openstack)
|
||||
|
||||
describe provider_class do
|
||||
|
||||
shared_examples 'authenticated with environment variables' do
|
||||
ENV['OS_USERNAME'] = 'test'
|
||||
ENV['OS_PASSWORD'] = 'abc123'
|
||||
ENV['OS_PROJECT_NAME'] = 'test'
|
||||
ENV['OS_AUTH_URL'] = 'http://127.0.0.1:35357/v2.0'
|
||||
end
|
||||
|
||||
describe 'when managing a tenant' do
|
||||
|
||||
let(:tenant_attrs) do
|
||||
{
|
||||
:name => 'foo',
|
||||
:description => 'foo',
|
||||
:ensure => 'present',
|
||||
:enabled => 'True',
|
||||
}
|
||||
end
|
||||
|
||||
let(:resource) do
|
||||
Puppet::Type::Keystone_tenant.new(tenant_attrs)
|
||||
end
|
||||
|
||||
let(:provider) do
|
||||
provider_class.new(resource)
|
||||
end
|
||||
|
||||
it_behaves_like 'authenticated with environment variables' do
|
||||
describe '#create' do
|
||||
it 'creates a tenant' do
|
||||
provider.class.stubs(:openstack)
|
||||
.with('project', 'list', '--quiet', '--format', 'csv', '--long')
|
||||
.returns('"ID","Name","Description","Enabled"
|
||||
"1cb05cfed7c24279be884ba4f6520262","foo","foo",True
|
||||
')
|
||||
provider.class.stubs(:openstack)
|
||||
.with('project', 'create', '--format', 'shell', ['foo', '--enable', '--description', 'foo'])
|
||||
.returns('description="foo"
|
||||
enabled="True"
|
||||
name="foo"
|
||||
')
|
||||
provider.create
|
||||
expect(provider.exists?).to be_truthy
|
||||
end
|
||||
end
|
||||
|
||||
describe '#destroy' do
|
||||
it 'destroys a tenant' do
|
||||
provider.class.stubs(:openstack)
|
||||
.with('project', 'list', '--quiet', '--format', 'csv', '--long')
|
||||
.returns('"ID","Name","Description","Enabled"')
|
||||
provider.class.stubs(:openstack)
|
||||
.with('project', 'delete', [])
|
||||
provider.destroy
|
||||
expect(provider.exists?).to be_falsey
|
||||
end
|
||||
end
|
||||
|
||||
context 'when tenant does not exist' do
|
||||
subject(:response) do
|
||||
provider.class.stubs(:openstack)
|
||||
.with('project', 'list', '--quiet', '--format', 'csv', '--long')
|
||||
.returns('"ID","Name","Description","Enabled"')
|
||||
response = provider.exists?
|
||||
end
|
||||
|
||||
it { is_expected.to be_falsey }
|
||||
end
|
||||
|
||||
describe '#instances' do
|
||||
it 'finds every tenant' do
|
||||
provider.class.stubs(:openstack)
|
||||
.with('project', 'list', '--quiet', '--format', 'csv', '--long')
|
||||
.returns('"ID","Name","Description","Enabled"
|
||||
"1cb05cfed7c24279be884ba4f6520262","foo","foo",True
|
||||
')
|
||||
instances = Puppet::Type::Keystone_tenant::ProviderOpenstack.instances
|
||||
expect(instances.count).to eq(1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -1,78 +0,0 @@
|
||||
require 'puppet'
|
||||
require 'spec_helper'
|
||||
require 'puppet/provider/keystone_user/keystone'
|
||||
|
||||
provider_class = Puppet::Type.type(:keystone_user).provider(:keystone)
|
||||
|
||||
describe provider_class do
|
||||
|
||||
describe 'when updating a user' do
|
||||
let :resource do
|
||||
Puppet::Type::Keystone_user.new(
|
||||
{
|
||||
:name => 'foo',
|
||||
:ensure => 'present',
|
||||
:enabled => 'True',
|
||||
:tenant => 'foo2',
|
||||
:email => 'foo@foo.com',
|
||||
:password => 'passwd'
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
let :provider do
|
||||
provider_class.new(resource)
|
||||
end
|
||||
|
||||
before :each do
|
||||
provider_class.expects(:build_user_hash).at_least(1).returns(
|
||||
'foo' => {:id => 'id', :name => 'foo', :tenant => 'foo2', :password => 'passwd'}
|
||||
)
|
||||
end
|
||||
|
||||
after :each do
|
||||
# reset global state
|
||||
provider_class.prefetch(nil)
|
||||
end
|
||||
|
||||
it 'should call user-password-update to change password' do
|
||||
provider.expects(:auth_keystone).with('user-password-update', '--pass', 'newpassword', 'id')
|
||||
provider.password=('newpassword')
|
||||
end
|
||||
end
|
||||
|
||||
describe 'when query keystone objects' do
|
||||
it 'should not cache keystone objects in catalog' do
|
||||
provider_class.stubs(:build_user_hash).returns({ 'foo' => 'bar' })
|
||||
provider_class.user_hash.should == ({ 'foo' => 'bar' })
|
||||
provider_class.stubs(:build_user_hash).returns({ 'baz' => 'qux' })
|
||||
provider_class.user_hash.should == ({ 'baz' => 'qux' })
|
||||
end
|
||||
end
|
||||
|
||||
describe 'when updating a user with unmanaged password' do
|
||||
let :resource do
|
||||
Puppet::Type::Keystone_user.new(
|
||||
{
|
||||
:name => 'foo',
|
||||
:ensure => 'present',
|
||||
:enabled => 'True',
|
||||
:tenant => 'foo2',
|
||||
:email => 'foo@foo.com',
|
||||
:password => 'passwd',
|
||||
:replace_password => 'False',
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
let :provider do
|
||||
provider_class.new(resource)
|
||||
end
|
||||
|
||||
it 'should not call user-password-update to change password' do
|
||||
provider.expects(:auth_keystone).with('user-password-update', '--pass', 'newpassword', 'id').times(0)
|
||||
provider.password=('newpassword')
|
||||
end
|
||||
end
|
||||
|
||||
end
|
@ -0,0 +1,277 @@
|
||||
require 'puppet'
|
||||
require 'spec_helper'
|
||||
require 'puppet/provider/keystone_user/openstack'
|
||||
|
||||
provider_class = Puppet::Type.type(:keystone_user).provider(:openstack)
|
||||
|
||||
describe provider_class do
|
||||
|
||||
shared_examples 'authenticated with environment variables' do
|
||||
ENV['OS_USERNAME'] = 'test'
|
||||
ENV['OS_PASSWORD'] = 'abc123'
|
||||
ENV['OS_PROJECT_NAME'] = 'test'
|
||||
ENV['OS_AUTH_URL'] = 'http://127.0.0.1:5000'
|
||||
end
|
||||
|
||||
let(:user_attrs) do
|
||||
{
|
||||
:name => 'foo',
|
||||
:ensure => :present,
|
||||
:enabled => 'True',
|
||||
:password => 'foo',
|
||||
:tenant => 'foo',
|
||||
:email => 'foo@example.com',
|
||||
}
|
||||
end
|
||||
|
||||
let(:resource) do
|
||||
Puppet::Type::Keystone_user.new(user_attrs)
|
||||
end
|
||||
|
||||
let(:provider) do
|
||||
provider_class.new(resource)
|
||||
end
|
||||
|
||||
describe 'when managing a user' do
|
||||
it_behaves_like 'authenticated with environment variables' do
|
||||
describe '#create' do
|
||||
it 'creates a user' do
|
||||
provider.class.stubs(:openstack)
|
||||
.with('user', 'list', '--quiet', '--format', 'csv', '--long')
|
||||
.returns('"ID","Name","Project","Email","Enabled"
|
||||
"1cb05cfed7c24279be884ba4f6520262","foo","foo","foo@example.com",True
|
||||
')
|
||||
provider.class.stubs(:openstack)
|
||||
.with('user', 'create', '--format', 'shell', ['foo', '--enable', '--password', 'foo', '--project', 'foo', '--email', 'foo@example.com'])
|
||||
.returns('email="foo@example.com"
|
||||
enabled="True"
|
||||
id="12b23f07d4a3448d8189521ab09610b0"
|
||||
name="foo"
|
||||
project_id="5e2001b2248540f191ff22627dc0c2d7"
|
||||
username="foo"
|
||||
')
|
||||
provider.create
|
||||
expect(provider.exists?).to be_truthy
|
||||
end
|
||||
end
|
||||
|
||||
describe '#destroy' do
|
||||
it 'destroys a user' do
|
||||
provider.class.stubs(:openstack)
|
||||
.with('user', 'list', '--quiet', '--format', 'csv', '--long')
|
||||
.returns('"ID","Name","Project","Email","Enabled"')
|
||||
provider.class.stubs(:openstack)
|
||||
.with('user', 'delete', [])
|
||||
provider.destroy
|
||||
expect(provider.exists?).to be_falsey
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe '#exists' do
|
||||
context 'when user does not exist' do
|
||||
subject(:response) do
|
||||
provider.class.stubs(:openstack)
|
||||
.with('user', 'list', '--quiet', '--format', 'csv', '--long')
|
||||
.returns('"ID","Name","Project","Email","Enabled"')
|
||||
response = provider.exists?
|
||||
end
|
||||
|
||||
it { is_expected.to be_falsey }
|
||||
end
|
||||
end
|
||||
|
||||
describe '#instances' do
|
||||
it 'finds every user' do
|
||||
provider.class.stubs(:openstack)
|
||||
.with('user', 'list', '--quiet', '--format', 'csv', '--long')
|
||||
.returns('"ID","Name","Project","Email","Enabled"
|
||||
"1cb05cfed7c24279be884ba4f6520262","foo","foo","foo@example.com",True
|
||||
')
|
||||
instances = Puppet::Type::Keystone_user::ProviderOpenstack.instances
|
||||
expect(instances.count).to eq(1)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#tenant' do
|
||||
it 'gets the tenant with default backend' do
|
||||
provider.class.stubs(:openstack)
|
||||
.with('user', 'list', '--quiet', '--format', 'csv', '--long')
|
||||
.returns('"ID","Name","Project","Email","Enabled"
|
||||
"1cb05cfed7c24279be884ba4f6520262","foo","foo","foo@example.com",True
|
||||
')
|
||||
provider.class.stubs(:openstack)
|
||||
.with('user role', 'list', '--quiet', '--format', 'csv', ['foo', '--project', 'foo'])
|
||||
.returns('"ID","Name","Project","User"
|
||||
"9fe2ff9ee4384b1894a90878d3e92bab","_member_","foo","foo"
|
||||
')
|
||||
tenant = provider.tenant
|
||||
expect(tenant).to eq('foo')
|
||||
end
|
||||
|
||||
it 'gets the tenant with LDAP backend' do
|
||||
provider.class.stubs(:openstack)
|
||||
.with('user', 'list', '--quiet', '--format', 'csv', '--long')
|
||||
.returns('"ID","Name","Project","Email","Enabled"
|
||||
"1cb05cfed7c24279be884ba4f6520262","foo","","foo@example.com",True
|
||||
')
|
||||
provider.class.expects(:openstack)
|
||||
.with('user role', 'list', '--quiet', '--format', 'csv', ['foo', '--project', 'foo'])
|
||||
.returns('"ID","Name","Project","User"
|
||||
"1cb05cfed7c24279be884ba4f6520262","foo","foo","foo"
|
||||
')
|
||||
tenant = provider.tenant
|
||||
expect(tenant).to eq('foo')
|
||||
end
|
||||
end
|
||||
|
||||
describe '#tenant=' do
|
||||
context 'when using default backend' do
|
||||
it 'sets the tenant' do
|
||||
provider.class.expects(:openstack)
|
||||
.with('user', 'set', ['foo', '--project', 'bar'])
|
||||
provider.class.expects(:openstack)
|
||||
.with('user role', 'list', '--quiet', '--format', 'csv', ['foo', '--project', 'bar'])
|
||||
.returns('"ID","Name","Project","User"
|
||||
"9fe2ff9ee4384b1894a90878d3e92bab","_member_","bar","foo"
|
||||
')
|
||||
provider.tenant=('bar')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when using LDAP read-write backend' do
|
||||
it 'sets the tenant when _member_ role exists' do
|
||||
provider.class.expects(:openstack)
|
||||
.with('user', 'set', ['foo', '--project', 'bar'])
|
||||
provider.class.expects(:openstack)
|
||||
.with('user role', 'list', '--quiet', '--format', 'csv', ['foo', '--project', 'bar'])
|
||||
.returns('')
|
||||
provider.class.expects(:openstack)
|
||||
.with('role', 'show', '--format', 'shell', ['_member_'])
|
||||
.returns('id="9fe2ff9ee4384b1894a90878d3e92bab"
|
||||
name="_member_"
|
||||
')
|
||||
provider.class.expects(:openstack)
|
||||
.with('role', 'add', ['_member_', '--project', 'bar', '--user', 'foo'])
|
||||
provider.tenant=('bar')
|
||||
end
|
||||
it 'sets the tenant when _member_ role does not exist' do
|
||||
provider.class.expects(:openstack)
|
||||
.with('user', 'set', ['foo', '--project', 'bar'])
|
||||
provider.class.expects(:openstack)
|
||||
.with('user role', 'list', '--quiet', '--format', 'csv', ['foo', '--project', 'bar'])
|
||||
.returns('')
|
||||
provider.class.expects(:openstack)
|
||||
.with('role', 'show', '--format', 'shell', ['_member_'])
|
||||
.raises(Puppet::ExecutionFailure, 'no such role _member_')
|
||||
provider.class.expects(:openstack)
|
||||
.with('role', 'create', '--format', 'shell', ['_member_'])
|
||||
.returns('name="_member_"')
|
||||
provider.class.expects(:openstack)
|
||||
.with('role', 'add', ['_member_', '--project', 'bar', '--user', 'foo'])
|
||||
.returns('id="8wr2ff9ee4384b1894a90878d3e92bab"
|
||||
name="_member_"
|
||||
')
|
||||
provider.tenant=('bar')
|
||||
end
|
||||
end
|
||||
|
||||
# This doesn't make sense, need to clarify what's happening with LDAP mock
|
||||
=begin
|
||||
context 'when using LDAP read-only backend' do
|
||||
it 'sets the tenant when _member_ role exists' do
|
||||
provider.class.expects(:openstack)
|
||||
.with('user', 'set', [['foo', '--project', 'bar']])
|
||||
.raises(Puppet::ExecutionFailure, 'You are not authorized to perform the requested action: LDAP user update')
|
||||
provider.class.expects(:openstack)
|
||||
.with('user role', 'list', '--quiet', '--format', 'csv', [['foo', '--project', 'bar']])
|
||||
.returns('')
|
||||
provider.class.expects(:openstack)
|
||||
.with('role', 'show', '--format', 'shell', [['_member_']])
|
||||
.returns('id="9fe2ff9ee4384b1894a90878d3e92bab"
|
||||
name="_member_"
|
||||
')
|
||||
provider.class.expects(:openstack)
|
||||
.with('role', 'add', [['_member_', '--project', 'bar', '--user', 'foo']])
|
||||
provider.tenant=('bar')
|
||||
end
|
||||
|
||||
it 'sets the tenant and gets an unexpected exception message' do
|
||||
provider.class.expects(:openstack)
|
||||
.with('user', 'set', [['foo', '--project', 'bar']])
|
||||
.raises(Puppet::ExecutionFailure, 'unknown error message')
|
||||
expect{ provider.tenant=('bar') }.to raise_error(Puppet::ExecutionFailure, /unknown error message/)
|
||||
end
|
||||
end
|
||||
=end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#password" do
|
||||
let(:user_attrs) do
|
||||
{
|
||||
:name => 'foo',
|
||||
:ensure => 'present',
|
||||
:enabled => 'True',
|
||||
:password => 'foo',
|
||||
:tenant => 'foo',
|
||||
:email => 'foo@example.com',
|
||||
}
|
||||
end
|
||||
|
||||
let(:resource) do
|
||||
Puppet::Type::Keystone_user.new(user_attrs)
|
||||
end
|
||||
|
||||
let :provider do
|
||||
provider_class.new(resource)
|
||||
end
|
||||
|
||||
shared_examples 'with auth-url environment variable' do
|
||||
ENV['OS_AUTH_URL'] = 'http://localhost:5000'
|
||||
end
|
||||
|
||||
it_behaves_like 'with auth-url environment variable' do
|
||||
it 'checks the password' do
|
||||
Puppet::Provider::Openstack.stubs(:openstack)
|
||||
.with('token', 'issue', ['--format', 'value'])
|
||||
.returns('2015-05-14T04:06:05Z
|
||||
e664a386befa4a30878dcef20e79f167
|
||||
8dce2ae9ecd34c199d2877bf319a3d06
|
||||
ac43ec53d5a74a0b9f51523ae41a29f0
|
||||
')
|
||||
password = provider.password
|
||||
expect(password).to eq('foo')
|
||||
end
|
||||
|
||||
it 'fails the password check' do
|
||||
Puppet::Provider::Openstack.stubs(:openstack)
|
||||
.with('token', 'issue', ['--format', 'value'])
|
||||
.raises(Puppet::ExecutionFailure, 'HTTP 401 invalid authentication')
|
||||
password = provider.password
|
||||
expect(password).to eq(nil)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'when updating a user with unmanaged password' do
|
||||
|
||||
let(:user_attrs) do
|
||||
{
|
||||
:name => 'foo',
|
||||
:ensure => 'present',
|
||||
:enabled => 'True',
|
||||
:password => 'foo',
|
||||
:replace_password => 'False',
|
||||
:tenant => 'foo',
|
||||
:email => 'foo@example.com',
|
||||
}
|
||||
end
|
||||
|
||||
it 'should not try to check password' do
|
||||
expect(provider.password).to eq('foo')
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
@ -1,50 +0,0 @@
|
||||
require 'puppet'
|
||||
require 'spec_helper'
|
||||
require 'puppet/provider/keystone_user_role/keystone'
|
||||
|
||||
provider_class = Puppet::Type.type(:keystone_user_role).provider(:keystone)
|
||||
|
||||
describe provider_class do
|
||||
|
||||
describe '#get_user_and_tenant' do
|
||||
|
||||
let :user do
|
||||
'username'
|
||||
end
|
||||
|
||||
let :tenant do
|
||||
'test@example.org'
|
||||
end
|
||||
|
||||
let :resource do
|
||||
Puppet::Type::Keystone_user_role.new(
|
||||
{
|
||||
:name => "#{user}@#{tenant}",
|
||||
:roles => [ '_member_' ],
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
let :provider do
|
||||
provider_class.new(resource)
|
||||
end
|
||||
|
||||
before :each do
|
||||
provider_class.expects(:get_user_and_tenant).with(user,tenant).returns([user,tenant])
|
||||
end
|
||||
|
||||
it 'should handle an email address as username' do
|
||||
provider.get_user_and_tenant.should == [ user, tenant ]
|
||||
end
|
||||
end
|
||||
|
||||
describe 'when query keystone objects' do
|
||||
it 'should not cache keystone objects in catalog' do
|
||||
provider_class.stubs(:build_user_role_hash).returns({ 'foo' => 'bar' })
|
||||
provider_class.user_role_hash.should == ({ 'foo' => 'bar' })
|
||||
provider_class.stubs(:build_user_role_hash).returns({ 'baz' => 'qux' })
|
||||
provider_class.user_role_hash.should == ({ 'baz' => 'qux' })
|
||||
end
|
||||
end
|
||||
|
||||
end
|
@ -0,0 +1,89 @@
|
||||
require 'puppet'
|
||||
require 'spec_helper'
|
||||
require 'puppet/provider/keystone_user_role/openstack'
|
||||
|
||||
provider_class = Puppet::Type.type(:keystone_user_role).provider(:openstack)
|
||||
|
||||
describe provider_class do
|
||||
|
||||
shared_examples 'authenticated with environment variables' do
|
||||
ENV['OS_USERNAME'] = 'test'
|
||||
ENV['OS_PASSWORD'] = 'abc123'
|
||||
ENV['OS_PROJECT_NAME'] = 'test'
|
||||
ENV['OS_AUTH_URL'] = 'http://127.0.0.1:5000'
|
||||
end
|
||||
|
||||
describe 'when updating a user\'s role' do
|
||||
it_behaves_like 'authenticated with environment variables' do
|
||||
let(:user_role_attrs) do
|
||||
{
|
||||
:name => 'foo@foo',
|
||||
:ensure => 'present',
|
||||
:roles => ['foo', 'bar'],
|
||||
}
|
||||
end
|
||||
|
||||
let(:resource) do
|
||||
Puppet::Type::Keystone_user_role.new(user_role_attrs)
|
||||
end
|
||||
|
||||
let(:provider) do
|
||||
provider_class.new(resource)
|
||||
end
|
||||
|
||||
before(:each) do
|
||||
provider.class.stubs(:openstack)
|
||||
.with('user', 'list', '--quiet', '--format', 'csv', ['foo', '--project', 'foo'])
|
||||
.returns('"ID","Name","Project","User"
|
||||
"1cb05cfed7c24279be884ba4f6520262","foo","foo","foo"
|
||||
')
|
||||
end
|
||||
|
||||
describe '#create' do
|
||||
it 'adds all the roles to the user' do
|
||||
provider.class.stubs(:openstack)
|
||||
.with('role', 'add', ['foo', '--project', 'foo', '--user', 'foo'])
|
||||
provider.class.stubs(:openstack)
|
||||
.with('role', 'add', ['bar', '--project', 'foo', '--user', 'foo'])
|
||||
provider.class.stubs(:openstack)
|
||||
.with('user role', 'list', '--quiet', '--format', 'csv', ['foo', '--project', 'foo'])
|
||||
.returns('"ID","Name","Project","User"
|
||||
"1cb05ed7c24279be884ba4f6520262","foo","foo","foo"
|
||||
"2cb05ed7c24279be884ba4f6520262","bar","foo","foo"
|
||||
')
|
||||
provider.create
|
||||
expect(provider.exists?).to be_truthy
|
||||
end
|
||||
end
|
||||
|
||||
describe '#destroy' do
|
||||
it 'removes all the roles from a user' do
|
||||
provider.class.stubs(:openstack)
|
||||
.with('user role', 'list', '--quiet', '--format', 'csv', ['foo', '--project', 'foo'])
|
||||
.returns('"ID","Name","Project","User"')
|
||||
provider.class.stubs(:openstack)
|
||||
.with('role', 'remove', ['foo', '--project', 'foo', '--user', 'foo'])
|
||||
provider.class.stubs(:openstack)
|
||||
.with('role', 'remove', ['bar', '--project', 'foo', '--user', 'foo'])
|
||||
provider.destroy
|
||||
expect(provider.exists?).to be_falsey
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe '#exists' do
|
||||
subject(:response) do
|
||||
provider.class.stubs(:openstack)
|
||||
.with('user role', 'list', '--quiet', '--format', 'csv', ['foo', '--project', 'foo'])
|
||||
.returns('"ID","Name","Project","User"
|
||||
"1cb05ed7c24279be884ba4f6520262","foo","foo","foo"
|
||||
')
|
||||
response = provider.exists?
|
||||
end
|
||||
|
||||
it { is_expected.to be_truthy }
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -0,0 +1,23 @@
|
||||
require 'spec_helper'
|
||||
# this hack is required for now to ensure that the path is set up correctly
|
||||
# to retrive the parent provider
|
||||
$LOAD_PATH.push(
|
||||
File.join(
|
||||
File.dirname(__FILE__),
|
||||
'..',
|
||||
'..',
|
||||
'fixtures',
|
||||
'modules',
|
||||
'inifile',
|
||||
'lib')
|
||||
)
|
||||
require 'puppet/type/keystone_paste_ini'
|
||||
describe 'Puppet::Type.type(:keystone_paste_ini)' do
|
||||
before :each do
|
||||
@keystone_paste_ini = Puppet::Type.type(:keystone_paste_ini).new(:name => 'DEFAULT/foo', :value => 'bar')
|
||||
end
|
||||
it 'should accept a valid value' do
|
||||
@keystone_paste_ini[:value] = 'bar'
|
||||
@keystone_paste_ini[:value].should == 'bar'
|
||||
end
|
||||
end
|
@ -0,0 +1,28 @@
|
||||
require 'spec_helper'
|
||||
require 'puppet'
|
||||
require 'puppet/type/keystone_user_role'
|
||||
|
||||
describe Puppet::Type.type(:keystone_user_role) do
|
||||
|
||||
before :each do
|
||||
@user_roles = Puppet::Type.type(:keystone_user_role).new(
|
||||
:name => 'foo@bar',
|
||||
:roles => ['a', 'b']
|
||||
)
|
||||
|
||||
@roles = @user_roles.parameter('roles')
|
||||
end
|
||||
|
||||
it 'should not be in sync for' do
|
||||
expect(@roles.insync?(['a', 'b', 'c'])).to be false
|
||||
expect(@roles.insync?('a')).to be false
|
||||
expect(@roles.insync?(['a'])).to be false
|
||||
expect(@roles.insync?(nil)).to be false
|
||||
end
|
||||
|
||||
it 'should be in sync for' do
|
||||
expect(@roles.insync?(['a', 'b'])).to be true
|
||||
expect(@roles.insync?(['b', 'a'])).to be true
|
||||
end
|
||||
|
||||
end
|
@ -5,36 +5,36 @@ package { 'curl': ensure => present }
|
||||
# example of how to build a single node
|
||||
# keystone instance backed by sqlite
|
||||
# with all of the default admin roles
|
||||
node keystone_sqlite {
|
||||
class { 'keystone':
|
||||
node 'keystone_sqlite' {
|
||||
class { '::keystone':
|
||||
verbose => true,
|
||||
debug => true,
|
||||
catalog_type => 'sql',
|
||||
admin_token => 'admin_token',
|
||||
}
|
||||
class { 'keystone::roles::admin':
|
||||
class { '::keystone::roles::admin':
|
||||
email => 'example@abc.com',
|
||||
password => 'ChangeMe',
|
||||
}
|
||||
class { 'keystone::endpoint':
|
||||
class { '::keystone::endpoint':
|
||||
public_url => "http://${::fqdn}:5000/",
|
||||
admin_url => "http://${::fqdn}:35357/",
|
||||
}
|
||||
}
|
||||
|
||||
node keystone_mysql {
|
||||
class { 'mysql::server': }
|
||||
class { 'keystone::db::mysql':
|
||||
class { '::mysql::server': }
|
||||
class { '::keystone::db::mysql':
|
||||
password => 'keystone',
|
||||
}
|
||||
class { 'keystone':
|
||||
verbose => true,
|
||||
debug => true,
|
||||
sql_connection => 'mysql://keystone:keystone@127.0.0.1/keystone',
|
||||
catalog_type => 'sql',
|
||||
admin_token => 'admin_token',
|
||||
class { '::keystone':
|
||||
verbose => true,
|
||||
debug => true,
|
||||
database_connection => 'mysql://keystone:keystone@127.0.0.1/keystone',
|
||||
catalog_type => 'sql',
|
||||
admin_token => 'admin_token',
|
||||
}
|
||||
class { 'keystone::roles::admin':
|
||||
class { '::keystone::roles::admin':
|
||||
email => 'test@puppetlabs.com',
|
||||
password => 'ChangeMe',
|
||||
}
|
||||
@ -43,21 +43,21 @@ node keystone_mysql {
|
||||
|
||||
# keystone with mysql on another node
|
||||
node keystone {
|
||||
class { 'keystone':
|
||||
verbose => true,
|
||||
debug => true,
|
||||
sql_connection => 'mysql://keystone:password@127.0.0.1/keystone',
|
||||
catalog_type => 'sql',
|
||||
admin_token => 'admin_token',
|
||||
class { '::keystone':
|
||||
verbose => true,
|
||||
debug => true,
|
||||
database_connection => 'mysql://keystone:password@127.0.0.1/keystone',
|
||||
catalog_type => 'sql',
|
||||
admin_token => 'admin_token',
|
||||
}
|
||||
class { 'keystone::db::mysql':
|
||||
class { '::keystone::db::mysql':
|
||||
password => 'keystone',
|
||||
}
|
||||
class { 'keystone::roles::admin':
|
||||
class { '::keystone::roles::admin':
|
||||
email => 'example@abc.com',
|
||||
password => 'ChangeMe',
|
||||
}
|
||||
class { 'keystone::endpoint':
|
||||
class { '::keystone::endpoint':
|
||||
public_url => "http://${::fqdn}:5000/",
|
||||
admin_url => "http://${::fqdn}:35357/",
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user