Merge lp:~rlane/nova/lp681164 into lp:~hudson-openstack/nova/trunk

Proposed by Ryan Lane
Status: Merged
Approved by: Todd Willey
Approved revision: 394
Merged at revision: 548
Proposed branch: lp:~rlane/nova/lp681164
Merge into: lp:~hudson-openstack/nova/trunk
Diff against target: 177 lines (+53/-38)
1 file modified
nova/auth/ldapdriver.py (+53/-38)
To merge this branch: bzr merge lp:~rlane/nova/lp681164
Reviewer Review Type Date Requested Status
Todd Willey (community) Approve
Vish Ishaya (community) Approve
Review via email: mp+44930@code.launchpad.net

Description of the change

Changing DN creation to do searches for entries.

This change adds additional interoperability (as many directory servers and LDAP admins use cn, or another attribute, as the naming attribute). DN creation will incur a slight performance penalty for doing so, as DNs must be searched for now. User and project creation skip this performance penalty, as there is no need to search for an entry that is being created.

To post a comment you must log in.
Revision history for this message
Vish Ishaya (vishvananda) wrote :

lgtm.

Ryan, you might want to do a bzr whoami "Ryan Lane <valid email>" at some point so your commits actually have the right email address and are linked to your bzr account.

review: Approve
Revision history for this message
Ryan Lane (rlane) wrote :

Ah. Didn't know about that. Just did it. Want me to recommit this?

Revision history for this message
Vish Ishaya (vishvananda) wrote :

Up to you. You haven't been getting karma for any of your work :(

lp:~rlane/nova/lp681164 updated
394. By Ryan Lane

Merge from trunk

Revision history for this message
Ryan Lane (rlane) wrote :

Pushed a trunk merge. Hopefully my email address shows properly now :)

Revision history for this message
Todd Willey (xtoddx) wrote :

lg

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'nova/auth/ldapdriver.py'
2--- nova/auth/ldapdriver.py 2010-12-22 23:47:31 +0000
3+++ nova/auth/ldapdriver.py 2011-01-07 00:36:42 +0000
4@@ -117,8 +117,7 @@
5
6 def get_project(self, pid):
7 """Retrieve project by id"""
8- dn = 'cn=%s,%s' % (pid,
9- FLAGS.ldap_project_subtree)
10+ dn = self.__project_to_dn(pid)
11 attr = self.__find_object(dn, LdapDriver.project_pattern)
12 return self.__to_project(attr)
13
14@@ -226,7 +225,8 @@
15 ('description', [description]),
16 (LdapDriver.project_attribute, [manager_dn]),
17 ('member', members)]
18- self.conn.add_s('cn=%s,%s' % (name, FLAGS.ldap_project_subtree), attr)
19+ dn = self.__project_to_dn(name, search=False)
20+ self.conn.add_s(dn, attr)
21 return self.__to_project(dict(attr))
22
23 def modify_project(self, project_id, manager_uid=None, description=None):
24@@ -244,23 +244,22 @@
25 manager_dn))
26 if description:
27 attr.append((self.ldap.MOD_REPLACE, 'description', description))
28- self.conn.modify_s('cn=%s,%s' % (project_id,
29- FLAGS.ldap_project_subtree),
30- attr)
31+ dn = self.__project_to_dn(project_id)
32+ self.conn.modify_s(dn, attr)
33
34 def add_to_project(self, uid, project_id):
35 """Add user to project"""
36- dn = 'cn=%s,%s' % (project_id, FLAGS.ldap_project_subtree)
37+ dn = self.__project_to_dn(project_id)
38 return self.__add_to_group(uid, dn)
39
40 def remove_from_project(self, uid, project_id):
41 """Remove user from project"""
42- dn = 'cn=%s,%s' % (project_id, FLAGS.ldap_project_subtree)
43+ dn = self.__project_to_dn(project_id)
44 return self.__remove_from_group(uid, dn)
45
46 def is_in_project(self, uid, project_id):
47 """Check if user is in project"""
48- dn = 'cn=%s,%s' % (project_id, FLAGS.ldap_project_subtree)
49+ dn = self.__project_to_dn(project_id)
50 return self.__is_in_group(uid, dn)
51
52 def has_role(self, uid, role, project_id=None):
53@@ -300,7 +299,7 @@
54 roles.append(role)
55 return roles
56 else:
57- project_dn = 'cn=%s,%s' % (project_id, FLAGS.ldap_project_subtree)
58+ project_dn = self.__project_to_dn(project_id)
59 query = ('(&(&(objectclass=groupOfNames)(!%s))(member=%s))' %
60 (LdapDriver.project_pattern, self.__uid_to_dn(uid)))
61 roles = self.__find_objects(project_dn, query)
62@@ -333,7 +332,7 @@
63
64 def delete_project(self, project_id):
65 """Delete a project"""
66- project_dn = 'cn=%s,%s' % (project_id, FLAGS.ldap_project_subtree)
67+ project_dn = self.__project_to_dn(project_id)
68 self.__delete_roles(project_dn)
69 self.__delete_group(project_dn)
70
71@@ -365,9 +364,10 @@
72
73 def __get_ldap_user(self, uid):
74 """Retrieve LDAP user entry by id"""
75- attr = self.__find_object(self.__uid_to_dn(uid),
76- '(objectclass=novaUser)')
77- return attr
78+ dn = FLAGS.ldap_user_subtree
79+ query = ('(&(%s=%s)(objectclass=novaUser))' %
80+ (FLAGS.ldap_user_id_attribute, uid))
81+ return self.__find_object(dn, query)
82
83 def __find_object(self, dn, query=None, scope=None):
84 """Find an object by dn and query"""
85@@ -418,15 +418,13 @@
86 query = '(objectclass=groupOfNames)'
87 return self.__find_object(dn, query) is not None
88
89- @staticmethod
90- def __role_to_dn(role, project_id=None):
91+ def __role_to_dn(self, role, project_id=None):
92 """Convert role to corresponding dn"""
93 if project_id is None:
94 return FLAGS.__getitem__("ldap_%s" % role).value
95 else:
96- return 'cn=%s,cn=%s,%s' % (role,
97- project_id,
98- FLAGS.ldap_project_subtree)
99+ project_dn = self.__project_to_dn(project_id)
100+ return 'cn=%s,%s' % (role, project_dn)
101
102 def __create_group(self, group_dn, name, uid,
103 description, member_uids=None):
104@@ -532,6 +530,42 @@
105 for role_dn in self.__find_role_dns(project_dn):
106 self.__delete_group(role_dn)
107
108+ def __to_project(self, attr):
109+ """Convert ldap attributes to Project object"""
110+ if attr is None:
111+ return None
112+ member_dns = attr.get('member', [])
113+ return {
114+ 'id': attr['cn'][0],
115+ 'name': attr['cn'][0],
116+ 'project_manager_id':
117+ self.__dn_to_uid(attr[LdapDriver.project_attribute][0]),
118+ 'description': attr.get('description', [None])[0],
119+ 'member_ids': [self.__dn_to_uid(x) for x in member_dns]}
120+
121+ def __uid_to_dn(self, uid, search=True):
122+ """Convert uid to dn"""
123+ # By default return a generated DN
124+ userdn = (FLAGS.ldap_user_id_attribute + '=%s,%s'
125+ % (uid, FLAGS.ldap_user_subtree))
126+ if search:
127+ query = ('%s=%s' % (FLAGS.ldap_user_id_attribute, uid))
128+ user = self.__find_dns(FLAGS.ldap_user_subtree, query)
129+ if len(user) > 0:
130+ userdn = user[0]
131+ return userdn
132+
133+ def __project_to_dn(self, pid, search=True):
134+ """Convert pid to dn"""
135+ # By default return a generated DN
136+ projectdn = ('cn=%s,%s' % (pid, FLAGS.ldap_project_subtree))
137+ if search:
138+ query = ('(&(cn=%s)%s)' % (pid, LdapDriver.project_pattern))
139+ project = self.__find_dns(FLAGS.ldap_project_subtree, query)
140+ if len(project) > 0:
141+ projectdn = project[0]
142+ return projectdn
143+
144 @staticmethod
145 def __to_user(attr):
146 """Convert ldap attributes to User object"""
147@@ -548,30 +582,11 @@
148 else:
149 return None
150
151- def __to_project(self, attr):
152- """Convert ldap attributes to Project object"""
153- if attr is None:
154- return None
155- member_dns = attr.get('member', [])
156- return {
157- 'id': attr['cn'][0],
158- 'name': attr['cn'][0],
159- 'project_manager_id':
160- self.__dn_to_uid(attr[LdapDriver.project_attribute][0]),
161- 'description': attr.get('description', [None])[0],
162- 'member_ids': [self.__dn_to_uid(x) for x in member_dns]}
163-
164 @staticmethod
165 def __dn_to_uid(dn):
166 """Convert user dn to uid"""
167 return dn.split(',')[0].split('=')[1]
168
169- @staticmethod
170- def __uid_to_dn(uid):
171- """Convert uid to dn"""
172- return (FLAGS.ldap_user_id_attribute + '=%s,%s'
173- % (uid, FLAGS.ldap_user_subtree))
174-
175
176 class FakeLdapDriver(LdapDriver):
177 """Fake Ldap Auth driver"""