From 9f20bb0c50a1a58397c15a28fbe5318a43e6fd60 Mon Sep 17 00:00:00 2001 From: Rich Megginson Date: Thu, 16 Oct 2014 18:26:50 -0600 Subject: [PATCH] support Keystone LDAP identity backend Add support for the Keystone LDAP identity backend. This includes all of the class parameters of the puppet-keystone keystone::ldap class. This also adds a validator for LDAP DN values and LDAP URL values. Closes-Bug: #1383793 Change-Id: I493c183335627a27d8061e0345948457c2bc8e42 --- packstack/installer/validators.py | 47 +- packstack/plugins/keystone_100.py | 876 ++++++++++++++++-- .../puppet/parser/functions/hiera_undef.rb | 21 + packstack/puppet/templates/keystone.pp | 59 ++ 4 files changed, 907 insertions(+), 96 deletions(-) create mode 100644 packstack/puppet/modules/packstack/lib/puppet/parser/functions/hiera_undef.rb diff --git a/packstack/installer/validators.py b/packstack/installer/validators.py index 6b6be3f90..d1785e2e0 100644 --- a/packstack/installer/validators.py +++ b/packstack/installer/validators.py @@ -19,7 +19,7 @@ __all__ = ('ParamValidationError', 'validate_integer', 'validate_float', 'validate_options', 'validate_multi_options', 'validate_ip', 'validate_multi_ip', 'validate_file', 'validate_ping', 'validate_multi_ping', 'validate_ssh', 'validate_multi_ssh', - 'validate_sshkey') + 'validate_sshkey', 'validate_ldap_url', 'validate_ldap_dn') def validate_integer(param, options=None): @@ -261,3 +261,48 @@ def validate_sshkey(param, options=None): msg = 'Public SSH key is required. You passed private key.' if msg: raise ParamValidationError(msg) + + +def validate_ldap_url(param, options=None): + """ + Raises ParamValidationError if provided param is not a valid LDAP URL + """ + if not param: + return + try: + import ldapurl + except ImportError: + msg = ( + 'The python ldap package is required to use this functionality.' + ) + raise ParamValidationError(msg) + + try: + ldapurl.LDAPUrl(param) + except ValueError as ve: + msg = ('The given string [%s] is not a valid LDAP URL: %s' % + (param, ve)) + raise ParamValidationError(msg) + + +def validate_ldap_dn(param, options=None): + """ + Raises ParamValidationError if provided param is not a valid LDAP DN + """ + if not param: + return + try: + import ldap + import ldap.dn + except ImportError: + msg = ( + 'The python ldap package is required to use this functionality.' + ) + raise ParamValidationError(msg) + + try: + ldap.dn.str2dn(param) + except ldap.DECODING_ERROR as de: + msg = ('The given string [%s] is not a valid LDAP DN: %s' % + (param, de)) + raise ParamValidationError(msg) diff --git a/packstack/plugins/keystone_100.py b/packstack/plugins/keystone_100.py index ef8c9086a..2dd1d31b7 100644 --- a/packstack/plugins/keystone_100.py +++ b/packstack/plugins/keystone_100.py @@ -22,112 +22,760 @@ PLUGIN_NAME_COLORED = utils.color_text(PLUGIN_NAME, 'blue') def initConfig(controller): - params = [ - {"CMD_OPTION": "keystone-db-passwd", - "USAGE": "The password to use for the Keystone to access DB", - "PROMPT": "Enter the password for the Keystone DB access", - "OPTION_LIST": [], - "VALIDATORS": [validators.validate_not_empty], - "PROCESSORS": [processors.process_password], - "DEFAULT_VALUE": "PW_PLACEHOLDER", - "MASK_INPUT": True, - "LOOSE_VALIDATION": False, - "CONF_NAME": "CONFIG_KEYSTONE_DB_PW", - "USE_DEFAULT": False, - "NEED_CONFIRM": True, - "CONDITION": False}, + keystone_params = { + "KEYSTONE": [ # base keystone options + {"CMD_OPTION": "keystone-db-passwd", + "USAGE": "The password to use for the Keystone to access DB", + "PROMPT": "Enter the password for the Keystone DB access", + "OPTION_LIST": [], + "VALIDATORS": [validators.validate_not_empty], + "PROCESSORS": [processors.process_password], + "DEFAULT_VALUE": "PW_PLACEHOLDER", + "MASK_INPUT": True, + "LOOSE_VALIDATION": False, + "CONF_NAME": "CONFIG_KEYSTONE_DB_PW", + "USE_DEFAULT": False, + "NEED_CONFIRM": True, + "CONDITION": False}, - {"CMD_OPTION": "keystone-region", - "USAGE": "Region name", - "PROMPT": "Region name", - "OPTION_LIST": [], - "VALIDATORS": [validators.validate_not_empty], - "DEFAULT_VALUE": "RegionOne", - "MASK_INPUT": False, - "LOOSE_VALIDATION": False, - "CONF_NAME": "CONFIG_KEYSTONE_REGION", - "USE_DEFAULT": True, - "NEED_CONFIRM": False, - "CONDITION": False}, + {"CMD_OPTION": "keystone-region", + "USAGE": "Region name", + "PROMPT": "Region name", + "OPTION_LIST": [], + "VALIDATORS": [validators.validate_not_empty], + "DEFAULT_VALUE": "RegionOne", + "MASK_INPUT": False, + "LOOSE_VALIDATION": False, + "CONF_NAME": "CONFIG_KEYSTONE_REGION", + "USE_DEFAULT": True, + "NEED_CONFIRM": False, + "CONDITION": False}, - {"CMD_OPTION": "keystone-admin-token", - "USAGE": "The token to use for the Keystone service api", - "PROMPT": "The token to use for the Keystone service api", - "OPTION_LIST": [], - "VALIDATORS": [validators.validate_not_empty], - "DEFAULT_VALUE": uuid.uuid4().hex, - "MASK_INPUT": True, - "LOOSE_VALIDATION": False, - "CONF_NAME": "CONFIG_KEYSTONE_ADMIN_TOKEN", - "USE_DEFAULT": True, - "NEED_CONFIRM": False, - "CONDITION": False}, + {"CMD_OPTION": "keystone-admin-token", + "USAGE": "The token to use for the Keystone service api", + "PROMPT": "The token to use for the Keystone service api", + "OPTION_LIST": [], + "VALIDATORS": [validators.validate_not_empty], + "DEFAULT_VALUE": uuid.uuid4().hex, + "MASK_INPUT": True, + "LOOSE_VALIDATION": False, + "CONF_NAME": "CONFIG_KEYSTONE_ADMIN_TOKEN", + "USE_DEFAULT": True, + "NEED_CONFIRM": False, + "CONDITION": False}, - {"CMD_OPTION": "keystone-admin-passwd", - "USAGE": "The password to use for the Keystone admin user", - "PROMPT": "Enter the password for the Keystone admin user", - "OPTION_LIST": [], - "VALIDATORS": [validators.validate_not_empty], - "DEFAULT_VALUE": "PW_PLACEHOLDER", - "PROCESSORS": [processors.process_password], - "MASK_INPUT": True, - "LOOSE_VALIDATION": False, - "CONF_NAME": "CONFIG_KEYSTONE_ADMIN_PW", - "USE_DEFAULT": False, - "NEED_CONFIRM": True, - "CONDITION": False}, + {"CMD_OPTION": "keystone-admin-passwd", + "USAGE": "The password to use for the Keystone admin user", + "PROMPT": "Enter the password for the Keystone admin user", + "OPTION_LIST": [], + "VALIDATORS": [validators.validate_not_empty], + "DEFAULT_VALUE": "PW_PLACEHOLDER", + "PROCESSORS": [processors.process_password], + "MASK_INPUT": True, + "LOOSE_VALIDATION": False, + "CONF_NAME": "CONFIG_KEYSTONE_ADMIN_PW", + "USE_DEFAULT": False, + "NEED_CONFIRM": True, + "CONDITION": False}, - {"CMD_OPTION": "keystone-demo-passwd", - "USAGE": "The password to use for the Keystone demo user", - "PROMPT": "Enter the password for the Keystone demo user", - "OPTION_LIST": [], - "VALIDATORS": [validators.validate_not_empty], - "DEFAULT_VALUE": "PW_PLACEHOLDER", - "PROCESSORS": [processors.process_password], - "MASK_INPUT": True, - "LOOSE_VALIDATION": False, - "CONF_NAME": "CONFIG_KEYSTONE_DEMO_PW", - "USE_DEFAULT": False, - "NEED_CONFIRM": True, - "CONDITION": False}, + {"CMD_OPTION": "keystone-demo-passwd", + "USAGE": "The password to use for the Keystone demo user", + "PROMPT": "Enter the password for the Keystone demo user", + "OPTION_LIST": [], + "VALIDATORS": [validators.validate_not_empty], + "DEFAULT_VALUE": "PW_PLACEHOLDER", + "PROCESSORS": [processors.process_password], + "MASK_INPUT": True, + "LOOSE_VALIDATION": False, + "CONF_NAME": "CONFIG_KEYSTONE_DEMO_PW", + "USE_DEFAULT": False, + "NEED_CONFIRM": True, + "CONDITION": False}, - {"CMD_OPTION": "keystone-token-format", - "USAGE": "Kestone token format. Use either UUID or PKI", - "PROMPT": "Enter the Keystone token format.", - "OPTION_LIST": ['UUID', 'PKI'], - "VALIDATORS": [validators.validate_options], - "DEFAULT_VALUE": 'UUID', - "MASK_INPUT": False, - "LOOSE_VALIDATION": False, - "CONF_NAME": 'CONFIG_KEYSTONE_TOKEN_FORMAT', - "USE_DEFAULT": True, - "NEED_CONFIRM": False, - "CONDITION": False}, + {"CMD_OPTION": "keystone-token-format", + "USAGE": "Keystone token format. Use either UUID or PKI", + "PROMPT": "Enter the Keystone token format.", + "OPTION_LIST": ['UUID', 'PKI'], + "VALIDATORS": [validators.validate_options], + "DEFAULT_VALUE": 'UUID', + "MASK_INPUT": False, + "LOOSE_VALIDATION": False, + "CONF_NAME": 'CONFIG_KEYSTONE_TOKEN_FORMAT', + "USE_DEFAULT": True, + "NEED_CONFIRM": False, + "CONDITION": False}, - {"CMD_OPTION": "keystone-service-name", - "USAGE": "Name of service to use to run keystone (keystone or httpd)", - "PROMPT": "Enter the Keystone service name.", - "OPTION_LIST": ['keystone', 'httpd'], - "VALIDATORS": [validators.validate_options], - "DEFAULT_VALUE": "httpd", - "MASK_INPUT": False, - "LOOSE_VALIDATION": False, - "CONF_NAME": 'CONFIG_KEYSTONE_SERVICE_NAME', - "USE_DEFAULT": True, - "NEED_CONFIRM": False, - "CONDITION": False}, + {"CMD_OPTION": "keystone-service-name", + "USAGE": ( + "Name of service to use to run keystone (keystone or httpd)" + ), + "PROMPT": "Enter the Keystone service name.", + "OPTION_LIST": ['keystone', 'httpd'], + "VALIDATORS": [validators.validate_options], + "DEFAULT_VALUE": "httpd", + "MASK_INPUT": False, + "LOOSE_VALIDATION": False, + "CONF_NAME": 'CONFIG_KEYSTONE_SERVICE_NAME', + "USE_DEFAULT": True, + "NEED_CONFIRM": False, + "CONDITION": False}, + + {"CMD_OPTION": "keystone-identity-backend", + "USAGE": "Type of identity backend (sql or ldap)", + "PROMPT": "Enter the Keystone identity backend type.", + "OPTION_LIST": ['sql', 'ldap'], + "VALIDATORS": [validators.validate_options], + "DEFAULT_VALUE": "sql", + "MASK_INPUT": False, + "LOOSE_VALIDATION": False, + "CONF_NAME": 'CONFIG_KEYSTONE_IDENTITY_BACKEND', + "USE_DEFAULT": False, + "NEED_CONFIRM": False, + "CONDITION": False} + ], + + "KEYSTONE_LDAP": [ # keystone ldap identity backend options + {"CMD_OPTION": "keystone-ldap-url", + "USAGE": "Keystone LDAP backend URL", + "PROMPT": "Enter the Keystone LDAP backend URL.", + "OPTION_LIST": [], + "VALIDATORS": [validators.validate_ldap_url], + "DEFAULT_VALUE": host_to_ldap_url(utils.get_localhost_ip()), + "MASK_INPUT": False, + "LOOSE_VALIDATION": False, + "CONF_NAME": 'CONFIG_KEYSTONE_LDAP_URL', + "USE_DEFAULT": False, + "NEED_CONFIRM": False, + "CONDITION": False}, + + {"CMD_OPTION": "keystone-ldap-user-dn", + "USAGE": ( + "Keystone LDAP backend user DN. Used to bind to the LDAP " + "server when the LDAP server does not allow anonymous " + "authentication." + ), + "PROMPT": "Enter the Keystone LDAP user DN.", + "OPTION_LIST": [], + "VALIDATORS": [validators.validate_ldap_dn], + "DEFAULT_VALUE": "", + "MASK_INPUT": False, + "LOOSE_VALIDATION": False, + "CONF_NAME": 'CONFIG_KEYSTONE_LDAP_USER_DN', + "USE_DEFAULT": False, + "NEED_CONFIRM": False, + "CONDITION": False}, + + {"CMD_OPTION": "keystone-ldap-user-password", + "USAGE": "Keystone LDAP backend password for user DN", + "PROMPT": "Enter the Keystone LDAP user password.", + "OPTION_LIST": [], + "VALIDATORS": [], + "DEFAULT_VALUE": "", + "PROCESSORS": [processors.process_password], + "MASK_INPUT": True, + "LOOSE_VALIDATION": False, + "CONF_NAME": 'CONFIG_KEYSTONE_LDAP_USER_PASSWORD', + "USE_DEFAULT": False, + "NEED_CONFIRM": False, + "CONDITION": False}, + + {"CMD_OPTION": "keystone-ldap-suffix", + "USAGE": "Keystone LDAP backend base suffix", + "PROMPT": "Enter the Keystone LDAP suffix.", + "OPTION_LIST": [], + "VALIDATORS": [validators.validate_not_empty, + validators.validate_ldap_dn], + "DEFAULT_VALUE": "", + "MASK_INPUT": False, + "LOOSE_VALIDATION": False, + "CONF_NAME": 'CONFIG_KEYSTONE_LDAP_SUFFIX', + "USE_DEFAULT": False, + "NEED_CONFIRM": False, + "CONDITION": False}, + + {"CMD_OPTION": "keystone-ldap-query-scope", + "USAGE": "Keystone LDAP backend query scope (base, one, sub)", + "PROMPT": "Enter the Keystone LDAP query scope.", + "OPTION_LIST": ['base', 'one', 'sub'], + "VALIDATORS": [validators.validate_options], + "DEFAULT_VALUE": "one", + "MASK_INPUT": False, + "LOOSE_VALIDATION": False, + "CONF_NAME": 'CONFIG_KEYSTONE_LDAP_QUERY_SCOPE', + "USE_DEFAULT": False, + "NEED_CONFIRM": False, + "CONDITION": False}, + + {"CMD_OPTION": "keystone-ldap-page-size", + "USAGE": "Keystone LDAP backend query page size", + "PROMPT": "Enter the Keystone LDAP query page size.", + "OPTION_LIST": [], + "VALIDATORS": [validators.validate_integer], + "DEFAULT_VALUE": "-1", + "MASK_INPUT": False, + "LOOSE_VALIDATION": False, + "CONF_NAME": 'CONFIG_KEYSTONE_LDAP_PAGE_SIZE', + "USE_DEFAULT": False, + "NEED_CONFIRM": False, + "CONDITION": False}, + + {"CMD_OPTION": "keystone-ldap-user-subtree", + "USAGE": "Keystone LDAP backend user subtree", + "PROMPT": "Enter the Keystone LDAP user subtree.", + "OPTION_LIST": [], + "VALIDATORS": [validators.validate_not_empty, + validators.validate_ldap_dn], + "DEFAULT_VALUE": "", + "MASK_INPUT": False, + "LOOSE_VALIDATION": False, + "CONF_NAME": 'CONFIG_KEYSTONE_LDAP_USER_SUBTREE', + "USE_DEFAULT": False, + "NEED_CONFIRM": False, + "CONDITION": False}, + + {"CMD_OPTION": "keystone-ldap-user-filter", + "USAGE": "Keystone LDAP backend user query filter", + "PROMPT": "Enter the Keystone LDAP user query filter.", + "OPTION_LIST": [], + "VALIDATORS": [], + "DEFAULT_VALUE": "", + "MASK_INPUT": False, + "LOOSE_VALIDATION": False, + "CONF_NAME": 'CONFIG_KEYSTONE_LDAP_USER_FILTER', + "USE_DEFAULT": False, + "NEED_CONFIRM": False, + "CONDITION": False}, + + {"CMD_OPTION": "keystone-ldap-user-objectclass", + "USAGE": "Keystone LDAP backend user objectclass", + "PROMPT": "Enter the Keystone LDAP user objectclass.", + "OPTION_LIST": [], + "VALIDATORS": [], + "DEFAULT_VALUE": "", + "MASK_INPUT": False, + "LOOSE_VALIDATION": False, + "CONF_NAME": 'CONFIG_KEYSTONE_LDAP_USER_OBJECTCLASS', + "USE_DEFAULT": False, + "NEED_CONFIRM": False, + "CONDITION": False}, + + {"CMD_OPTION": "keystone-ldap-user-id-attribute", + "USAGE": "Keystone LDAP backend user ID attribute", + "PROMPT": "Enter the Keystone LDAP user ID attribute.", + "OPTION_LIST": [], + "VALIDATORS": [], + "DEFAULT_VALUE": "", + "MASK_INPUT": False, + "LOOSE_VALIDATION": False, + "CONF_NAME": 'CONFIG_KEYSTONE_LDAP_USER_ID_ATTRIBUTE', + "USE_DEFAULT": False, + "NEED_CONFIRM": False, + "CONDITION": False}, + + {"CMD_OPTION": "keystone-ldap-user-name-attribute", + "USAGE": "Keystone LDAP backend user name attribute", + "PROMPT": "Enter the Keystone LDAP user name attribute.", + "OPTION_LIST": [], + "VALIDATORS": [], + "DEFAULT_VALUE": "", + "MASK_INPUT": False, + "LOOSE_VALIDATION": False, + "CONF_NAME": 'CONFIG_KEYSTONE_LDAP_USER_NAME_ATTRIBUTE', + "USE_DEFAULT": False, + "NEED_CONFIRM": False, + "CONDITION": False}, + + {"CMD_OPTION": "keystone-ldap-user-mail-attribute", + "USAGE": "Keystone LDAP backend user email address attribute", + "PROMPT": "Enter the Keystone LDAP user email address attribute.", + "OPTION_LIST": [], + "VALIDATORS": [], + "DEFAULT_VALUE": "", + "MASK_INPUT": False, + "LOOSE_VALIDATION": False, + "CONF_NAME": 'CONFIG_KEYSTONE_LDAP_USER_MAIL_ATTRIBUTE', + "USE_DEFAULT": False, + "NEED_CONFIRM": False, + "CONDITION": False}, + + {"CMD_OPTION": "keystone-ldap-user-enabled-attribute", + "USAGE": "Keystone LDAP backend user enabled attribute", + "PROMPT": "Enter the Keystone LDAP user enabled attribute.", + "OPTION_LIST": [], + "VALIDATORS": [], + "DEFAULT_VALUE": "", + "MASK_INPUT": False, + "LOOSE_VALIDATION": False, + "CONF_NAME": 'CONFIG_KEYSTONE_LDAP_USER_ENABLED_ATTRIBUTE', + "USE_DEFAULT": False, + "NEED_CONFIRM": False, + "CONDITION": False}, + + {"CMD_OPTION": "keystone-ldap-user-enabled-mask", + "USAGE": ( + "Keystone LDAP backend - bit mask applied to " + "user enabled attribute" + ), + "PROMPT": "Enter the Keystone LDAP user enabled mask.", + "OPTION_LIST": [], + "VALIDATORS": [validators.validate_integer], + "DEFAULT_VALUE": "-1", + "MASK_INPUT": False, + "LOOSE_VALIDATION": False, + "CONF_NAME": 'CONFIG_KEYSTONE_LDAP_USER_ENABLED_MASK', + "USE_DEFAULT": False, + "NEED_CONFIRM": False, + "CONDITION": False}, + + {"CMD_OPTION": "keystone-ldap-user-enabled-default", + "USAGE": ( + "Keystone LDAP backend - value of enabled attribute which " + "indicates user is enabled" + ), + "PROMPT": "Enter the Keystone LDAP user enabled default.", + "OPTION_LIST": [], + "VALIDATORS": [], + "DEFAULT_VALUE": "TRUE", + "MASK_INPUT": False, + "LOOSE_VALIDATION": False, + "CONF_NAME": 'CONFIG_KEYSTONE_LDAP_USER_ENABLED_DEFAULT', + "USE_DEFAULT": False, + "NEED_CONFIRM": False, + "CONDITION": False}, + + {"CMD_OPTION": "keystone-ldap-user-enabled-invert", + "USAGE": "Keystone LDAP backend - users are disabled not enabled", + "PROMPT": "Enter the Keystone LDAP user enabled invert (n or y).", + "OPTION_LIST": ['n', 'y'], + "VALIDATORS": [validators.validate_options], + "DEFAULT_VALUE": 'n', + "MASK_INPUT": False, + "LOOSE_VALIDATION": False, + "CONF_NAME": 'CONFIG_KEYSTONE_LDAP_USER_ENABLED_INVERT', + "USE_DEFAULT": False, + "NEED_CONFIRM": False, + "CONDITION": False}, + + {"CMD_OPTION": "keystone-ldap-user-attribute-ignore", + "USAGE": ( + "Comma separated list of attributes stripped " + "from user entry upon update" + ), + "PROMPT": ( + "Enter the comma separated Keystone LDAP user " + "attributes to ignore." + ), + "OPTION_LIST": [], + "DEFAULT_VALUE": "", + "MASK_INPUT": False, + "LOOSE_VALIDATION": False, + "CONF_NAME": 'CONFIG_KEYSTONE_LDAP_USER_ATTRIBUTE_IGNORE', + "USE_DEFAULT": False, + "NEED_CONFIRM": False, + "CONDITION": False}, + + {"CMD_OPTION": "keystone-ldap-user-default-project-id-attribute", + "USAGE": ( + "Keystone LDAP attribute mapped to default_project_id " + "for users" + ), + "PROMPT": ( + "Enter the Keystone LDAP user default_project_id attribute." + ), + "OPTION_LIST": [], + "DEFAULT_VALUE": "", + "MASK_INPUT": False, + "LOOSE_VALIDATION": False, + "CONF_NAME": + 'CONFIG_KEYSTONE_LDAP_USER_DEFAULT_PROJECT_ID_ATTRIBUTE', + "USE_DEFAULT": False, + "NEED_CONFIRM": False, + "CONDITION": False}, + + {"CMD_OPTION": "keystone-ldap-user-allow-create", + "USAGE": ( + "Set to 'y' if you want to be able to create Keystone " + "users through the Keystone interface. Set to 'n' if you " + "will create directly in the LDAP backend." + ), + "PROMPT": ( + "Do you want to allow user create through Keystone (n or y)." + ), + "OPTION_LIST": ['n', 'y'], + "VALIDATORS": [validators.validate_options], + "DEFAULT_VALUE": 'n', + "MASK_INPUT": False, + "LOOSE_VALIDATION": False, + "CONF_NAME": 'CONFIG_KEYSTONE_LDAP_USER_ALLOW_CREATE', + "USE_DEFAULT": False, + "NEED_CONFIRM": False, + "CONDITION": False}, + + {"CMD_OPTION": "keystone-ldap-user-allow-update", + "USAGE": ( + "Set to 'y' if you want to be able to update Keystone " + "users through the Keystone interface. Set to 'n' if you " + "will update directly in the LDAP backend." + ), + "PROMPT": ( + "Do you want to allow user update through Keystone (n or y)." + ), + "OPTION_LIST": ['n', 'y'], + "VALIDATORS": [validators.validate_options], + "DEFAULT_VALUE": 'n', + "MASK_INPUT": False, + "LOOSE_VALIDATION": False, + "CONF_NAME": 'CONFIG_KEYSTONE_LDAP_USER_ALLOW_UPDATE', + "USE_DEFAULT": False, + "NEED_CONFIRM": False, + "CONDITION": False}, + + {"CMD_OPTION": "keystone-ldap-user-allow-delete", + "USAGE": ( + "Set to 'y' if you want to be able to delete Keystone " + "users through the Keystone interface. Set to 'n' if you " + "will delete directly in the LDAP backend." + ), + "PROMPT": ( + "Do you want to allow user delete through Keystone (n or y)." + ), + "OPTION_LIST": ['n', 'y'], + "VALIDATORS": [validators.validate_options], + "DEFAULT_VALUE": 'n', + "MASK_INPUT": False, + "LOOSE_VALIDATION": False, + "CONF_NAME": 'CONFIG_KEYSTONE_LDAP_USER_ALLOW_DELETE', + "USE_DEFAULT": False, + "NEED_CONFIRM": False, + "CONDITION": False}, + + {"CMD_OPTION": "keystone-ldap-user-pass-attribute", + "USAGE": "Keystone LDAP attribute mapped to password", + "PROMPT": "Enter the Keystone LDAP user password attribute.", + "OPTION_LIST": [], + "DEFAULT_VALUE": "", + "MASK_INPUT": False, + "LOOSE_VALIDATION": False, + "CONF_NAME": 'CONFIG_KEYSTONE_LDAP_USER_PASS_ATTRIBUTE', + "USE_DEFAULT": False, + "NEED_CONFIRM": False, + "CONDITION": False}, + + {"CMD_OPTION": "keystone-ldap-user-enabled-emulation-dn", + "USAGE": ( + "DN of the group entry to hold enabled users when " + "using enabled emulation." + ), + "PROMPT": "Enter the Keystone LDAP enabled emulation DN.", + "OPTION_LIST": [], + "VALIDATORS": [validators.validate_ldap_dn], + "DEFAULT_VALUE": "", + "MASK_INPUT": False, + "LOOSE_VALIDATION": False, + "CONF_NAME": 'CONFIG_KEYSTONE_LDAP_USER_ENABLED_EMULATION_DN', + "USE_DEFAULT": False, + "NEED_CONFIRM": False, + "CONDITION": False}, + + {"CMD_OPTION": "keystone-ldap-user-additional-attribute-mapping", + "USAGE": ( + 'List of additional LDAP attributes used for mapping ' + 'additional attribute mappings for users. Attribute ' + 'mapping format is :, where ' + 'ldap_attr is the attribute in the LDAP entry and ' + 'user_attr is the Identity API attribute.' + ), + "PROMPT": ( + "Enter the comma separated Keystone LDAP user additional " + "attribute mappings in the form " + "ldap_attr:user_attr[,ldap_attr:user_attr]...." + ), + "OPTION_LIST": [], + "DEFAULT_VALUE": "", + "MASK_INPUT": False, + "LOOSE_VALIDATION": False, + "CONF_NAME": + 'CONFIG_KEYSTONE_LDAP_USER_ADDITIONAL_ATTRIBUTE_MAPPING', + "USE_DEFAULT": False, + "NEED_CONFIRM": False, + "CONDITION": False}, + + {"CMD_OPTION": "keystone-ldap-group-subtree", + "USAGE": "Keystone LDAP backend group subtree", + "PROMPT": "Enter the Keystone LDAP group subtree.", + "OPTION_LIST": [], + "VALIDATORS": [validators.validate_not_empty, + validators.validate_ldap_dn], + "DEFAULT_VALUE": "", + "MASK_INPUT": False, + "LOOSE_VALIDATION": False, + "CONF_NAME": 'CONFIG_KEYSTONE_LDAP_GROUP_SUBTREE', + "USE_DEFAULT": False, + "NEED_CONFIRM": False, + "CONDITION": False}, + + {"CMD_OPTION": "keystone-ldap-group-filter", + "USAGE": "Keystone LDAP backend group query filter", + "PROMPT": "Enter the Keystone LDAP group query filter.", + "OPTION_LIST": [], + "VALIDATORS": [], + "DEFAULT_VALUE": "", + "MASK_INPUT": False, + "LOOSE_VALIDATION": False, + "CONF_NAME": 'CONFIG_KEYSTONE_LDAP_GROUP_FILTER', + "USE_DEFAULT": False, + "NEED_CONFIRM": False, + "CONDITION": False}, + + {"CMD_OPTION": "keystone-ldap-group-objectclass", + "USAGE": "Keystone LDAP backend group objectclass", + "PROMPT": "Enter the Keystone LDAP group objectclass.", + "OPTION_LIST": [], + "VALIDATORS": [], + "DEFAULT_VALUE": "", + "MASK_INPUT": False, + "LOOSE_VALIDATION": False, + "CONF_NAME": 'CONFIG_KEYSTONE_LDAP_GROUP_OBJECTCLASS', + "USE_DEFAULT": False, + "NEED_CONFIRM": False, + "CONDITION": False}, + + {"CMD_OPTION": "keystone-ldap-group-id-attribute", + "USAGE": "Keystone LDAP backend group ID attribute", + "PROMPT": "Enter the Keystone LDAP group ID attribute.", + "OPTION_LIST": [], + "VALIDATORS": [], + "DEFAULT_VALUE": "", + "MASK_INPUT": False, + "LOOSE_VALIDATION": False, + "CONF_NAME": 'CONFIG_KEYSTONE_LDAP_GROUP_ID_ATTRIBUTE', + "USE_DEFAULT": False, + "NEED_CONFIRM": False, + "CONDITION": False}, + + {"CMD_OPTION": "keystone-ldap-group-name-attribute", + "USAGE": "Keystone LDAP backend group name attribute", + "PROMPT": "Enter the Keystone LDAP group name attribute.", + "OPTION_LIST": [], + "VALIDATORS": [], + "DEFAULT_VALUE": "", + "MASK_INPUT": False, + "LOOSE_VALIDATION": False, + "CONF_NAME": 'CONFIG_KEYSTONE_LDAP_GROUP_NAME_ATTRIBUTE', + "USE_DEFAULT": False, + "NEED_CONFIRM": False, + "CONDITION": False}, + + {"CMD_OPTION": "keystone-ldap-group-member-attribute", + "USAGE": "Keystone LDAP backend group member attribute", + "PROMPT": "Enter the Keystone LDAP group member attribute.", + "OPTION_LIST": [], + "VALIDATORS": [], + "DEFAULT_VALUE": "", + "MASK_INPUT": False, + "LOOSE_VALIDATION": False, + "CONF_NAME": 'CONFIG_KEYSTONE_LDAP_GROUP_MEMBER_ATTRIBUTE', + "USE_DEFAULT": False, + "NEED_CONFIRM": False, + "CONDITION": False}, + + {"CMD_OPTION": "keystone-ldap-group-desc-attribute", + "USAGE": "Keystone LDAP backend group description attribute", + "PROMPT": "Enter the Keystone LDAP group description attribute.", + "OPTION_LIST": [], + "VALIDATORS": [], + "DEFAULT_VALUE": "", + "MASK_INPUT": False, + "LOOSE_VALIDATION": False, + "CONF_NAME": 'CONFIG_KEYSTONE_LDAP_GROUP_DESC_ATTRIBUTE', + "USE_DEFAULT": False, + "NEED_CONFIRM": False, + "CONDITION": False}, + + {"CMD_OPTION": "keystone-ldap-group-attribute-ignore", + "USAGE": ( + "Comma separated list of attributes stripped from " + "group entry upon update" + ), + "PROMPT": ( + "Enter the comma separated Keystone LDAP group " + "attributes to ignore." + ), + "OPTION_LIST": [], + "DEFAULT_VALUE": "", + "MASK_INPUT": False, + "LOOSE_VALIDATION": False, + "CONF_NAME": 'CONFIG_KEYSTONE_LDAP_GROUP_ATTRIBUTE_IGNORE', + "USE_DEFAULT": False, + "NEED_CONFIRM": False, + "CONDITION": False}, + + {"CMD_OPTION": "keystone-ldap-group-allow-create", + "USAGE": ( + "Set to 'y' if you want to be able to create Keystone " + "groups through the Keystone interface. Set to 'n' if you " + "will create directly in the LDAP backend." + ), + "PROMPT": ( + "Do you want to allow group create through Keystone (n or y)." + ), + "OPTION_LIST": ['n', 'y'], + "VALIDATORS": [validators.validate_options], + "DEFAULT_VALUE": 'n', + "MASK_INPUT": False, + "LOOSE_VALIDATION": False, + "CONF_NAME": 'CONFIG_KEYSTONE_LDAP_GROUP_ALLOW_CREATE', + "USE_DEFAULT": False, + "NEED_CONFIRM": False, + "CONDITION": False}, + + {"CMD_OPTION": "keystone-ldap-group-allow-update", + "USAGE": ( + "Set to 'y' if you want to be able to update Keystone " + "groups through the Keystone interface. Set to 'n' if you " + "will update directly in the LDAP backend." + ), + "PROMPT": ( + "Do you want to allow group update through Keystone (n or y)." + ), + "OPTION_LIST": ['n', 'y'], + "VALIDATORS": [validators.validate_options], + "DEFAULT_VALUE": 'n', + "MASK_INPUT": False, + "LOOSE_VALIDATION": False, + "CONF_NAME": 'CONFIG_KEYSTONE_LDAP_GROUP_ALLOW_UPDATE', + "USE_DEFAULT": False, + "NEED_CONFIRM": False, + "CONDITION": False}, + + {"CMD_OPTION": "keystone-ldap-group-allow-delete", + "USAGE": ( + "Set to 'y' if you want to be able to delete Keystone " + "groups through the Keystone interface. Set to 'n' if you " + "will delete directly in the LDAP backend." + ), + "PROMPT": ( + "Do you want to allow group delete through Keystone (n or y)." + ), + "OPTION_LIST": ['n', 'y'], + "VALIDATORS": [validators.validate_options], + "DEFAULT_VALUE": 'n', + "MASK_INPUT": False, + "LOOSE_VALIDATION": False, + "CONF_NAME": 'CONFIG_KEYSTONE_LDAP_GROUP_ALLOW_DELETE', + "USE_DEFAULT": False, + "NEED_CONFIRM": False, + "CONDITION": False}, + + {"CMD_OPTION": "keystone-ldap-group-additional-attribute-mapping", + "USAGE": ( + 'List of additional LDAP attributes used for mapping ' + 'additional attribute mappings for groups. Attribute ' + 'mapping format is :, where ' + 'ldap_attr is the attribute in the LDAP entry and ' + 'group_attr is the Identity API attribute.' + ), + "PROMPT": ( + "Enter the comma separated Keystone LDAP group additional " + "attribute mappings in the form " + "ldap_attr:group_attr[,ldap_attr:group_attr]...." + ), + "OPTION_LIST": [], + "DEFAULT_VALUE": "", + "MASK_INPUT": False, + "LOOSE_VALIDATION": False, + "CONF_NAME": + 'CONFIG_KEYSTONE_LDAP_GROUP_ADDITIONAL_ATTRIBUTE_MAPPING', + "USE_DEFAULT": False, + "NEED_CONFIRM": False, + "CONDITION": False}, + + {"CMD_OPTION": "keystone-ldap-use-tls", + "USAGE": "Should Keystone LDAP use TLS", + "PROMPT": ( + "Enable TLS for Keystone communicating with " + "LDAP servers (n or y)." + ), + "OPTION_LIST": ['n', 'y'], + "VALIDATORS": [validators.validate_options], + "DEFAULT_VALUE": 'n', + "MASK_INPUT": False, + "LOOSE_VALIDATION": False, + "CONF_NAME": 'CONFIG_KEYSTONE_LDAP_USE_TLS', + "USE_DEFAULT": False, + "NEED_CONFIRM": False, + "CONDITION": False}, + + {"CMD_OPTION": "keystone-ldap-tls-cacertdir", + "USAGE": "Keystone LDAP CA certificate directory", + "PROMPT": "CA Certificate directory for Keystone LDAP.", + "OPTION_LIST": [], + "DEFAULT_VALUE": "", + "MASK_INPUT": False, + "LOOSE_VALIDATION": False, + "CONF_NAME": 'CONFIG_KEYSTONE_LDAP_TLS_CACERTDIR', + "USE_DEFAULT": False, + "NEED_CONFIRM": False, + "CONDITION": False}, + + {"CMD_OPTION": "keystone-ldap-tls-cacertfile", + "USAGE": "Keystone LDAP CA certificate file", + "PROMPT": "CA Certificate file for Keystone LDAP.", + "OPTION_LIST": [], + "DEFAULT_VALUE": "", + "MASK_INPUT": False, + "LOOSE_VALIDATION": False, + "CONF_NAME": 'CONFIG_KEYSTONE_LDAP_TLS_CACERTFILE', + "USE_DEFAULT": False, + "NEED_CONFIRM": False, + "CONDITION": False}, + + {"CMD_OPTION": "keystone-ldap-tls-req-cert", + "USAGE": ( + "Keystone LDAP certificate checking strictness " + "(never, allow, demand)" + ), + "PROMPT": ( + "Keystone LDAP certificate checking strictness " + "(never, allow, demand)" + ), + "OPTION_LIST": ["never", "allow", "demand"], + "VALIDATORS": [validators.validate_options], + "DEFAULT_VALUE": "demand", + "MASK_INPUT": False, + "LOOSE_VALIDATION": False, + "CONF_NAME": 'CONFIG_KEYSTONE_LDAP_TLS_REQ_CERT', + "USE_DEFAULT": False, + "NEED_CONFIRM": False, + "CONDITION": False} + ] + } + + keystone_groups = [ + {"GROUP_NAME": "KEYSTONE", + "DESCRIPTION": "Keystone Config parameters", + "PRE_CONDITION": lambda x: 'yes', + "PRE_CONDITION_MATCH": "yes", + "POST_CONDITION": False, + "POST_CONDITION_MATCH": True}, + + {"GROUP_NAME": "KEYSTONE_LDAP", + "DESCRIPTION": "Keystone LDAP Identity Backend Config parameters", + "PRE_CONDITION": 'CONFIG_KEYSTONE_IDENTITY_BACKEND', + "PRE_CONDITION_MATCH": "ldap", + "POST_CONDITION": False, + "POST_CONDITION_MATCH": True} ] - group = {"GROUP_NAME": "KEYSTONE", - "DESCRIPTION": "Keystone Config parameters", - "PRE_CONDITION": lambda x: 'yes', - "PRE_CONDITION_MATCH": "yes", - "POST_CONDITION": False, - "POST_CONDITION_MATCH": True} - controller.addGroup(group, params) + for group in keystone_groups: + params = keystone_params[group["GROUP_NAME"]] + controller.addGroup(group, params) def initSequences(controller): keystonesteps = [ + {'title': + 'Fixing Keystone LDAP config parameters to be undef if empty', + 'functions': [munge_ldap_config_params]}, {'title': 'Adding Keystone manifest entries', 'functions': [create_manifest]}, ] @@ -135,8 +783,46 @@ def initSequences(controller): keystonesteps) +# ------------------------- helper functions ------------------------- + +def host_to_ldap_url(hostfqdn): + """Converts a host fqdn into an appropriate default + LDAP URL. + """ + return "ldap://%s" % hostfqdn + + # -------------------------- step functions -------------------------- +def munge_ldap_config_params(config, messages): + def is_bool(keyname): + return keyname in ( + 'CONFIG_KEYSTONE_LDAP_USER_ENABLED_INVERT', + 'CONFIG_KEYSTONE_LDAP_USER_ALLOW_CREATE', + 'CONFIG_KEYSTONE_LDAP_USER_ALLOW_UPDATE', + 'CONFIG_KEYSTONE_LDAP_USER_ALLOW_DELETE', + 'CONFIG_KEYSTONE_LDAP_GROUP_ALLOW_CREATE', + 'CONFIG_KEYSTONE_LDAP_GROUP_ALLOW_UPDATE', + 'CONFIG_KEYSTONE_LDAP_GROUP_ALLOW_DELETE', + 'CONFIG_KEYSTONE_LDAP_USE_TLS' + ) + + def yn_to_bool(val): + return {'n': False, 'y': True}.get(val, False) + + for key in config: + if not key.startswith('CONFIG_KEYSTONE_LDAP_'): + continue + if key in ('CONFIG_KEYSTONE_LDAP_PAGE_SIZE', + 'CONFIG_KEYSTONE_LDAP_USER_ENABLED_MASK'): + if config[key] == '-1': + config[key] = None + elif is_bool(key): + config[key] = yn_to_bool(config[key]) + elif config[key] == '': + config[key] = None + + def create_manifest(config, messages): manifestfile = "%s_keystone.pp" % config['CONFIG_CONTROLLER_HOST'] manifestdata = getManifestTemplate("keystone") diff --git a/packstack/puppet/modules/packstack/lib/puppet/parser/functions/hiera_undef.rb b/packstack/puppet/modules/packstack/lib/puppet/parser/functions/hiera_undef.rb new file mode 100644 index 000000000..cf6881895 --- /dev/null +++ b/packstack/puppet/modules/packstack/lib/puppet/parser/functions/hiera_undef.rb @@ -0,0 +1,21 @@ +# Copyright (c) 2013 puppet@camptocamp.com All rights reserved. + +# 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. + +module Puppet::Parser::Functions + newfunction(:hiera_undef, :type => :rvalue) do |*args| + require 'hiera_puppet' + key, override = HieraPuppet.parse_args(args) + HieraPuppet.lookup(key, :undef, self, override, :priority) + end +end diff --git a/packstack/puppet/templates/keystone.pp b/packstack/puppet/templates/keystone.pp index 7f04e541d..d4b61df99 100644 --- a/packstack/puppet/templates/keystone.pp +++ b/packstack/puppet/templates/keystone.pp @@ -40,6 +40,65 @@ keystone::resource::service_identity { 'keystone': configure_user_role => false, } +# default assignment driver is SQL +$assignment_driver = "keystone.assignment.backends.sql.Assignment" + +if hiera('CONFIG_KEYSTONE_IDENTITY_BACKEND') == 'ldap' { + + if hiera_undef('CONFIG_KEYSTONE_LDAP_USER_ENABLED_EMULATION_DN', undef) { + $user_enabled_emulation = true + } else { + $user_enabled_emulation = false + } + + # should be supported and enabled in the next release of puppet-keystone +# user_enabled_invert => hiera_undef('CONFIG_KEYSTONE_LDAP_USER_ENABLED_INVERT'), + class {"keystone::ldap": + url => hiera_undef('CONFIG_KEYSTONE_LDAP_URL', undef), + user => hiera_undef('CONFIG_KEYSTONE_LDAP_USER_DN', undef), + password => hiera_undef('CONFIG_KEYSTONE_LDAP_USER_PASSWORD', undef), + suffix => hiera_undef('CONFIG_KEYSTONE_LDAP_SUFFIX', undef), + query_scope => hiera_undef('CONFIG_KEYSTONE_LDAP_QUERY_SCOPE', undef), + page_size => hiera_undef('CONFIG_KEYSTONE_LDAP_PAGE_SIZE', undef), + user_tree_dn => hiera_undef('CONFIG_KEYSTONE_LDAP_USER_SUBTREE', undef), + user_filter => hiera_undef('CONFIG_KEYSTONE_LDAP_USER_FILTER', undef), + user_objectclass => hiera_undef('CONFIG_KEYSTONE_LDAP_USER_OBJECTCLASS', undef), + user_id_attribute => hiera_undef('CONFIG_KEYSTONE_LDAP_USER_ID_ATTRIBUTE', undef), + user_name_attribute => hiera_undef('CONFIG_KEYSTONE_LDAP_USER_NAME_ATTRIBUTE', undef), + user_mail_attribute => hiera_undef('CONFIG_KEYSTONE_LDAP_USER_MAIL_ATTRIBUTE', undef), + user_enabled_attribute => hiera_undef('CONFIG_KEYSTONE_LDAP_USER_ENABLED_ATTRIBUTE', undef), + user_enabled_mask => hiera_undef('CONFIG_KEYSTONE_LDAP_USER_ENABLED_MASK', undef), + user_enabled_default => hiera_undef('CONFIG_KEYSTONE_LDAP_USER_ENABLED_DEFAULT', undef), + user_attribute_ignore => hiera_undef('CONFIG_KEYSTONE_LDAP_USER_ATTRIBUTE_IGNORE', undef), + user_default_project_id_attribute => hiera_undef('CONFIG_KEYSTONE_LDAP_USER_DEFAULT_PROJECT_ID_ATTRIBUTE', undef), + user_allow_create => hiera_undef('CONFIG_KEYSTONE_LDAP_USER_ALLOW_CREATE', undef), + user_allow_update => hiera_undef('CONFIG_KEYSTONE_LDAP_USER_ALLOW_UPDATE', undef), + user_allow_delete => hiera_undef('CONFIG_KEYSTONE_LDAP_USER_ALLOW_DELETE', undef), + user_pass_attribute => hiera_undef('CONFIG_KEYSTONE_LDAP_USER_PASS_ATTRIBUTE', undef), + user_enabled_emulation => $user_enabled_emulation, + user_enabled_emulation_dn => hiera_undef('CONFIG_KEYSTONE_LDAP_USER_ENABLED_EMULATION_DN', undef), + user_additional_attribute_mapping => hiera_undef('CONFIG_KEYSTONE_LDAP_USER_ADDITIONAL_ATTRIBUTE_MAPPING', undef), + group_tree_dn => hiera_undef('CONFIG_KEYSTONE_LDAP_GROUP_SUBTREE', undef), + group_filter => hiera_undef('CONFIG_KEYSTONE_LDAP_GROUP_FILTER', undef), + group_objectclass => hiera_undef('CONFIG_KEYSTONE_LDAP_GROUP_OBJECTCLASS', undef), + group_id_attribute => hiera_undef('CONFIG_KEYSTONE_LDAP_GROUP_ID_ATTRIBUTE', undef), + group_name_attribute => hiera_undef('CONFIG_KEYSTONE_LDAP_GROUP_NAME_ATTRIBUTE', undef), + group_member_attribute => hiera_undef('CONFIG_KEYSTONE_LDAP_GROUP_MEMBER_ATTRIBUTE', undef), + group_desc_attribute => hiera_undef('CONFIG_KEYSTONE_LDAP_GROUP_DESC_ATTRIBUTE', undef), + group_attribute_ignore => hiera_undef('CONFIG_KEYSTONE_LDAP_GROUP_ATTRIBUTE_IGNORE', undef), + group_allow_create => hiera_undef('CONFIG_KEYSTONE_LDAP_GROUP_ALLOW_CREATE', undef), + group_allow_update => hiera_undef('CONFIG_KEYSTONE_LDAP_GROUP_ALLOW_UPDATE', undef), + group_allow_delete => hiera_undef('CONFIG_KEYSTONE_LDAP_GROUP_ALLOW_DELETE', undef), + group_additional_attribute_mapping => hiera_undef('CONFIG_KEYSTONE_LDAP_GROUP_ADDITIONAL_ATTRIBUTE_MAPPING', undef), + use_tls => hiera_undef('CONFIG_KEYSTONE_LDAP_USE_TLS', undef), + tls_cacertdir => hiera_undef('CONFIG_KEYSTONE_LDAP_TLS_CACERTDIR', undef), + tls_cacertfile => hiera_undef('CONFIG_KEYSTONE_LDAP_TLS_CACERTFILE', undef), + tls_req_cert => hiera_undef('CONFIG_KEYSTONE_LDAP_TLS_REQ_CERT', undef), + identity_driver => "keystone.identity.backends.ldap.Identity", + assignment_driver => $assignment_driver, + } +} + # Run token flush every minute (without output so we won't spam admins) cron { 'token-flush': ensure => 'present',