Bug 1347394 - keystone LDAP configuration chase_referrals is only accepted as integer when using domain_configurations_from_database
Summary: keystone LDAP configuration chase_referrals is only accepted as integer when ...
Keywords:
Status: CLOSED NOTABUG
Alias: None
Product: Red Hat OpenStack
Classification: Red Hat
Component: openstack-keystone
Version: 7.0 (Kilo)
Hardware: Unspecified
OS: Unspecified
unspecified
unspecified
Target Milestone: ---
: ---
Assignee: John Dennis
QA Contact: nlevinki
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2016-06-16 17:12 UTC by Andreas Karis
Modified: 2019-11-14 08:25 UTC (History)
3 users (show)

Fixed In Version:
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Environment:
Last Closed: 2016-06-24 18:17:42 UTC
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)

Description Andreas Karis 2016-06-16 17:12:10 UTC
Description of problem:
keystone LDAP configuration chase_referrals is only accepted as integer when using domain_configurations_from_database

Version-Release number of selected component (if applicable):
in OSP 7

How reproducible:
all the time

Steps to Reproduce:
Domain based configuration with domain_configurations_from_database set to true in keystone.conf.

So instead of having the configuration in the /etc/keystone/domain/keystone.domain.conf file it is uploaded into the database, this is done initially with the 'keystone-manage domain_config_upload'.

Unfortunately once it is updated the only way to change data is to modify it with curl.  To do that, you can use curl to get the OS_TOKEN and then run a curl command to make the change.  

The command to get the token:
curl -i -H "Content-Type: application/json" -d '
{ "auth": {
      "identity": {
         "methods": ["password"],
         "password": {
            "user": {
            "name": "'${OS_USERNAME}'",
            "domain": { "name": "Default" },
            "password": "'$OS_PASSWORD'"
            }
         }
      },
         "scope": {
            "project": {
            "name": "admin",
            "domain": { "name": "Default" }
         }
      }
   }
}' ${OS_AUTH_URL}/auth/tokens |grep X-Subject-Token:

Once I set the OS_TOKEN with the value from X-Subject-Token:
I run the following command to make the change, initially to "False":
curl -s -X PATCH -H "X-Auth-Token: $OS_TOKEN" -H "Content-Type: application/json" \
-d '
{
 "config": {
    "ldap": {
        "tls_cacertdir" : "/etc/pki/ca-trust/extracted/pem/",
		"chase_referrals": "False"
	}
 }
}' \
${OS_AUTH_URL}//v3/domains/ce954c66406e4f19b5cc28ce2eac8d0c/config/ldap

At that point I get the error described. 

 Received the error:
2016-06-15 12:45:18.482 3852 ERROR keystone.common.wsgi [-] invalid literal for int() with base 10: 'False'
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi Traceback (most recent call last):
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi   File "/usr/lib/python2.7/site-packages/keystone/common/wsgi.py", line 238, in __call__
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi     result = method(context, **params)
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi   File "/usr/lib/python2.7/site-packages/keystone/auth/controllers.py", line 377, in authenticate_for_token
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi     self.authenticate(context, auth_info, auth_context)
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi   File "/usr/lib/python2.7/site-packages/keystone/auth/controllers.py", line 502, in authenticate
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi     auth_context)
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi   File "/usr/lib/python2.7/site-packages/keystone/auth/plugins/password.py", line 35, in authenticate
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi     user_info = auth_plugins.UserAuthInfo.create(auth_payload, self.method)
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi   File "/usr/lib/python2.7/site-packages/keystone/auth/plugins/core.py", line 106, in create
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi     user_auth_info._validate_and_normalize_auth_data(auth_payload)
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi   File "/usr/lib/python2.7/site-packages/keystone/auth/plugins/core.py", line 174, in _validate_and_normalize_auth_data
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi     user_name, domain_ref['id'])
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi   File "/usr/lib/python2.7/site-packages/keystone/identity/core.py", line 342, in wrapper
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi     return f(self, *args, **kwargs)
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi   File "/usr/lib/python2.7/site-packages/keystone/identity/core.py", line 353, in wrapper
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi     return f(self, *args, **kwargs)
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi   File "/usr/lib/python2.7/site-packages/dogpile/cache/region.py", line 1040, in decorate
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi     should_cache_fn)
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi   File "/usr/lib/python2.7/site-packages/dogpile/cache/region.py", line 651, in get_or_create
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi     async_creator) as value:
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi   File "/usr/lib/python2.7/site-packages/dogpile/core/dogpile.py", line 158, in __enter__
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi     return self._enter()
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi   File "/usr/lib/python2.7/site-packages/dogpile/core/dogpile.py", line 98, in _enter
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi     generated = self._enter_create(createdtime)
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi   File "/usr/lib/python2.7/site-packages/dogpile/core/dogpile.py", line 149, in _enter_create
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi     created = self.creator()
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi   File "/usr/lib/python2.7/site-packages/dogpile/cache/region.py", line 619, in gen_value
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi     created_value = creator()
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi   File "/usr/lib/python2.7/site-packages/dogpile/cache/region.py", line 1036, in creator
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi     return fn(*arg, **kw)
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi   File "/usr/lib/python2.7/site-packages/keystone/identity/core.py", line 773, in get_user_by_name
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi     ref = driver.get_user_by_name(user_name, domain_id)
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi   File "/usr/lib/python2.7/site-packages/keystone/identity/backends/ldap.py", line 87, in get_user_by_name
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi     return self.user.filter_attributes(self.user.get_by_name(user_name))
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi   File "/usr/lib/python2.7/site-packages/keystone/common/ldap/core.py", line 1497, in get_by_name
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi     res = self.get_all(query)
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi   File "/usr/lib/python2.7/site-packages/keystone/common/ldap/core.py", line 1891, in get_all
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi     return super(EnabledEmuMixIn, self).get_all(ldap_filter)
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi   File "/usr/lib/python2.7/site-packages/keystone/common/ldap/core.py", line 1505, in get_all
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi     for x in self._ldap_get_all(ldap_filter)]
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi   File "/usr/lib/python2.7/site-packages/keystone/common/ldap/core.py", line 1459, in _ldap_get_all
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi     with self.get_connection() as conn:
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi   File "/usr/lib/python2.7/site-packages/keystone/common/ldap/core.py", line 1271, in get_connection
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi     pool_conn_lifetime=pool_conn_lifetime
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi   File "/usr/lib/python2.7/site-packages/keystone/common/ldap/core.py", line 886, in connect
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi     pool_conn_lifetime=pool_conn_lifetime)
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi   File "/usr/lib/python2.7/site-packages/keystone/common/ldap/core.py", line 704, in connect
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi     self.set_option(ldap.OPT_REFERRALS, int(chase_referrals))
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi ValueError: invalid literal for int() with base 10: 'False'
2016-06-15 12:45:18.482 3852 TRACE keystone.common.wsgi
2016-06-15 12:45:18.485 3852 INFO eventlet.wsgi.server [-] 10.199.8.34 - - [15/Jun/2016 12:45:18] "POST /v3/auth/tokens HTTP/1.1" 500 453 0.031947
2016-06-15 12:45:18.489 3852 DEBUG keystone.middleware.core [-] Auth token not in the request header. Will not build auth context. process_request /usr/lib/python2.7/site-packages/keystone/middleware/core.py:223

Then changed the value to be the integer value 0 (for false) via the command:
curl -s -X PATCH -H "X-Auth-Token: $OS_TOKEN" -H "Content-Type: application/json" \
-d '
{
 "config": {
    "ldap": {
        "tls_cacertdir" : "/etc/pki/ca-trust/extracted/pem/",
		"chase_referrals": 0
	}
 }
}' \
${OS_AUTH_URL}//v3/domains/ce954c66406e4f19b5cc28ce2eac8d0c/config/ldap

Now the script works and my issue that I was setting chase_referrals to False for is now resolved.  The reason I opened this case as I think there is a bug
from the /etc/keystone/keystone.conf file:
# Override the system's default referral chasing behavior for queries. (boolean
# value)
#chase_referrals = <None>

Since it is a boolean it should be true or false, however from the code it wants an integer.

From the code:
/usr/lib/python2.7/site-packages/keystone/common/ldap/core.py line 704:
       if chase_referrals is not None:
            self.set_option(ldap.OPT_REFERRALS, int(chase_referrals))

Comment 2 Andreas Karis 2016-06-17 00:59:53 UTC
This looks related to
https://bugzilla.redhat.com/show_bug.cgi?id=1343143

Comment 3 Andreas Karis 2016-06-20 15:28:24 UTC
"If you do false in lower case it works.  However, it is consistent to how other booleans are treated as a quick search group the output shows:

            "chase_referrals": false,
            "group_allow_create": "False",
            "group_allow_delete": "False",
            "group_allow_update": "False",
            "use_auth_pool": "false",
            "use_dumb_member": "False",
            "use_pool": "false",
            "use_tls": "True",
            "user_allow_create": "False",
            "user_allow_delete": "False",
            "user_allow_update": "False",


Note only chase_referrals appears to work that way."

Comment 4 John Dennis 2016-06-23 22:36:07 UTC
chase_referrals is a boolean. JSON has an explicit boolean type whose possible values are true or false. Note there is no quotation marks around these values! They are NOT strings!

Due to a historical quirk of how Python handles booleans Python will also accept an integer where zero has the truth value of false and non-zero has the truth value of true (just like in C and other languages).

The important point is they are not string values.

Many of the examples you cite a deprecated LDAP values. I suspect the only reason some boolean values will work as strings when they are used in LDAP, all values stored in LDAP are strings and there is Python code to convert booleans to and from strings when stored and read from LDAP respectively. But that is specific to values *in* LDAP, not to JSON interchange nor run time usage in other parts of keystone.

The bottom line is that you should have formatted your JSON as:

"chase_referrals": false


Note You need to log in before you can comment on or make changes to this bug.